diff --git a/docs/internals/STRPARSE.md b/docs/internals/STRPARSE.md index 2ae92595e61e..b6117df9acef 100644 --- a/docs/internals/STRPARSE.md +++ b/docs/internals/STRPARSE.md @@ -151,6 +151,15 @@ int Curl_str_casecompare(struct Curl_str *str, const char *check); Returns true if the provided string in the `str` argument matches the `check` string case insensitively. +## `Curl_str_cmp` + +~~~c +int Curl_str_cmp(struct Curl_str *str, const char *check); +~~~ + +Returns true if the provided string in the `str` argument matches the `check` +string case sensitively. This is *not* the same return code as `strcmp`. + ## `Curl_str_nudge` ~~~c diff --git a/lib/http.c b/lib/http.c index ca8debe79d67..76cd9bcc6be4 100644 --- a/lib/http.c +++ b/lib/http.c @@ -3987,30 +3987,22 @@ static CURLcode http_rw_hd(struct Curl_easy *data, } else if(data->conn->handler->protocol & CURLPROTO_RTSP) { const char *p = hd; - while(ISBLANK(*p)) - p++; - if(!strncmp(p, "RTSP/", 5)) { - p += 5; - if(ISDIGIT(*p)) { - p++; - if((p[0] == '.') && ISDIGIT(p[1])) { - if(ISBLANK(p[2])) { - p += 3; - if(ISDIGIT(p[0]) && ISDIGIT(p[1]) && ISDIGIT(p[2])) { - k->httpcode = (p[0] - '0') * 100 + (p[1] - '0') * 10 + - (p[2] - '0'); - p += 3; - if(ISSPACE(*p)) { - fine_statusline = TRUE; - k->httpversion = 11; /* RTSP acts like HTTP 1.1 */ - } - } - } - } + struct Curl_str ver; + curl_off_t status; + /* we set the max string a little excessive to forgive some leading + spaces */ + if(!Curl_str_until(&p, &ver, 32, ' ') && + !Curl_str_single(&p, ' ') && + !Curl_str_number(&p, &status, 999)) { + Curl_str_trimblanks(&ver); + if(Curl_str_cmp(&ver, "RTSP/1.0")) { + k->httpcode = (int)status; + fine_statusline = TRUE; + k->httpversion = 11; /* RTSP acts like HTTP 1.1 */ } - if(!fine_statusline) - return CURLE_WEIRD_SERVER_REPLY; } + if(!fine_statusline) + return CURLE_WEIRD_SERVER_REPLY; } if(fine_statusline) { diff --git a/lib/strparse.c b/lib/strparse.c index 076b91d69fe0..97f70ba7b221 100644 --- a/lib/strparse.c +++ b/lib/strparse.c @@ -203,6 +203,16 @@ int Curl_str_casecompare(struct Curl_str *str, const char *check) return ((str->len == clen) && strncasecompare(str->str, check, clen)); } +/* case sensitive string compare. Returns non-zero on match. */ +int Curl_str_cmp(struct Curl_str *str, const char *check) +{ + if(check) { + size_t clen = strlen(check); + return ((str->len == clen) && !strncmp(str->str, check, clen)); + } + return !!(str->len); +} + /* Trim off 'num' number of bytes from the beginning (left side) of the string. If 'num' is larger than the string, return error. */ int Curl_str_nudge(struct Curl_str *str, size_t num) diff --git a/lib/strparse.h b/lib/strparse.h index f096526452a3..3dbbf9a26238 100644 --- a/lib/strparse.h +++ b/lib/strparse.h @@ -85,6 +85,7 @@ int Curl_str_newline(const char **linep); /* case insensitive compare that the parsed string matches the given string. */ int Curl_str_casecompare(struct Curl_str *str, const char *check); +int Curl_str_cmp(struct Curl_str *str, const char *check); int Curl_str_nudge(struct Curl_str *str, size_t num); diff --git a/tests/data/test689 b/tests/data/test689 index 381ae225ae21..31f81983d104 100644 --- a/tests/data/test689 +++ b/tests/data/test689 @@ -11,7 +11,7 @@ OPTIONS # Server-side -RTSP/7.1 786 +RTSP/1.0 786 RTSP/