Skip HTTP header fields to long to parse.

Nowadays many HTTP server set cookies which may easily result in HTTP header fields longer than our 'httpheaderline' buffer. It doesn't hurt if we can't parse them but we need to be able to skip them and continue to parse the following header fields.
This commit is contained in:
Oliver Schmidt 2015-05-02 00:11:59 +02:00
parent 085b7d8898
commit 40417a2bcd

View file

@ -63,11 +63,11 @@ struct webclient_state {
uint16_t port; uint16_t port;
char host[40]; char host[40];
char file[WWW_CONF_MAX_URLLEN]; char file[WWW_CONF_MAX_URLLEN - 10]; // URL - "http://<host>/"
uint16_t getrequestptr; uint16_t getrequestptr;
uint16_t getrequestleft; uint16_t getrequestleft;
char httpheaderline[200]; char httpheaderline[WWW_CONF_MAX_URLLEN + 10]; // URL + "Location: "
uint16_t httpheaderlineptr; uint16_t httpheaderlineptr;
char mimetype[32]; char mimetype[32];
@ -327,13 +327,12 @@ parse_headers(uint16_t len)
char *cptr; char *cptr;
static unsigned char i; static unsigned char i;
while(len > 0 && s.httpheaderlineptr < sizeof(s.httpheaderline)) { while(len > 0) {
s.httpheaderline[s.httpheaderlineptr] = *(char *)uip_appdata; s.httpheaderline[s.httpheaderlineptr] = *(char *)uip_appdata;
uip_appdata = (char *)uip_appdata + 1; uip_appdata = (char *)uip_appdata + 1;
--len; --len;
if(s.httpheaderline[s.httpheaderlineptr] == ISO_nl) { if(s.httpheaderline[s.httpheaderlineptr] == ISO_nl) {
/* We have an entire HTTP header line in s.httpheaderline, so /* We reached the end of an HTTP header line. */
we parse it. */
if(s.httpheaderline[0] == ISO_cr) { if(s.httpheaderline[0] == ISO_cr) {
/* This was the last header line (i.e., and empty "\r\n"), so /* This was the last header line (i.e., and empty "\r\n"), so
we are done with the headers and proceed with the actual we are done with the headers and proceed with the actual
@ -342,46 +341,51 @@ parse_headers(uint16_t len)
return len; return len;
} }
s.httpheaderline[s.httpheaderlineptr - 1] = 0; if(s.httpheaderlineptr < sizeof(s.httpheaderline) - 1) {
/* Check for specific HTTP header fields. */ /* We have an entire HTTP header line in s.httpheaderline, so
if(casecmp(s.httpheaderline, http_content_type, we parse it. */
sizeof(http_content_type) - 1) == 0) { s.httpheaderline[s.httpheaderlineptr - 1] = 0;
/* Found Content-type field. */ /* Check for specific HTTP header fields. */
cptr = strchr(s.httpheaderline, ';'); if(casecmp(s.httpheaderline, http_content_type,
if(cptr != NULL) { sizeof(http_content_type) - 1) == 0) {
*cptr = 0; /* Found Content-type field. */
} cptr = strchr(s.httpheaderline, ';');
strncpy(s.mimetype, s.httpheaderline + if(cptr != NULL) {
sizeof(http_content_type) - 1, sizeof(s.mimetype)); *cptr = 0;
} else if(casecmp(s.httpheaderline, http_location,
sizeof(http_location) - 1) == 0) {
cptr = s.httpheaderline +
sizeof(http_location) - 1;
if(strncmp(cptr, http_http, 7) == 0) {
cptr += 7;
for(i = 0; i < s.httpheaderlineptr - 7; ++i) {
if(*cptr == 0 ||
*cptr == '/' ||
*cptr == ' ' ||
*cptr == ':') {
s.host[i] = 0;
break;
}
s.host[i] = *cptr;
++cptr;
} }
strncpy(s.mimetype, s.httpheaderline +
sizeof(http_content_type) - 1, sizeof(s.mimetype));
} else if(casecmp(s.httpheaderline, http_location,
sizeof(http_location) - 1) == 0) {
cptr = s.httpheaderline +
sizeof(http_location) - 1;
if(strncmp(cptr, http_http, 7) == 0) {
cptr += 7;
for(i = 0; i < s.httpheaderlineptr - 7; ++i) {
if(*cptr == 0 ||
*cptr == '/' ||
*cptr == ' ' ||
*cptr == ':') {
s.host[i] = 0;
break;
}
s.host[i] = *cptr;
++cptr;
}
}
strncpy(s.file, cptr, sizeof(s.file));
/* s.file[s.httpheaderlineptr - i] = 0;*/
} }
strncpy(s.file, cptr, sizeof(s.file));
/* s.file[s.httpheaderlineptr - i] = 0;*/
} }
/* We're done parsing, so we reset the pointer and start the /* We're done parsing, so we reset the pointer and start the
next line. */ next line. */
s.httpheaderlineptr = 0; s.httpheaderlineptr = 0;
} else { } else {
++s.httpheaderlineptr; if(s.httpheaderlineptr < sizeof(s.httpheaderline) - 1) {
++s.httpheaderlineptr;
}
} }
} }
return len; return len;