< prev index next >

src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java

Print this page
rev 54110 : 8244205: HTTP/2 tunnel connections through proxy may be reused regardless of which proxy is selected
Summary: The key used in the HTTP/2 connection pool is updated to take into account the proxy address in case of tunnel connections
Reviewed-by: chegar
   1 /*
   2  * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


 497                 })
 498                 .thenCompose(checkAlpnCF);
 499     }
 500 
 501     synchronized boolean finalStream() {
 502         return finalStream;
 503     }
 504 
 505     /**
 506      * Mark this connection so no more streams created on it and it will close when
 507      * all are complete.
 508      */
 509     synchronized void setFinalStream() {
 510         finalStream = true;
 511     }
 512 
 513     static String keyFor(HttpConnection connection) {
 514         boolean isProxy = connection.isProxied(); // tunnel or plain clear connection through proxy
 515         boolean isSecure = connection.isSecure();
 516         InetSocketAddress addr = connection.address();


 517 
 518         return keyString(isSecure, isProxy, addr.getHostString(), addr.getPort());
 519     }
 520 
 521     static String keyFor(URI uri, InetSocketAddress proxy) {
 522         boolean isSecure = uri.getScheme().equalsIgnoreCase("https");
 523         boolean isProxy = proxy != null;
 524 
 525         String host;
 526         int port;
 527 
 528         if (proxy != null && !isSecure) {
 529             // clear connection through proxy: use
 530             // proxy host / proxy port
 531             host = proxy.getHostString();
 532             port = proxy.getPort();
 533         } else {
 534             // either secure tunnel connection through proxy
 535             // or direct connection to host, but in either
 536             // case only that host can be reached through
 537             // the connection: use target host / target port
 538             host = uri.getHost();
 539             port = uri.getPort();
 540         }
 541         return keyString(isSecure, isProxy, host, port);
 542     }
 543 
 544     // {C,S}:{H:P}:host:port





 545     // C indicates clear text connection "http"
 546     // S indicates secure "https"
 547     // H indicates host (direct) connection
 548     // P indicates proxy
 549     // Eg: "S:H:foo.com:80"
 550     static String keyString(boolean secure, boolean proxy, String host, int port) {











 551         if (secure && port == -1)
 552             port = 443;
 553         else if (!secure && port == -1)
 554             port = 80;
 555         return (secure ? "S:" : "C:") + (proxy ? "P:" : "H:") + host + ":" + port;











 556     }
 557 
 558     String key() {
 559         return this.key;
 560     }
 561 
 562     boolean offerConnection() {
 563         return client2.offerConnection(this);
 564     }
 565 
 566     private HttpPublisher publisher() {
 567         return connection.publisher();
 568     }
 569 
 570     private void decodeHeaders(HeaderFrame frame, DecodingCallback decoder)
 571             throws IOException
 572     {
 573         if (debugHpack.on()) debugHpack.log("decodeHeaders(%s)", decoder);
 574 
 575         boolean endOfHeaders = frame.getFlag(HeaderFrame.END_HEADERS);


   1 /*
   2  * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


 497                 })
 498                 .thenCompose(checkAlpnCF);
 499     }
 500 
 501     synchronized boolean finalStream() {
 502         return finalStream;
 503     }
 504 
 505     /**
 506      * Mark this connection so no more streams created on it and it will close when
 507      * all are complete.
 508      */
 509     synchronized void setFinalStream() {
 510         finalStream = true;
 511     }
 512 
 513     static String keyFor(HttpConnection connection) {
 514         boolean isProxy = connection.isProxied(); // tunnel or plain clear connection through proxy
 515         boolean isSecure = connection.isSecure();
 516         InetSocketAddress addr = connection.address();
 517         InetSocketAddress proxyAddr = connection.proxy();
 518         assert isProxy == (proxyAddr != null);
 519 
 520         return keyString(isSecure, proxyAddr, addr.getHostString(), addr.getPort());
 521     }
 522 
 523     static String keyFor(URI uri, InetSocketAddress proxy) {
 524         boolean isSecure = uri.getScheme().equalsIgnoreCase("https");

 525 
 526         String host = uri.getHost();
 527         int port = uri.getPort();
 528         return keyString(isSecure, proxy, host, port);














 529     }
 530 
 531 
 532     // Compute the key for an HttpConnection in the Http2ClientImpl pool:
 533     // The key string follows one of the three forms below:
 534     //    {C,S}:H:host:port
 535     //    C:P:proxy-host:proxy-port
 536     //    S:T:H:host:port;P:proxy-host:proxy-port
 537     // C indicates clear text connection "http"
 538     // S indicates secure "https"
 539     // H indicates host (direct) connection
 540     // P indicates proxy
 541     // T indicates a tunnel connection through a proxy
 542     //
 543     // The first form indicates a direct connection to a server:
 544     //   - direct clear connection to an HTTP host:
 545     //     e.g.: "C:H:foo.com:80"
 546     //   - direct secure connection to an HTTPS host:
 547     //     e.g.: "S:H:foo.com:443"
 548     // The second form indicates a clear connection to an HTTP/1.1 proxy:
 549     //     e.g.: "C:P:myproxy:8080"
 550     // The third form indicates a secure tunnel connection to an HTTPS
 551     // host through an HTTP/1.1 proxy:
 552     //     e.g: "S:T:H:foo.com:80;P:myproxy:8080"
 553     static String keyString(boolean secure, InetSocketAddress proxy, String host, int port) {
 554         if (secure && port == -1)
 555             port = 443;
 556         else if (!secure && port == -1)
 557             port = 80;
 558         var key = (secure ? "S:" : "C:");
 559         if (proxy != null && !secure) {
 560             // clear connection through proxy
 561             key = key + "P:" + proxy.getHostString() + ":" + proxy.getPort();
 562         } else if (proxy == null) {
 563             // direct connection to host
 564             key = key + "H:" + host + ":" + port;
 565         } else {
 566             // tunnel connection through proxy
 567             key = key + "T:H:" + host + ":" + port + ";P:" + proxy.getHostString() + ":" + proxy.getPort();
 568         }
 569         return  key;
 570     }
 571 
 572     String key() {
 573         return this.key;
 574     }
 575 
 576     boolean offerConnection() {
 577         return client2.offerConnection(this);
 578     }
 579 
 580     private HttpPublisher publisher() {
 581         return connection.publisher();
 582     }
 583 
 584     private void decodeHeaders(HeaderFrame frame, DecodingCallback decoder)
 585             throws IOException
 586     {
 587         if (debugHpack.on()) debugHpack.log("decodeHeaders(%s)", decoder);
 588 
 589         boolean endOfHeaders = frame.getFlag(HeaderFrame.END_HEADERS);


< prev index next >