Skip to content

Commit 793171e

Browse files
authored
Merge pull request #2793 from cesanta/tabs
Fix #2790 - allow tabs as the HTTP header whitespace
2 parents 8fd7e87 + cee7087 commit 793171e

File tree

3 files changed

+30
-6
lines changed

3 files changed

+30
-6
lines changed

mongoose.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2401,7 +2401,7 @@ int mg_url_decode(const char *src, size_t src_len, char *dst, size_t dst_len,
24012401
}
24022402

24032403
static bool isok(uint8_t c) {
2404-
return c == '\n' || c == '\r' || c >= ' ';
2404+
return c == '\n' || c == '\r' || c == '\t' || c >= ' ';
24052405
}
24062406

24072407
int mg_http_get_request_len(const unsigned char *buf, size_t buf_len) {
@@ -2463,9 +2463,11 @@ static bool mg_http_parse_headers(const char *s, const char *end,
24632463
if (s >= end || clen(s, end) == 0) return false; // Invalid UTF-8
24642464
if (*s++ != ':') return false; // Invalid, not followed by :
24652465
// if (clen(s, end) == 0) return false; // Invalid UTF-8
2466-
while (s < end && s[0] == ' ') s++; // Skip spaces
2466+
while (s < end && (s[0] == ' ' || s[0] == '\t')) s++; // Skip spaces
24672467
if ((s = skiptorn(s, end, &v)) == NULL) return false;
2468-
while (v.len > 0 && v.buf[v.len - 1] == ' ') v.len--; // Trim spaces
2468+
while (v.len > 0 && (v.buf[v.len - 1] == ' ' || v.buf[v.len - 1] == '\t')) {
2469+
v.len--; // Trim spaces
2470+
}
24692471
// MG_INFO(("--HH [%.*s] [%.*s]", (int) k.len, k.buf, (int) v.len, v.buf));
24702472
h[i].name = k, h[i].value = v; // Success. Assign values
24712473
}

src/http.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ int mg_url_decode(const char *src, size_t src_len, char *dst, size_t dst_len,
185185
}
186186

187187
static bool isok(uint8_t c) {
188-
return c == '\n' || c == '\r' || c >= ' ';
188+
return c == '\n' || c == '\r' || c == '\t' || c >= ' ';
189189
}
190190

191191
int mg_http_get_request_len(const unsigned char *buf, size_t buf_len) {
@@ -247,9 +247,11 @@ static bool mg_http_parse_headers(const char *s, const char *end,
247247
if (s >= end || clen(s, end) == 0) return false; // Invalid UTF-8
248248
if (*s++ != ':') return false; // Invalid, not followed by :
249249
// if (clen(s, end) == 0) return false; // Invalid UTF-8
250-
while (s < end && s[0] == ' ') s++; // Skip spaces
250+
while (s < end && (s[0] == ' ' || s[0] == '\t')) s++; // Skip spaces
251251
if ((s = skiptorn(s, end, &v)) == NULL) return false;
252-
while (v.len > 0 && v.buf[v.len - 1] == ' ') v.len--; // Trim spaces
252+
while (v.len > 0 && (v.buf[v.len - 1] == ' ' || v.buf[v.len - 1] == '\t')) {
253+
v.len--; // Trim spaces
254+
}
253255
// MG_INFO(("--HH [%.*s] [%.*s]", (int) k.len, k.buf, (int) v.len, v.buf));
254256
h[i].name = k, h[i].value = v; // Success. Assign values
255257
}

test/unit_test.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -868,6 +868,10 @@ static void test_http_server(void) {
868868
ASSERT(cmpbody(buf, "hello\n") == 0);
869869
ASSERT(cmpheader(buf, "C", "D"));
870870

871+
ASSERT(fetch(&mgr, buf, url, "GET /a.txt HTTP/1.0\nA:\tB\n\n") == 200);
872+
ASSERT(cmpbody(buf, "hello\n") == 0);
873+
ASSERT(cmpheader(buf, "A", "B") == 0);
874+
871875
// Invalid header: failure
872876
ASSERT(fetch(&mgr, buf, url, "GET /a.txt HTTP/1.0\nA B\n\n") == 0);
873877

@@ -1613,6 +1617,22 @@ static void test_http_parse(void) {
16131617
s = "a b\n\xc0: 2\n\n"; // Invalid UTF in the header name: do NOT accept
16141618
ASSERT(mg_http_parse(s, strlen(s), &hm) == -1);
16151619
}
1620+
1621+
{
1622+
struct mg_http_message hm;
1623+
const char *s;
1624+
s = "a b c\nd:e\n\n";
1625+
ASSERT(mg_http_parse(s, strlen(s), &hm) == (int) strlen(s));
1626+
s = "a b c\nd: e\n\n";
1627+
ASSERT(mg_http_parse(s, strlen(s), &hm) == (int) strlen(s));
1628+
s = "a b c\nd:\te\n\n";
1629+
ASSERT(mg_http_parse(s, strlen(s), &hm) == (int) strlen(s));
1630+
s = "a b c\nd:\t e\n\n";
1631+
ASSERT(mg_http_parse(s, strlen(s), &hm) == (int) strlen(s));
1632+
s = "a b c\nd: \te\t \n\n";
1633+
ASSERT(mg_http_parse(s, strlen(s), &hm) == (int) strlen(s));
1634+
ASSERT(mg_strcmp(hm.headers[0].value, mg_str("e")) == 0);
1635+
}
16161636
}
16171637

16181638
static void ehr(struct mg_connection *c, int ev, void *ev_data) {

0 commit comments

Comments
 (0)