vtls: use ALPN HTTP/1.0 when HTTP/1.0 is used
Previously libcurl would use the HTTP/1.1 ALPN id even when the application specified HTTP/1.0. Reported-by: William Tang Ref: #10183
This commit is contained in:
Родитель
49f39dfac9
Коммит
df856cb5c9
|
@ -698,19 +698,25 @@ static CURLcode bearssl_connect_step1(struct Curl_cfilter *cf,
|
|||
* protocols array in `struct ssl_backend_data`.
|
||||
*/
|
||||
|
||||
#ifdef USE_HTTP2
|
||||
if(data->state.httpwant >= CURL_HTTP_VERSION_2
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
&& (!Curl_ssl_cf_is_proxy(cf) || !cf->conn->bits.tunnel_proxy)
|
||||
#endif
|
||||
) {
|
||||
backend->protocols[cur++] = ALPN_H2;
|
||||
infof(data, VTLS_INFOF_ALPN_OFFER_1STR, ALPN_H2);
|
||||
if(data->state.httpwant == CURL_HTTP_VERSION_1_0) {
|
||||
backend->protocols[cur++] = ALPN_HTTP_1_0;
|
||||
infof(data, VTLS_INFOF_ALPN_OFFER_1STR, ALPN_HTTP_1_0);
|
||||
}
|
||||
else {
|
||||
#ifdef USE_HTTP2
|
||||
if(data->state.httpwant >= CURL_HTTP_VERSION_2
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
&& (!Curl_ssl_cf_is_proxy(cf) || !cf->conn->bits.tunnel_proxy)
|
||||
#endif
|
||||
) {
|
||||
backend->protocols[cur++] = ALPN_H2;
|
||||
infof(data, VTLS_INFOF_ALPN_OFFER_1STR, ALPN_H2);
|
||||
}
|
||||
#endif
|
||||
|
||||
backend->protocols[cur++] = ALPN_HTTP_1_1;
|
||||
infof(data, VTLS_INFOF_ALPN_OFFER_1STR, ALPN_HTTP_1_1);
|
||||
backend->protocols[cur++] = ALPN_HTTP_1_1;
|
||||
infof(data, VTLS_INFOF_ALPN_OFFER_1STR, ALPN_HTTP_1_1);
|
||||
}
|
||||
|
||||
br_ssl_engine_set_protocol_names(&backend->ctx.eng,
|
||||
backend->protocols, cur);
|
||||
|
|
|
@ -704,23 +704,28 @@ gtls_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
|
|||
int cur = 0;
|
||||
gnutls_datum_t protocols[2];
|
||||
|
||||
#ifdef USE_HTTP2
|
||||
if(data->state.httpwant >= CURL_HTTP_VERSION_2
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
&& (!Curl_ssl_cf_is_proxy(cf) || !cf->conn->bits.tunnel_proxy)
|
||||
#endif
|
||||
) {
|
||||
protocols[cur].data = (unsigned char *)ALPN_H2;
|
||||
protocols[cur].size = ALPN_H2_LENGTH;
|
||||
cur++;
|
||||
infof(data, VTLS_INFOF_ALPN_OFFER_1STR, ALPN_H2);
|
||||
if(data->state.httpwant == CURL_HTTP_VERSION_1_0) {
|
||||
protocols[cur].data = (unsigned char *)ALPN_HTTP_1_0;
|
||||
protocols[cur++].size = ALPN_HTTP_1_0_LENGTH;
|
||||
infof(data, VTLS_INFOF_ALPN_OFFER_1STR, ALPN_HTTP_1_0);
|
||||
}
|
||||
else {
|
||||
#ifdef USE_HTTP2
|
||||
if(data->state.httpwant >= CURL_HTTP_VERSION_2
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
&& (!Curl_ssl_cf_is_proxy(cf) || !cf->conn->bits.tunnel_proxy)
|
||||
#endif
|
||||
) {
|
||||
protocols[cur].data = (unsigned char *)ALPN_H2;
|
||||
protocols[cur++].size = ALPN_H2_LENGTH;
|
||||
infof(data, VTLS_INFOF_ALPN_OFFER_1STR, ALPN_H2);
|
||||
}
|
||||
#endif
|
||||
|
||||
protocols[cur].data = (unsigned char *)ALPN_HTTP_1_1;
|
||||
protocols[cur].size = ALPN_HTTP_1_1_LENGTH;
|
||||
cur++;
|
||||
infof(data, VTLS_INFOF_ALPN_OFFER_1STR, ALPN_HTTP_1_1);
|
||||
protocols[cur].data = (unsigned char *)ALPN_HTTP_1_1;
|
||||
protocols[cur++].size = ALPN_HTTP_1_1_LENGTH;
|
||||
infof(data, VTLS_INFOF_ALPN_OFFER_1STR, ALPN_HTTP_1_1);
|
||||
}
|
||||
|
||||
if(gnutls_alpn_set_protocols(backend->gtls.session, protocols, cur, 0)) {
|
||||
failf(data, "failed setting ALPN");
|
||||
|
|
|
@ -650,11 +650,16 @@ mbed_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
|
|||
#ifdef HAS_ALPN
|
||||
if(cf->conn->bits.tls_enable_alpn) {
|
||||
const char **p = &backend->protocols[0];
|
||||
if(data->state.httpwant == CURL_HTTP_VERSION_1_0) {
|
||||
*p++ = ALPN_HTTP_1_0;
|
||||
}
|
||||
else {
|
||||
#ifdef USE_HTTP2
|
||||
if(data->state.httpwant >= CURL_HTTP_VERSION_2)
|
||||
*p++ = ALPN_H2;
|
||||
if(data->state.httpwant >= CURL_HTTP_VERSION_2)
|
||||
*p++ = ALPN_H2;
|
||||
#endif
|
||||
*p++ = ALPN_HTTP_1_1;
|
||||
*p++ = ALPN_HTTP_1_1;
|
||||
}
|
||||
*p = NULL;
|
||||
/* this function doesn't clone the protocols array, which is why we need
|
||||
to keep it around */
|
||||
|
|
|
@ -896,6 +896,10 @@ static void HandshakeCallback(PRFileDesc *sock, void *arg)
|
|||
!memcmp(ALPN_HTTP_1_1, buf, ALPN_HTTP_1_1_LENGTH)) {
|
||||
cf->conn->alpn = CURL_HTTP_VERSION_1_1;
|
||||
}
|
||||
else if(buflen == ALPN_HTTP_1_0_LENGTH &&
|
||||
!memcmp(ALPN_HTTP_1_0, buf, ALPN_HTTP_1_0_LENGTH)) {
|
||||
cf->conn->alpn = CURL_HTTP_VERSION_1_0;
|
||||
}
|
||||
|
||||
/* This callback might get called when PR_Recv() is used within
|
||||
* close_one() during a connection shutdown. At that point there might not
|
||||
|
@ -2167,20 +2171,27 @@ static CURLcode nss_setup_connect(struct Curl_cfilter *cf,
|
|||
int cur = 0;
|
||||
unsigned char protocols[128];
|
||||
|
||||
#ifdef USE_HTTP2
|
||||
if(data->state.httpwant >= CURL_HTTP_VERSION_2
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
&& (!Curl_ssl_cf_is_proxy(cf) || !cf->conn->bits.tunnel_proxy)
|
||||
#endif
|
||||
) {
|
||||
protocols[cur++] = ALPN_H2_LENGTH;
|
||||
memcpy(&protocols[cur], ALPN_H2, ALPN_H2_LENGTH);
|
||||
cur += ALPN_H2_LENGTH;
|
||||
if(data->state.httpwant == CURL_HTTP_VERSION_1_0) {
|
||||
protocols[cur++] = ALPN_HTTP_1_0_LENGTH;
|
||||
memcpy(&protocols[cur], ALPN_HTTP_1_0, ALPN_HTTP_1_0_LENGTH);
|
||||
cur += ALPN_HTTP_1_0_LENGTH;
|
||||
}
|
||||
else {
|
||||
#ifdef USE_HTTP2
|
||||
if(data->state.httpwant >= CURL_HTTP_VERSION_2
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
&& (!Curl_ssl_cf_is_proxy(cf) || !cf->conn->bits.tunnel_proxy)
|
||||
#endif
|
||||
protocols[cur++] = ALPN_HTTP_1_1_LENGTH;
|
||||
memcpy(&protocols[cur], ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH);
|
||||
cur += ALPN_HTTP_1_1_LENGTH;
|
||||
) {
|
||||
protocols[cur++] = ALPN_H2_LENGTH;
|
||||
memcpy(&protocols[cur], ALPN_H2, ALPN_H2_LENGTH);
|
||||
cur += ALPN_H2_LENGTH;
|
||||
}
|
||||
#endif
|
||||
protocols[cur++] = ALPN_HTTP_1_1_LENGTH;
|
||||
memcpy(&protocols[cur], ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH);
|
||||
cur += ALPN_HTTP_1_1_LENGTH;
|
||||
}
|
||||
|
||||
if(SSL_SetNextProtoNego(backend->handle, protocols, cur) != SECSuccess)
|
||||
goto error;
|
||||
|
|
|
@ -3642,25 +3642,32 @@ static CURLcode ossl_connect_step1(struct Curl_cfilter *cf,
|
|||
int cur = 0;
|
||||
unsigned char protocols[128];
|
||||
|
||||
#ifdef USE_HTTP2
|
||||
if(data->state.httpwant >= CURL_HTTP_VERSION_2
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
&& (!Curl_ssl_cf_is_proxy(cf) || !cf->conn->bits.tunnel_proxy)
|
||||
#endif
|
||||
) {
|
||||
protocols[cur++] = ALPN_H2_LENGTH;
|
||||
|
||||
memcpy(&protocols[cur], ALPN_H2, ALPN_H2_LENGTH);
|
||||
cur += ALPN_H2_LENGTH;
|
||||
infof(data, VTLS_INFOF_ALPN_OFFER_1STR, ALPN_H2);
|
||||
if(data->state.httpwant == CURL_HTTP_VERSION_1_0) {
|
||||
protocols[cur++] = ALPN_HTTP_1_0_LENGTH;
|
||||
memcpy(&protocols[cur], ALPN_HTTP_1_0, ALPN_HTTP_1_0_LENGTH);
|
||||
cur += ALPN_HTTP_1_0_LENGTH;
|
||||
infof(data, VTLS_INFOF_ALPN_OFFER_1STR, ALPN_HTTP_1_0);
|
||||
}
|
||||
else {
|
||||
#ifdef USE_HTTP2
|
||||
if(data->state.httpwant >= CURL_HTTP_VERSION_2
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
&& (!Curl_ssl_cf_is_proxy(cf) || !cf->conn->bits.tunnel_proxy)
|
||||
#endif
|
||||
) {
|
||||
protocols[cur++] = ALPN_H2_LENGTH;
|
||||
|
||||
memcpy(&protocols[cur], ALPN_H2, ALPN_H2_LENGTH);
|
||||
cur += ALPN_H2_LENGTH;
|
||||
infof(data, VTLS_INFOF_ALPN_OFFER_1STR, ALPN_H2);
|
||||
}
|
||||
#endif
|
||||
|
||||
protocols[cur++] = ALPN_HTTP_1_1_LENGTH;
|
||||
memcpy(&protocols[cur], ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH);
|
||||
cur += ALPN_HTTP_1_1_LENGTH;
|
||||
infof(data, VTLS_INFOF_ALPN_OFFER_1STR, ALPN_HTTP_1_1);
|
||||
|
||||
protocols[cur++] = ALPN_HTTP_1_1_LENGTH;
|
||||
memcpy(&protocols[cur], ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH);
|
||||
cur += ALPN_HTTP_1_1_LENGTH;
|
||||
infof(data, VTLS_INFOF_ALPN_OFFER_1STR, ALPN_HTTP_1_1);
|
||||
}
|
||||
/* expects length prefixed preference ordered list of protocols in wire
|
||||
* format
|
||||
*/
|
||||
|
|
|
@ -349,22 +349,40 @@ cr_init_backend(struct Curl_cfilter *cf, struct Curl_easy *data,
|
|||
char errorbuf[256];
|
||||
size_t errorlen;
|
||||
int result;
|
||||
rustls_slice_bytes alpn[2] = {
|
||||
{ (const uint8_t *)ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH },
|
||||
{ (const uint8_t *)ALPN_H2, ALPN_H2_LENGTH },
|
||||
};
|
||||
|
||||
DEBUGASSERT(backend);
|
||||
rconn = backend->conn;
|
||||
|
||||
config_builder = rustls_client_config_builder_new();
|
||||
if(data->state.httpwant == CURL_HTTP_VERSION_1_0) {
|
||||
rustls_slice_bytes alpn[] = {
|
||||
{ (const uint8_t *)ALPN_HTTP_1_0, ALPN_HTTP_1_0_LENGTH }
|
||||
};
|
||||
infof(data, VTLS_INFOF_ALPN_OFFER_1STR, ALPN_HTTP_1_0);
|
||||
rustls_client_config_builder_set_alpn_protocols(config_builder, alpn, 1);
|
||||
}
|
||||
else {
|
||||
rustls_slice_bytes alpn[2] = {
|
||||
{ (const uint8_t *)ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH },
|
||||
{ (const uint8_t *)ALPN_H2, ALPN_H2_LENGTH },
|
||||
};
|
||||
#ifdef USE_HTTP2
|
||||
infof(data, VTLS_INFOF_ALPN_OFFER_1STR, ALPN_H2);
|
||||
rustls_client_config_builder_set_alpn_protocols(config_builder, alpn, 2);
|
||||
#else
|
||||
rustls_client_config_builder_set_alpn_protocols(config_builder, alpn, 1);
|
||||
if(data->state.httpwant >= CURL_HTTP_VERSION_2
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
&& (!Curl_ssl_cf_is_proxy(cf) || !cf->conn->bits.tunnel_proxy)
|
||||
#endif
|
||||
infof(data, VTLS_INFOF_ALPN_OFFER_1STR, ALPN_HTTP_1_1);
|
||||
) {
|
||||
infof(data, VTLS_INFOF_ALPN_OFFER_1STR, ALPN_HTTP_1_1);
|
||||
infof(data, VTLS_INFOF_ALPN_OFFER_1STR, ALPN_H2);
|
||||
rustls_client_config_builder_set_alpn_protocols(config_builder, alpn, 2);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
infof(data, VTLS_INFOF_ALPN_OFFER_1STR, ALPN_HTTP_1_1);
|
||||
rustls_client_config_builder_set_alpn_protocols(config_builder, alpn, 1);
|
||||
}
|
||||
}
|
||||
if(!verifypeer) {
|
||||
rustls_client_config_builder_dangerous_set_certificate_verifier(
|
||||
config_builder, cr_verify_none);
|
||||
|
|
|
@ -1215,19 +1215,27 @@ schannel_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
|
|||
|
||||
list_start_index = cur;
|
||||
|
||||
#ifdef USE_HTTP2
|
||||
if(data->state.httpwant >= CURL_HTTP_VERSION_2) {
|
||||
alpn_buffer[cur++] = ALPN_H2_LENGTH;
|
||||
memcpy(&alpn_buffer[cur], ALPN_H2, ALPN_H2_LENGTH);
|
||||
cur += ALPN_H2_LENGTH;
|
||||
infof(data, VTLS_INFOF_ALPN_OFFER_1STR, ALPN_H2);
|
||||
if(data->state.httpwant == CURL_HTTP_VERSION_1_0) {
|
||||
alpn_buffer[cur++] = ALPN_HTTP_1_0_LENGTH;
|
||||
memcpy(&alpn_buffer[cur], ALPN_HTTP_1_0, ALPN_HTTP_1_0_LENGTH);
|
||||
cur += ALPN_HTTP_1_0_LENGTH;
|
||||
infof(data, VTLS_INFOF_ALPN_OFFER_1STR, ALPN_HTTP_1_0);
|
||||
}
|
||||
else {
|
||||
#ifdef USE_HTTP2
|
||||
if(data->state.httpwant >= CURL_HTTP_VERSION_2) {
|
||||
alpn_buffer[cur++] = ALPN_H2_LENGTH;
|
||||
memcpy(&alpn_buffer[cur], ALPN_H2, ALPN_H2_LENGTH);
|
||||
cur += ALPN_H2_LENGTH;
|
||||
infof(data, VTLS_INFOF_ALPN_OFFER_1STR, ALPN_H2);
|
||||
}
|
||||
#endif
|
||||
|
||||
alpn_buffer[cur++] = ALPN_HTTP_1_1_LENGTH;
|
||||
memcpy(&alpn_buffer[cur], ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH);
|
||||
cur += ALPN_HTTP_1_1_LENGTH;
|
||||
infof(data, VTLS_INFOF_ALPN_OFFER_1STR, ALPN_HTTP_1_1);
|
||||
alpn_buffer[cur++] = ALPN_HTTP_1_1_LENGTH;
|
||||
memcpy(&alpn_buffer[cur], ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH);
|
||||
cur += ALPN_HTTP_1_1_LENGTH;
|
||||
infof(data, VTLS_INFOF_ALPN_OFFER_1STR, ALPN_HTTP_1_1);
|
||||
}
|
||||
|
||||
*list_len = curlx_uitous(cur - list_start_index);
|
||||
*extension_len = *list_len + sizeof(unsigned int) + sizeof(unsigned short);
|
||||
|
|
|
@ -1790,20 +1790,25 @@ static CURLcode sectransp_connect_step1(struct Curl_cfilter *cf,
|
|||
CFMutableArrayRef alpnArr = CFArrayCreateMutable(NULL, 0,
|
||||
&kCFTypeArrayCallBacks);
|
||||
|
||||
#ifdef USE_HTTP2
|
||||
if(data->state.httpwant >= CURL_HTTP_VERSION_2
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
&& (!isproxy || !cf->conn->bits.tunnel_proxy)
|
||||
#endif
|
||||
) {
|
||||
CFArrayAppendValue(alpnArr, CFSTR(ALPN_H2));
|
||||
infof(data, VTLS_INFOF_ALPN_OFFER_1STR, ALPN_H2);
|
||||
if(data->state.httpwant == CURL_HTTP_VERSION_1_0) {
|
||||
CFArrayAppendValue(alpnArr, CFSTR(ALPN_HTTP_1_0));
|
||||
infof(data, VTLS_INFOF_ALPN_OFFER_1STR, ALPN_HTTP_1_0);
|
||||
}
|
||||
else {
|
||||
#ifdef USE_HTTP2
|
||||
if(data->state.httpwant >= CURL_HTTP_VERSION_2
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
&& (!isproxy || !cf->conn->bits.tunnel_proxy)
|
||||
#endif
|
||||
) {
|
||||
CFArrayAppendValue(alpnArr, CFSTR(ALPN_H2));
|
||||
infof(data, VTLS_INFOF_ALPN_OFFER_1STR, ALPN_H2);
|
||||
}
|
||||
#endif
|
||||
|
||||
CFArrayAppendValue(alpnArr, CFSTR(ALPN_HTTP_1_1));
|
||||
infof(data, VTLS_INFOF_ALPN_OFFER_1STR, ALPN_HTTP_1_1);
|
||||
|
||||
CFArrayAppendValue(alpnArr, CFSTR(ALPN_HTTP_1_1));
|
||||
infof(data, VTLS_INFOF_ALPN_OFFER_1STR, ALPN_HTTP_1_1);
|
||||
}
|
||||
/* expects length prefixed preference ordered list of protocols in wire
|
||||
* format
|
||||
*/
|
||||
|
|
|
@ -69,6 +69,8 @@ CURLsslset Curl_init_sslset_nolock(curl_sslbackend id, const char *name,
|
|||
/* see https://www.iana.org/assignments/tls-extensiontype-values/ */
|
||||
#define ALPN_HTTP_1_1_LENGTH 8
|
||||
#define ALPN_HTTP_1_1 "http/1.1"
|
||||
#define ALPN_HTTP_1_0_LENGTH 8
|
||||
#define ALPN_HTTP_1_0 "http/1.0"
|
||||
#define ALPN_H2_LENGTH 2
|
||||
#define ALPN_H2 "h2"
|
||||
|
||||
|
|
|
@ -640,16 +640,21 @@ wolfssl_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
|
|||
/* wolfSSL's ALPN protocol name list format is a comma separated string of
|
||||
protocols in descending order of preference, eg: "h2,http/1.1" */
|
||||
|
||||
#ifdef USE_HTTP2
|
||||
if(data->state.httpwant >= CURL_HTTP_VERSION_2) {
|
||||
strcpy(protocols + strlen(protocols), ALPN_H2 ",");
|
||||
infof(data, VTLS_INFOF_ALPN_OFFER_1STR, ALPN_H2);
|
||||
if(data->state.httpwant == CURL_HTTP_VERSION_1_0) {
|
||||
strcpy(protocols, ALPN_HTTP_1_0);
|
||||
infof(data, VTLS_INFOF_ALPN_OFFER_1STR, ALPN_HTTP_1_0);
|
||||
}
|
||||
else {
|
||||
#ifdef USE_HTTP2
|
||||
if(data->state.httpwant >= CURL_HTTP_VERSION_2) {
|
||||
strcpy(protocols + strlen(protocols), ALPN_H2 ",");
|
||||
infof(data, VTLS_INFOF_ALPN_OFFER_1STR, ALPN_H2);
|
||||
}
|
||||
#endif
|
||||
|
||||
strcpy(protocols + strlen(protocols), ALPN_HTTP_1_1);
|
||||
infof(data, VTLS_INFOF_ALPN_OFFER_1STR, ALPN_HTTP_1_1);
|
||||
|
||||
strcpy(protocols + strlen(protocols), ALPN_HTTP_1_1);
|
||||
infof(data, VTLS_INFOF_ALPN_OFFER_1STR, ALPN_HTTP_1_1);
|
||||
}
|
||||
if(wolfSSL_UseALPN(backend->handle, protocols,
|
||||
(unsigned)strlen(protocols),
|
||||
WOLFSSL_ALPN_CONTINUE_ON_MISMATCH) != SSL_SUCCESS) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче