1 module hunt.net.secure.conscrypt.ConscryptALPNSelector;
2 
3 // dfmt off
4 version(WITH_HUNT_SECURITY):
5 // dfmt on
6 
7 import hunt.net.secure.ProtocolSelector;
8 import hunt.net.secure.conscrypt.ApplicationProtocolSelector;
9 import hunt.net.secure.conscrypt.Conscrypt;
10 
11 import hunt.net.ssl.SSLEngine;
12 
13 
14 import hunt.text.Common;
15 import hunt.logging;
16 
17 
18 class ConscryptALPNSelector : ProtocolSelector {
19 
20     private string[] supportedProtocols;
21     private string[] supportedProtocolList;
22 
23     private SSLEngine sslEngine;
24 
25     this(SSLEngine sslEngine, string[] supportedProtocolList) {
26         if (supportedProtocolList is null) {
27             this.supportedProtocolList = ["h2", "http/1.1"];
28         } else {
29             this.supportedProtocolList = supportedProtocolList;
30         }
31         supportedProtocols = this.supportedProtocolList;
32         this.sslEngine = sslEngine;
33         if (sslEngine.getUseClientMode()) {
34             Conscrypt.setApplicationProtocols(sslEngine, supportedProtocols);
35         } else {
36             Conscrypt.setApplicationProtocolSelector(sslEngine, new ConscryptApplicationProtocolSelector());
37         }
38     }
39 
40     private class ConscryptApplicationProtocolSelector : ApplicationProtocolSelector {
41 
42         override
43         string selectApplicationProtocol(SSLEngine sslEngine, string[] protocols) {
44             return select(protocols);
45         }
46 
47         // override
48         // string selectApplicationProtocol(SSLSocket sslSocket, string[] protocols) {
49         //     return select(protocols);
50         // }
51 
52         string select(string[] clientProtocols) {
53             if (clientProtocols is null)
54                 return null;
55 
56             foreach (string p ; supportedProtocols) {
57                 if (clientProtocols.contains(p)) {
58                     tracef("ALPN local server selected protocol -> %s", p);
59                     return p;
60                 }
61             }
62 
63             return null;
64         }
65     }
66 
67     override
68     string getApplicationProtocol() {
69         return Conscrypt.getApplicationProtocol(sslEngine);
70     }
71 
72     override
73     string[] getSupportedApplicationProtocols() {
74         return supportedProtocolList;
75     }
76 }