23 * questions. |
23 * questions. |
24 */ |
24 */ |
25 |
25 |
26 package jdk.internal.net.http; |
26 package jdk.internal.net.http; |
27 |
27 |
|
28 import java.io.IOException; |
|
29 import java.io.UncheckedIOException; |
|
30 import java.net.ConnectException; |
28 import java.net.InetSocketAddress; |
31 import java.net.InetSocketAddress; |
29 import java.net.URI; |
32 import java.net.URI; |
30 import java.util.Base64; |
33 import java.util.Base64; |
31 import java.util.Collections; |
34 import java.util.Collections; |
32 import java.util.HashSet; |
35 import java.util.HashSet; |
93 String key = Http2Connection.keyFor(uri, proxy); |
96 String key = Http2Connection.keyFor(uri, proxy); |
94 |
97 |
95 synchronized (this) { |
98 synchronized (this) { |
96 Http2Connection connection = connections.get(key); |
99 Http2Connection connection = connections.get(key); |
97 if (connection != null) { |
100 if (connection != null) { |
98 if (connection.closed || !connection.reserveStream(true)) { |
101 try { |
99 if (debug.on()) |
102 if (connection.closed || !connection.reserveStream(true)) { |
100 debug.log("removing found closed or closing connection: %s", connection); |
103 if (debug.on()) |
101 deleteConnection(connection); |
104 debug.log("removing found closed or closing connection: %s", connection); |
102 } else { |
105 deleteConnection(connection); |
103 // fast path if connection already exists |
106 } else { |
104 if (debug.on()) |
107 // fast path if connection already exists |
105 debug.log("found connection in the pool: %s", connection); |
108 if (debug.on()) |
106 return MinimalFuture.completedFuture(connection); |
109 debug.log("found connection in the pool: %s", connection); |
|
110 return MinimalFuture.completedFuture(connection); |
|
111 } |
|
112 } catch (IOException e) { |
|
113 // thrown by connection.reserveStream() |
|
114 return MinimalFuture.failedFuture(e); |
107 } |
115 } |
108 } |
116 } |
109 |
117 |
110 if (!req.secure() || failures.contains(key)) { |
118 if (!req.secure() || failures.contains(key)) { |
111 // secure: negotiate failed before. Use http/1.1 |
119 // secure: negotiate failed before. Use http/1.1 |
117 return Http2Connection |
125 return Http2Connection |
118 .createAsync(req, this) |
126 .createAsync(req, this) |
119 .whenComplete((conn, t) -> { |
127 .whenComplete((conn, t) -> { |
120 synchronized (Http2ClientImpl.this) { |
128 synchronized (Http2ClientImpl.this) { |
121 if (conn != null) { |
129 if (conn != null) { |
|
130 try { |
|
131 conn.reserveStream(true); |
|
132 } catch (IOException e) { |
|
133 throw new UncheckedIOException(e); // shouldn't happen |
|
134 } |
122 offerConnection(conn); |
135 offerConnection(conn); |
123 } else { |
136 } else { |
124 Throwable cause = Utils.getCompletionCause(t); |
137 Throwable cause = Utils.getCompletionCause(t); |
125 if (cause instanceof Http2Connection.ALPNException) |
138 if (cause instanceof Http2Connection.ALPNException) |
126 failures.add(key); |
139 failures.add(key); |