-
Notifications
You must be signed in to change notification settings - Fork 6.1k
8349910: Implement JEP 517: HTTP/3 for the HTTP Client API #24751
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
3759c87
26cc681
63c7bbe
7c19fc8
4da8dbd
4ca33f5
8793e84
816012c
68a5558
1492416
540c5d9
40cb71c
6e9226b
fd6ca77
bcd2073
892c089
fab8c39
84e0b6e
b224b9b
25d2614
e89450e
697b407
5c51a75
4dc27f2
bfa3c3c
386fbf2
2ff12fe
86e50bd
f2cef20
c8502d1
77ca235
e4c8bee
acfd90a
ff9c8b8
84f7a92
0d35650
25d7fbe
45c8b07
6ad3d75
1ef3b1a
a252f42
271f76c
3b32d58
e9aea03
c5af305
558c160
0d516bb
d529219
ba49221
3aacfdc
af4b739
0b9ef4b
46196fb
51561cc
4912ef6
d811e5b
275f998
d0cd7c9
a687b7e
131d88e
70e8c56
27f80cc
cf582fa
e199336
dad2cdb
495bf6d
f8aac7c
07225f3
d03baf0
dfdb940
357ddd3
5f8930f
4ae1032
6c565ca
b600f35
f65eb0c
0f40e41
9fa0498
743887c
7fd505f
2c4be89
221906d
762ca63
71cf354
c2bca64
a716629
0f79f19
b66923a
1b3df46
00499ee
5a8a9f7
e0d07a8
34b8dd8
b794f15
c24760a
1ee9368
5032548
0d46489
5408200
f0dad06
05d9ba1
4320954
d5b424d
678aa85
7e9e1cf
46c8e0b
aa0a51a
d10a1bc
1eab8c2
e4d2a0e
2be11a2
877f0f3
057f434
5011962
e2cb896
0f6e85e
372469b
6f613fe
07e5d70
d15d0a8
1a32b19
86996bd
9c2da66
116227c
6735141
40f2050
30828f4
31c135b
23ba22e
6cd6729
633375f
22b4560
b90b18d
4da61bb
c8d5df2
dfa2604
9156a51
d58b1f3
6137044
6dd2f96
a1e4547
e3c6aa7
b34c893
871b6b7
89cc2d2
eb896c4
8c27f53
9c6f625
f1f67ca
7390421
8e9793a
6df15ff
5c4a6a2
44e8a3b
2bc7fa4
e11998d
9f7f9e1
10e3e35
368f9b5
1b75ef8
df4898e
afbaf47
f750e8d
fe7054f
5267e8e
9d0ec22
36ca0a8
600d863
49a72f0
7dba9ca
dd8f0bc
9ae0a57
735c9b5
b96c730
bbfd501
aa42bef
4ed32d5
b81a559
6ce42f4
8782372
88f5315
9125717
ad0cf42
5a771d8
c6d648a
d363ab5
106b801
9d5bfcd
ee96f28
be31391
6611c82
31f5197
d7ff1de
bd817c0
007d95a
8110b31
87b7327
9449b90
8bbf552
4106b0f
74c27e9
2e8c2ab
8d53b08
78ed9c1
fc03aac
5605719
89dcc99
4ab2dba
ef465cf
f54fe26
0cfcecf
e9098e7
e4b3276
1e622ba
a90a440
fd1aef9
3a287f3
93a184e
1abbb7f
a41217f
e503537
99d3c1e
2cbb064
a5a0c7f
7c1f31d
2140d54
75bd7fb
ac6499c
4cee27b
c4bcb39
d4984d5
9f202c8
54a5ccb
dde844c
63e3662
cc26511
1875396
0863c7b
d4031c0
fefa748
70142b1
249858a
33de679
0843d3e
a33ea31
ea6cced
ca830ec
800b565
8f89ef4
0229c21
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
/* | ||
* Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. | ||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
* | ||
* This code is free software; you can redistribute it and/or modify it | ||
* under the terms of the GNU General Public License version 2 only, as | ||
* published by the Free Software Foundation. Oracle designates this | ||
* particular file as subject to the "Classpath" exception as provided | ||
* by Oracle in the LICENSE file that accompanied this code. | ||
* | ||
* This code is distributed in the hope that it will be useful, but WITHOUT | ||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
* version 2 for more details (a copy is included in the LICENSE file that | ||
* accompanied this code). | ||
* | ||
* You should have received a copy of the GNU General Public License version | ||
* 2 along with this work; if not, write to the Free Software Foundation, | ||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
* | ||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
* or visit www.oracle.com if you need additional information or have any | ||
* questions. | ||
*/ | ||
package jdk.internal.net.quic; | ||
|
||
|
||
import java.util.Objects; | ||
|
||
import jdk.internal.net.quic.QuicTLSEngine.KeySpace; | ||
|
||
/** | ||
* Thrown when an operation on {@link QuicTLSEngine} doesn't have the necessary | ||
* QUIC keys for encrypting or decrypting packets. This can either be because | ||
* the keys aren't available for a particular {@linkplain KeySpace keyspace} or | ||
* the keys for the {@code keyspace} have been discarded. | ||
*/ | ||
public final class QuicKeyUnavailableException extends Exception { | ||
@java.io.Serial | ||
private static final long serialVersionUID = 8553365136999153478L; | ||
|
||
public QuicKeyUnavailableException(final String message, final KeySpace keySpace) { | ||
super(Objects.requireNonNull(keySpace) + " keyspace: " + message); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
/* | ||
* Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. | ||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
* | ||
* This code is free software; you can redistribute it and/or modify it | ||
* under the terms of the GNU General Public License version 2 only, as | ||
* published by the Free Software Foundation. Oracle designates this | ||
* particular file as subject to the "Classpath" exception as provided | ||
* by Oracle in the LICENSE file that accompanied this code. | ||
* | ||
* This code is distributed in the hope that it will be useful, but WITHOUT | ||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
* version 2 for more details (a copy is included in the LICENSE file that | ||
* accompanied this code). | ||
* | ||
* You should have received a copy of the GNU General Public License version | ||
* 2 along with this work; if not, write to the Free Software Foundation, | ||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
* | ||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
* or visit www.oracle.com if you need additional information or have any | ||
* questions. | ||
*/ | ||
package jdk.internal.net.quic; | ||
|
||
/** | ||
* Supplies contextual 1-RTT information that's available in the QUIC implementation of the | ||
* {@code java.net.http} module, to the QUIC TLS layer in the {@code java.base} module. | ||
*/ | ||
public interface QuicOneRttContext { | ||
|
||
/** | ||
* {@return the largest packet number that was acknowledged by | ||
* the peer in the 1-RTT packet space} | ||
*/ | ||
long getLargestPeerAckedPN(); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
/* | ||
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. | ||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
* | ||
* This code is free software; you can redistribute it and/or modify it | ||
* under the terms of the GNU General Public License version 2 only, as | ||
* published by the Free Software Foundation. Oracle designates this | ||
* particular file as subject to the "Classpath" exception as provided | ||
* by Oracle in the LICENSE file that accompanied this code. | ||
* | ||
* This code is distributed in the hope that it will be useful, but WITHOUT | ||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
* version 2 for more details (a copy is included in the LICENSE file that | ||
* accompanied this code). | ||
* | ||
* You should have received a copy of the GNU General Public License version | ||
* 2 along with this work; if not, write to the Free Software Foundation, | ||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
* | ||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
* or visit www.oracle.com if you need additional information or have any | ||
* questions. | ||
*/ | ||
package jdk.internal.net.quic; | ||
|
||
import java.lang.invoke.MethodHandles; | ||
import java.lang.invoke.VarHandle; | ||
import java.util.Arrays; | ||
import java.util.Objects; | ||
|
||
import javax.net.ssl.SSLContext; | ||
import javax.net.ssl.SSLContextSpi; | ||
import javax.net.ssl.SSLParameters; | ||
|
||
import sun.security.ssl.QuicTLSEngineImpl; | ||
import sun.security.ssl.SSLContextImpl; | ||
|
||
/** | ||
* Instances of this class act as a factory for creation | ||
* of {@link QuicTLSEngine QUIC TLS engine}. | ||
*/ | ||
public final class QuicTLSContext { | ||
|
||
// In this implementation, we have a dependency on | ||
// sun.security.ssl.SSLContextImpl. We can only support | ||
// Quic on SSLContext instances created by the default | ||
// SunJSSE Provider | ||
private final SSLContextImpl sslCtxImpl; | ||
|
||
/** | ||
* {@return {@code true} if the given {@code sslContext} supports QUIC TLS, {@code false} otherwise} | ||
* @param sslContext an {@link SSLContext} | ||
*/ | ||
public static boolean isQuicCompatible(final SSLContext sslContext) { | ||
boolean parametersSupported = isQuicCompatible(sslContext.getSupportedSSLParameters()); | ||
if (!parametersSupported) { | ||
return false; | ||
} | ||
// horrible hack - what we do here is try and get hold of a SSLContext | ||
// that has already been initialised and configured with the HttpClient. | ||
// We see if that SSLContext is created using an implementation of | ||
// sun.security.ssl.SSLContextImpl. Since there's no API | ||
// available to get hold of that underlying implementation, we use | ||
// MethodHandle lookup to get access to the field which holds that | ||
// detail. | ||
final Object underlyingImpl = CONTEXT_SPI.get(sslContext); | ||
if (!(underlyingImpl instanceof SSLContextImpl ssci)) { | ||
return false; | ||
} | ||
return ssci.isUsableWithQuic(); | ||
} | ||
|
||
/** | ||
* {@return {@code true} if protocols of the given {@code parameters} support QUIC TLS, {@code false} otherwise} | ||
*/ | ||
public static boolean isQuicCompatible(SSLParameters parameters) { | ||
String[] protocols = parameters.getProtocols(); | ||
return protocols != null && Arrays.asList(protocols).contains("TLSv1.3"); | ||
} | ||
|
||
private static SSLContextImpl getSSLContextImpl( | ||
final SSLContext sslContext) { | ||
final Object underlyingImpl = CONTEXT_SPI.get(sslContext); | ||
assert underlyingImpl instanceof SSLContextImpl; | ||
return (SSLContextImpl) underlyingImpl; | ||
} | ||
|
||
/** | ||
* Constructs a QuicTLSContext for the given {@code sslContext} | ||
* | ||
* @param sslContext The SSLContext | ||
* @throws IllegalArgumentException If the passed {@code sslContext} isn't | ||
* supported by the QuicTLSContext | ||
* @see #isQuicCompatible(SSLContext) | ||
*/ | ||
public QuicTLSContext(final SSLContext sslContext) { | ||
Objects.requireNonNull(sslContext); | ||
if (!isQuicCompatible(sslContext)) { | ||
throw new IllegalArgumentException( | ||
"Cannot construct a QUIC TLS context with the given SSLContext"); | ||
} | ||
this.sslCtxImpl = getSSLContextImpl(sslContext); | ||
} | ||
|
||
/** | ||
* Creates a {@link QuicTLSEngine} using this context | ||
* <p> | ||
* This method does not provide hints for session caching. | ||
* | ||
* @return the newly created QuicTLSEngine | ||
*/ | ||
public QuicTLSEngine createEngine() { | ||
return createEngine(null, -1); | ||
} | ||
|
||
/** | ||
* Creates a {@link QuicTLSEngine} using this context using | ||
* advisory peer information. | ||
* <p> | ||
* The provided parameters will be used as hints for session caching. | ||
* The {@code peerHost} parameter will be used in the server_name extension, | ||
* unless overridden later. | ||
* | ||
* @param peerHost The peer hostname or IP address. Can be null. | ||
* @param peerPort The peer port, can be -1 if the port is unknown | ||
Comment on lines
+125
to
+126
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would that be the hostname in the URI, or in the AltService? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well the javadoc here was written to match the one on SSLContext#createSSLEngine. The peer information is used for caching, but it's also used in the SNI extension, so ideally users should use the URI address, not the alt service one. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK. Maybe that would deserve a note - since with HTTP/3 we have potentially two addresses and two ports. |
||
* @return the newly created QuicTLSEngine | ||
*/ | ||
public QuicTLSEngine createEngine(final String peerHost, final int peerPort) { | ||
return new QuicTLSEngineImpl(this.sslCtxImpl, peerHost, peerPort); | ||
} | ||
|
||
// This VarHandle is used to access the SSLContext::contextSpi | ||
// field which is not publicly accessible. | ||
// In this implementation, Quic is only supported for SSLContext | ||
// instances whose underlying implementation is provided by a | ||
// sun.security.ssl.SSLContextImpl | ||
private static final VarHandle CONTEXT_SPI; | ||
static { | ||
try { | ||
final MethodHandles.Lookup lookup = | ||
MethodHandles.privateLookupIn(SSLContext.class, | ||
MethodHandles.lookup()); | ||
final VarHandle vh = lookup.findVarHandle(SSLContext.class, | ||
"contextSpi", SSLContextSpi.class); | ||
CONTEXT_SPI = vh; | ||
} catch (Exception x) { | ||
throw new ExceptionInInitializerError(x); | ||
} | ||
} | ||
} | ||
|
Uh oh!
There was an error while loading. Please reload this page.