mirror of
https://github.com/owntone/owntone-server.git
synced 2025-01-26 22:23:17 -05:00
[jsonapi] Rework outputs endpoint and strictly match uris by request
method
This commit is contained in:
parent
83bb06225b
commit
0e9feac829
@ -64,13 +64,13 @@
|
||||
* }
|
||||
*/
|
||||
static int
|
||||
pairing_kickoff(struct evhttp_request *req)
|
||||
jsonapi_reply_pairing_kickoff(struct httpd_request *hreq)
|
||||
{
|
||||
struct evbuffer *evbuf;
|
||||
json_object* request;
|
||||
const char* message;
|
||||
|
||||
evbuf = evhttp_request_get_input_buffer(req);
|
||||
evbuf = evhttp_request_get_input_buffer(hreq->req);
|
||||
request = jparse_obj_from_evbuffer(evbuf);
|
||||
if (!request)
|
||||
{
|
||||
@ -102,7 +102,7 @@ pairing_kickoff(struct evhttp_request *req)
|
||||
* }
|
||||
*/
|
||||
static int
|
||||
pairing_get(struct evbuffer *evbuf)
|
||||
jsonapi_reply_pairing_get(struct httpd_request *hreq)
|
||||
{
|
||||
char *remote_name;
|
||||
json_object *jreply;
|
||||
@ -121,7 +121,7 @@ pairing_get(struct evbuffer *evbuf)
|
||||
json_object_object_add(jreply, "active", json_object_new_boolean(false));
|
||||
}
|
||||
|
||||
CHECK_ERRNO(L_WEB, evbuffer_add_printf(evbuf, "%s", json_object_to_json_string(jreply)));
|
||||
CHECK_ERRNO(L_WEB, evbuffer_add_printf(hreq->reply, "%s", json_object_to_json_string(jreply)));
|
||||
|
||||
jparse_free(jreply);
|
||||
free(remote_name);
|
||||
@ -371,23 +371,6 @@ jsonapi_reply_spotify_login(struct httpd_request *hreq)
|
||||
return HTTP_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Endpoint to pair daap/dacp client
|
||||
*
|
||||
* If request is a GET request, returns information about active pairing remote.
|
||||
* If request is a POST request, tries to pair the active remote with the given pin.
|
||||
*/
|
||||
static int
|
||||
jsonapi_reply_pairing(struct httpd_request *hreq)
|
||||
{
|
||||
if (evhttp_request_get_command(hreq->req) == EVHTTP_REQ_POST)
|
||||
{
|
||||
return pairing_kickoff(hreq->req);
|
||||
}
|
||||
|
||||
return pairing_get(hreq->reply);
|
||||
}
|
||||
|
||||
static int
|
||||
jsonapi_reply_lastfm(struct httpd_request *hreq)
|
||||
{
|
||||
@ -494,14 +477,18 @@ jsonapi_reply_lastfm_logout(struct httpd_request *hreq)
|
||||
return HTTP_NOCONTENT;
|
||||
}
|
||||
|
||||
static void
|
||||
speaker_enum_cb(struct spk_info *spk, void *arg)
|
||||
struct outputs_param
|
||||
{
|
||||
json_object *output;
|
||||
uint64_t output_id;
|
||||
};
|
||||
|
||||
static json_object *
|
||||
speaker_to_json(struct spk_info *spk)
|
||||
{
|
||||
json_object *outputs;
|
||||
json_object *output;
|
||||
char output_id[21];
|
||||
|
||||
outputs = arg;
|
||||
output = json_object_new_object();
|
||||
|
||||
snprintf(output_id, sizeof(output_id), "%" PRIu64, spk->id);
|
||||
@ -514,14 +501,132 @@ speaker_enum_cb(struct spk_info *spk, void *arg)
|
||||
json_object_object_add(output, "needs_auth_key", json_object_new_boolean(spk->needs_auth_key));
|
||||
json_object_object_add(output, "volume", json_object_new_int(spk->absvol));
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
static void
|
||||
speaker_enum_cb(struct spk_info *spk, void *arg)
|
||||
{
|
||||
json_object *outputs;
|
||||
json_object *output;
|
||||
|
||||
outputs = arg;
|
||||
|
||||
output = speaker_to_json(spk);
|
||||
json_object_array_add(outputs, output);
|
||||
}
|
||||
|
||||
static void
|
||||
speaker_get_cb(struct spk_info *spk, void *arg)
|
||||
{
|
||||
struct outputs_param *outputs_param = arg;
|
||||
|
||||
if (outputs_param->output_id == spk->id)
|
||||
{
|
||||
outputs_param->output = speaker_to_json(spk);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* GET /api/outputs/[output_id]
|
||||
*/
|
||||
static int
|
||||
jsonapi_reply_outputs_get_byid(struct httpd_request *hreq)
|
||||
{
|
||||
struct outputs_param outputs_param;
|
||||
uint64_t output_id;
|
||||
int ret;
|
||||
|
||||
ret = safe_atou64(hreq->uri_parsed->path_parts[2], &output_id);
|
||||
if (ret < 0)
|
||||
{
|
||||
DPRINTF(E_LOG, L_WEB, "No valid output id given to outputs endpoint '%s'\n", hreq->uri_parsed->path);
|
||||
|
||||
return HTTP_BADREQUEST;
|
||||
}
|
||||
|
||||
outputs_param.output_id = output_id;
|
||||
outputs_param.output = NULL;
|
||||
|
||||
player_speaker_enumerate(speaker_get_cb, &outputs_param);
|
||||
|
||||
if (!outputs_param.output)
|
||||
{
|
||||
DPRINTF(E_LOG, L_WEB, "No output found for '%s'\n", hreq->uri_parsed->path);
|
||||
|
||||
return HTTP_BADREQUEST;
|
||||
}
|
||||
|
||||
CHECK_ERRNO(L_WEB, evbuffer_add_printf(hreq->reply, "%s", json_object_to_json_string(outputs_param.output)));
|
||||
|
||||
jparse_free(outputs_param.output);
|
||||
|
||||
return HTTP_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* PUT /api/outputs/[output_id]
|
||||
*/
|
||||
static int
|
||||
jsonapi_reply_outputs_put_byid(struct httpd_request *hreq)
|
||||
{
|
||||
uint64_t output_id;
|
||||
struct evbuffer *in_evbuf;
|
||||
json_object* request;
|
||||
bool selected;
|
||||
int volume;
|
||||
int ret;
|
||||
|
||||
ret = safe_atou64(hreq->uri_parsed->path_parts[2], &output_id);
|
||||
if (ret < 0)
|
||||
{
|
||||
DPRINTF(E_LOG, L_WEB, "No valid output id given to outputs endpoint '%s'\n", hreq->uri_parsed->path);
|
||||
|
||||
return HTTP_BADREQUEST;
|
||||
}
|
||||
|
||||
in_evbuf = evhttp_request_get_input_buffer(hreq->req);
|
||||
request = jparse_obj_from_evbuffer(in_evbuf);
|
||||
if (!request)
|
||||
{
|
||||
DPRINTF(E_LOG, L_WEB, "Failed to parse incoming request\n");
|
||||
|
||||
return HTTP_BADREQUEST;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
if (jparse_contains_key(request, "selected", json_type_boolean))
|
||||
{
|
||||
selected = jparse_bool_from_obj(request, "selected");
|
||||
if (selected)
|
||||
ret = player_speaker_enable(output_id);
|
||||
else
|
||||
ret = player_speaker_disable(output_id);
|
||||
}
|
||||
|
||||
if (ret == 0 && jparse_contains_key(request, "volume", json_type_int))
|
||||
{
|
||||
volume = jparse_int_from_obj(request, "volume");
|
||||
ret = player_volume_setabs_speaker(output_id, volume);
|
||||
}
|
||||
|
||||
jparse_free(request);
|
||||
|
||||
if (ret < 0)
|
||||
return HTTP_INTERNAL;
|
||||
|
||||
return HTTP_NOCONTENT;
|
||||
}
|
||||
|
||||
/*
|
||||
* Endpoint "/api/outputs"
|
||||
*/
|
||||
static int
|
||||
jsonapi_reply_outputs(struct httpd_request *hreq)
|
||||
{
|
||||
json_object *jreply;
|
||||
json_object *outputs;
|
||||
json_object *jreply;
|
||||
|
||||
outputs = json_object_new_array();
|
||||
|
||||
@ -544,12 +649,6 @@ jsonapi_reply_verification(struct httpd_request *hreq)
|
||||
json_object* request;
|
||||
const char* message;
|
||||
|
||||
if (evhttp_request_get_command(hreq->req) != EVHTTP_REQ_POST)
|
||||
{
|
||||
DPRINTF(E_LOG, L_WEB, "Verification: request is not a POST request\n");
|
||||
return HTTP_BADREQUEST;
|
||||
}
|
||||
|
||||
in_evbuf = evhttp_request_get_input_buffer(hreq->req);
|
||||
request = jparse_obj_from_evbuffer(in_evbuf);
|
||||
if (!request)
|
||||
@ -572,7 +671,7 @@ jsonapi_reply_verification(struct httpd_request *hreq)
|
||||
}
|
||||
|
||||
static int
|
||||
jsonapi_reply_select_outputs(struct httpd_request *hreq)
|
||||
jsonapi_reply_outputs_set(struct httpd_request *hreq)
|
||||
{
|
||||
struct evbuffer *in_evbuf;
|
||||
json_object *request;
|
||||
@ -581,12 +680,6 @@ jsonapi_reply_select_outputs(struct httpd_request *hreq)
|
||||
int nspk, i, ret;
|
||||
uint64_t *ids;
|
||||
|
||||
if (evhttp_request_get_command(hreq->req) != EVHTTP_REQ_POST)
|
||||
{
|
||||
DPRINTF(E_LOG, L_WEB, "Select outputs: request is not a POST request\n");
|
||||
return HTTP_BADREQUEST;
|
||||
}
|
||||
|
||||
in_evbuf = evhttp_request_get_input_buffer(hreq->req);
|
||||
request = jparse_obj_from_evbuffer(in_evbuf);
|
||||
if (!request)
|
||||
@ -986,30 +1079,38 @@ jsonapi_reply_player_volume(struct httpd_request *hreq)
|
||||
|
||||
static struct httpd_uri_map adm_handlers[] =
|
||||
{
|
||||
{ .regexp = "^/api/config", .handler = jsonapi_reply_config },
|
||||
{ .regexp = "^/api/library", .handler = jsonapi_reply_library },
|
||||
{ .regexp = "^/api/update", .handler = jsonapi_reply_update },
|
||||
{ .regexp = "^/api/spotify-login", .handler = jsonapi_reply_spotify_login },
|
||||
{ .regexp = "^/api/spotify", .handler = jsonapi_reply_spotify },
|
||||
{ .regexp = "^/api/pairing", .handler = jsonapi_reply_pairing },
|
||||
{ .regexp = "^/api/lastfm-login", .handler = jsonapi_reply_lastfm_login },
|
||||
{ .regexp = "^/api/lastfm-logout", .handler = jsonapi_reply_lastfm_logout },
|
||||
{ .regexp = "^/api/lastfm", .handler = jsonapi_reply_lastfm },
|
||||
{ .regexp = "^/api/outputs", .handler = jsonapi_reply_outputs },
|
||||
{ .regexp = "^/api/select-outputs", .handler = jsonapi_reply_select_outputs },
|
||||
{ .regexp = "^/api/verification", .handler = jsonapi_reply_verification },
|
||||
{ .regexp = "^/api/player/play", .handler = jsonapi_reply_player_play },
|
||||
{ .regexp = "^/api/player/pause", .handler = jsonapi_reply_player_pause },
|
||||
{ .regexp = "^/api/player/stop", .handler = jsonapi_reply_player_stop },
|
||||
{ .regexp = "^/api/player/next", .handler = jsonapi_reply_player_next },
|
||||
{ .regexp = "^/api/player/previous", .handler = jsonapi_reply_player_previous },
|
||||
{ .regexp = "^/api/player/shuffle", .handler = jsonapi_reply_player_shuffle },
|
||||
{ .regexp = "^/api/player/repeat", .handler = jsonapi_reply_player_repeat },
|
||||
{ .regexp = "^/api/player/consume", .handler = jsonapi_reply_player_consume },
|
||||
{ .regexp = "^/api/player/volume", .handler = jsonapi_reply_player_volume },
|
||||
{ .regexp = "^/api/player", .handler = jsonapi_reply_player },
|
||||
{ .regexp = "^/api/queue", .handler = jsonapi_reply_queue },
|
||||
{ .regexp = NULL, .handler = NULL }
|
||||
{ EVHTTP_REQ_GET, "^/api/config$", jsonapi_reply_config },
|
||||
{ EVHTTP_REQ_GET, "^/api/library$", jsonapi_reply_library },
|
||||
{ EVHTTP_REQ_GET, "^/api/update$", jsonapi_reply_update },
|
||||
{ EVHTTP_REQ_POST, "^/api/spotify-login$", jsonapi_reply_spotify_login },
|
||||
{ EVHTTP_REQ_GET, "^/api/spotify$", jsonapi_reply_spotify },
|
||||
{ EVHTTP_REQ_GET, "^/api/pairing$", jsonapi_reply_pairing_get },
|
||||
{ EVHTTP_REQ_POST, "^/api/pairing$", jsonapi_reply_pairing_kickoff },
|
||||
{ EVHTTP_REQ_POST, "^/api/lastfm-login$", jsonapi_reply_lastfm_login },
|
||||
{ EVHTTP_REQ_GET, "^/api/lastfm-logout$", jsonapi_reply_lastfm_logout },
|
||||
{ EVHTTP_REQ_GET, "^/api/lastfm$", jsonapi_reply_lastfm },
|
||||
{ EVHTTP_REQ_POST, "^/api/verification$", jsonapi_reply_verification },
|
||||
|
||||
{ EVHTTP_REQ_GET, "^/api/outputs$", jsonapi_reply_outputs },
|
||||
{ EVHTTP_REQ_PUT, "^/api/outputs/set$", jsonapi_reply_outputs_set },
|
||||
{ EVHTTP_REQ_POST, "^/api/select-outputs$", jsonapi_reply_outputs_set }, // deprecated: use "/api/outputs/set"
|
||||
{ EVHTTP_REQ_GET, "^/api/outputs/[[:digit:]]+$", jsonapi_reply_outputs_get_byid },
|
||||
{ EVHTTP_REQ_PUT, "^/api/outputs/[[:digit:]]+$", jsonapi_reply_outputs_put_byid },
|
||||
|
||||
{ EVHTTP_REQ_PUT, "^/api/player/play$", jsonapi_reply_player_play },
|
||||
{ EVHTTP_REQ_PUT, "^/api/player/pause$", jsonapi_reply_player_pause },
|
||||
{ EVHTTP_REQ_PUT, "^/api/player/stop$", jsonapi_reply_player_stop },
|
||||
{ EVHTTP_REQ_PUT, "^/api/player/next$", jsonapi_reply_player_next },
|
||||
{ EVHTTP_REQ_PUT, "^/api/player/previous$", jsonapi_reply_player_previous },
|
||||
{ EVHTTP_REQ_PUT, "^/api/player/shuffle$", jsonapi_reply_player_shuffle },
|
||||
{ EVHTTP_REQ_PUT, "^/api/player/repeat$", jsonapi_reply_player_repeat },
|
||||
{ EVHTTP_REQ_PUT, "^/api/player/consume$", jsonapi_reply_player_consume },
|
||||
{ EVHTTP_REQ_PUT, "^/api/player/volume$", jsonapi_reply_player_volume },
|
||||
{ EVHTTP_REQ_GET, "^/api/player$", jsonapi_reply_player },
|
||||
|
||||
{ EVHTTP_REQ_GET, "^/api/queue$", jsonapi_reply_queue },
|
||||
|
||||
{ 0, NULL, NULL }
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user