mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-10 04:50:37 -04:00
low-level interfaces for streaming; from dug song
i applied some bug fixes and slight re-arranged the logic on when to call the close notification callback; i also don't like the streaming interface; i'd rather see it do the chunked response formatting explicitly. svn:r298
This commit is contained in:
parent
852d05a3c0
commit
de7db33a61
13
evhttp.h
13
evhttp.h
@ -87,6 +87,11 @@ void evhttp_send_error(struct evhttp_request *, int, const char *);
|
|||||||
void evhttp_send_reply(struct evhttp_request *, int, const char *,
|
void evhttp_send_reply(struct evhttp_request *, int, const char *,
|
||||||
struct evbuffer *);
|
struct evbuffer *);
|
||||||
|
|
||||||
|
/* Low-level response interface, for streaming/chunked replies */
|
||||||
|
void evhttp_send_reply_start(struct evhttp_request *, int, const char *);
|
||||||
|
void evhttp_send_reply_data(struct evhttp_request *, struct evbuffer *);
|
||||||
|
void evhttp_send_reply_done(struct evhttp_request *);
|
||||||
|
|
||||||
/* Interfaces for making requests */
|
/* Interfaces for making requests */
|
||||||
enum evhttp_cmd_type { EVHTTP_REQ_GET, EVHTTP_REQ_POST, EVHTTP_REQ_HEAD };
|
enum evhttp_cmd_type { EVHTTP_REQ_GET, EVHTTP_REQ_POST, EVHTTP_REQ_HEAD };
|
||||||
|
|
||||||
@ -164,6 +169,14 @@ void evhttp_connection_set_timeout(struct evhttp_connection *evcon,
|
|||||||
void evhttp_connection_set_retries(struct evhttp_connection *evcon,
|
void evhttp_connection_set_retries(struct evhttp_connection *evcon,
|
||||||
int retry_max);
|
int retry_max);
|
||||||
|
|
||||||
|
/* Set a callback for connection close. */
|
||||||
|
void evhttp_connection_set_closecb(struct evhttp_connection *evcon,
|
||||||
|
void (*)(struct evhttp_connection *, void *), void *);
|
||||||
|
|
||||||
|
/* Get the remote address and port associated with this connection. */
|
||||||
|
void evhttp_connection_get_peer(struct evhttp_connection *evcon,
|
||||||
|
char **address, u_short *port);
|
||||||
|
|
||||||
/* The connection gets ownership of the request */
|
/* The connection gets ownership of the request */
|
||||||
int evhttp_make_request(struct evhttp_connection *evcon,
|
int evhttp_make_request(struct evhttp_connection *evcon,
|
||||||
struct evhttp_request *req,
|
struct evhttp_request *req,
|
||||||
|
@ -65,6 +65,9 @@ struct evhttp_connection {
|
|||||||
|
|
||||||
void (*cb)(struct evhttp_connection *, void *);
|
void (*cb)(struct evhttp_connection *, void *);
|
||||||
void *cb_arg;
|
void *cb_arg;
|
||||||
|
|
||||||
|
void (*closecb)(struct evhttp_connection *, void *);
|
||||||
|
void *closecb_arg;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct evhttp_cb {
|
struct evhttp_cb {
|
||||||
|
66
http.c
66
http.c
@ -523,7 +523,8 @@ evhttp_write(int fd, short what, void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Activate our call back */
|
/* Activate our call back */
|
||||||
(*evcon->cb)(evcon, evcon->cb_arg);
|
if (evcon->cb != NULL)
|
||||||
|
(*evcon->cb)(evcon, evcon->cb_arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -640,6 +641,12 @@ evhttp_connection_free(struct evhttp_connection *evcon)
|
|||||||
{
|
{
|
||||||
struct evhttp_request *req;
|
struct evhttp_request *req;
|
||||||
|
|
||||||
|
/* notify interested parties that this connection is going down */
|
||||||
|
if (evcon->fd != -1) {
|
||||||
|
if (evcon->closecb != NULL)
|
||||||
|
(*evcon->closecb)(evcon, evcon->closecb_arg);
|
||||||
|
}
|
||||||
|
|
||||||
/* remove all requests that might be queued on this connection */
|
/* remove all requests that might be queued on this connection */
|
||||||
while ((req = TAILQ_FIRST(&evcon->requests)) != NULL) {
|
while ((req = TAILQ_FIRST(&evcon->requests)) != NULL) {
|
||||||
TAILQ_REMOVE(&evcon->requests, req, next);
|
TAILQ_REMOVE(&evcon->requests, req, next);
|
||||||
@ -698,6 +705,10 @@ evhttp_connection_reset(struct evhttp_connection *evcon)
|
|||||||
event_del(&evcon->ev);
|
event_del(&evcon->ev);
|
||||||
|
|
||||||
if (evcon->fd != -1) {
|
if (evcon->fd != -1) {
|
||||||
|
/* inform interested parties about connection close */
|
||||||
|
if (evcon->closecb != NULL)
|
||||||
|
(*evcon->closecb)(evcon, evcon->closecb_arg);
|
||||||
|
|
||||||
close(evcon->fd);
|
close(evcon->fd);
|
||||||
evcon->fd = -1;
|
evcon->fd = -1;
|
||||||
}
|
}
|
||||||
@ -717,7 +728,6 @@ evhttp_detect_close_cb(int fd, short what, void *arg)
|
|||||||
static void
|
static void
|
||||||
evhttp_connection_start_detectclose(struct evhttp_connection *evcon)
|
evhttp_connection_start_detectclose(struct evhttp_connection *evcon)
|
||||||
{
|
{
|
||||||
assert((evcon->flags & EVHTTP_REQ_OWN_CONNECTION) == 0);
|
|
||||||
evcon->flags |= EVHTTP_CON_CLOSEDETECT;
|
evcon->flags |= EVHTTP_CON_CLOSEDETECT;
|
||||||
|
|
||||||
event_del(&evcon->ev);
|
event_del(&evcon->ev);
|
||||||
@ -1248,6 +1258,27 @@ evhttp_connection_set_retries(struct evhttp_connection *evcon,
|
|||||||
evcon->retry_max = retry_max;
|
evcon->retry_max = retry_max;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
evhttp_connection_set_closecb(struct evhttp_connection *evcon,
|
||||||
|
void (*cb)(struct evhttp_connection *, void *), void *cbarg)
|
||||||
|
{
|
||||||
|
evcon->closecb = cb;
|
||||||
|
evcon->closecb_arg = cbarg;
|
||||||
|
/*
|
||||||
|
* xxx: we cannot just call evhttp_connection_start_detectclose here
|
||||||
|
* that's valid only for client initiated connections that currently
|
||||||
|
* do not process any requests.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
evhttp_connection_get_peer(struct evhttp_connection *evcon,
|
||||||
|
char **address, u_short *port)
|
||||||
|
{
|
||||||
|
*address = evcon->address;
|
||||||
|
*port = evcon->port;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
evhttp_connection_connect(struct evhttp_connection *evcon)
|
evhttp_connection_connect(struct evhttp_connection *evcon)
|
||||||
{
|
{
|
||||||
@ -1417,6 +1448,37 @@ evhttp_send_reply(struct evhttp_request *req, int code, const char *reason,
|
|||||||
evhttp_send(req, databuf);
|
evhttp_send(req, databuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
evhttp_send_reply_start(struct evhttp_request *req, int code,
|
||||||
|
const char *reason)
|
||||||
|
{
|
||||||
|
evhttp_response_code(req, code, reason);
|
||||||
|
evhttp_make_header(req->evcon, req);
|
||||||
|
evhttp_write_buffer(req->evcon, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
evhttp_send_reply_data(struct evhttp_request *req, struct evbuffer *databuf)
|
||||||
|
{
|
||||||
|
evbuffer_add_buffer(req->evcon->output_buffer, databuf);
|
||||||
|
evhttp_write_buffer(req->evcon, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
evhttp_send_reply_done(struct evhttp_request *req)
|
||||||
|
{
|
||||||
|
struct evhttp_connection *evcon = req->evcon;
|
||||||
|
|
||||||
|
if (!event_pending(&evcon->ev, EV_WRITE|EV_TIMEOUT, NULL)) {
|
||||||
|
/* let the connection know that we are done with the request */
|
||||||
|
evhttp_send_done(evcon, NULL);
|
||||||
|
} else {
|
||||||
|
/* make the callback execute after all data has been written */
|
||||||
|
evcon->cb = evhttp_send_done;
|
||||||
|
evcon->cb_arg = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
evhttp_response_code(struct evhttp_request *req, int code, const char *reason)
|
evhttp_response_code(struct evhttp_request *req, int code, const char *reason)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user