diff --git a/src/httpd.c b/src/httpd.c index 69b14cc0..4212e463 100644 --- a/src/httpd.c +++ b/src/httpd.c @@ -716,7 +716,7 @@ stream_end(struct stream_ctx *st, int failed) httpd_request_closecb_set(st->hreq, NULL, NULL); if (!failed) - httpd_reply_end_send(st->hreq); + httpd_send_reply_end(st->hreq); evbuffer_free(st->evbuf); event_free(st->ev); @@ -813,7 +813,7 @@ stream_chunk_xcode_cb(int fd, short event, void *arg) else ret = xcoded; - httpd_reply_chunk_send(st->hreq, st->evbuf, stream_chunk_resched_cb, st); + httpd_send_reply_chunk(st->hreq, st->evbuf, stream_chunk_resched_cb, st); st->offset += ret; @@ -869,7 +869,7 @@ stream_chunk_raw_cb(int fd, short event, void *arg) evbuffer_add(st->evbuf, st->buf, ret); - httpd_reply_chunk_send(st->hreq, st->evbuf, stream_chunk_resched_cb, st); + httpd_send_reply_chunk(st->hreq, st->evbuf, stream_chunk_resched_cb, st); st->offset += ret; @@ -941,7 +941,7 @@ handle_cors_preflight(struct httpd_request *hreq, const char *allow_origin) httpd_header_add(hreq->out_headers, "Access-Control-Allow-Headers", "authorization"); // In this case there is no reason to go through httpd_send_reply - httpd_reply_backend_send(hreq, HTTP_OK, "OK", NULL); + httpd_backend_reply_send(hreq->backend, HTTP_OK, "OK", NULL); return 0; } @@ -1236,7 +1236,7 @@ httpd_stream_file(struct httpd_request *hreq, int id) httpd_header_add(hreq->out_headers, "Content-Length", buf); } - httpd_reply_start_send(hreq, HTTP_OK, "OK"); + httpd_send_reply_start(hreq, HTTP_OK, "OK"); } else { @@ -1260,7 +1260,7 @@ httpd_stream_file(struct httpd_request *hreq, int id) else httpd_header_add(hreq->out_headers, "Content-Length", buf); - httpd_reply_start_send(hreq, 206, "Partial Content"); + httpd_send_reply_start(hreq, 206, "Partial Content"); } #ifdef HAVE_POSIX_FADVISE @@ -1388,7 +1388,7 @@ httpd_send_reply(struct httpd_request *hreq, int code, const char *reason, struc DPRINTF(E_DBG, L_HTTPD, "Gzipping response\n"); httpd_header_add(hreq->out_headers, "Content-Encoding", "gzip"); - httpd_reply_backend_send(hreq, code, reason, gzbuf); + httpd_backend_reply_send(hreq->backend, code, reason, gzbuf); evbuffer_free(gzbuf); // Drain original buffer, as would be after evhttp_send_reply() @@ -1396,10 +1396,28 @@ httpd_send_reply(struct httpd_request *hreq, int code, const char *reason, struc } else { - httpd_reply_backend_send(hreq, code, reason, evbuf); + httpd_backend_reply_send(hreq->backend, code, reason, evbuf); } } +void +httpd_send_reply_start(struct httpd_request *hreq, int code, const char *reason) +{ + httpd_backend_reply_start_send(hreq->backend, code, reason); +} + +void +httpd_send_reply_chunk(struct httpd_request *hreq, struct evbuffer *evbuf, httpd_connection_chunkcb cb, void *arg) +{ + httpd_backend_reply_chunk_send(hreq->backend, evbuf, cb, arg); +} + +void +httpd_send_reply_end(struct httpd_request *hreq) +{ + httpd_backend_reply_end_send(hreq->backend); +} + // This is a modified version of evhttp_send_error (credit libevent) void httpd_send_error(struct httpd_request *hreq, int error, const char *reason) @@ -1419,7 +1437,7 @@ httpd_send_error(struct httpd_request *hreq, int error, const char *reason) else evbuffer_add_printf(evbuf, ERR_PAGE, error, reason, reason); - httpd_reply_backend_send(hreq, error, reason, evbuf); + httpd_backend_reply_send(hreq->backend, error, reason, evbuf); if (evbuf) evbuffer_free(evbuf); diff --git a/src/httpd_internal.h b/src/httpd_internal.h index d76cdfde..0dd65a9a 100644 --- a/src/httpd_internal.h +++ b/src/httpd_internal.h @@ -16,6 +16,11 @@ typedef struct evhttp_request httpd_backend; typedef struct evkeyvalq httpd_headers; typedef struct evkeyvalq httpd_query; +typedef void (*httpd_general_cb)(httpd_backend *backend, void *arg); +typedef void (*httpd_connection_closecb)(httpd_connection *conn, void *arg); +typedef void (*httpd_connection_chunkcb)(httpd_connection *conn, void *arg); +typedef void (*httpd_query_iteratecb)(const char *key, const char *val, void *arg); + enum httpd_methods { HTTPD_METHOD_GET = 1 << 0, @@ -180,6 +185,15 @@ httpd_response_not_cachable(struct httpd_request *hreq); void httpd_send_reply(struct httpd_request *hreq, int code, const char *reason, struct evbuffer *evbuf, enum httpd_send_flags flags); +void +httpd_send_reply_start(struct httpd_request *hreq, int code, const char *reason); + +void +httpd_send_reply_chunk(struct httpd_request *hreq, struct evbuffer *evbuf, httpd_connection_chunkcb cb, void *arg); + +void +httpd_send_reply_end(struct httpd_request *hreq); + /* * This is a substitute for evhttp_send_error that should be used whenever an * error may be returned to a browser. It will set CORS headers as appropriate, @@ -209,11 +223,6 @@ httpd_basic_auth(struct httpd_request *hreq, const char *user, const char *passw /*-------------------------- WRAPPERS FOR EVHTTP -----------------------------*/ -typedef void (*httpd_general_cb)(httpd_backend *backend, void *arg); -typedef void (*httpd_connection_closecb)(httpd_connection *conn, void *arg); -typedef void (*httpd_connection_chunkcb)(httpd_connection *conn, void *arg); -typedef void (*httpd_query_iteratecb)(const char *key, const char *val, void *arg); - const char * httpd_query_value_find(httpd_query *query, const char *key); @@ -253,18 +262,6 @@ httpd_request_backend_free(struct httpd_request *hreq); int httpd_request_closecb_set(struct httpd_request *hreq, httpd_connection_closecb cb, void *arg); -void -httpd_reply_backend_send(struct httpd_request *hreq, int code, const char *reason, struct evbuffer *evbuf); - -void -httpd_reply_start_send(struct httpd_request *hreq, int code, const char *reason); - -void -httpd_reply_chunk_send(struct httpd_request *hreq, struct evbuffer *evbuf, httpd_connection_chunkcb cb, void *arg); - -void -httpd_reply_end_send(struct httpd_request *hreq); - void httpd_server_free(httpd_server *server); @@ -275,6 +272,21 @@ void httpd_server_allow_origin_set(httpd_server *server, bool allow); +/*----------------- Only called by httpd.c to send raw replies ---------------*/ + +void +httpd_backend_reply_send(httpd_backend *backend, int code, const char *reason, struct evbuffer *evbuf); + +void +httpd_backend_reply_start_send(httpd_backend *backend, int code, const char *reason); + +void +httpd_backend_reply_chunk_send(httpd_backend *backend, struct evbuffer *evbuf, httpd_connection_chunkcb cb, void *arg); + +void +httpd_backend_reply_end_send(httpd_backend *backend); + + /*---------- Only called by httpd.c to populate struct httpd_request ---------*/ httpd_connection * diff --git a/src/httpd_libevhttp.c b/src/httpd_libevhttp.c index 5b302c9c..604f48b7 100644 --- a/src/httpd_libevhttp.c +++ b/src/httpd_libevhttp.c @@ -7,48 +7,6 @@ #include "misc.h" // For net_evhttp_bind #include "httpd_internal.h" -int -httpd_connection_closecb_set(httpd_connection *conn, httpd_connection_closecb cb, void *arg) -{ - evhttp_connection_set_closecb(conn, cb, arg); - return 0; -} - -int -httpd_connection_peer_get(char **addr, uint16_t *port, httpd_connection *conn) -{ - evhttp_connection_get_peer(conn, addr, port); - return 0; -} - -void -httpd_connection_free(httpd_connection *conn) -{ - evhttp_connection_free(conn); -} - -httpd_connection * -httpd_request_connection_get(struct httpd_request *hreq) -{ - return httpd_backend_connection_get(hreq->backend); -} - -void -httpd_request_backend_free(struct httpd_request *hreq) -{ - evhttp_request_free(hreq->backend); -} - -int -httpd_request_closecb_set(struct httpd_request *hreq, httpd_connection_closecb cb, void *arg) -{ - httpd_connection *conn = httpd_request_connection_get(hreq); - if (!conn) - return -1; - - return httpd_connection_closecb_set(conn, cb, arg); -} - const char * httpd_query_value_find(httpd_query *query, const char *key) { @@ -96,34 +54,46 @@ httpd_headers_clear(httpd_headers *headers) evhttp_clear_headers(headers); } -httpd_headers * -httpd_request_output_headers_get(struct httpd_request *hreq) +int +httpd_connection_closecb_set(httpd_connection *conn, httpd_connection_closecb cb, void *arg) { - return evhttp_request_get_output_headers(hreq->backend); + evhttp_connection_set_closecb(conn, cb, arg); + return 0; +} + +int +httpd_connection_peer_get(char **addr, uint16_t *port, httpd_connection *conn) +{ + evhttp_connection_get_peer(conn, addr, port); + return 0; } void -httpd_reply_backend_send(struct httpd_request *hreq, int code, const char *reason, struct evbuffer *evbuf) +httpd_connection_free(httpd_connection *conn) { - evhttp_send_reply(hreq->backend, code, reason, evbuf); + evhttp_connection_free(conn); +} + +httpd_connection * +httpd_request_connection_get(struct httpd_request *hreq) +{ + return httpd_backend_connection_get(hreq->backend); } void -httpd_reply_start_send(struct httpd_request *hreq, int code, const char *reason) +httpd_request_backend_free(struct httpd_request *hreq) { - evhttp_send_reply_start(hreq->backend, code, reason); + evhttp_request_free(hreq->backend); } -void -httpd_reply_chunk_send(struct httpd_request *hreq, struct evbuffer *evbuf, httpd_connection_chunkcb cb, void *arg) +int +httpd_request_closecb_set(struct httpd_request *hreq, httpd_connection_closecb cb, void *arg) { - evhttp_send_reply_chunk_with_cb(hreq->backend, evbuf, cb, arg); -} + httpd_connection *conn = httpd_request_connection_get(hreq); + if (!conn) + return -1; -void -httpd_reply_end_send(struct httpd_request *hreq) -{ - evhttp_send_reply_end(hreq->backend); + return httpd_connection_closecb_set(conn, cb, arg); } void @@ -163,6 +133,30 @@ httpd_server_allow_origin_set(httpd_server *server, bool allow) evhttp_set_allowed_methods(server, EVHTTP_REQ_GET | EVHTTP_REQ_POST | EVHTTP_REQ_PUT | EVHTTP_REQ_DELETE | EVHTTP_REQ_HEAD | EVHTTP_REQ_OPTIONS); } +void +httpd_backend_reply_send(httpd_backend *backend, int code, const char *reason, struct evbuffer *evbuf) +{ + evhttp_send_reply(backend, code, reason, evbuf); +} + +void +httpd_backend_reply_start_send(httpd_backend *backend, int code, const char *reason) +{ + evhttp_send_reply_start(backend, code, reason); +} + +void +httpd_backend_reply_chunk_send(httpd_backend *backend, struct evbuffer *evbuf, httpd_connection_chunkcb cb, void *arg) +{ + evhttp_send_reply_chunk_with_cb(backend, evbuf, cb, arg); +} + +void +httpd_backend_reply_end_send(httpd_backend *backend) +{ + evhttp_send_reply_end(backend); +} + httpd_connection * httpd_backend_connection_get(httpd_backend *backend) { diff --git a/src/httpd_streaming.c b/src/httpd_streaming.c index 64e78179..d0a18fde 100644 --- a/src/httpd_streaming.c +++ b/src/httpd_streaming.c @@ -148,7 +148,7 @@ streaming_close_cb(httpd_connection *conn, void *arg) // Valgrind says libevent doesn't free the request on disconnect (even though it owns it - libevent bug?), // so we do it with a reply end - httpd_reply_end_send(session->hreq); + httpd_send_reply_end(session->hreq); free(session); if (!streaming_sessions) @@ -172,7 +172,7 @@ streaming_end(void) DPRINTF(E_INFO, L_STREAMING, "Force close stream to %s:%d\n", session->hreq->peer_address, (int)session->hreq->peer_port); httpd_request_closecb_set(session->hreq, NULL, NULL); - httpd_reply_end_send(session->hreq); + httpd_send_reply_end(session->hreq); streaming_sessions = session->next; free(session); @@ -440,7 +440,7 @@ streaming_send_cb(evutil_socket_t fd, short event, void *arg) free(splice_buf); splice_buf = NULL; - httpd_reply_chunk_send(session->hreq, evbuf, NULL, NULL); + httpd_send_reply_chunk(session->hreq, evbuf, NULL, NULL); if (session->next == NULL) { @@ -455,11 +455,11 @@ streaming_send_cb(evutil_socket_t fd, short event, void *arg) { buf = evbuffer_pullup(streaming_encoded_data, -1); evbuffer_add(evbuf, buf, len); - httpd_reply_chunk_send(session->hreq, evbuf, NULL, NULL); + httpd_send_reply_chunk(session->hreq, evbuf, NULL, NULL); } else { - httpd_reply_chunk_send(session->hreq, streaming_encoded_data, NULL, NULL); + httpd_send_reply_chunk(session->hreq, streaming_encoded_data, NULL, NULL); } session->bytes_sent += len; } @@ -575,7 +575,7 @@ streaming_request(struct httpd_request *hreq) httpd_header_add(hreq->out_headers, "Access-Control-Allow-Origin", "*"); httpd_header_add(hreq->out_headers, "Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS"); - httpd_reply_start_send(hreq, HTTP_OK, "OK"); + httpd_send_reply_start(hreq, HTTP_OK, "OK"); session = calloc(1, sizeof(struct streaming_session)); if (!session)