mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-08 11:53:00 -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 *,
|
||||
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 */
|
||||
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,
|
||||
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 */
|
||||
int evhttp_make_request(struct evhttp_connection *evcon,
|
||||
struct evhttp_request *req,
|
||||
|
@ -65,6 +65,9 @@ struct evhttp_connection {
|
||||
|
||||
void (*cb)(struct evhttp_connection *, void *);
|
||||
void *cb_arg;
|
||||
|
||||
void (*closecb)(struct evhttp_connection *, void *);
|
||||
void *closecb_arg;
|
||||
};
|
||||
|
||||
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 */
|
||||
(*evcon->cb)(evcon, evcon->cb_arg);
|
||||
if (evcon->cb != NULL)
|
||||
(*evcon->cb)(evcon, evcon->cb_arg);
|
||||
}
|
||||
|
||||
void
|
||||
@ -640,6 +641,12 @@ evhttp_connection_free(struct evhttp_connection *evcon)
|
||||
{
|
||||
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 */
|
||||
while ((req = TAILQ_FIRST(&evcon->requests)) != NULL) {
|
||||
TAILQ_REMOVE(&evcon->requests, req, next);
|
||||
@ -698,6 +705,10 @@ evhttp_connection_reset(struct evhttp_connection *evcon)
|
||||
event_del(&evcon->ev);
|
||||
|
||||
if (evcon->fd != -1) {
|
||||
/* inform interested parties about connection close */
|
||||
if (evcon->closecb != NULL)
|
||||
(*evcon->closecb)(evcon, evcon->closecb_arg);
|
||||
|
||||
close(evcon->fd);
|
||||
evcon->fd = -1;
|
||||
}
|
||||
@ -717,7 +728,6 @@ evhttp_detect_close_cb(int fd, short what, void *arg)
|
||||
static void
|
||||
evhttp_connection_start_detectclose(struct evhttp_connection *evcon)
|
||||
{
|
||||
assert((evcon->flags & EVHTTP_REQ_OWN_CONNECTION) == 0);
|
||||
evcon->flags |= EVHTTP_CON_CLOSEDETECT;
|
||||
|
||||
event_del(&evcon->ev);
|
||||
@ -1248,6 +1258,27 @@ evhttp_connection_set_retries(struct evhttp_connection *evcon,
|
||||
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
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
evhttp_response_code(struct evhttp_request *req, int code, const char *reason)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user