|
1 | 1 | /*
|
2 |
| - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. |
| 2 | + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. |
3 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
4 | 4 | *
|
5 | 5 | * This code is free software; you can redistribute it and/or modify it
|
|
28 | 28 | import java.io.Closeable;
|
29 | 29 | import java.io.IOException;
|
30 | 30 | import java.net.InetSocketAddress;
|
| 31 | +import java.net.http.HttpResponse; |
31 | 32 | import java.nio.ByteBuffer;
|
32 | 33 | import java.nio.channels.SocketChannel;
|
33 | 34 | import java.util.Arrays;
|
|
39 | 40 | import java.util.concurrent.CompletionStage;
|
40 | 41 | import java.util.concurrent.ConcurrentLinkedDeque;
|
41 | 42 | import java.util.concurrent.Flow;
|
| 43 | +import java.util.concurrent.atomic.AtomicLong; |
42 | 44 | import java.util.function.BiPredicate;
|
43 | 45 | import java.util.function.Predicate;
|
44 | 46 | import java.net.http.HttpClient;
|
@@ -76,17 +78,46 @@ abstract class HttpConnection implements Closeable {
|
76 | 78 | public static final Comparator<HttpConnection> COMPARE_BY_ID
|
77 | 79 | = Comparator.comparing(HttpConnection::id);
|
78 | 80 |
|
| 81 | + private static final AtomicLong LABEL_COUNTER = new AtomicLong(); |
| 82 | + |
79 | 83 | /** The address this connection is connected to. Could be a server or a proxy. */
|
80 | 84 | final InetSocketAddress address;
|
81 | 85 | private final HttpClientImpl client;
|
82 | 86 | private final TrailingOperations trailingOperations;
|
| 87 | + |
| 88 | + /** |
| 89 | + * A unique identifier that provides a total order among instances. |
| 90 | + */ |
83 | 91 | private final long id;
|
84 | 92 |
|
85 |
| - HttpConnection(InetSocketAddress address, HttpClientImpl client) { |
| 93 | + /** |
| 94 | + * A label to identify the connection. |
| 95 | + * <p> |
| 96 | + * This label helps with associating multiple components participating in a |
| 97 | + * connection. For instance, an {@link AsyncSSLConnection} and the |
| 98 | + * {@link PlainHttpConnection} it wraps will share the same label. |
| 99 | + * </p> |
| 100 | + */ |
| 101 | + private final String label; |
| 102 | + |
| 103 | + HttpConnection(InetSocketAddress address, HttpClientImpl client, String label) { |
86 | 104 | this.address = address;
|
87 | 105 | this.client = client;
|
88 | 106 | trailingOperations = new TrailingOperations();
|
89 | 107 | this.id = newConnectionId(client);
|
| 108 | + this.label = label; |
| 109 | + } |
| 110 | + |
| 111 | + private static String nextLabel() { |
| 112 | + return "" + LABEL_COUNTER.incrementAndGet(); |
| 113 | + } |
| 114 | + |
| 115 | + /** |
| 116 | + * {@return a label identifying the connection to facilitate |
| 117 | + * {@link HttpResponse#connectionLabel() HttpResponse::connectionLabel}} |
| 118 | + */ |
| 119 | + public final String label() { |
| 120 | + return label; |
90 | 121 | }
|
91 | 122 |
|
92 | 123 | // This is overridden in tests
|
@@ -303,11 +334,13 @@ private static HttpConnection getSSLConnection(InetSocketAddress addr,
|
303 | 334 | String[] alpn,
|
304 | 335 | HttpRequestImpl request,
|
305 | 336 | HttpClientImpl client) {
|
| 337 | + String label = nextLabel(); |
306 | 338 | if (proxy != null)
|
307 | 339 | return new AsyncSSLTunnelConnection(addr, client, alpn, proxy,
|
308 |
| - proxyTunnelHeaders(request)); |
| 340 | + proxyTunnelHeaders(request), |
| 341 | + label); |
309 | 342 | else
|
310 |
| - return new AsyncSSLConnection(addr, client, alpn); |
| 343 | + return new AsyncSSLConnection(addr, client, alpn, label); |
311 | 344 | }
|
312 | 345 |
|
313 | 346 | /**
|
@@ -381,14 +414,16 @@ private static HttpConnection getPlainConnection(InetSocketAddress addr,
|
381 | 414 | InetSocketAddress proxy,
|
382 | 415 | HttpRequestImpl request,
|
383 | 416 | HttpClientImpl client) {
|
| 417 | + String label = nextLabel(); |
384 | 418 | if (request.isWebSocket() && proxy != null)
|
385 | 419 | return new PlainTunnelingConnection(addr, proxy, client,
|
386 |
| - proxyTunnelHeaders(request)); |
| 420 | + proxyTunnelHeaders(request), |
| 421 | + label); |
387 | 422 |
|
388 | 423 | if (proxy == null)
|
389 |
| - return new PlainHttpConnection(addr, client); |
| 424 | + return new PlainHttpConnection(addr, client, label); |
390 | 425 | else
|
391 |
| - return new PlainProxyConnection(proxy, client); |
| 426 | + return new PlainProxyConnection(proxy, client, label); |
392 | 427 | }
|
393 | 428 |
|
394 | 429 | void closeOrReturnToCache(HttpHeaders hdrs) {
|
|
0 commit comments