mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-10 04:50:37 -04:00
support multi-line http headers; based on a patch from Moshe Litvin
svn:r890
This commit is contained in:
parent
9998c0cbc8
commit
cb7c3bd671
@ -112,6 +112,7 @@ Changes in current version:
|
||||
o Do not use SO_REUSEADDR when connecting
|
||||
o Support 64-bit integers in RPC structs
|
||||
o Correct handling of trailing headers in chunked replies; from Scott Lamb.
|
||||
o Support multi-line HTTP headers; based on a patch from Moshe Litvin
|
||||
|
||||
Changes in 1.4.0:
|
||||
o allow \r or \n individually to separate HTTP headers instead of the standard "\r\n"; from Charles Kerr.
|
||||
|
30
http.c
30
http.c
@ -1412,6 +1412,29 @@ evhttp_parse_firstline(struct evhttp_request *req, struct evbuffer *buffer)
|
||||
return (status);
|
||||
}
|
||||
|
||||
static int
|
||||
evhttp_append_to_last_header(struct evkeyvalq *headers, const char *line)
|
||||
{
|
||||
struct evkeyval *header = TAILQ_LAST(headers, evkeyvalq);
|
||||
char *newval;
|
||||
size_t old_len, line_len;
|
||||
|
||||
if (header == NULL)
|
||||
return (-1);
|
||||
|
||||
old_len = strlen(header->value);
|
||||
line_len = strlen(line);
|
||||
|
||||
newval = mm_realloc(header->value, old_len + line_len + 1);
|
||||
if (newval == NULL)
|
||||
return (-1);
|
||||
|
||||
memcpy(newval + old_len, line, line_len + 1);
|
||||
header->value = newval;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
enum message_read_status
|
||||
evhttp_parse_headers(struct evhttp_request *req, struct evbuffer* buffer)
|
||||
{
|
||||
@ -1429,6 +1452,13 @@ evhttp_parse_headers(struct evhttp_request *req, struct evbuffer* buffer)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check if this is a continuation line */
|
||||
if (*line == ' ' || *line == '\t') {
|
||||
if (evhttp_append_to_last_header(headers, line) == -1)
|
||||
goto error;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Processing of header lines */
|
||||
svalue = line;
|
||||
skey = strsep(&svalue, ":");
|
||||
|
@ -232,6 +232,17 @@ http_basic_cb(struct evhttp_request *req, void *arg)
|
||||
event_debug(("%s: called\n", __func__));
|
||||
evbuffer_add_printf(evb, "This is funny");
|
||||
|
||||
/* For multi-line headers test */
|
||||
{
|
||||
const char *multi =
|
||||
evhttp_find_header(req->input_headers,"X-multi");
|
||||
if (multi) {
|
||||
if (strcmp("END", multi + strlen(multi) - 3) == 0)
|
||||
test_ok++;
|
||||
if (evhttp_find_header(req->input_headers, "X-Last"))
|
||||
test_ok++;
|
||||
}
|
||||
}
|
||||
/* allow sending of an empty reply */
|
||||
evhttp_send_reply(req, HTTP_OK, "Everything is fine",
|
||||
!empty ? evb : NULL);
|
||||
@ -2126,6 +2137,52 @@ failed:
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void
|
||||
http_multi_line_header_test(void)
|
||||
{
|
||||
struct bufferevent *bev;
|
||||
int fd;
|
||||
const char *http_start_request;
|
||||
short port = -1;
|
||||
|
||||
test_ok = 0;
|
||||
fprintf(stdout, "Testing HTTP Server with multi line: ");
|
||||
|
||||
http = http_setup(&port, NULL);
|
||||
|
||||
fd = http_connect("127.0.0.1", port);
|
||||
|
||||
/* Stupid thing to send a request */
|
||||
bev = bufferevent_new(fd, http_readcb, http_writecb,
|
||||
http_errorcb, NULL);
|
||||
|
||||
http_start_request =
|
||||
"GET /test HTTP/1.1\r\n"
|
||||
"Host: somehost\r\n"
|
||||
"Connection: close\r\n"
|
||||
"X-Multi: aaaaaaaa\r\n"
|
||||
" a\r\n"
|
||||
"\tEND\r\n"
|
||||
"X-Last: last\r\n"
|
||||
"\r\n";
|
||||
|
||||
bufferevent_write(bev, http_start_request, strlen(http_start_request));
|
||||
|
||||
event_dispatch();
|
||||
|
||||
bufferevent_free(bev);
|
||||
close(fd);
|
||||
|
||||
evhttp_free(http);
|
||||
|
||||
if (test_ok != 4) {
|
||||
fprintf(stdout, "FAILED\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fprintf(stdout, "OK\n");
|
||||
}
|
||||
|
||||
void
|
||||
http_suite(void)
|
||||
{
|
||||
@ -2146,6 +2203,8 @@ http_suite(void)
|
||||
http_highport_test();
|
||||
http_dispatcher_test();
|
||||
|
||||
http_multi_line_header_test();
|
||||
|
||||
http_incomplete_test(0 /* use_timeout */);
|
||||
http_incomplete_test(1 /* use_timeout */);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user