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 nullencodedName - 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 nulljava.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.Objectpublic boolean equals(java.lang.Object obj)
equals in class java.lang.Objecttrue 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.Objectpublic java.lang.String toString()
toString in class java.lang.Object