[httpd] Hooks for OAuth user interface and callbacks

This commit is contained in:
ejurgensen 2016-11-05 13:38:15 +01:00
parent 807951976c
commit 575b6e13a8
1 changed files with 66 additions and 6 deletions

View File

@ -64,6 +64,9 @@
#ifdef LASTFM #ifdef LASTFM
# include "lastfm.h" # include "lastfm.h"
#endif #endif
#ifdef HAVE_SPOTIFY_H
# include "spotify.h"
#endif
/* /*
* HTTP client quirks by User-Agent, from mt-daapd * HTTP client quirks by User-Agent, from mt-daapd
@ -140,6 +143,7 @@ static struct evhttp *evhttpd;
static pthread_t tid_httpd; static pthread_t tid_httpd;
static char *allow_origin; static char *allow_origin;
static int httpd_port;
#ifdef HAVE_LIBEVENT2_OLD #ifdef HAVE_LIBEVENT2_OLD
struct stream_ctx *g_st; struct stream_ctx *g_st;
@ -198,6 +202,57 @@ scrobble_cb(void *arg)
} }
#endif #endif
static void
oauth_interface(struct evhttp_request *req, const char *uri)
{
struct evbuffer *evbuf;
struct evkeyvalq query;
const char *req_uri;
const char *ptr;
char redirect_uri[256];
int ret;
req_uri = evhttp_request_get_uri(req);
evbuf = evbuffer_new();
if (!evbuf)
{
DPRINTF(E_LOG, L_HTTPD, "Could not alloc evbuf for oauth\n");
return;
}
evbuffer_add_printf(evbuf, "<H1>forked-daapd oauth</H1>\n\n");
ptr = strchr(req_uri, '?');
if (ptr)
{
ret = evhttp_parse_query_str(ptr + 1, &query);
if (ret < 0)
{
evbuffer_add_printf(evbuf, "OAuth error: Could not parse parameters in callback (%s)\n", req_uri);
httpd_send_reply(req, HTTP_OK, "OK", evbuf, 0);
evbuffer_free(evbuf);
return;
}
}
#ifdef HAVE_SPOTIFY_H
snprintf(redirect_uri, sizeof(redirect_uri), "http://forked-daapd.local:%d/oauth/spotify", httpd_port);
if (strncmp(uri, "/oauth/spotify", strlen("/oauth/spotify")) == 0)
spotify_oauth_callback(evbuf, &query, redirect_uri);
else
spotify_oauth_interface(evbuf, redirect_uri);
#endif
evhttp_clear_headers(&query);
httpd_send_reply(req, HTTP_OK, "OK", evbuf, 0);
evbuffer_free(evbuf);
}
static void static void
stream_end_register(struct stream_ctx *st) stream_end_register(struct stream_ctx *st)
{ {
@ -912,6 +967,12 @@ serve_file(struct evhttp_request *req, char *uri)
} }
} }
if (strncmp(uri, "/oauth", strlen("/oauth")) == 0)
{
oauth_interface(req, uri);
return;
}
ret = snprintf(path, sizeof(path), "%s%s", WEBFACE_ROOT, uri + 1); /* skip starting '/' */ ret = snprintf(path, sizeof(path), "%s%s", WEBFACE_ROOT, uri + 1); /* skip starting '/' */
if ((ret < 0) || (ret >= sizeof(path))) if ((ret < 0) || (ret >= sizeof(path)))
{ {
@ -1357,7 +1418,6 @@ int
httpd_init(void) httpd_init(void)
{ {
int v6enabled; int v6enabled;
unsigned short port;
int ret; int ret;
httpd_exit = 0; httpd_exit = 0;
@ -1438,7 +1498,7 @@ httpd_init(void)
} }
v6enabled = cfg_getbool(cfg_getsec(cfg, "general"), "ipv6"); v6enabled = cfg_getbool(cfg_getsec(cfg, "general"), "ipv6");
port = cfg_getint(cfg_getsec(cfg, "library"), "port"); httpd_port = cfg_getint(cfg_getsec(cfg, "library"), "port");
// For CORS headers // For CORS headers
allow_origin = cfg_getstr(cfg_getsec(cfg, "general"), "allow_origin"); allow_origin = cfg_getstr(cfg_getsec(cfg, "general"), "allow_origin");
@ -1452,20 +1512,20 @@ httpd_init(void)
if (v6enabled) if (v6enabled)
{ {
ret = evhttp_bind_socket(evhttpd, "::", port); ret = evhttp_bind_socket(evhttpd, "::", httpd_port);
if (ret < 0) if (ret < 0)
{ {
DPRINTF(E_LOG, L_HTTPD, "Could not bind to port %d with IPv6, falling back to IPv4\n", port); DPRINTF(E_LOG, L_HTTPD, "Could not bind to port %d with IPv6, falling back to IPv4\n", httpd_port);
v6enabled = 0; v6enabled = 0;
} }
} }
if (!v6enabled) if (!v6enabled)
{ {
ret = evhttp_bind_socket(evhttpd, "0.0.0.0", port); ret = evhttp_bind_socket(evhttpd, "0.0.0.0", httpd_port);
if (ret < 0) if (ret < 0)
{ {
DPRINTF(E_FATAL, L_HTTPD, "Could not bind to port %d (forked-daapd already running?)\n", port); DPRINTF(E_FATAL, L_HTTPD, "Could not bind to port %d (forked-daapd already running?)\n", httpd_port);
goto bind_fail; goto bind_fail;
} }
} }