mirror of
https://github.com/owntone/owntone-server.git
synced 2025-11-10 22:10:15 -05:00
Implement URI encoding quirk for iTunes and Roku
iTunes and Roku devices do not encode + as %2B in the query string and do not encode space as + either in the query string (though at least the Roku encode space as %20 everywhere). This needs to be worked around or browse queries fail to parse because + was decoded as space when the query really needs a + character.
This commit is contained in:
88
src/httpd.c
88
src/httpd.c
@@ -49,15 +49,19 @@
|
||||
/*
|
||||
* HTTP client quirks by User-Agent, from mt-daapd
|
||||
*
|
||||
* - Roku:
|
||||
* + Does not encode space as + in query string
|
||||
* - iTunes:
|
||||
* + Does not encode space as + in query string
|
||||
* + Connection: Keep-Alive on HTTP error 401
|
||||
* - Hifidelio:
|
||||
* + Connection: Keep-Alive for streaming (Connection: close not honoured)
|
||||
*
|
||||
* These quirks are not implemented. Implement as needed.
|
||||
*
|
||||
* Implemented quirks:
|
||||
*
|
||||
* - Roku:
|
||||
* + Does not encode space as + in query string
|
||||
* - iTunes:
|
||||
* + Does not encode space as + in query string
|
||||
*/
|
||||
|
||||
|
||||
@@ -715,6 +719,84 @@ exit_cb(int fd, short event, void *arg)
|
||||
httpd_exit = 1;
|
||||
}
|
||||
|
||||
char *
|
||||
httpd_fixup_uri(struct evhttp_request *req)
|
||||
{
|
||||
const char *ua;
|
||||
const char *uri;
|
||||
const char *u;
|
||||
const char *q;
|
||||
char *fixed;
|
||||
char *f;
|
||||
int len;
|
||||
|
||||
uri = evhttp_request_uri(req);
|
||||
if (!uri)
|
||||
return NULL;
|
||||
|
||||
/* No query string, nothing to do */
|
||||
q = strchr(uri, '?');
|
||||
if (!q)
|
||||
return strdup(uri);
|
||||
|
||||
ua = evhttp_find_header(req->input_headers, "User-Agent");
|
||||
if (!ua)
|
||||
return strdup(uri);
|
||||
|
||||
if ((strncmp(ua, "iTunes", strlen("iTunes")) != 0)
|
||||
&& (strncmp(ua, "Roku", strlen("Roku")) != 0))
|
||||
return strdup(uri);
|
||||
|
||||
/* Reencode + as %2B and space as + in the query,
|
||||
which iTunes and Roku devices don't do */
|
||||
len = strlen(uri);
|
||||
|
||||
u = q;
|
||||
while (*u)
|
||||
{
|
||||
if (*u == '+')
|
||||
len += 2;
|
||||
|
||||
u++;
|
||||
}
|
||||
|
||||
fixed = (char *)malloc(len + 1);
|
||||
if (!fixed)
|
||||
return NULL;
|
||||
|
||||
strncpy(fixed, uri, q - uri);
|
||||
|
||||
f = fixed + (q - uri);
|
||||
while (*q)
|
||||
{
|
||||
switch (*q)
|
||||
{
|
||||
case '+':
|
||||
*f = '%';
|
||||
f++;
|
||||
*f = '2';
|
||||
f++;
|
||||
*f = 'B';
|
||||
break;
|
||||
|
||||
case ' ':
|
||||
*f = '+';
|
||||
break;
|
||||
|
||||
default:
|
||||
*f = *q;
|
||||
break;
|
||||
}
|
||||
|
||||
q++;
|
||||
f++;
|
||||
}
|
||||
|
||||
*f = '\0';
|
||||
|
||||
return fixed;
|
||||
}
|
||||
|
||||
static char *http_reply_401 = "<html><head><title>401 Unauthorized</title></head><body>Authorization required</body></html>";
|
||||
|
||||
int
|
||||
|
||||
Reference in New Issue
Block a user