diff options
author | Michael Tokarev <mjt@tls.msk.ru> | 2024-06-29 16:27:00 +0300 |
---|---|---|
committer | Michael Tokarev <mjt@tls.msk.ru> | 2024-07-17 14:04:15 +0300 |
commit | 2abc22e63943371128990e4dffcf8d1f7d44c10f (patch) | |
tree | 787be7737fbbcfc25b12f3914121d49e5eef121d | |
parent | e2f346aa98646e84eabe0256f89d08e89b1837cf (diff) | |
download | qemu-2abc22e63943371128990e4dffcf8d1f7d44c10f.zip qemu-2abc22e63943371128990e4dffcf8d1f7d44c10f.tar.gz qemu-2abc22e63943371128990e4dffcf8d1f7d44c10f.tar.bz2 |
block/curl: rewrite http header parsing function
Existing code was long, unclear and twisty.
This also relaxes the rules a tiny bit: allows to have
whitespace before header name and colon and makes the
header value match to be case-insensitive.
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
-rw-r--r-- | block/curl.c | 44 |
1 files changed, 18 insertions, 26 deletions
diff --git a/block/curl.c b/block/curl.c index ef5252d..0fdb6d3 100644 --- a/block/curl.c +++ b/block/curl.c @@ -210,37 +210,29 @@ static size_t curl_header_cb(void *ptr, size_t size, size_t nmemb, void *opaque) { BDRVCURLState *s = opaque; size_t realsize = size * nmemb; - const char *header = (char *)ptr; - const char *end = header + realsize; - const char *accept_ranges = "accept-ranges:"; - const char *bytes = "bytes"; + const char *p = ptr; + const char *end = p + realsize; + const char *t = "accept-ranges : bytes "; /* A lowercase template */ - if (realsize >= strlen(accept_ranges) - && g_ascii_strncasecmp(header, accept_ranges, - strlen(accept_ranges)) == 0) { - - char *p = strchr(header, ':') + 1; - - /* Skip whitespace between the header name and value. */ - while (p < end && *p && g_ascii_isspace(*p)) { - p++; - } - - if (end - p >= strlen(bytes) - && strncmp(p, bytes, strlen(bytes)) == 0) { - - /* Check that there is nothing but whitespace after the value. */ - p += strlen(bytes); - while (p < end && *p && g_ascii_isspace(*p)) { - p++; - } - - if (p == end || !*p) { - s->accept_range = true; + /* check if header matches the "t" template */ + for (;;) { + if (*t == ' ') { /* space in t matches any amount of isspace in p */ + if (p < end && g_ascii_isspace(*p)) { + ++p; + } else { + ++t; } + } else if (*t && p < end && *t == g_ascii_tolower(*p)) { + ++p, ++t; + } else { + break; } } + if (!*t && p == end) { /* if we managed to reach ends of both strings */ + s->accept_range = true; + } + return realsize; } |