public class ALPNProtocolName
extends java.lang.Object
implements java.lang.Cloneable
ProtocolName
as used by the
TLS application_layer_protocol_negotiation extension
(see RFC 7301).
The application_layer_protocol_negotiation (ALPN) extension allows to negotiate the application layer protocol within the TLS handshake. For doing so the client sends an ALPN extension containing the names of the application layer protocols it supports (in preference order). The server compares the protocol names got from the client with its locally configured list and sends back an ALPN extension containing the first of its protocol names that matches to any of the protocol names received from the client. If the server does not support any of the client protocols it sends back a fatal "NO APPLICATION PROTOCOL" alert.
RFC 7301 defines an ALPN ProtocolName
as opaque, non-empty
byte string identifying the protocol name:
opaque ProtocolName<1..2^8-1>; struct { ProtocolName protocol_name_list<2..2^16-1> } ProtocolNameList;
When creating
an ALPNProtocolName
object the encoded and/or not encoded name value have to be specified, e.g.:
String protocolName = ...; byte[] encodedProtocolName = ...; ALPNProtocolName protocolName = new ALPNProtocolName(protocolName, encodedProtocolName);If the encoded name is not specified it is UTF-8 encoding before sent to the peer. If the name is not specified the encoded name is UTF-8 decoded.
For getting the (String or encoded) representation from a ALPNProtocolName
object, use method getName
or getEncodedName
, respectively, e.g.:
String name = protocolName.getName();
On the client side you will use the ALPNProtocolName
class
to build an ALPNProtocolNameList
to be sent to the
server. You can create ALPNProtocolName objects on your own or use any of the
predefined names e.g.:
// create protocol name list for http/1.1 and http/2 ALPNProtocolName[] protocolNames = { ALPNProtocolName.PN_HTTP_11, ALPNProtocolName.PN_H_2 }; ALPNProtocolNameList protocolNameList = new ALPNProtocolNameList(protocolNames); // add to ExtensionList ExtensionList extensions = new ExtensionList(); ... extensions.addExtension(protocolNameList); ... // set extensions for the SSLClientContext configuration: SSLClientContext clientContext = new SSLClientContext(); ... clientContext.setExtensions(extensions); ...When having finished the handshake you may get the negotiated protocol name by asking the SSLSocket for the ProtocolNameList included in the active extension list (extensions negotiated between client and server) or in the peer extension list (extensions got from the server). Since the server is only allowed to send an ALPN extension containing one protocol name only, the ALPNProtocolNameList got from the active extension list should be equal to the one got from the peer extension list (if the server has sent back an ALPN extension):
SSLContext clientContext = ...; ... // set extensions (including ALPN) ... String serverName = ...; int serverPort = ...; // create SSLSocket, perform handshake, e.g.: SSLSocket sslSocket = new SSLSocket(serverName, serverPort, clientContext); sslSocket.startHandshake(); ... // get ALPN extension and protocol name sent by the server: ExtensionList activeExtensions = socket.getActiveExtensions(); if (activeExtensions != null) { ALPNProtocolNameList protocolNameList = (ALPNProtocolNameList)activeExtensions.getExtension(ALPNProtocolNameList.TYPE); if (protocolNameList != null) { ALPNProtocolName[] protocolNames = protocolNameList.getProtocolNames(); System.out.println("Using ALPN protocol: " + protocolNames[0]); } }On the server side you may use the
ALPNProtocolName
class
to build an ALPNProtocolNameList
to tell
the server which protocol names may be accepted from the client e.g.:
// create protocol name list for http/1.1 and http/2 ALPNProtocolName[] protocolNames = { ALPNProtocolName.PN_HTTP_11, ALPNProtocolName.PN_H_2 }; ALPNProtocolNameList protocolNameList = new ALPNProtocolNameList(protocolNames); // add to ExtensionList ExtensionList extensions = new ExtensionList(); ... extensions.addExtension(protocolNameList); ... // set extensions for the SSLServerContext configuration: SSLServerContext serverContext = new SSLServerContext(); ... serverContext.setExtensions(extensions); ...
ALPNProtocolNameList
Modifier and Type | Field and Description |
---|---|
static ALPNProtocolName |
PN_H_2
ProtocolName http/2 (h2) (0x68 0x32).
|
static ALPNProtocolName |
PN_HTTP_11
ProtocolName http/1.1 (0x68 0x74 0x74 0x70 0x2f 0x31 0x2e 0x31).
|
static ALPNProtocolName |
PN_SPDY_1
ProtocolName spdy/1 (0x68 0x74 0x74 0x70 0x2f 0x31 0x2e 0x31).
|
static ALPNProtocolName |
PN_SPDY_2
ProtocolName spdy/2 (0x68 0x74 0x74 0x70 0x2f 0x31 0x2e 0x31).
|
Constructor and Description |
---|
ALPNProtocolName(byte[] encodedName)
Creates a new ALPN ProtocolName for the given encoded protocol name.
|
ALPNProtocolName(java.lang.String name)
Creates a new ALPN ProtocolName for the given protocol name.
|
ALPNProtocolName(java.lang.String name,
byte[] encodedName)
Creates a new ALPN ProtocolName from given name and encoded name.
|
Modifier and Type | Method and Description |
---|---|
java.lang.Object |
clone()
Gets a clone of this ProtocolName.
|
boolean |
equals(java.lang.Object obj)
Checks if this ProtocolName is equal to the given object.
|
byte[] |
getEncodedName()
Gets the encoded protocol name.
|
java.lang.String |
getName()
Gets the protocol name as String.
|
int |
hashCode()
Gets a hash code of this ProtocolName.
|
java.lang.String |
toString()
Gets a String representation of this ProtocolName.
|
public static final ALPNProtocolName PN_HTTP_11
public static final ALPNProtocolName PN_H_2
public static final ALPNProtocolName PN_SPDY_1
public static final ALPNProtocolName PN_SPDY_2
public ALPNProtocolName(byte[] encodedName)
encodedName
- the (e.g. UTF-8) encoded protocol name (identification sequence)
(the encodedName
byte array is not cloned or copied by this constructor)public ALPNProtocolName(java.lang.String name) throws java.io.UnsupportedEncodingException
name
- the protocol name as String (will be UTF-8 encoded)java.io.UnsupportedEncodingException
- if an error occurs
when trying to encode the namejava.lang.IllegalArgumentException
- if the given protocolName
represents an ipAddresspublic ALPNProtocolName(java.lang.String name, byte[] encodedName) throws java.io.UnsupportedEncodingException
Both name
and encodedName
are not allowed
to be null
. If encodedName
is null
the given name String is UTF-8 encoded.
If name
is null
this default implementation
tries to UTF-8 decode the given encoded name when method
is called.getName
name
- the protocol name as String; maybe null
if encodedName
is not null
encodedName
- the (e.g. UTF-8) encoded protocol name (identification sequence);
maybe null
if null
.
(the encodedName
array is not cloned or copied by this method)java.lang.IllegalArgumentException
- if encodedName is greater than 2^8-1,
or if name
and encodedName
are both null
java.io.UnsupportedEncodingException
- if an error occurs
when trying to encode the name (if encodedName
is null
)public java.lang.String getName() throws java.io.UnsupportedEncodingException
java.io.UnsupportedEncodingException
- if an error occurs
when trying to decode the protocol name to get its String
representation (if it has not been decoded so far)public byte[] getEncodedName() throws java.io.UnsupportedEncodingException
java.io.UnsupportedEncodingException
- if an error occurs
when trying to (UTF-8) encode the name (if it has
not been encoded yet)public int hashCode()
hashCode
in class java.lang.Object
public boolean equals(java.lang.Object obj)
equals
in class java.lang.Object
true
if this ProtocolName is equal to the
given object, false
if it is not equal
to itpublic java.lang.Object clone()
clone
in class java.lang.Object
public java.lang.String toString()
toString
in class java.lang.Object