Merge branch 'cors' (includes modified gzip and daap cache)

This commit is contained in:
ejurgensen 2016-10-21 23:06:45 +02:00
commit 2f8c061c11
9 changed files with 331 additions and 222 deletions

View File

@ -38,6 +38,7 @@
#include "conffile.h"
#include "logger.h"
#include "httpd.h"
#include "httpd_daap.h"
#include "db.h"
#include "cache.h"
@ -680,7 +681,8 @@ cache_daap_query_add(void *arg, int *retval)
#undef Q_TMPL
}
/* Gets a reply from the cache */
// Gets a reply from the cache.
// cmdarg->evbuf will be filled with the reply (gzipped)
static enum command_state
cache_daap_query_get(void *arg, int *retval)
{
@ -783,6 +785,7 @@ cache_daap_update_cb(int fd, short what, void *arg)
{
sqlite3_stmt *stmt;
struct evbuffer *evbuf;
struct evbuffer *gzbuf;
char *errmsg;
char *query;
int ret;
@ -818,10 +821,23 @@ cache_daap_update_cb(int fd, short what, void *arg)
continue;
}
cache_daap_reply_add(query, evbuf);
gzbuf = httpd_gzip_deflate(evbuf);
if (!gzbuf)
{
DPRINTF(E_LOG, L_CACHE, "Error gzipping DAAP reply for query: %s\n", query);
cache_daap_query_delete(sqlite3_column_int(stmt, 0));
free(query);
evbuffer_free(evbuf);
continue;
}
evbuffer_free(evbuf);
cache_daap_reply_add(query, gzbuf);
free(query);
evbuffer_free(evbuf);
evbuffer_free(gzbuf);
}
if (ret != SQLITE_DONE)

View File

@ -56,7 +56,7 @@ static cfg_opt_t sec_general[] =
CFG_STR("cache_path", STATEDIR "/cache/" PACKAGE "/cache.db", CFGF_NONE),
CFG_INT("cache_daap_threshold", 1000, CFGF_NONE),
CFG_BOOL("speaker_autoselect", cfg_true, CFGF_NONE),
CFG_STR("allow_origin", NULL, CFGF_NONE),
CFG_STR("allow_origin", "*", CFGF_NONE),
CFG_END()
};

View File

@ -25,6 +25,7 @@
#include "db.h"
#include "misc.h"
#include "httpd.h"
#include "logger.h"
#include "dmap_common.h"
@ -355,7 +356,7 @@ dmap_send_error(struct evhttp_request *req, const char *container, const char *e
{
DPRINTF(E_LOG, L_DMAP, "Could not allocate evbuffer for DMAP error\n");
evhttp_send_error(req, HTTP_SERVUNAVAIL, "Internal Server Error");
httpd_send_error(req, HTTP_SERVUNAVAIL, "Internal Server Error");
return;
}
@ -366,7 +367,7 @@ dmap_send_error(struct evhttp_request *req, const char *container, const char *e
{
DPRINTF(E_LOG, L_DMAP, "Could not expand evbuffer for DMAP error\n");
evhttp_send_error(req, HTTP_SERVUNAVAIL, "Internal Server Error");
httpd_send_error(req, HTTP_SERVUNAVAIL, "Internal Server Error");
evbuffer_free(evbuf);
return;
@ -376,7 +377,7 @@ dmap_send_error(struct evhttp_request *req, const char *container, const char *e
dmap_add_int(evbuf, "mstt", 500);
dmap_add_string(evbuf, "msts", errmsg);
evhttp_send_reply(req, HTTP_OK, "OK", evbuf);
httpd_send_reply(req, HTTP_OK, "OK", evbuf, HTTPD_SEND_NO_GZIP);
evbuffer_free(evbuf);
}

View File

@ -86,6 +86,11 @@
#define STREAM_CHUNK_SIZE (64 * 1024)
#define WEBFACE_ROOT DATADIR "/webface/"
#define ERR_PAGE "<html>\n<head>\n" \
"<title>%d %s</title>\n" \
"</head>\n<body>\n" \
"<h1>%s</h1>\n" \
"</body>\n</html>\n"
struct content_type_map {
char *ext;
@ -134,6 +139,8 @@ static struct event *exitev;
static struct evhttp *evhttpd;
static pthread_t tid_httpd;
static char *allow_origin;
#ifdef HAVE_LIBEVENT2_OLD
struct stream_ctx *g_st;
#endif
@ -693,135 +700,141 @@ httpd_stream_file(struct evhttp_request *req, int id)
free_mfi(mfi, 0);
}
/* Thread: httpd */
void
httpd_send_reply(struct evhttp_request *req, int code, const char *reason, struct evbuffer *evbuf)
struct evbuffer *
httpd_gzip_deflate(struct evbuffer *in)
{
unsigned char outbuf[128 * 1024];
struct evbuffer *out;
struct evbuffer_iovec iovec[1];
z_stream strm;
struct evbuffer *gzbuf;
struct evkeyvalq *headers;
const char *param;
int flush;
int zret;
int ret;
char *origin;
if (!req)
return;
if (!evbuf || (evbuffer_get_length(evbuf) == 0))
{
DPRINTF(E_DBG, L_HTTPD, "Not gzipping body-less reply\n");
goto no_gzip;
}
headers = evhttp_request_get_input_headers(req);
param = evhttp_find_header(headers, "Accept-Encoding");
if (!param)
{
DPRINTF(E_DBG, L_HTTPD, "Not gzipping; no Accept-Encoding header\n");
goto no_gzip;
}
else if (!strstr(param, "gzip") && !strstr(param, "*"))
{
DPRINTF(E_DBG, L_HTTPD, "Not gzipping; gzip not in Accept-Encoding (%s)\n", param);
goto no_gzip;
}
gzbuf = evbuffer_new();
if (!gzbuf)
{
DPRINTF(E_LOG, L_HTTPD, "Could not allocate evbuffer for gzipped reply\n");
goto no_gzip;
}
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
/* Set up a gzip stream (the "+ 16" in 15 + 16), instead of a zlib stream (default) */
zret = deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 15 + 16, 8, Z_DEFAULT_STRATEGY);
if (zret != Z_OK)
// Set up a gzip stream (the "+ 16" in 15 + 16), instead of a zlib stream (default)
ret = deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 15 + 16, 8, Z_DEFAULT_STRATEGY);
if (ret != Z_OK)
{
DPRINTF(E_DBG, L_HTTPD, "zlib setup failed: %s\n", zError(zret));
goto out_fail_init;
DPRINTF(E_LOG, L_HTTPD, "zlib setup failed: %s\n", zError(ret));
return NULL;
}
strm.next_in = evbuffer_pullup(evbuf, -1);
strm.avail_in = evbuffer_get_length(evbuf);
strm.next_in = evbuffer_pullup(in, -1);
strm.avail_in = evbuffer_get_length(in);
flush = Z_NO_FLUSH;
/* 2 iterations: Z_NO_FLUSH until input is consumed, then Z_FINISH */
for (;;)
out = evbuffer_new();
if (!out)
{
do
{
strm.next_out = outbuf;
strm.avail_out = sizeof(outbuf);
zret = deflate(&strm, flush);
if (zret == Z_STREAM_ERROR)
{
DPRINTF(E_LOG, L_HTTPD, "Could not deflate data: %s\n", strm.msg);
goto out_fail_gz;
}
ret = evbuffer_add(gzbuf, outbuf, sizeof(outbuf) - strm.avail_out);
if (ret < 0)
{
DPRINTF(E_LOG, L_HTTPD, "Out of memory adding gzipped data to evbuffer\n");
goto out_fail_gz;
}
}
while (strm.avail_out == 0);
if (flush == Z_FINISH)
break;
flush = Z_FINISH;
DPRINTF(E_LOG, L_HTTPD, "Could not allocate evbuffer for gzipped reply\n");
goto out_deflate_end;
}
if (zret != Z_STREAM_END)
// We use this to avoid a memcpy. The 512 is an arbitrary padding to make sure
// there is enough space, even if the compressed output should be slightly
// larger than input (could happen with small inputs).
ret = evbuffer_reserve_space(out, strm.avail_in + 512, iovec, 1);
if (ret < 0)
{
DPRINTF(E_LOG, L_HTTPD, "Compressed data not finalized!\n");
goto out_fail_gz;
DPRINTF(E_LOG, L_HTTPD, "Could not reserve memory for gzipped reply\n");
goto out_evbuf_free;
}
strm.next_out = iovec[0].iov_base;
strm.avail_out = iovec[0].iov_len;
ret = deflate(&strm, Z_FINISH);
if (ret != Z_STREAM_END)
goto out_evbuf_free;
iovec[0].iov_len -= strm.avail_out;
evbuffer_commit_space(out, iovec, 1);
deflateEnd(&strm);
headers = evhttp_request_get_output_headers(req);
return out;
origin = cfg_getstr(cfg_getsec(cfg, "general"), "allow_origin");
if (origin && strlen(origin))
evhttp_add_header(headers, "Access-Control-Allow-Origin", origin);
out_evbuf_free:
evbuffer_free(out);
evhttp_add_header(headers, "Content-Encoding", "gzip");
evhttp_send_reply(req, code, reason, gzbuf);
evbuffer_free(gzbuf);
/* Drain original buffer, as would be after evhttp_send_reply() */
evbuffer_drain(evbuf, evbuffer_get_length(evbuf));
return;
out_fail_gz:
out_deflate_end:
deflateEnd(&strm);
out_fail_init:
evbuffer_free(gzbuf);
no_gzip:
evhttp_send_reply(req, code, reason, evbuf);
return NULL;
}
void
httpd_send_reply(struct evhttp_request *req, int code, const char *reason, struct evbuffer *evbuf, enum httpd_send_flags flags)
{
struct evbuffer *gzbuf;
struct evkeyvalq *input_headers;
struct evkeyvalq *output_headers;
const char *param;
int do_gzip;
if (!req)
return;
input_headers = evhttp_request_get_input_headers(req);
output_headers = evhttp_request_get_output_headers(req);
do_gzip = ( (!(flags & HTTPD_SEND_NO_GZIP)) &&
evbuf && (evbuffer_get_length(evbuf) > 512) &&
(param = evhttp_find_header(input_headers, "Accept-Encoding")) &&
(strstr(param, "gzip") || strstr(param, "*"))
);
if (allow_origin)
evhttp_add_header(output_headers, "Access-Control-Allow-Origin", allow_origin);
if (do_gzip && (gzbuf = httpd_gzip_deflate(evbuf)))
{
DPRINTF(E_DBG, L_HTTPD, "Gzipping response\n");
evhttp_add_header(output_headers, "Content-Encoding", "gzip");
evhttp_send_reply(req, code, reason, gzbuf);
evbuffer_free(gzbuf);
// Drain original buffer, as would be after evhttp_send_reply()
evbuffer_drain(evbuf, evbuffer_get_length(evbuf));
}
else
{
evhttp_send_reply(req, code, reason, evbuf);
}
}
// This is a modified version of evhttp_send_error (credit libevent)
void
httpd_send_error(struct evhttp_request* req, int error, const char* reason)
{
struct evkeyvalq *output_headers;
struct evbuffer *evbuf;
if (!allow_origin)
{
evhttp_send_error(req, error, reason);
return;
}
output_headers = evhttp_request_get_output_headers(req);
evhttp_clear_headers(output_headers);
evhttp_add_header(output_headers, "Access-Control-Allow-Origin", allow_origin);
evhttp_add_header(output_headers, "Content-Type", "text/html");
evhttp_add_header(output_headers, "Connection", "close");
evbuf = evbuffer_new();
if (!evbuf)
DPRINTF(E_LOG, L_HTTPD, "Could not allocate evbuffer for error page\n");
else
evbuffer_add_printf(evbuf, ERR_PAGE, error, reason, reason);
evhttp_send_reply(req, error, reason, evbuf);
if (evbuf)
evbuffer_free(evbuf);
}
/* Thread: httpd */
@ -847,14 +860,14 @@ redirect_to_index(struct evhttp_request *req, char *uri)
{
DPRINTF(E_LOG, L_HTTPD, "Redirection URL exceeds buffer length\n");
evhttp_send_error(req, HTTP_NOTFOUND, "Not Found");
httpd_send_error(req, HTTP_NOTFOUND, "Not Found");
return;
}
headers = evhttp_request_get_output_headers(req);
evhttp_add_header(headers, "Location", buf);
evhttp_send_reply(req, HTTP_MOVETEMP, "Moved", NULL);
httpd_send_reply(req, HTTP_MOVETEMP, "Moved", NULL, HTTPD_SEND_NO_GZIP);
}
/* Thread: httpd */
@ -894,7 +907,7 @@ serve_file(struct evhttp_request *req, char *uri)
{
DPRINTF(E_LOG, L_HTTPD, "Remote web interface request denied; no password set\n");
evhttp_send_error(req, 403, "Forbidden");
httpd_send_error(req, 403, "Forbidden");
return;
}
}
@ -904,7 +917,7 @@ serve_file(struct evhttp_request *req, char *uri)
{
DPRINTF(E_LOG, L_HTTPD, "Request exceeds PATH_MAX: %s\n", uri);
evhttp_send_error(req, HTTP_NOTFOUND, "Not Found");
httpd_send_error(req, HTTP_NOTFOUND, "Not Found");
return;
}
@ -914,7 +927,7 @@ serve_file(struct evhttp_request *req, char *uri)
{
DPRINTF(E_LOG, L_HTTPD, "Could not lstat() %s: %s\n", path, strerror(errno));
evhttp_send_error(req, HTTP_NOTFOUND, "Not Found");
httpd_send_error(req, HTTP_NOTFOUND, "Not Found");
return;
}
@ -932,7 +945,7 @@ serve_file(struct evhttp_request *req, char *uri)
{
DPRINTF(E_LOG, L_HTTPD, "Could not dereference %s: %s\n", path, strerror(errno));
evhttp_send_error(req, HTTP_NOTFOUND, "Not Found");
httpd_send_error(req, HTTP_NOTFOUND, "Not Found");
return;
}
@ -941,7 +954,7 @@ serve_file(struct evhttp_request *req, char *uri)
{
DPRINTF(E_LOG, L_HTTPD, "Dereferenced path exceeds PATH_MAX: %s\n", path);
evhttp_send_error(req, HTTP_NOTFOUND, "Not Found");
httpd_send_error(req, HTTP_NOTFOUND, "Not Found");
free(deref);
return;
@ -955,7 +968,7 @@ serve_file(struct evhttp_request *req, char *uri)
{
DPRINTF(E_LOG, L_HTTPD, "Could not stat() %s: %s\n", path, strerror(errno));
evhttp_send_error(req, HTTP_NOTFOUND, "Not Found");
httpd_send_error(req, HTTP_NOTFOUND, "Not Found");
return;
}
@ -970,7 +983,7 @@ serve_file(struct evhttp_request *req, char *uri)
if (path_is_legal(path) != 0)
{
evhttp_send_error(req, 403, "Forbidden");
httpd_send_error(req, 403, "Forbidden");
return;
}
@ -980,7 +993,7 @@ serve_file(struct evhttp_request *req, char *uri)
{
DPRINTF(E_LOG, L_HTTPD, "Could not create evbuffer\n");
evhttp_send_error(req, HTTP_SERVUNAVAIL, "Internal error");
httpd_send_error(req, HTTP_SERVUNAVAIL, "Internal error");
return;
}
@ -989,7 +1002,7 @@ serve_file(struct evhttp_request *req, char *uri)
{
DPRINTF(E_LOG, L_HTTPD, "Could not open %s: %s\n", path, strerror(errno));
evhttp_send_error(req, HTTP_NOTFOUND, "Not Found");
httpd_send_error(req, HTTP_NOTFOUND, "Not Found");
return;
}
@ -1002,7 +1015,7 @@ serve_file(struct evhttp_request *req, char *uri)
{
DPRINTF(E_LOG, L_HTTPD, "Could not read file into evbuffer\n");
evhttp_send_error(req, HTTP_SERVUNAVAIL, "Internal error");
httpd_send_error(req, HTTP_SERVUNAVAIL, "Internal error");
return;
}
@ -1021,9 +1034,9 @@ serve_file(struct evhttp_request *req, char *uri)
}
headers = evhttp_request_get_output_headers(req);
evhttp_add_header(headers, "Content-Type", ctype);
evhttp_send_reply(req, HTTP_OK, "OK", evbuf);
httpd_send_reply(req, HTTP_OK, "OK", evbuf, HTTPD_SEND_NO_GZIP);
evbuffer_free(evbuf);
}
@ -1032,10 +1045,32 @@ serve_file(struct evhttp_request *req, char *uri)
static void
httpd_gen_cb(struct evhttp_request *req, void *arg)
{
struct evkeyvalq *input_headers;
struct evkeyvalq *output_headers;
const char *req_uri;
char *uri;
char *ptr;
// Did we get a CORS preflight request?
input_headers = evhttp_request_get_input_headers(req);
if ( input_headers && allow_origin &&
(evhttp_request_get_command(req) == EVHTTP_REQ_OPTIONS) &&
evhttp_find_header(input_headers, "Origin") &&
evhttp_find_header(input_headers, "Access-Control-Request-Method") )
{
output_headers = evhttp_request_get_output_headers(req);
evhttp_add_header(output_headers, "Access-Control-Allow-Origin", allow_origin);
// Allow only GET method and authorization header in cross origin requests
evhttp_add_header(output_headers, "Access-Control-Allow-Method", "GET");
evhttp_add_header(output_headers, "Access-Control-Allow-Headers", "authorization");
// In this case there is no reason to go through httpd_send_reply
evhttp_send_reply(req, HTTP_OK, "OK", NULL);
return;
}
req_uri = evhttp_request_get_uri(req);
if (!req_uri)
{
@ -1286,28 +1321,30 @@ httpd_basic_auth(struct evhttp_request *req, char *user, char *passwd, char *rea
header = (char *)malloc(len);
if (!header)
{
evhttp_send_error(req, HTTP_SERVUNAVAIL, "Internal Server Error");
httpd_send_error(req, HTTP_SERVUNAVAIL, "Internal Server Error");
return -1;
}
ret = snprintf(header, len, "Basic realm=\"%s\"", realm);
if ((ret < 0) || (ret >= len))
{
evhttp_send_error(req, HTTP_SERVUNAVAIL, "Internal Server Error");
httpd_send_error(req, HTTP_SERVUNAVAIL, "Internal Server Error");
return -1;
}
evbuf = evbuffer_new();
if (!evbuf)
{
evhttp_send_error(req, HTTP_SERVUNAVAIL, "Internal Server Error");
httpd_send_error(req, HTTP_SERVUNAVAIL, "Internal Server Error");
return -1;
}
headers = evhttp_request_get_output_headers(req);
evhttp_add_header(headers, "WWW-Authenticate", header);
evbuffer_add(evbuf, http_reply_401, strlen(http_reply_401));
evhttp_send_reply(req, 401, "Unauthorized", evbuf);
httpd_send_reply(req, 401, "Unauthorized", evbuf, HTTPD_SEND_NO_GZIP);
free(header);
evbuffer_free(evbuf);
@ -1403,6 +1440,16 @@ httpd_init(void)
v6enabled = cfg_getbool(cfg_getsec(cfg, "general"), "ipv6");
port = cfg_getint(cfg_getsec(cfg, "library"), "port");
// For CORS headers
allow_origin = cfg_getstr(cfg_getsec(cfg, "general"), "allow_origin");
if (allow_origin)
{
if (strlen(allow_origin) != 0)
evhttp_set_allowed_methods(evhttpd, EVHTTP_REQ_GET | EVHTTP_REQ_POST | EVHTTP_REQ_HEAD | EVHTTP_REQ_OPTIONS);
else
allow_origin = NULL;
}
if (v6enabled)
{
ret = evhttp_bind_socket(evhttpd, "::", port);

View File

@ -5,11 +5,52 @@
#include <event2/http.h>
#include <event2/buffer.h>
enum httpd_send_flags
{
HTTPD_SEND_NO_GZIP = (1 << 0),
};
void
httpd_stream_file(struct evhttp_request *req, int id);
/*
* Gzips an evbuffer
*
* @in in Data to be compressed
* @return Compressed data - must be freed by caller
*/
struct evbuffer *
httpd_gzip_deflate(struct evbuffer *in);
/*
* This wrapper around evhttp_send_reply should be used whenever a request may
* come from a browser. It will automatically gzip if feasible, but the caller
* may direct it not to. It will set CORS headers as appropriate. Should be
* thread safe.
*
* @in req The evhttp request struct
* @in code HTTP code, e.g. 200
* @in reason A brief explanation of the error - if NULL the standard meaning
of the error code will be used
* @in evbuf Data for the response body
* @in flags See flags above
*/
void
httpd_send_reply(struct evhttp_request *req, int code, const char *reason, struct evbuffer *evbuf);
httpd_send_reply(struct evhttp_request *req, int code, const char *reason, struct evbuffer *evbuf, enum httpd_send_flags flags);
/*
* 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,
* which is not possible with evhttp_send_error, because it clears the headers.
* Should be thread safe.
*
* @in req The evhttp request struct
* @in error HTTP code, e.g. 200
* @in reason A brief explanation of the error - if NULL the standard meaning
of the error code will be used
*/
void
httpd_send_error(struct evhttp_request *req, int error, const char *reason);
char *
httpd_fixup_uri(struct evhttp_request *req);

View File

@ -282,7 +282,7 @@ daap_session_find(struct evhttp_request *req, struct evkeyvalq *query, struct ev
return s;
invalid:
evhttp_send_error(req, 403, "Forbidden");
httpd_send_error(req, 403, "Forbidden");
return NULL;
}
@ -355,7 +355,7 @@ update_refresh_cb(int fd, short event, void *arg)
evcon = evhttp_request_get_connection(ur->req);
evhttp_connection_set_closecb(evcon, NULL, NULL);
httpd_send_reply(ur->req, HTTP_OK, "OK", evbuf);
httpd_send_reply(ur->req, HTTP_OK, "OK", evbuf, 0);
update_remove(ur);
}
@ -882,7 +882,7 @@ daap_reply_server_info(struct evhttp_request *req, struct evbuffer *evbuf, char
evbuffer_add_buffer(evbuf, content);
evbuffer_free(content);
httpd_send_reply(req, HTTP_OK, "OK", evbuf);
httpd_send_reply(req, HTTP_OK, "OK", evbuf, 0);
return 0;
}
@ -924,7 +924,7 @@ daap_reply_content_codes(struct evhttp_request *req, struct evbuffer *evbuf, cha
dmap_add_short(evbuf, "mcty", dmap_fields[i].type); /* 10 */
}
httpd_send_reply(req, HTTP_OK, "OK", evbuf);
httpd_send_reply(req, HTTP_OK, "OK", evbuf, 0);
return 0;
}
@ -954,7 +954,7 @@ daap_reply_login(struct evhttp_request *req, struct evbuffer *evbuf, char **uri,
{
DPRINTF(E_LOG, L_DAAP, "Login attempt with U-A: Remote and no pairing-guid\n");
evhttp_send_error(req, 403, "Forbidden");
httpd_send_error(req, 403, "Forbidden");
return -1;
}
@ -967,7 +967,7 @@ daap_reply_login(struct evhttp_request *req, struct evbuffer *evbuf, char **uri,
DPRINTF(E_LOG, L_DAAP, "Login attempt with invalid pairing-guid\n");
free_pi(&pi, 1);
evhttp_send_error(req, 403, "Forbidden");
httpd_send_error(req, 403, "Forbidden");
return -1;
}
@ -999,7 +999,7 @@ daap_reply_login(struct evhttp_request *req, struct evbuffer *evbuf, char **uri,
dmap_add_int(evbuf, "mstt", 200); /* 12 */
dmap_add_int(evbuf, "mlid", s->id); /* 12 */
httpd_send_reply(req, HTTP_OK, "OK", evbuf);
httpd_send_reply(req, HTTP_OK, "OK", evbuf, 0);
return 0;
}
@ -1015,7 +1015,7 @@ daap_reply_logout(struct evhttp_request *req, struct evbuffer *evbuf, char **uri
daap_session_remove(s);
httpd_send_reply(req, 204, "Logout Successful", evbuf);
httpd_send_reply(req, 204, "Logout Successful", evbuf, 0);
return 0;
}
@ -1068,7 +1068,7 @@ daap_reply_update(struct evhttp_request *req, struct evbuffer *evbuf, char **uri
dmap_add_int(evbuf, "mstt", 200); /* 12 */
dmap_add_int(evbuf, "musr", current_rev); /* 12 */
httpd_send_reply(req, HTTP_OK, "OK", evbuf);
httpd_send_reply(req, HTTP_OK, "OK", evbuf, 0);
return 0;
}
@ -1122,7 +1122,7 @@ static int
daap_reply_activity(struct evhttp_request *req, struct evbuffer *evbuf, char **uri, struct evkeyvalq *query, const char *ua)
{
/* That's so nice, thanks for letting us know */
evhttp_send_reply(req, HTTP_NOCONTENT, "No Content", evbuf);
httpd_send_reply(req, HTTP_NOCONTENT, "No Content", evbuf, HTTPD_SEND_NO_GZIP);
return 0;
}
@ -1222,7 +1222,7 @@ daap_reply_dblist(struct evhttp_request *req, struct evbuffer *evbuf, char **uri
evbuffer_add_buffer(evbuf, content);
evbuffer_free(content);
httpd_send_reply(req, HTTP_OK, "OK", evbuf);
httpd_send_reply(req, HTTP_OK, "OK", evbuf, 0);
return 0;
}
@ -1510,7 +1510,7 @@ daap_reply_songlist_generic(struct evhttp_request *req, struct evbuffer *evbuf,
}
}
httpd_send_reply(req, HTTP_OK, "OK", evbuf);
httpd_send_reply(req, HTTP_OK, "OK", evbuf, 0);
return 0;
@ -1821,7 +1821,7 @@ daap_reply_playlists(struct evhttp_request *req, struct evbuffer *evbuf, char **
return -1;
}
httpd_send_reply(req, HTTP_OK, "OK", evbuf);
httpd_send_reply(req, HTTP_OK, "OK", evbuf, 0);
return 0;
@ -2132,7 +2132,7 @@ daap_reply_groups(struct evhttp_request *req, struct evbuffer *evbuf, char **uri
}
}
httpd_send_reply(req, HTTP_OK, "OK", evbuf);
httpd_send_reply(req, HTTP_OK, "OK", evbuf, 0);
return 0;
@ -2338,7 +2338,7 @@ daap_reply_browse(struct evhttp_request *req, struct evbuffer *evbuf, char **uri
}
}
httpd_send_reply(req, HTTP_OK, "OK", evbuf);
httpd_send_reply(req, HTTP_OK, "OK", evbuf, 0);
ret = 0;
@ -2378,7 +2378,7 @@ daap_reply_extra_data(struct evhttp_request *req, struct evbuffer *evbuf, char *
ret = safe_atoi32(uri[3], &id);
if (ret < 0)
{
evhttp_send_error(req, HTTP_BADREQUEST, "Bad Request");
httpd_send_error(req, HTTP_BADREQUEST, "Bad Request");
return -1;
}
@ -2390,7 +2390,7 @@ daap_reply_extra_data(struct evhttp_request *req, struct evbuffer *evbuf, char *
{
DPRINTF(E_LOG, L_DAAP, "Could not convert mw parameter to integer\n");
evhttp_send_error(req, HTTP_BADREQUEST, "Bad Request");
httpd_send_error(req, HTTP_BADREQUEST, "Bad Request");
return -1;
}
@ -2400,7 +2400,7 @@ daap_reply_extra_data(struct evhttp_request *req, struct evbuffer *evbuf, char *
{
DPRINTF(E_LOG, L_DAAP, "Could not convert mh parameter to integer\n");
evhttp_send_error(req, HTTP_BADREQUEST, "Bad Request");
httpd_send_error(req, HTTP_BADREQUEST, "Bad Request");
return -1;
}
}
@ -2442,12 +2442,11 @@ daap_reply_extra_data(struct evhttp_request *req, struct evbuffer *evbuf, char *
snprintf(clen, sizeof(clen), "%ld", (long)len);
evhttp_add_header(headers, "Content-Length", clen);
/* No gzip compression for artwork */
evhttp_send_reply(req, HTTP_OK, "OK", evbuf);
httpd_send_reply(req, HTTP_OK, "OK", evbuf, HTTPD_SEND_NO_GZIP);
return 0;
no_artwork:
evhttp_send_reply(req, HTTP_NOCONTENT, "No Content", evbuf);
httpd_send_reply(req, HTTP_NOCONTENT, "No Content", evbuf, HTTPD_SEND_NO_GZIP);
return -1;
}
@ -2459,7 +2458,7 @@ daap_stream(struct evhttp_request *req, struct evbuffer *evbuf, char **uri, stru
ret = safe_atoi32(uri[3], &id);
if (ret < 0)
evhttp_send_error(req, HTTP_BADREQUEST, "Bad Request");
httpd_send_error(req, HTTP_BADREQUEST, "Bad Request");
else
httpd_stream_file(req, id);
@ -2602,7 +2601,7 @@ daap_reply_dmap_test(struct evhttp_request *req, struct evbuffer *evbuf, char **
return -1;
}
evhttp_send_reply(req, HTTP_OK, "OK", evbuf);
httpd_send_reply(req, HTTP_OK, "OK", evbuf, HTTPD_SEND_NO_GZIP);
return 0;
}
@ -2711,7 +2710,7 @@ daap_request(struct evhttp_request *req)
full_uri = httpd_fixup_uri(req);
if (!full_uri)
{
evhttp_send_error(req, HTTP_BADREQUEST, "Bad Request");
httpd_send_error(req, HTTP_BADREQUEST, "Bad Request");
return;
}
@ -2719,7 +2718,7 @@ daap_request(struct evhttp_request *req)
if (!ptr)
{
free(full_uri);
evhttp_send_error(req, HTTP_BADREQUEST, "Bad Request");
httpd_send_error(req, HTTP_BADREQUEST, "Bad Request");
return;
}
@ -2730,7 +2729,7 @@ daap_request(struct evhttp_request *req)
if (!uri)
{
evhttp_send_error(req, HTTP_BADREQUEST, "Bad Request");
httpd_send_error(req, HTTP_BADREQUEST, "Bad Request");
return;
}
@ -2741,7 +2740,7 @@ daap_request(struct evhttp_request *req)
if (!uri)
{
free(full_uri);
evhttp_send_error(req, HTTP_BADREQUEST, "Bad Request");
httpd_send_error(req, HTTP_BADREQUEST, "Bad Request");
return;
}
@ -2762,7 +2761,7 @@ daap_request(struct evhttp_request *req)
{
DPRINTF(E_LOG, L_DAAP, "Unrecognized DAAP request\n");
evhttp_send_error(req, HTTP_BADREQUEST, "Bad Request");
httpd_send_error(req, HTTP_BADREQUEST, "Bad Request");
free(uri);
free(full_uri);
@ -2820,7 +2819,7 @@ daap_request(struct evhttp_request *req)
{
DPRINTF(E_LOG, L_DAAP, "DAAP URI has too many/few components (%d)\n", (uri_parts[0]) ? i : 0);
evhttp_send_error(req, HTTP_BADREQUEST, "Bad Request");
httpd_send_error(req, HTTP_BADREQUEST, "Bad Request");
free(uri);
free(full_uri);
@ -2842,7 +2841,7 @@ daap_request(struct evhttp_request *req)
{
DPRINTF(E_LOG, L_DAAP, "Could not allocate evbuffer for DAAP reply\n");
evhttp_send_error(req, HTTP_SERVUNAVAIL, "Internal Server Error");
httpd_send_error(req, HTTP_SERVUNAVAIL, "Internal Server Error");
free(uri);
free(full_uri);
@ -2853,7 +2852,9 @@ daap_request(struct evhttp_request *req)
ret = cache_daap_get(full_uri, evbuf);
if (ret == 0)
{
httpd_send_reply(req, HTTP_OK, "OK", evbuf); // TODO not all want this reply
// The cache will return the data gzipped, so httpd_send_reply won't need to do it
evhttp_add_header(headers, "Content-Encoding", "gzip");
httpd_send_reply(req, HTTP_OK, "OK", evbuf, HTTPD_SEND_NO_GZIP); // TODO not all want this reply
evbuffer_free(evbuf);
free(uri);

View File

@ -368,10 +368,10 @@ playstatusupdate_cb(int fd, short what, void *arg)
{
buf = evbuffer_pullup(update, -1);
evbuffer_add(evbuf, buf, len);
httpd_send_reply(ur->req, HTTP_OK, "OK", evbuf);
httpd_send_reply(ur->req, HTTP_OK, "OK", evbuf, 0);
}
else
httpd_send_reply(ur->req, HTTP_OK, "OK", update);
httpd_send_reply(ur->req, HTTP_OK, "OK", update, 0);
free(ur);
}
@ -774,7 +774,7 @@ dacp_reply_ctrlint(struct evhttp_request *req, struct evbuffer *evbuf, char **ur
dmap_add_char(evbuf, "cmrl", 1); /* 9, unknown */
dmap_add_long(evbuf, "ceSX", (1 << 1 | 1)); /* 16, unknown dacp - lowest bit announces support for playqueue-contents/-edit */
httpd_send_reply(req, HTTP_OK, "OK", evbuf);
httpd_send_reply(req, HTTP_OK, "OK", evbuf, 0);
}
static int
@ -1103,7 +1103,7 @@ dacp_reply_cue_play(struct evhttp_request *req, struct evbuffer *evbuf, char **u
dmap_add_int(evbuf, "mstt", 200); /* 12 */
dmap_add_int(evbuf, "miid", id); /* 12 */
httpd_send_reply(req, HTTP_OK, "OK", evbuf);
httpd_send_reply(req, HTTP_OK, "OK", evbuf, 0);
}
static void
@ -1119,7 +1119,7 @@ dacp_reply_cue_clear(struct evhttp_request *req, struct evbuffer *evbuf, char **
dmap_add_int(evbuf, "mstt", 200); /* 12 */
dmap_add_int(evbuf, "miid", 0); /* 12 */
httpd_send_reply(req, HTTP_OK, "OK", evbuf);
httpd_send_reply(req, HTTP_OK, "OK", evbuf, 0);
}
static void
@ -1282,11 +1282,11 @@ dacp_reply_playspec(struct evhttp_request *req, struct evbuffer *evbuf, char **u
}
/* 204 No Content is the canonical reply */
evhttp_send_reply(req, HTTP_NOCONTENT, "No Content", evbuf);
httpd_send_reply(req, HTTP_NOCONTENT, "No Content", evbuf, HTTPD_SEND_NO_GZIP);
return;
out_fail:
evhttp_send_error(req, 500, "Internal Server Error");
httpd_send_error(req, 500, "Internal Server Error");
}
static void
@ -1301,7 +1301,7 @@ dacp_reply_pause(struct evhttp_request *req, struct evbuffer *evbuf, char **uri,
player_playback_pause();
/* 204 No Content is the canonical reply */
evhttp_send_reply(req, HTTP_NOCONTENT, "No Content", evbuf);
httpd_send_reply(req, HTTP_NOCONTENT, "No Content", evbuf, HTTPD_SEND_NO_GZIP);
}
static void
@ -1328,13 +1328,13 @@ dacp_reply_playpause(struct evhttp_request *req, struct evbuffer *evbuf, char **
{
DPRINTF(E_LOG, L_DACP, "Player returned an error for start after pause\n");
evhttp_send_error(req, 500, "Internal Server Error");
httpd_send_error(req, 500, "Internal Server Error");
return;
}
}
/* 204 No Content is the canonical reply */
evhttp_send_reply(req, HTTP_NOCONTENT, "No Content", evbuf);
httpd_send_reply(req, HTTP_NOCONTENT, "No Content", evbuf, HTTPD_SEND_NO_GZIP);
}
static void
@ -1352,7 +1352,7 @@ dacp_reply_nextitem(struct evhttp_request *req, struct evbuffer *evbuf, char **u
{
DPRINTF(E_LOG, L_DACP, "Player returned an error for nextitem\n");
evhttp_send_error(req, 500, "Internal Server Error");
httpd_send_error(req, 500, "Internal Server Error");
return;
}
@ -1361,12 +1361,12 @@ dacp_reply_nextitem(struct evhttp_request *req, struct evbuffer *evbuf, char **u
{
DPRINTF(E_LOG, L_DACP, "Player returned an error for start after nextitem\n");
evhttp_send_error(req, 500, "Internal Server Error");
httpd_send_error(req, 500, "Internal Server Error");
return;
}
/* 204 No Content is the canonical reply */
evhttp_send_reply(req, HTTP_NOCONTENT, "No Content", evbuf);
httpd_send_reply(req, HTTP_NOCONTENT, "No Content", evbuf, HTTPD_SEND_NO_GZIP);
}
static void
@ -1384,7 +1384,7 @@ dacp_reply_previtem(struct evhttp_request *req, struct evbuffer *evbuf, char **u
{
DPRINTF(E_LOG, L_DACP, "Player returned an error for previtem\n");
evhttp_send_error(req, 500, "Internal Server Error");
httpd_send_error(req, 500, "Internal Server Error");
return;
}
@ -1393,12 +1393,12 @@ dacp_reply_previtem(struct evhttp_request *req, struct evbuffer *evbuf, char **u
{
DPRINTF(E_LOG, L_DACP, "Player returned an error for start after previtem\n");
evhttp_send_error(req, 500, "Internal Server Error");
httpd_send_error(req, 500, "Internal Server Error");
return;
}
/* 204 No Content is the canonical reply */
evhttp_send_reply(req, HTTP_NOCONTENT, "No Content", evbuf);
httpd_send_reply(req, HTTP_NOCONTENT, "No Content", evbuf, HTTPD_SEND_NO_GZIP);
}
static void
@ -1413,7 +1413,7 @@ dacp_reply_beginff(struct evhttp_request *req, struct evbuffer *evbuf, char **ur
/* TODO */
/* 204 No Content is the canonical reply */
evhttp_send_reply(req, HTTP_NOCONTENT, "No Content", evbuf);
httpd_send_reply(req, HTTP_NOCONTENT, "No Content", evbuf, HTTPD_SEND_NO_GZIP);
}
static void
@ -1428,7 +1428,7 @@ dacp_reply_beginrew(struct evhttp_request *req, struct evbuffer *evbuf, char **u
/* TODO */
/* 204 No Content is the canonical reply */
evhttp_send_reply(req, HTTP_NOCONTENT, "No Content", evbuf);
httpd_send_reply(req, HTTP_NOCONTENT, "No Content", evbuf, HTTPD_SEND_NO_GZIP);
}
static void
@ -1443,7 +1443,7 @@ dacp_reply_playresume(struct evhttp_request *req, struct evbuffer *evbuf, char *
/* TODO */
/* 204 No Content is the canonical reply */
evhttp_send_reply(req, HTTP_NOCONTENT, "No Content", evbuf);
httpd_send_reply(req, HTTP_NOCONTENT, "No Content", evbuf, HTTPD_SEND_NO_GZIP);
}
static int
@ -1673,7 +1673,7 @@ dacp_reply_playqueuecontents(struct evhttp_request *req, struct evbuffer *evbuf,
dmap_add_char(evbuf, "apsm", status.shuffle); /* 9, daap.playlistshufflemode - not part of mlcl container */
dmap_add_char(evbuf, "aprm", status.repeat); /* 9, daap.playlistrepeatmode - not part of mlcl container */
httpd_send_reply(req, HTTP_OK, "OK", evbuf);
httpd_send_reply(req, HTTP_OK, "OK", evbuf, 0);
}
static void
@ -1697,7 +1697,7 @@ dacp_reply_playqueueedit_clear(struct evhttp_request *req, struct evbuffer *evbu
dmap_add_int(evbuf, "mstt", 200); /* 12 */
dmap_add_int(evbuf, "miid", 0); /* 12 */
httpd_send_reply(req, HTTP_OK, "OK", evbuf);
httpd_send_reply(req, HTTP_OK, "OK", evbuf, 0);
}
static void
@ -1826,7 +1826,7 @@ dacp_reply_playqueueedit_add(struct evhttp_request *req, struct evbuffer *evbuf,
}
/* 204 No Content is the canonical reply */
evhttp_send_reply(req, HTTP_NOCONTENT, "No Content", evbuf);
httpd_send_reply(req, HTTP_NOCONTENT, "No Content", evbuf, HTTPD_SEND_NO_GZIP);
}
static void
@ -1871,7 +1871,7 @@ dacp_reply_playqueueedit_move(struct evhttp_request *req, struct evbuffer *evbuf
}
/* 204 No Content is the canonical reply */
evhttp_send_reply(req, HTTP_NOCONTENT, "No Content", evbuf);
httpd_send_reply(req, HTTP_NOCONTENT, "No Content", evbuf, HTTPD_SEND_NO_GZIP);
}
static void
@ -1903,7 +1903,7 @@ dacp_reply_playqueueedit_remove(struct evhttp_request *req, struct evbuffer *evb
}
/* 204 No Content is the canonical reply */
evhttp_send_reply(req, HTTP_NOCONTENT, "No Content", evbuf);
httpd_send_reply(req, HTTP_NOCONTENT, "No Content", evbuf, HTTPD_SEND_NO_GZIP);
}
static void
@ -2023,9 +2023,9 @@ dacp_reply_playstatusupdate(struct evhttp_request *req, struct evbuffer *evbuf,
{
ret = make_playstatusupdate(evbuf);
if (ret < 0)
evhttp_send_error(req, 500, "Internal Server Error");
httpd_send_error(req, 500, "Internal Server Error");
else
httpd_send_reply(req, HTTP_OK, "OK", evbuf);
httpd_send_reply(req, HTTP_OK, "OK", evbuf, 0);
return;
}
@ -2076,7 +2076,7 @@ dacp_reply_nowplayingartwork(struct evhttp_request *req, struct evbuffer *evbuf,
{
DPRINTF(E_LOG, L_DACP, "Request for artwork without mw parameter\n");
evhttp_send_error(req, HTTP_BADREQUEST, "Bad Request");
httpd_send_error(req, HTTP_BADREQUEST, "Bad Request");
return;
}
@ -2085,7 +2085,7 @@ dacp_reply_nowplayingartwork(struct evhttp_request *req, struct evbuffer *evbuf,
{
DPRINTF(E_LOG, L_DACP, "Could not convert mw parameter to integer\n");
evhttp_send_error(req, HTTP_BADREQUEST, "Bad Request");
httpd_send_error(req, HTTP_BADREQUEST, "Bad Request");
return;
}
@ -2094,7 +2094,7 @@ dacp_reply_nowplayingartwork(struct evhttp_request *req, struct evbuffer *evbuf,
{
DPRINTF(E_LOG, L_DACP, "Request for artwork without mh parameter\n");
evhttp_send_error(req, HTTP_BADREQUEST, "Bad Request");
httpd_send_error(req, HTTP_BADREQUEST, "Bad Request");
return;
}
@ -2103,7 +2103,7 @@ dacp_reply_nowplayingartwork(struct evhttp_request *req, struct evbuffer *evbuf,
{
DPRINTF(E_LOG, L_DACP, "Could not convert mh parameter to integer\n");
evhttp_send_error(req, HTTP_BADREQUEST, "Bad Request");
httpd_send_error(req, HTTP_BADREQUEST, "Bad Request");
return;
}
@ -2137,12 +2137,11 @@ dacp_reply_nowplayingartwork(struct evhttp_request *req, struct evbuffer *evbuf,
snprintf(clen, sizeof(clen), "%ld", (long)len);
evhttp_add_header(headers, "Content-Length", clen);
/* No gzip compression for artwork */
evhttp_send_reply(req, HTTP_OK, "OK", evbuf);
httpd_send_reply(req, HTTP_OK, "OK", evbuf, HTTPD_SEND_NO_GZIP);
return;
no_artwork:
evhttp_send_error(req, HTTP_NOTFOUND, "Not Found");
httpd_send_error(req, HTTP_NOTFOUND, "Not Found");
}
static void
@ -2243,7 +2242,7 @@ dacp_reply_getproperty(struct evhttp_request *req, struct evbuffer *evbuf, char
return;
}
httpd_send_reply(req, HTTP_OK, "OK", evbuf);
httpd_send_reply(req, HTTP_OK, "OK", evbuf, 0);
return;
@ -2291,7 +2290,7 @@ dacp_reply_setproperty(struct evhttp_request *req, struct evbuffer *evbuf, char
}
/* 204 No Content is the canonical reply */
evhttp_send_reply(req, HTTP_NOCONTENT, "No Content", evbuf);
httpd_send_reply(req, HTTP_NOCONTENT, "No Content", evbuf, HTTPD_SEND_NO_GZIP);
}
static void
@ -2354,7 +2353,7 @@ dacp_reply_getspeakers(struct evhttp_request *req, struct evbuffer *evbuf, char
evbuffer_free(spklist);
httpd_send_reply(req, HTTP_OK, "OK", evbuf);
httpd_send_reply(req, HTTP_OK, "OK", evbuf, 0);
}
static void
@ -2377,7 +2376,7 @@ dacp_reply_setspeakers(struct evhttp_request *req, struct evbuffer *evbuf, char
{
DPRINTF(E_LOG, L_DACP, "Missing speaker-id parameter in DACP setspeakers request\n");
evhttp_send_error(req, HTTP_BADREQUEST, "Bad Request");
httpd_send_error(req, HTTP_BADREQUEST, "Bad Request");
return;
}
@ -2397,7 +2396,7 @@ dacp_reply_setspeakers(struct evhttp_request *req, struct evbuffer *evbuf, char
{
DPRINTF(E_LOG, L_DACP, "Out of memory for speaker ids\n");
evhttp_send_error(req, HTTP_SERVUNAVAIL, "Internal Server Error");
httpd_send_error(req, HTTP_SERVUNAVAIL, "Internal Server Error");
return;
}
@ -2437,15 +2436,15 @@ dacp_reply_setspeakers(struct evhttp_request *req, struct evbuffer *evbuf, char
/* Password problem */
if (ret == -2)
evhttp_send_error(req, 902, "");
httpd_send_error(req, 902, "");
else
evhttp_send_error(req, 500, "Internal Server Error");
httpd_send_error(req, 500, "Internal Server Error");
return;
}
/* 204 No Content is the canonical reply */
evhttp_send_reply(req, HTTP_NOCONTENT, "No Content", evbuf);
httpd_send_reply(req, HTTP_NOCONTENT, "No Content", evbuf, HTTPD_SEND_NO_GZIP);
}
@ -2548,7 +2547,7 @@ dacp_request(struct evhttp_request *req)
full_uri = httpd_fixup_uri(req);
if (!full_uri)
{
evhttp_send_error(req, HTTP_BADREQUEST, "Bad Request");
httpd_send_error(req, HTTP_BADREQUEST, "Bad Request");
return;
}
@ -2560,7 +2559,7 @@ dacp_request(struct evhttp_request *req)
if (!uri)
{
free(full_uri);
evhttp_send_error(req, HTTP_BADREQUEST, "Bad Request");
httpd_send_error(req, HTTP_BADREQUEST, "Bad Request");
return;
}
@ -2588,7 +2587,7 @@ dacp_request(struct evhttp_request *req)
{
DPRINTF(E_LOG, L_DACP, "Unrecognized DACP request\n");
evhttp_send_error(req, HTTP_BADREQUEST, "Bad Request");
httpd_send_error(req, HTTP_BADREQUEST, "Bad Request");
free(uri);
free(full_uri);
@ -2609,7 +2608,7 @@ dacp_request(struct evhttp_request *req)
{
DPRINTF(E_LOG, L_DACP, "DACP URI has too many/few components (%d)\n", (uri_parts[0]) ? i : 0);
evhttp_send_error(req, HTTP_BADREQUEST, "Bad Request");
httpd_send_error(req, HTTP_BADREQUEST, "Bad Request");
free(uri);
free(full_uri);
@ -2621,7 +2620,7 @@ dacp_request(struct evhttp_request *req)
{
DPRINTF(E_LOG, L_DACP, "Could not allocate evbuffer for DACP reply\n");
evhttp_send_error(req, HTTP_SERVUNAVAIL, "Internal Server Error");
httpd_send_error(req, HTTP_SERVUNAVAIL, "Internal Server Error");
free(uri);
free(full_uri);

View File

@ -251,7 +251,7 @@ rsp_send_error(struct evhttp_request *req, char *errmsg)
if (!evbuf)
{
evhttp_send_error(req, HTTP_SERVUNAVAIL, "Internal Server Error");
httpd_send_error(req, HTTP_SERVUNAVAIL, "Internal Server Error");
return;
}
@ -259,7 +259,8 @@ rsp_send_error(struct evhttp_request *req, char *errmsg)
headers = evhttp_request_get_output_headers(req);
evhttp_add_header(headers, "Content-Type", "text/xml; charset=utf-8");
evhttp_add_header(headers, "Connection", "close");
evhttp_send_reply(req, HTTP_OK, "OK", evbuf);
httpd_send_reply(req, HTTP_OK, "OK", evbuf, HTTPD_SEND_NO_GZIP);
evbuffer_free(evbuf);
}
@ -283,7 +284,8 @@ rsp_send_reply(struct evhttp_request *req, mxml_node_t *reply)
headers = evhttp_request_get_output_headers(req);
evhttp_add_header(headers, "Content-Type", "text/xml; charset=utf-8");
evhttp_add_header(headers, "Connection", "close");
httpd_send_reply(req, HTTP_OK, "OK", evbuf);
httpd_send_reply(req, HTTP_OK, "OK", evbuf, 0);
evbuffer_free(evbuf);
}
@ -745,7 +747,7 @@ rsp_stream(struct evhttp_request *req, char **uri, struct evkeyvalq *query)
ret = safe_atoi32(uri[2], &id);
if (ret < 0)
evhttp_send_error(req, HTTP_BADREQUEST, "Bad Request");
httpd_send_error(req, HTTP_BADREQUEST, "Bad Request");
else
httpd_stream_file(req, id);
}

View File

@ -55,6 +55,7 @@
#include "logger.h"
#include "db.h"
#include "conffile.h"
#include "httpd.h"
#include "misc.h"
#include "listener.h"
#include "artwork.h"
@ -4534,7 +4535,7 @@ artwork_cb(struct evhttp_request *req, void *arg)
if (evhttp_request_get_command(req) != EVHTTP_REQ_GET)
{
DPRINTF(E_LOG, L_MPD, "Unsupported request type for artwork\n");
evhttp_send_error(req, HTTP_BADMETHOD, "Method not allowed");
httpd_send_error(req, HTTP_BADMETHOD, "Method not allowed");
return;
}
@ -4545,7 +4546,7 @@ artwork_cb(struct evhttp_request *req, void *arg)
if (!decoded)
{
DPRINTF(E_LOG, L_MPD, "Bad artwork request with uri '%s'\n", uri);
evhttp_send_error(req, HTTP_BADREQUEST, 0);
httpd_send_error(req, HTTP_BADREQUEST, 0);
return;
}
@ -4553,7 +4554,7 @@ artwork_cb(struct evhttp_request *req, void *arg)
if (!path)
{
DPRINTF(E_LOG, L_MPD, "Invalid path from artwork request with uri '%s'\n", uri);
evhttp_send_error(req, HTTP_BADREQUEST, 0);
httpd_send_error(req, HTTP_BADREQUEST, 0);
evhttp_uri_free(decoded);
return;
}
@ -4562,7 +4563,7 @@ artwork_cb(struct evhttp_request *req, void *arg)
if (!decoded_path)
{
DPRINTF(E_LOG, L_MPD, "Error decoding path from artwork request with uri '%s'\n", uri);
evhttp_send_error(req, HTTP_BADREQUEST, 0);
httpd_send_error(req, HTTP_BADREQUEST, 0);
evhttp_uri_free(decoded);
return;
}
@ -4577,7 +4578,7 @@ artwork_cb(struct evhttp_request *req, void *arg)
if (!itemid)
{
DPRINTF(E_WARN, L_MPD, "No item found for path '%s' from request uri '%s'\n", decoded_path, uri);
evhttp_send_error(req, HTTP_NOTFOUND, "Document was not found");
httpd_send_error(req, HTTP_NOTFOUND, "Document was not found");
evhttp_uri_free(decoded);
free(decoded_path);
return;
@ -4587,7 +4588,7 @@ artwork_cb(struct evhttp_request *req, void *arg)
if (!evbuffer)
{
DPRINTF(E_LOG, L_MPD, "Could not allocate an evbuffer for artwork request\n");
evhttp_send_error(req, HTTP_INTERNAL, "Document was not found");
httpd_send_error(req, HTTP_INTERNAL, "Document was not found");
evhttp_uri_free(decoded);
free(decoded_path);
return;
@ -4596,7 +4597,7 @@ artwork_cb(struct evhttp_request *req, void *arg)
format = artwork_get_item(evbuffer, itemid, 600, 600);
if (format < 0)
{
evhttp_send_error(req, HTTP_NOTFOUND, "Document was not found");
httpd_send_error(req, HTTP_NOTFOUND, "Document was not found");
}
else
{
@ -4610,7 +4611,8 @@ artwork_cb(struct evhttp_request *req, void *arg)
evhttp_add_header(evhttp_request_get_output_headers(req), "Content-Type", "image/jpeg");
break;
}
evhttp_send_reply(req, HTTP_OK, "OK", evbuffer);
httpd_send_reply(req, HTTP_OK, "OK", evbuffer, HTTPD_SEND_NO_GZIP);
}
evbuffer_free(evbuffer);