Adjust daapcache so it serves User-Agent to httpd_daap's reply handlers

This commit is contained in:
ejurgensen 2014-08-23 00:02:01 +02:00
parent 624dd40c59
commit cf091e8d8b
7 changed files with 99 additions and 91 deletions

View File

@ -38,34 +38,43 @@
#include "daap_cache.h" #include "daap_cache.h"
/* The DAAP cache will only cache raw daap replies for these queries. /* The DAAP cache will only cache raw daap replies for these queries.
* Remove session_id and revision-number from the query, if you add a new one * Remove session_id and revision-number from the query, if you add a new one.
* You can't add queries where the canonical reply is not HTTP_OK, because
* daap_request will use that as default for cache replies.
*
* TODO: Don't hardcode, detect slow queries and add them dynamically * TODO: Don't hardcode, detect slow queries and add them dynamically
*/ */
static const char *daapcache_queries[] = struct daapcache_query_t
{ {
// Remote 4.2, Playlist 1 - Library const char *ua;
"/databases/1/containers/1/items?meta=dmap.itemname,dmap.itemid,daap.songartist,daap.songalbumartist,daap.songalbum,com.apple.itunes.cloud-id,dmap.containeritemid,com.apple.itunes.has-video,com.apple.itunes.itms-songid,com.apple.itunes.extended-media-kind,dmap.downloadstatus,daap.songdisabled&type=music&sort=name&include-sort-headers=1&query=('com.apple.itunes.extended-media-kind:1','com.apple.itunes.extended-media-kind:32')", const char *query;
// Remote 4.2, Albums };
"/databases/1/groups?meta=dmap.itemname,dmap.itemid,dmap.persistentid,daap.songartist,com.apple.itunes.cloud-id,daap.songartistid,daap.songalbumid,dmap.persistentid,daap.songtime,daap.songdatereleased,dmap.downloadstatus&type=music&group-type=albums&sort=album&include-sort-headers=0&query=('daap.songalbum!:'%2B('com.apple.itunes.extended-media-kind:1','com.apple.itunes.extended-media-kind:32'))",
// Remote 4.2, Artists static const struct daapcache_query_t daapcache_queries[] =
"/databases/1/groups?meta=dmap.itemname,dmap.itemid,dmap.persistentid,daap.songartist,daap.groupalbumcount,daap.songartistid&type=music&group-type=artists&sort=album&include-sort-headers=1&query=('daap.songartist!:'%2B('com.apple.itunes.extended-media-kind:1','com.apple.itunes.extended-media-kind:32'))", {
// iTunes 11.3, DB song list // Remote 4.2, Playlist 1 - Library
"/databases/1/items?delta=0&type=music&meta=all", { "Remote", "/databases/1/containers/1/items?meta=dmap.itemname,dmap.itemid,daap.songartist,daap.songalbumartist,daap.songalbum,com.apple.itunes.cloud-id,dmap.containeritemid,com.apple.itunes.has-video,com.apple.itunes.itms-songid,com.apple.itunes.extended-media-kind,dmap.downloadstatus,daap.songdisabled&type=music&sort=name&include-sort-headers=1&query=('com.apple.itunes.extended-media-kind:1','com.apple.itunes.extended-media-kind:32')" },
// iTunes 11.3, Playlist 1 - Library // Remote 4.2, Albums
"/databases/1/containers/1/items?delta=0&type=music&meta=dmap.itemkind,dmap.itemid,dmap.containeritemid", { "Remote", "/databases/1/groups?meta=dmap.itemname,dmap.itemid,dmap.persistentid,daap.songartist,com.apple.itunes.cloud-id,daap.songartistid,daap.songalbumid,dmap.persistentid,daap.songtime,daap.songdatereleased,dmap.downloadstatus&type=music&group-type=albums&sort=album&include-sort-headers=0&query=('daap.songalbum!:'%2B('com.apple.itunes.extended-media-kind:1','com.apple.itunes.extended-media-kind:32'))" },
// iTunes 11.3, Playlist 2 - Music // Remote 4.2, Artists
"/databases/1/containers/2/items?delta=0&type=music&meta=dmap.itemkind,dmap.itemid,dmap.containeritemid", { "Remote", "/databases/1/groups?meta=dmap.itemname,dmap.itemid,dmap.persistentid,daap.songartist,daap.groupalbumcount,daap.songartistid&type=music&group-type=artists&sort=album&include-sort-headers=1&query=('daap.songartist!:'%2B('com.apple.itunes.extended-media-kind:1','com.apple.itunes.extended-media-kind:32'))" },
// TunesRemote+, Albums // iTunes 11.3, DB song list
"/databases/1/groups?meta=dmap.itemname,dmap.itemid,dmap.persistentid,daap.songartist&type=music&group-type=albums&sort=album&include-sort-headers=1", { "iTunes", "/databases/1/items?delta=0&type=music&meta=all" },
// TunesRemote+, Artists // iTunes 11.3, Playlist 1 - Library
"/databases/1/browse/artists?include-sort-headers=1", { "iTunes", "/databases/1/containers/1/items?delta=0&type=music&meta=dmap.itemkind,dmap.itemid,dmap.containeritemid" },
// Retune, Artists // iTunes 11.3, Playlist 2 - Music
"/databases/1/groups?meta=dmap.itemname,dmap.itemid,dmap.persistentid,daap.songartist,daap.groupalbumcount&type=music&group-type=artists&sort=album&include-sort-headers=1&query=(('com.apple.itunes.mediakind:1','com.apple.itunes.mediakind:32')+'daap.songartist!:')", { "iTunes", "/databases/1/containers/2/items?delta=0&type=music&meta=dmap.itemkind,dmap.itemid,dmap.containeritemid" },
// Retune, Albums // TunesRemote+, Albums
"/databases/1/groups?meta=dmap.itemname,dmap.itemid,dmap.persistentid,daap.songartist,daap.songdatereleased,dmap.itemcount,daap.songtime&type=music&group-type=albums&sort=album&include-sort-headers=1&query=(('com.apple.itunes.mediakind:1','com.apple.itunes.mediakind:32')+'daap.songalbum!:')", { "Remote", "/databases/1/groups?meta=dmap.itemname,dmap.itemid,dmap.persistentid,daap.songartist&type=music&group-type=albums&sort=album&include-sort-headers=1" },
// Retune, Playlist 1 - Library // TunesRemote+, Artists
"/databases/1/containers/1/items?meta=dmap.itemname,dmap.itemid,daap.songartist,daap.songalbum,daap.songtime,dmap.containeritemid,com.apple.tunes.has-video,com.apple.itunes.can-be-genius-seed&type=music&sort=artist&include-sort-headers=1&query=(('com.apple.itunes.mediakind:1','com.apple.itunes.mediakind:32'))", { "Remote", "/databases/1/browse/artists?include-sort-headers=1" },
}; // Retune, Artists
{ "Remote", "/databases/1/groups?meta=dmap.itemname,dmap.itemid,dmap.persistentid,daap.songartist,daap.groupalbumcount&type=music&group-type=artists&sort=album&include-sort-headers=1&query=(('com.apple.itunes.mediakind:1','com.apple.itunes.mediakind:32')+'daap.songartist!:')" },
// Retune, Albums
{ "Remote", "/databases/1/groups?meta=dmap.itemname,dmap.itemid,dmap.persistentid,daap.songartist,daap.songdatereleased,dmap.itemcount,daap.songtime&type=music&group-type=albums&sort=album&include-sort-headers=1&query=(('com.apple.itunes.mediakind:1','com.apple.itunes.mediakind:32')+'daap.songalbum!:')" },
// Retune, Playlist 1 - Library
{ "Remote", "/databases/1/containers/1/items?meta=dmap.itemname,dmap.itemid,daap.songartist,daap.songalbum,daap.songtime,dmap.containeritemid,com.apple.tunes.has-video,com.apple.itunes.can-be-genius-seed&type=music&sort=artist&include-sort-headers=1&query=(('com.apple.itunes.mediakind:1','com.apple.itunes.mediakind:32'))" },
};
struct daapcache_command; struct daapcache_command;
@ -432,9 +441,9 @@ daapcache_update_cb(int fd, short what, void *arg)
for (i = 0; i < (sizeof(daapcache_queries) / sizeof(daapcache_queries[0])); i++) for (i = 0; i < (sizeof(daapcache_queries) / sizeof(daapcache_queries[0])); i++)
{ {
query = strdup(daapcache_queries[i]); query = strdup(daapcache_queries[i].query);
evbuf = daap_reply_build(query); evbuf = daap_reply_build(query, daapcache_queries[i].ua);
if (!evbuf) if (!evbuf)
{ {
DPRINTF(E_LOG, L_DCACHE, "Error building DAAP reply for query: %s\n", query); DPRINTF(E_LOG, L_DCACHE, "Error building DAAP reply for query: %s\n", query);

View File

@ -357,6 +357,8 @@ httpd_stream_file(struct evhttp_request *req, int id)
struct evkeyvalq *output_headers; struct evkeyvalq *output_headers;
const char *param; const char *param;
const char *param_end; const char *param_end;
const char *ua;
const char *client_codecs;
char buf[64]; char buf[64];
int64_t offset; int64_t offset;
int64_t end_offset; int64_t end_offset;
@ -431,7 +433,10 @@ httpd_stream_file(struct evhttp_request *req, int id)
memset(st, 0, sizeof(struct stream_ctx)); memset(st, 0, sizeof(struct stream_ctx));
st->fd = -1; st->fd = -1;
transcode = transcode_needed(input_headers, mfi->codectype); ua = evhttp_find_header(input_headers, "User-Agent");
client_codecs = evhttp_find_header(input_headers, "Accept-Codecs");
transcode = transcode_needed(ua, client_codecs, mfi->codectype);
output_headers = evhttp_request_get_output_headers(req); output_headers = evhttp_request_get_output_headers(req);
@ -665,6 +670,9 @@ httpd_send_reply(struct evhttp_request *req, int code, const char *reason, struc
int zret; int zret;
int ret; int ret;
if (!req)
return;
if (!evbuf || (EVBUFFER_LENGTH(evbuf) == 0)) if (!evbuf || (EVBUFFER_LENGTH(evbuf) == 0))
{ {
DPRINTF(E_DBG, L_HTTPD, "Not gzipping body-less reply\n"); DPRINTF(E_DBG, L_HTTPD, "Not gzipping body-less reply\n");

View File

@ -72,7 +72,7 @@ extern struct event_base *evbase_httpd;
struct uri_map { struct uri_map {
regex_t preg; regex_t preg;
char *regexp; char *regexp;
int (*handler)(struct evhttp_request *req, struct evbuffer *evbuf, char **uri, struct evkeyvalq *query); int (*handler)(struct evhttp_request *req, struct evbuffer *evbuf, char **uri, struct evkeyvalq *query, const char *ua);
}; };
struct daap_session { struct daap_session {
@ -760,7 +760,7 @@ parse_meta(struct evhttp_request *req, char *tag, const char *param, const struc
static int static int
daap_reply_server_info(struct evhttp_request *req, struct evbuffer *evbuf, char **uri, struct evkeyvalq *query) daap_reply_server_info(struct evhttp_request *req, struct evbuffer *evbuf, char **uri, struct evkeyvalq *query, const char *ua)
{ {
struct evbuffer *content; struct evbuffer *content;
struct evkeyvalq *headers; struct evkeyvalq *headers;
@ -857,7 +857,7 @@ daap_reply_server_info(struct evhttp_request *req, struct evbuffer *evbuf, char
} }
static int static int
daap_reply_content_codes(struct evhttp_request *req, struct evbuffer *evbuf, char **uri, struct evkeyvalq *query) daap_reply_content_codes(struct evhttp_request *req, struct evbuffer *evbuf, char **uri, struct evkeyvalq *query, const char *ua)
{ {
const struct dmap_field *dmap_fields; const struct dmap_field *dmap_fields;
int nfields; int nfields;
@ -899,12 +899,10 @@ daap_reply_content_codes(struct evhttp_request *req, struct evbuffer *evbuf, cha
} }
static int static int
daap_reply_login(struct evhttp_request *req, struct evbuffer *evbuf, char **uri, struct evkeyvalq *query) daap_reply_login(struct evhttp_request *req, struct evbuffer *evbuf, char **uri, struct evkeyvalq *query, const char *ua)
{ {
struct pairing_info pi; struct pairing_info pi;
struct daap_session *s; struct daap_session *s;
struct evkeyvalq *headers;
const char *ua;
const char *param; const char *param;
int request_session_id; int request_session_id;
int ret; int ret;
@ -918,8 +916,6 @@ daap_reply_login(struct evhttp_request *req, struct evbuffer *evbuf, char **uri,
return -1; return -1;
} }
headers = evhttp_request_get_input_headers(req);
ua = evhttp_find_header(headers, "User-Agent");
if (ua && (strncmp(ua, "Remote", strlen("Remote")) == 0)) if (ua && (strncmp(ua, "Remote", strlen("Remote")) == 0))
{ {
param = evhttp_find_header(query, "pairing-guid"); param = evhttp_find_header(query, "pairing-guid");
@ -978,7 +974,7 @@ daap_reply_login(struct evhttp_request *req, struct evbuffer *evbuf, char **uri,
} }
static int static int
daap_reply_logout(struct evhttp_request *req, struct evbuffer *evbuf, char **uri, struct evkeyvalq *query) daap_reply_logout(struct evhttp_request *req, struct evbuffer *evbuf, char **uri, struct evkeyvalq *query, const char *ua)
{ {
struct daap_session *s; struct daap_session *s;
@ -994,7 +990,7 @@ daap_reply_logout(struct evhttp_request *req, struct evbuffer *evbuf, char **uri
} }
static int static int
daap_reply_update(struct evhttp_request *req, struct evbuffer *evbuf, char **uri, struct evkeyvalq *query) daap_reply_update(struct evhttp_request *req, struct evbuffer *evbuf, char **uri, struct evkeyvalq *query, const char *ua)
{ {
struct timeval tv; struct timeval tv;
struct daap_session *s; struct daap_session *s;
@ -1094,7 +1090,7 @@ daap_reply_update(struct evhttp_request *req, struct evbuffer *evbuf, char **uri
} }
static int static int
daap_reply_activity(struct evhttp_request *req, struct evbuffer *evbuf, char **uri, struct evkeyvalq *query) 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 */ /* That's so nice, thanks for letting us know */
evhttp_send_reply(req, HTTP_NOCONTENT, "No Content", evbuf); evhttp_send_reply(req, HTTP_NOCONTENT, "No Content", evbuf);
@ -1103,7 +1099,7 @@ daap_reply_activity(struct evhttp_request *req, struct evbuffer *evbuf, char **u
} }
static int static int
daap_reply_dblist(struct evhttp_request *req, struct evbuffer *evbuf, char **uri, struct evkeyvalq *query) daap_reply_dblist(struct evhttp_request *req, struct evbuffer *evbuf, char **uri, struct evkeyvalq *query, const char *ua)
{ {
struct evbuffer *content; struct evbuffer *content;
struct daap_session *s; struct daap_session *s;
@ -1159,7 +1155,7 @@ daap_reply_dblist(struct evhttp_request *req, struct evbuffer *evbuf, char **uri
} }
static int static int
daap_reply_songlist_generic(struct evhttp_request *req, struct evbuffer *evbuf, int playlist, struct evkeyvalq *query) daap_reply_songlist_generic(struct evhttp_request *req, struct evbuffer *evbuf, int playlist, struct evkeyvalq *query, const char *ua)
{ {
struct daap_session *s; struct daap_session *s;
struct query_params qp; struct query_params qp;
@ -1170,6 +1166,7 @@ daap_reply_songlist_generic(struct evhttp_request *req, struct evbuffer *evbuf,
const struct dmap_field **meta; const struct dmap_field **meta;
struct sort_ctx *sctx; struct sort_ctx *sctx;
const char *param; const char *param;
const char *client_codecs;
char *tag; char *tag;
int nmeta; int nmeta;
int sort_headers; int sort_headers;
@ -1263,8 +1260,8 @@ daap_reply_songlist_generic(struct evhttp_request *req, struct evbuffer *evbuf,
memset(&qp, 0, sizeof(struct query_params)); memset(&qp, 0, sizeof(struct query_params));
get_query_params(query, &sort_headers, &qp); get_query_params(query, &sort_headers, &qp);
if (req && (playlist == -1)) if (playlist == -1)
user_agent_filter(s->user_agent, &qp); user_agent_filter(ua, &qp);
sctx = NULL; sctx = NULL;
if (sort_headers) if (sort_headers)
@ -1305,13 +1302,14 @@ daap_reply_songlist_generic(struct evhttp_request *req, struct evbuffer *evbuf,
{ {
nsongs++; nsongs++;
// TODO client_codecs = NULL;
if (req) { if (req)
headers = evhttp_request_get_input_headers(req); {
transcode = transcode_needed(headers, dbmfi.codectype); headers = evhttp_request_get_input_headers(req);
} else { client_codecs = evhttp_find_header(headers, "Accept-Codecs");
transcode = 1; }
}
transcode = transcode_needed(ua, client_codecs, dbmfi.codectype);
ret = dmap_encode_file_metadata(songlist, song, &dbmfi, meta, nmeta, sort_headers, transcode); ret = dmap_encode_file_metadata(songlist, song, &dbmfi, meta, nmeta, sort_headers, transcode);
if (ret < 0) if (ret < 0)
@ -1410,8 +1408,7 @@ if (req) {
} }
} }
if (req) httpd_send_reply(req, HTTP_OK, "OK", evbuf);
httpd_send_reply(req, HTTP_OK, "OK", evbuf);
return 0; return 0;
@ -1432,13 +1429,13 @@ if (req) {
} }
static int static int
daap_reply_dbsonglist(struct evhttp_request *req, struct evbuffer *evbuf, char **uri, struct evkeyvalq *query) daap_reply_dbsonglist(struct evhttp_request *req, struct evbuffer *evbuf, char **uri, struct evkeyvalq *query, const char *ua)
{ {
return daap_reply_songlist_generic(req, evbuf, -1, query); return daap_reply_songlist_generic(req, evbuf, -1, query, ua);
} }
static int static int
daap_reply_plsonglist(struct evhttp_request *req, struct evbuffer *evbuf, char **uri, struct evkeyvalq *query) daap_reply_plsonglist(struct evhttp_request *req, struct evbuffer *evbuf, char **uri, struct evkeyvalq *query, const char *ua)
{ {
int playlist; int playlist;
int ret; int ret;
@ -1451,11 +1448,11 @@ daap_reply_plsonglist(struct evhttp_request *req, struct evbuffer *evbuf, char *
return -1; return -1;
} }
return daap_reply_songlist_generic(req, evbuf, playlist, query); return daap_reply_songlist_generic(req, evbuf, playlist, query, ua);
} }
static int static int
daap_reply_playlists(struct evhttp_request *req, struct evbuffer *evbuf, char **uri, struct evkeyvalq *query) daap_reply_playlists(struct evhttp_request *req, struct evbuffer *evbuf, char **uri, struct evkeyvalq *query, const char *ua)
{ {
struct query_params qp; struct query_params qp;
struct db_playlist_info dbpli; struct db_playlist_info dbpli;
@ -1701,7 +1698,7 @@ daap_reply_playlists(struct evhttp_request *req, struct evbuffer *evbuf, char **
} }
static int static int
daap_reply_groups(struct evhttp_request *req, struct evbuffer *evbuf, char **uri, struct evkeyvalq *query) daap_reply_groups(struct evhttp_request *req, struct evbuffer *evbuf, char **uri, struct evkeyvalq *query, const char *ua)
{ {
struct query_params qp; struct query_params qp;
struct db_group_info dbgri; struct db_group_info dbgri;
@ -1730,8 +1727,7 @@ daap_reply_groups(struct evhttp_request *req, struct evbuffer *evbuf, char **uri
get_query_params(query, &sort_headers, &qp); get_query_params(query, &sort_headers, &qp);
if (req) user_agent_filter(ua, &qp);
user_agent_filter(s->user_agent, &qp);
param = evhttp_find_header(query, "group-type"); param = evhttp_find_header(query, "group-type");
if (strcmp(param, "artists") == 0) if (strcmp(param, "artists") == 0)
@ -1981,8 +1977,7 @@ daap_reply_groups(struct evhttp_request *req, struct evbuffer *evbuf, char **uri
} }
} }
if (req) httpd_send_reply(req, HTTP_OK, "OK", evbuf);
httpd_send_reply(req, HTTP_OK, "OK", evbuf);
return 0; return 0;
@ -2003,7 +1998,7 @@ daap_reply_groups(struct evhttp_request *req, struct evbuffer *evbuf, char **uri
} }
static int static int
daap_reply_browse(struct evhttp_request *req, struct evbuffer *evbuf, char **uri, struct evkeyvalq *query) daap_reply_browse(struct evhttp_request *req, struct evbuffer *evbuf, char **uri, struct evkeyvalq *query, const char *ua)
{ {
struct query_params qp; struct query_params qp;
struct daap_session *s; struct daap_session *s;
@ -2017,13 +2012,14 @@ daap_reply_browse(struct evhttp_request *req, struct evbuffer *evbuf, char **uri
int ret; int ret;
s = daap_session_find(req, query, evbuf); s = daap_session_find(req, query, evbuf);
if (!s) if (!s && req)
return -1; return -1;
memset(&qp, 0, sizeof(struct query_params)); memset(&qp, 0, sizeof(struct query_params));
get_query_params(query, &sort_headers, &qp); get_query_params(query, &sort_headers, &qp);
user_agent_filter(s->user_agent, &qp);
user_agent_filter(ua, &qp);
if (strcmp(uri[3], "artists") == 0) if (strcmp(uri[3], "artists") == 0)
{ {
@ -2203,7 +2199,7 @@ daap_reply_browse(struct evhttp_request *req, struct evbuffer *evbuf, char **uri
/* NOTE: We only handle artwork at the moment */ /* NOTE: We only handle artwork at the moment */
static int static int
daap_reply_extra_data(struct evhttp_request *req, struct evbuffer *evbuf, char **uri, struct evkeyvalq *query) daap_reply_extra_data(struct evhttp_request *req, struct evbuffer *evbuf, char **uri, struct evkeyvalq *query, const char *ua)
{ {
char clen[32]; char clen[32];
struct daap_session *s; struct daap_session *s;
@ -2294,7 +2290,7 @@ daap_reply_extra_data(struct evhttp_request *req, struct evbuffer *evbuf, char *
} }
static int static int
daap_stream(struct evhttp_request *req, struct evbuffer *evbuf, char **uri, struct evkeyvalq *query) daap_stream(struct evhttp_request *req, struct evbuffer *evbuf, char **uri, struct evkeyvalq *query, const char *ua)
{ {
struct daap_session *s; struct daap_session *s;
int id; int id;
@ -2356,7 +2352,7 @@ static const struct dmap_field dmap_TST8 = { "test.long", "TST8", NULL, DMA
static const struct dmap_field dmap_TST9 = { "test.string", "TST9", NULL, DMAP_TYPE_STRING }; static const struct dmap_field dmap_TST9 = { "test.string", "TST9", NULL, DMAP_TYPE_STRING };
static int static int
daap_reply_dmap_test(struct evhttp_request *req, struct evbuffer *evbuf, char **uri, struct evkeyvalq *query) daap_reply_dmap_test(struct evhttp_request *req, struct evbuffer *evbuf, char **uri, struct evkeyvalq *query, const char *ua)
{ {
char buf[64]; char buf[64];
struct evbuffer *test; struct evbuffer *test;
@ -2694,7 +2690,7 @@ daap_request(struct evhttp_request *req)
evhttp_parse_query(full_uri, &query); evhttp_parse_query(full_uri, &query);
daap_handlers[handler].handler(req, evbuf, uri_parts, &query); daap_handlers[handler].handler(req, evbuf, uri_parts, &query, ua);
evhttp_clear_headers(&query); evhttp_clear_headers(&query);
evbuffer_free(evbuf); evbuffer_free(evbuf);
@ -2735,7 +2731,7 @@ daap_is_request(struct evhttp_request *req, char *uri)
} }
struct evbuffer * struct evbuffer *
daap_reply_build(char *full_uri) daap_reply_build(char *full_uri, const char *ua)
{ {
char *uri; char *uri;
char *ptr; char *ptr;
@ -2802,7 +2798,7 @@ daap_reply_build(char *full_uri)
evhttp_parse_query(full_uri, &query); evhttp_parse_query(full_uri, &query);
ret = daap_handlers[handler].handler(NULL, evbuf, uri_parts, &query); ret = daap_handlers[handler].handler(NULL, evbuf, uri_parts, &query, ua);
if (ret < 0) if (ret < 0)
{ {
evbuffer_free(evbuf); evbuffer_free(evbuf);

View File

@ -22,6 +22,6 @@ int
daap_is_request(struct evhttp_request *req, char *uri); daap_is_request(struct evhttp_request *req, char *uri);
struct evbuffer * struct evbuffer *
daap_reply_build(char *query); daap_reply_build(char *full_uri, const char *ua);
#endif /* !__HTTPD_DAAP_H__ */ #endif /* !__HTTPD_DAAP_H__ */

View File

@ -439,6 +439,8 @@ rsp_reply_playlist(struct evhttp_request *req, char **uri, struct evkeyvalq *que
struct db_media_file_info dbmfi; struct db_media_file_info dbmfi;
struct evkeyvalq *headers; struct evkeyvalq *headers;
const char *param; const char *param;
const char *ua;
const char *client_codecs;
char **strval; char **strval;
mxml_node_t *reply; mxml_node_t *reply;
mxml_node_t *status; mxml_node_t *status;
@ -531,7 +533,11 @@ rsp_reply_playlist(struct evhttp_request *req, char **uri, struct evkeyvalq *que
while (((ret = db_query_fetch_file(&qp, &dbmfi)) == 0) && (dbmfi.id)) while (((ret = db_query_fetch_file(&qp, &dbmfi)) == 0) && (dbmfi.id))
{ {
headers = evhttp_request_get_input_headers(req); headers = evhttp_request_get_input_headers(req);
transcode = transcode_needed(headers, dbmfi.codectype);
ua = evhttp_find_header(headers, "User-Agent");
client_codecs = evhttp_find_header(headers, "Accept-Codecs");
transcode = transcode_needed(ua, client_codecs, dbmfi.codectype);
/* Item block (one item) */ /* Item block (one item) */
item = mxmlNewElement(items, "item"); item = mxmlNewElement(items, "item");

View File

@ -712,15 +712,17 @@ transcode_cleanup(struct transcode_ctx *ctx)
int int
transcode_needed(struct evkeyvalq *headers, char *file_codectype) transcode_needed(const char *user_agent, const char *client_codecs, char *file_codectype)
{ {
const char *client_codecs;
const char *user_agent;
char *codectype; char *codectype;
cfg_t *lib; cfg_t *lib;
int size; int size;
int i; int i;
// If client is a Remote we will AirPlay, which means we will transcode to PCM
if (user_agent && strcasestr(user_agent, "remote"))
return 1;
if (!file_codectype) if (!file_codectype)
{ {
DPRINTF(E_LOG, L_XCODE, "Can't proceed, codectype is unknown (null)\n"); DPRINTF(E_LOG, L_XCODE, "Can't proceed, codectype is unknown (null)\n");
@ -763,10 +765,8 @@ transcode_needed(struct evkeyvalq *headers, char *file_codectype)
} }
} }
client_codecs = evhttp_find_header(headers, "Accept-Codecs");
if (!client_codecs) if (!client_codecs)
{ {
user_agent = evhttp_find_header(headers, "User-Agent");
if (user_agent) if (user_agent)
{ {
DPRINTF(E_DBG, L_XCODE, "User-Agent: %s\n", user_agent); DPRINTF(E_DBG, L_XCODE, "User-Agent: %s\n", user_agent);
@ -787,12 +787,6 @@ transcode_needed(struct evkeyvalq *headers, char *file_codectype)
{ {
DPRINTF(E_DBG, L_XCODE, "Client is Front Row, using iTunes codecs\n"); DPRINTF(E_DBG, L_XCODE, "Client is Front Row, using iTunes codecs\n");
client_codecs = itunes_codecs;
}
else if (strncmp(user_agent, "Remote", strlen("Remote")) == 0)
{
DPRINTF(E_DBG, L_XCODE, "Client is Remote, using iTunes codecs\n");
client_codecs = itunes_codecs; client_codecs = itunes_codecs;
} }
else if (strncmp(user_agent, "AppleCoreMedia", strlen("AppleCoreMedia")) == 0) else if (strncmp(user_agent, "AppleCoreMedia", strlen("AppleCoreMedia")) == 0)

View File

@ -3,11 +3,6 @@
#define __TRANSCODE_H__ #define __TRANSCODE_H__
#include <event.h> #include <event.h>
#ifdef HAVE_LIBEVENT2
# include <event2/http.h>
#else
# include "evhttp/evhttp.h"
#endif
struct transcode_ctx; struct transcode_ctx;
@ -24,6 +19,6 @@ void
transcode_cleanup(struct transcode_ctx *ctx); transcode_cleanup(struct transcode_ctx *ctx);
int int
transcode_needed(struct evkeyvalq *headers, char *file_codectype); transcode_needed(const char *user_agent, const char *client_codecs, char *file_codectype);
#endif /* !__TRANSCODE_H__ */ #endif /* !__TRANSCODE_H__ */