@@ -1573,6 +1573,35 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
15731573 }
15741574#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
15751575
1576+ #if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 ) && HAVE_BUILTIN_AVAILABLE == 1
1577+ if (conn -> bits .tls_enable_alpn ) {
1578+ if (__builtin_available (macOS 10.13 .4 , iOS 11 , * )) {
1579+ CFMutableArrayRef alpnArr = CFArrayCreateMutable (NULL , 0 ,
1580+ & kCFTypeArrayCallBacks );
1581+
1582+ #ifdef USE_NGHTTP2
1583+ if (data -> set .httpversion >= CURL_HTTP_VERSION_2 &&
1584+ (!SSL_IS_PROXY () || !conn -> bits .tunnel_proxy )) {
1585+ CFArrayAppendValue (alpnArr , CFSTR (NGHTTP2_PROTO_VERSION_ID ));
1586+ infof (data , "ALPN, offering %s\n" , NGHTTP2_PROTO_VERSION_ID );
1587+ }
1588+ #endif
1589+
1590+ CFArrayAppendValue (alpnArr , CFSTR (ALPN_HTTP_1_1 ));
1591+ infof (data , "ALPN, offering %s\n" , ALPN_HTTP_1_1 );
1592+
1593+ /* expects length prefixed preference ordered list of protocols in wire
1594+ * format
1595+ */
1596+ err = SSLSetALPNProtocols (BACKEND -> ssl_ctx , alpnArr );
1597+ if (err != noErr )
1598+ infof (data , "WARNING: failed to set ALPN protocols; OSStatus %d\n" ,
1599+ err );
1600+ CFRelease (alpnArr );
1601+ }
1602+ }
1603+ #endif
1604+
15761605 if (SSL_SET_OPTION (key )) {
15771606 infof (data , "WARNING: SSL: CURLOPT_SSLKEY is ignored by Secure "
15781607 "Transport. The private key must be in the Keychain.\n" );
@@ -2467,6 +2496,39 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex)
24672496 break ;
24682497 }
24692498
2499+ #if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 ) && HAVE_BUILTIN_AVAILABLE == 1
2500+ if (conn -> bits .tls_enable_alpn ) {
2501+ if (__builtin_available (macOS 10.13 .4 , iOS 11 , * )) {
2502+ CFArrayRef alpnArr = NULL ;
2503+ CFStringRef chosenProtocol = NULL ;
2504+ err = SSLCopyALPNProtocols (BACKEND -> ssl_ctx , & alpnArr );
2505+
2506+ if (err == noErr && alpnArr && CFArrayGetCount (alpnArr ) >= 1 )
2507+ chosenProtocol = CFArrayGetValueAtIndex (alpnArr , 0 );
2508+
2509+ #ifdef USE_NGHTTP2
2510+ if (chosenProtocol &&
2511+ !CFStringCompare (chosenProtocol , CFSTR (NGHTTP2_PROTO_VERSION_ID ),
2512+ 0 )) {
2513+ conn -> negnpn = CURL_HTTP_VERSION_2 ;
2514+ }
2515+ else
2516+ #endif
2517+ if (chosenProtocol &&
2518+ !CFStringCompare (chosenProtocol , CFSTR (ALPN_HTTP_1_1 ), 0 )) {
2519+ conn -> negnpn = CURL_HTTP_VERSION_1_1 ;
2520+ }
2521+ else
2522+ infof (data , "ALPN, server did not agree to a protocol\n" );
2523+
2524+ /* chosenProtocol is a reference to the string within alpnArr
2525+ and doesn't need to be freed separately */
2526+ if (alpnArr )
2527+ CFRelease (alpnArr );
2528+ }
2529+ }
2530+ #endif
2531+
24702532 return CURLE_OK ;
24712533 }
24722534}
0 commit comments