mirror of
https://github.com/libevent/libevent.git
synced 2025-01-31 09:12:55 +08:00
make chunked requests work correctly; this is done by providing
a separate callback for invidiual chunks. if this callback is not set, all the data is going to be delivered at the end. svn:r327
This commit is contained in:
parent
36950cef58
commit
8901c141c9
9
evhttp.h
9
evhttp.h
@ -138,6 +138,13 @@ struct evhttp_request {
|
||||
/* Callback */
|
||||
void (*cb)(struct evhttp_request *, void *);
|
||||
void *cb_arg;
|
||||
|
||||
/*
|
||||
* Chunked data callback - call for each completed chunk if
|
||||
* specified. If not specified, all the data is delivered via
|
||||
* the regular callback.
|
||||
*/
|
||||
void (*chunk_cb)(struct evhttp_request *, void *);
|
||||
};
|
||||
|
||||
/*
|
||||
@ -147,6 +154,8 @@ struct evhttp_request {
|
||||
*/
|
||||
struct evhttp_request *evhttp_request_new(
|
||||
void (*cb)(struct evhttp_request *, void *), void *arg);
|
||||
void evhttp_request_set_chunked_cb(struct evhttp_request *,
|
||||
void (*cb)(struct evhttp_request *, void *));
|
||||
|
||||
/* Frees the request object and removes associated events. */
|
||||
void evhttp_request_free(struct evhttp_request *req);
|
||||
|
38
http.c
38
http.c
@ -631,6 +631,9 @@ evhttp_handle_chunked_read(struct evhttp_request *req, struct evbuffer *buf)
|
||||
int error;
|
||||
if (p == NULL)
|
||||
break;
|
||||
/* the last chunk is on a new line? */
|
||||
if (strlen(p) == 0)
|
||||
continue;
|
||||
req->ntoread = strtol(p, &endp, 16);
|
||||
error = *p == '\0' || *endp != '\0';
|
||||
free(p);
|
||||
@ -642,18 +645,22 @@ evhttp_handle_chunked_read(struct evhttp_request *req, struct evbuffer *buf)
|
||||
/* Last chunk */
|
||||
return (1);
|
||||
}
|
||||
} else if (len >= req->ntoread) {
|
||||
/* Completed chunk */
|
||||
evbuffer_add(req->input_buffer,
|
||||
EVBUFFER_DATA(buf), req->ntoread);
|
||||
evbuffer_drain(buf, req->ntoread);
|
||||
req->ntoread = -1;
|
||||
if (req->cb != NULL) {
|
||||
(*req->cb)(req, req->cb_arg);
|
||||
/* XXX(niels): not sure if i like semantics */
|
||||
evbuffer_drain(req->input_buffer,
|
||||
EVBUFFER_LENGTH(req->input_buffer));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/* don't have enough to complete a chunk; wait for more */
|
||||
if (len < req->ntoread)
|
||||
return (0);
|
||||
|
||||
/* Completed chunk */
|
||||
evbuffer_add(req->input_buffer,
|
||||
EVBUFFER_DATA(buf), req->ntoread);
|
||||
evbuffer_drain(buf, req->ntoread);
|
||||
req->ntoread = -1;
|
||||
if (req->chunk_cb != NULL) {
|
||||
(*req->chunk_cb)(req, req->cb_arg);
|
||||
evbuffer_drain(req->input_buffer,
|
||||
EVBUFFER_LENGTH(req->input_buffer));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2029,6 +2036,13 @@ evhttp_request_free(struct evhttp_request *req)
|
||||
free(req);
|
||||
}
|
||||
|
||||
void
|
||||
evhttp_request_set_chunked_cb(struct evhttp_request *req,
|
||||
void (*cb)(struct evhttp_request *, void *))
|
||||
{
|
||||
req->chunk_cb = cb;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allows for inspection of the request URI
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user