http_proxy: fix adding custom proxy headers
No binary (build failed)
—
(log yok)
| @@ -48,18 +48,11 @@ | |
| #include "curl_memory.h" | |
| #include "memdebug.h" | |
| - | static bool hd_name_eq(const char *n1, size_t n1len, |
| - | const char *n2, size_t n2len) |
| - | { |
| - | return (n1len == n2len) ? curl_strnequal(n1, n2, n1len) : FALSE; |
| - | } |
| - | |
| static CURLcode dynhds_add_custom(struct Curl_easy *data, | |
| bool is_connect, int httpversion, | |
| struct dynhds *hds) | |
| { | |
| struct connectdata *conn = data->conn; | |
| - | const char *ptr; |
| struct curl_slist *h[2]; | |
| struct curl_slist *headers; | |
| int numlists = 1; /* by default */ | |
| @@ -95,86 +88,76 @@ static CURLcode dynhds_add_custom(struct Curl_easy *data, | |
| /* loop through one or two lists */ | |
| for(i = 0; i < numlists; i++) { | |
| for(headers = h[i]; headers; headers = headers->next) { | |
| - | const char *name, *value; |
| - | size_t namelen, valuelen; |
| + | struct Curl_str name; |
| + | const char *value = NULL; |
| + | size_t valuelen = 0; |
| + | const char *ptr = headers->data; |
| /* There are 2 quirks in place for custom headers: | |
| * 1. setting only 'name:' to suppress a header from being sent | |
| * 2. setting only 'name;' to send an empty (illegal) header | |
| */ | |
| - | ptr = strchr(headers->data, ':'); |
| - | if(ptr) { |
| - | name = headers->data; |
| - | namelen = ptr - headers->data; |
| - | ptr++; /* pass the colon */ |
| - | curlx_str_passblanks(&ptr); |
| - | if(*ptr) { |
| - | value = ptr; |
| - | valuelen = strlen(value); |
| + | if(!curlx_str_cspn(&ptr, &name, ";:")) { |
| + | if(!curlx_str_single(&ptr, ':')) { |
| + | curlx_str_passblanks(&ptr); |
| + | if(*ptr) { |
| + | value = ptr; |
| + | valuelen = strlen(value); |
| + | } |
| + | else { |
| + | /* quirk #1, suppress this header */ |
| + | continue; |
| + | } |
| } | |
| - | else { |
| - | /* quirk #1, suppress this header */ |
| - | continue; |
| + | else if(!curlx_str_single(&ptr, ';')) { |
| + | curlx_str_passblanks(&ptr); |
| + | if(!*ptr) { |
| + | /* quirk #2, send an empty header */ |
| + | value = ""; |
| + | valuelen = 0; |
| + | } |
| + | else { |
| + | /* this may be used for something else in the future, |
| + | * ignore this for now */ |
| + | continue; |
| + | } |
| } | |
| - | } |
| - | else { |
| - | ptr = strchr(headers->data, ';'); |
| - | |
| - | if(!ptr) { |
| - | /* neither : nor ; in provided header value. We seem |
| - | * to ignore this silently */ |
| + | else |
| + | /* neither : nor ; in provided header value. We ignore this |
| + | * silently */ |
| continue; | |
| - | } |
| - | |
| - | name = headers->data; |
| - | namelen = ptr - headers->data; |
| - | ptr++; /* pass the semicolon */ |
| - | curlx_str_passblanks(&ptr); |
| - | if(!*ptr) { |
| - | /* quirk #2, send an empty header */ |
| - | value = ""; |
| - | valuelen = 0; |
| - | } |
| - | else { |
| - | /* this may be used for something else in the future, |
| - | * ignore this for now */ |
| - | continue; |
| - | } |
| } | |
| + | else |
| + | /* no name, move on */ |
| + | continue; |
| - | DEBUGASSERT(name && value); |
| + | DEBUGASSERT(curlx_strlen(&name) && value); |
| if(data->state.aptr.host && | |
| /* a Host: header was sent already, do not pass on any custom Host: | |
| header as that will produce *two* in the same request! */ | |
| - | hd_name_eq(name, namelen, STRCONST("Host:"))) |
| - | ; |
| + | curlx_str_casecompare(&name, "Host")); |
| else if(data->state.httpreq == HTTPREQ_POST_FORM && | |
| /* this header (extended by formdata.c) is sent later */ | |
| - | hd_name_eq(name, namelen, STRCONST("Content-Type:"))) |
| - | ; |
| + | curlx_str_casecompare(&name, "Content-Type")); |
| else if(data->state.httpreq == HTTPREQ_POST_MIME && | |
| /* this header is sent later */ | |
| - | hd_name_eq(name, namelen, STRCONST("Content-Type:"))) |
| - | ; |
| + | curlx_str_casecompare(&name, "Content-Type")); |
| else if(data->req.authneg && | |
| /* while doing auth neg, do not allow the custom length since | |
| we will force length zero then */ | |
| - | hd_name_eq(name, namelen, STRCONST("Content-Length:"))) |
| - | ; |
| + | curlx_str_casecompare(&name, "Content-Length")); |
| else if((httpversion >= 20) && | |
| - | hd_name_eq(name, namelen, STRCONST("Transfer-Encoding:"))) |
| - | /* HTTP/2 and HTTP/3 do not support chunked requests */ |
| - | ; |
| - | else if((hd_name_eq(name, namelen, STRCONST("Authorization:")) || |
| - | hd_name_eq(name, namelen, STRCONST("Cookie:"))) && |
| + | curlx_str_casecompare(&name, "Transfer-Encoding")); |
| + | /* HTTP/2 and HTTP/3 do not support chunked requests */ |
| + | else if((curlx_str_casecompare(&name, "Authorization") || |
| + | curlx_str_casecompare(&name, "Cookie")) && |
| /* be careful of sending this potentially sensitive header to | |
| other hosts */ | |
| - | !Curl_auth_allowed_to_host(data)) |
| - | ; |
| + | !Curl_auth_allowed_to_host(data)); |
| else { | |
| - | CURLcode result; |
| - | |
| - | result = Curl_dynhds_add(hds, name, namelen, value, valuelen); |
| + | CURLcode result = |
| + | Curl_dynhds_add(hds, curlx_str(&name), curlx_strlen(&name), |
| + | value, valuelen); |
| if(result) | |
| return result; | |
| } | |