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:
Niels Provos 2007-02-14 06:10:32 +00:00
parent 36950cef58
commit 8901c141c9
2 changed files with 35 additions and 12 deletions

View File

@ -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
View File

@ -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
*/