mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-09 04:19:10 -04:00
from dug song:
the original code failed in the case of a large single client request+body write - for instance, over loopback (with a larger MTU exceeding EVBUFFER_MAX_READ). svn:r307
This commit is contained in:
parent
0db257b828
commit
ba8289bea5
74
http.c
74
http.c
@ -125,6 +125,7 @@ static void evhttp_connection_stop_detectclose(
|
|||||||
struct evhttp_connection *evcon);
|
struct evhttp_connection *evcon);
|
||||||
static void evhttp_request_dispatch(struct evhttp_connection* evcon);
|
static void evhttp_request_dispatch(struct evhttp_connection* evcon);
|
||||||
|
|
||||||
|
void evhttp_read(int, short, void *);
|
||||||
void evhttp_write(int, short, void *);
|
void evhttp_write(int, short, void *);
|
||||||
|
|
||||||
#ifndef HAVE_STRSEP
|
#ifndef HAVE_STRSEP
|
||||||
@ -625,6 +626,40 @@ evhttp_handle_chunked_read(struct evhttp_request *req, struct evbuffer *buf)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
evhttp_read_body(struct evhttp_connection *evcon, struct evhttp_request *req)
|
||||||
|
{
|
||||||
|
struct evbuffer *buf = evcon->input_buffer;
|
||||||
|
|
||||||
|
if (req->chunked) {
|
||||||
|
int res = evhttp_handle_chunked_read(req, buf);
|
||||||
|
if (res == 1) {
|
||||||
|
/* finished last chunk */
|
||||||
|
evhttp_connection_done(evcon);
|
||||||
|
return;
|
||||||
|
} else if (res == -1) {
|
||||||
|
/* corrupted data */
|
||||||
|
evhttp_connection_fail(evcon,
|
||||||
|
EVCON_HTTP_INVALID_HEADER);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else if (req->ntoread < 0) {
|
||||||
|
/* Read until connection close. */
|
||||||
|
evbuffer_add_buffer(req->input_buffer, buf);
|
||||||
|
} else if (EVBUFFER_LENGTH(buf) >= req->ntoread) {
|
||||||
|
/* Completed content length */
|
||||||
|
evbuffer_add(req->input_buffer, EVBUFFER_DATA(buf),
|
||||||
|
req->ntoread);
|
||||||
|
evbuffer_drain(buf, req->ntoread);
|
||||||
|
req->ntoread = 0;
|
||||||
|
evhttp_connection_done(evcon);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* Read more! */
|
||||||
|
event_set(&evcon->ev, evcon->fd, EV_READ, evhttp_read, evcon);
|
||||||
|
evhttp_add_event(&evcon->ev, evcon->timeout, HTTP_READ_TIMEOUT);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reads data into a buffer structure until no more data
|
* Reads data into a buffer structure until no more data
|
||||||
* can be read on the file descriptor or we have read all
|
* can be read on the file descriptor or we have read all
|
||||||
@ -657,32 +692,7 @@ evhttp_read(int fd, short what, void *arg)
|
|||||||
evhttp_connection_done(evcon);
|
evhttp_connection_done(evcon);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (req->chunked) {
|
evhttp_read_body(evcon, req);
|
||||||
int res = evhttp_handle_chunked_read(req, buf);
|
|
||||||
if (res == 1) {
|
|
||||||
/* finished last chunk */
|
|
||||||
evhttp_connection_done(evcon);
|
|
||||||
return;
|
|
||||||
} else if (res == -1) {
|
|
||||||
/* corrupted data */
|
|
||||||
evhttp_connection_fail(evcon,
|
|
||||||
EVCON_HTTP_INVALID_HEADER);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else if (req->ntoread < 0) {
|
|
||||||
/* Read until connection close. */
|
|
||||||
evbuffer_add_buffer(req->input_buffer, buf);
|
|
||||||
} else if (len >= req->ntoread) {
|
|
||||||
/* Completed content length */
|
|
||||||
evbuffer_add(req->input_buffer, EVBUFFER_DATA(buf),
|
|
||||||
req->ntoread);
|
|
||||||
evbuffer_drain(buf, req->ntoread);
|
|
||||||
req->ntoread = 0;
|
|
||||||
evhttp_connection_done(evcon);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
/* Read more! */
|
|
||||||
evhttp_add_event(&evcon->ev, evcon->timeout, HTTP_READ_TIMEOUT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1202,18 +1212,8 @@ evhttp_get_body(struct evhttp_connection *evcon, struct evhttp_request *req)
|
|||||||
EVCON_HTTP_INVALID_HEADER);
|
EVCON_HTTP_INVALID_HEADER);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (req->ntoread > 0)
|
|
||||||
req->ntoread -= EVBUFFER_LENGTH(evcon->input_buffer);
|
|
||||||
|
|
||||||
if (req->ntoread == 0) {
|
|
||||||
evbuffer_add_buffer(req->input_buffer,
|
|
||||||
evcon->input_buffer);
|
|
||||||
evhttp_connection_done(evcon);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
event_set(&evcon->ev, evcon->fd, EV_READ, evhttp_read, evcon);
|
evhttp_read_body(evcon, req);
|
||||||
evhttp_add_event(&evcon->ev, evcon->timeout, HTTP_READ_TIMEOUT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
Loading…
x
Reference in New Issue
Block a user