http: make Curl_compareheader() take string length arguments too

Also add STRCONST, a macro that returns a string literal and it's length
for functions that take "string,len"

Removes unnecesary calls to strlen().

Closes #8391
This commit is contained in:
HenrikHolst 2022-02-04 20:41:35 +01:00 committed by Daniel Stenberg
parent a42677f0d8
commit 4028892f14
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
4 changed files with 39 additions and 17 deletions

View file

@ -772,6 +772,11 @@ endings either CRLF or LF so 't' is appropriate.
#define CURLMAX(x,y) ((x)>(y)?(x):(y))
#define CURLMIN(x,y) ((x)<(y)?(x):(y))
/* A convenience macro to provide both the string literal and the length of
the string literal in one go, useful for functions that take "string,len"
as their argument */
#define STRCONST(x) x,sizeof(x)-1
/* Some versions of the Android SDK is missing the declaration */
#if defined(HAVE_GETPWUID_R) && defined(HAVE_DECL_GETPWUID_R_MISSING)
struct passwd;

View file

@ -1416,18 +1416,22 @@ CURLcode Curl_buffer_send(struct dynbuf *in,
bool
Curl_compareheader(const char *headerline, /* line to check */
const char *header, /* header keyword _with_ colon */
const char *content) /* content string to find */
const size_t hlen, /* len of the keyword in bytes */
const char *content, /* content string to find */
const size_t clen) /* len of the content in bytes */
{
/* RFC2616, section 4.2 says: "Each header field consists of a name followed
* by a colon (":") and the field value. Field names are case-insensitive.
* The field value MAY be preceded by any amount of LWS, though a single SP
* is preferred." */
size_t hlen = strlen(header);
size_t clen;
size_t len;
const char *start;
const char *end;
DEBUGASSERT(hlen);
DEBUGASSERT(clen);
DEBUGASSERT(header);
DEBUGASSERT(content);
if(!strncasecompare(headerline, header, hlen))
return FALSE; /* doesn't start with header */
@ -1451,7 +1455,6 @@ Curl_compareheader(const char *headerline, /* line to check */
}
len = end-start; /* length of the content part of the input line */
clen = strlen(content); /* length of the word to find */
/* find the content string in the rest of the line */
for(; len >= clen; len--, start++) {
@ -1707,7 +1710,7 @@ static CURLcode expect100(struct Curl_easy *data,
const char *ptr = Curl_checkheaders(data, "Expect");
if(ptr) {
data->state.expect100header =
Curl_compareheader(ptr, "Expect:", "100-continue");
Curl_compareheader(ptr, STRCONST("Expect:"), STRCONST("100-continue"));
}
else {
result = Curl_dyn_add(req, "Expect: 100-continue\r\n");
@ -2325,7 +2328,8 @@ CURLcode Curl_http_body(struct Curl_easy *data, struct connectdata *conn,
if(ptr) {
/* Some kind of TE is requested, check if 'chunked' is chosen */
data->req.upload_chunky =
Curl_compareheader(ptr, "Transfer-Encoding:", "chunked");
Curl_compareheader(ptr,
STRCONST("Transfer-Encoding:"), STRCONST("chunked"));
}
else {
if((conn->handler->protocol & PROTO_FAMILY_HTTP) &&
@ -2475,7 +2479,7 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn,
ptr = Curl_checkheaders(data, "Expect");
if(ptr) {
data->state.expect100header =
Curl_compareheader(ptr, "Expect:", "100-continue");
Curl_compareheader(ptr, STRCONST("Expect:"), STRCONST("100-continue"));
}
else if(http->postsize > EXPECT_100_THRESHOLD || http->postsize < 0) {
result = expect100(data, conn, r);
@ -2548,7 +2552,7 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn,
ptr = Curl_checkheaders(data, "Expect");
if(ptr) {
data->state.expect100header =
Curl_compareheader(ptr, "Expect:", "100-continue");
Curl_compareheader(ptr, STRCONST("Expect:"), STRCONST("100-continue"));
}
else if(http->postsize > EXPECT_100_THRESHOLD || http->postsize < 0) {
result = expect100(data, conn, r);
@ -3393,7 +3397,9 @@ CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn,
#ifndef CURL_DISABLE_PROXY
else if((conn->httpversion == 10) &&
conn->bits.httpproxy &&
Curl_compareheader(headp, "Proxy-Connection:", "keep-alive")) {
Curl_compareheader(headp,
STRCONST("Proxy-Connection:"),
STRCONST("keep-alive"))) {
/*
* When a HTTP/1.0 reply comes when using a proxy, the
* 'Proxy-Connection: keep-alive' line tells us the
@ -3405,7 +3411,9 @@ CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn,
}
else if((conn->httpversion == 11) &&
conn->bits.httpproxy &&
Curl_compareheader(headp, "Proxy-Connection:", "close")) {
Curl_compareheader(headp,
STRCONST("Proxy-Connection:"),
STRCONST("close"))) {
/*
* We get a HTTP/1.1 response from a proxy and it says it'll
* close down after this transfer.
@ -3415,7 +3423,9 @@ CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn,
}
#endif
else if((conn->httpversion == 10) &&
Curl_compareheader(headp, "Connection:", "keep-alive")) {
Curl_compareheader(headp,
STRCONST("Connection:"),
STRCONST("keep-alive"))) {
/*
* A HTTP/1.0 reply with the 'Connection: keep-alive' line
* tells us the connection will be kept alive for our
@ -3425,7 +3435,8 @@ CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn,
connkeep(conn, "Connection keep-alive");
infof(data, "HTTP/1.0 connection set to keep alive!");
}
else if(Curl_compareheader(headp, "Connection:", "close")) {
else if(Curl_compareheader(headp,
STRCONST("Connection:"), STRCONST("close"))) {
/*
* [RFC 2616, section 8.1.2.1]
* "Connection: close" is HTTP/1.1 language and means that

View file

@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@ -47,7 +47,9 @@ extern const struct Curl_handler Curl_handler_https;
/* Header specific functions */
bool Curl_compareheader(const char *headerline, /* line to check */
const char *header, /* header keyword _with_ colon */
const char *content); /* content string to find */
const size_t hlen, /* len of the keyword in bytes */
const char *content, /* content string to find */
const size_t clen); /* len of the content in bytes */
char *Curl_copy_header_value(const char *header);

View file

@ -589,7 +589,8 @@ static CURLcode CONNECT(struct Curl_easy *data,
strlen("Content-Length:"), NULL, 10, &s->cl);
}
}
else if(Curl_compareheader(linep, "Connection:", "close"))
else if(Curl_compareheader(linep,
STRCONST("Connection:"), STRCONST("close")))
s->close_connection = TRUE;
else if(checkprefix("Transfer-Encoding:", linep)) {
if(k->httpcode/100 == 2) {
@ -600,14 +601,17 @@ static CURLcode CONNECT(struct Curl_easy *data,
"CONNECT %03d response", k->httpcode);
}
else if(Curl_compareheader(linep,
"Transfer-Encoding:", "chunked")) {
STRCONST("Transfer-Encoding:"),
STRCONST("chunked"))) {
infof(data, "CONNECT responded chunked");
s->chunked_encoding = TRUE;
/* init our chunky engine */
Curl_httpchunk_init(data);
}
}
else if(Curl_compareheader(linep, "Proxy-Connection:", "close"))
else if(Curl_compareheader(linep,
STRCONST("Proxy-Connection:"),
STRCONST("close")))
s->close_connection = TRUE;
else if(2 == sscanf(linep, "HTTP/1.%d %d",
&subversion,