/*
* Strip off leading and trailing whitespace from the value in the given HTTP
- * header line and return a strdup()ed copy. Returns NULL in case of
- * allocation failure or bad input. Returns an empty string if the header
- * value consists entirely of whitespace.
+ * header line and return a strdup()ed copy in 'valp' - returns an empty
+ * string if the header value consists entirely of whitespace.
*
- * If the header is provided as "name;", ending with a semicolon, it must
- * return a blank string.
+ * If the header is provided as "name;", ending with a semicolon, it returns a
+ * blank string.
*/
-char *Curl_copy_header_value(const char *header)
+static CURLcode copy_custom_value(const char *header, char **valp)
{
struct Curl_str out;
curlx_str_untilnl(&header, &out, MAX_HTTP_RESP_HEADER_SIZE);
curlx_str_trimblanks(&out);
- return Curl_memdup0(curlx_str(&out), curlx_strlen(&out));
+ *valp = Curl_memdup0(curlx_str(&out), curlx_strlen(&out));
+ if(*valp)
+ return CURLE_OK;
+ return CURLE_OUT_OF_MEMORY;
}
/* bad input */
+ *valp = NULL;
+ return CURLE_BAD_FUNCTION_ARGUMENT;
+}
+
+/*
+ * Strip off leading and trailing whitespace from the value in the given HTTP
+ * header line and return a strdup()ed copy in 'valp' - returns an empty
+ * string if the header value consists entirely of whitespace.
+ *
+ * This function MUST be used after the header has already been confirmed to
+ * lead with "word:".
+ */
+char *Curl_copy_header_value(const char *header)
+{
+ struct Curl_str out;
+
+ /* find the end of the header name */
+ if(!curlx_str_until(&header, &out, MAX_HTTP_RESP_HEADER_SIZE, ':') &&
+ !curlx_str_single(&header, ':')) {
+ curlx_str_untilnl(&header, &out, MAX_HTTP_RESP_HEADER_SIZE);
+ curlx_str_trimblanks(&out);
+ return Curl_memdup0(curlx_str(&out), curlx_strlen(&out));
+ }
+ /* bad input, should never happen */
+ DEBUGASSERT(0);
return NULL;
}
custom Host: header if this is NOT a redirect, as setting Host: in the
redirected request is being out on thin ice. Except if the hostname
is the same as the first one! */
- char *cookiehost = Curl_copy_header_value(ptr);
- if(!cookiehost)
- return CURLE_OUT_OF_MEMORY;
+ char *cookiehost;
+ CURLcode result = copy_custom_value(ptr, &cookiehost);
+ if(result)
+ return result;
if(!*cookiehost)
/* ignore empty data */
free(cookiehost);
const char *sep = "Connection: ";
CURLcode result = CURLE_OK;
size_t rlen = curlx_dyn_len(req);
- char *value;
bool skip;
/* Add the 1st custom "Connection: " header, if there is one */
if(curl_strnequal(head->data, "Connection", 10) &&
Curl_headersep(head->data[10]) &&
!http_header_is_empty(head->data)) {
- value = Curl_copy_header_value(head->data);
- if(!value)
- return CURLE_OUT_OF_MEMORY;
+ char *value;
+ result = copy_custom_value(head->data, &value);
+ if(result)
+ return result;
result = curlx_dyn_addf(req, "%s%s", sep, value);
sep = ", ";
free(value);
#endif
if((407 == k->httpcode) && HD_IS(hd, hdlen, "Proxy-authenticate:")) {
char *auth = Curl_copy_header_value(hd);
- CURLcode result;
- if(!auth)
- return CURLE_OUT_OF_MEMORY;
- result = Curl_http_input_auth(data, TRUE, auth);
- free(auth);
+ CURLcode result = auth ? CURLE_OK : CURLE_OUT_OF_MEMORY;
+ if(!result) {
+ result = Curl_http_input_auth(data, TRUE, auth);
+ free(auth);
+ }
return result;
}
#ifdef USE_SPNEGO
if((401 == k->httpcode) && HD_IS(hd, hdlen, "WWW-Authenticate:")) {
char *auth = Curl_copy_header_value(hd);
if(!auth)
- return CURLE_OUT_OF_MEMORY;
- result = Curl_http_input_auth(data, FALSE, auth);
- free(auth);
+ result = CURLE_OUT_OF_MEMORY;
+ else {
+ result = Curl_http_input_auth(data, FALSE, auth);
+ free(auth);
+ }
}
return result;
}