1 module hunt.net.secure.conscrypt.ApplicationProtocolSelectorAdapter; 2 3 // dfmt off 4 version(WITH_HUNT_SECURITY): 5 // dfmt on 6 7 import hunt.net.secure.conscrypt.ApplicationProtocolSelector; 8 import hunt.net.secure.conscrypt.SSLUtils; 9 10 import hunt.net.ssl.SSLEngine; 11 12 13 import hunt.text.Common; 14 import std.array; 15 16 17 /** 18 * An adapter to bridge between the native code and the {@link ApplicationProtocolSelector} API. 19 */ 20 final class ApplicationProtocolSelectorAdapter { 21 private enum int NO_PROTOCOL_SELECTED = -1; 22 23 private SSLEngine engine; 24 // private SSLSocket socket; 25 private ApplicationProtocolSelector selector; 26 27 this(SSLEngine engine, ApplicationProtocolSelector selector) { 28 this.engine = engine; 29 // this.socket = null; 30 this.selector = selector; 31 } 32 33 // this(SSLSocket socket, ApplicationProtocolSelector selector) { 34 // this.engine = null; 35 // this.socket = socket; 36 // this.selector = selector; 37 // } 38 39 /** 40 * Performs the ALPN protocol selection from the given list of length-delimited peer protocols. 41 * @param encodedProtocols the peer protocols in length-delimited form. 42 * @return If successful, returns the offset into the {@code lenghPrefixedList} array of the 43 * selected protocol (i.e. points to the length prefix). Otherwise, returns 44 * {@link #NO_PROTOCOL_SELECTED}. 45 */ 46 int selectApplicationProtocol(ubyte[] encodedProtocols) { 47 if (encodedProtocols.length == 0) { 48 return NO_PROTOCOL_SELECTED; 49 } 50 51 // Decode the protocols. 52 string[] protocols = SSLUtils.decodeProtocols(encodedProtocols); 53 54 // Select the protocol. 55 string selected; 56 57 selected = selector.selectApplicationProtocol(engine, protocols); 58 if (selected.empty()) { 59 return NO_PROTOCOL_SELECTED; 60 } 61 62 int offset = 0; 63 foreach (string protocol ; protocols) { 64 if (selected.equals(protocol)) { 65 // Found the selected protocol. Return the index position of the beginning of 66 // the protocol. 67 return offset; 68 } 69 70 // Add 1 byte for the length prefix. 71 offset += 1 + cast(int)protocol.length; 72 } 73 74 return NO_PROTOCOL_SELECTED; 75 } 76 } 77