From: Jaroslav Kysela Date: Sat, 28 Nov 2015 16:40:43 +0000 (+0100) Subject: HTSP server: add proxy to HTTP API X-Git-Tag: v4.2.1~1452 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f44dcce3f0252fc8ad92a0495dd3a718021d349b;p=thirdparty%2Ftvheadend.git HTSP server: add proxy to HTTP API --- diff --git a/src/access.h b/src/access.h index 4c9ef8cd5..9620b1966 100644 --- a/src/access.h +++ b/src/access.h @@ -170,12 +170,13 @@ typedef struct access_ticket { #define ACCESS_ADVANCED_STREAMING (1<<1) #define ACCESS_HTSP_STREAMING (1<<2) #define ACCESS_WEB_INTERFACE (1<<3) -#define ACCESS_RECORDER (1<<4) -#define ACCESS_HTSP_RECORDER (1<<5) -#define ACCESS_ALL_RECORDER (1<<6) -#define ACCESS_ALL_RW_RECORDER (1<<7) -#define ACCESS_FAILED_RECORDER (1<<8) -#define ACCESS_ADMIN (1<<9) +#define ACCESS_HTSP_INTERFACE (1<<4) +#define ACCESS_RECORDER (1<<5) +#define ACCESS_HTSP_RECORDER (1<<6) +#define ACCESS_ALL_RECORDER (1<<7) +#define ACCESS_ALL_RW_RECORDER (1<<8) +#define ACCESS_FAILED_RECORDER (1<<9) +#define ACCESS_ADMIN (1<<10) #define ACCESS_OR (1<<30) #define ACCESS_FULL \ diff --git a/src/api/api_config.c b/src/api/api_config.c index 2a842b10c..6a85622cd 100644 --- a/src/api/api_config.c +++ b/src/api/api_config.c @@ -35,7 +35,7 @@ void api_config_init ( void ) { static api_hook_t ah[] = { - { "config/capabilities", ACCESS_WEB_INTERFACE, api_config_capabilities, NULL }, + { "config/capabilities", ACCESS_OR|ACCESS_WEB_INTERFACE|ACCESS_HTSP_INTERFACE, api_config_capabilities, NULL }, { "config/load", ACCESS_ADMIN, api_idnode_load_simple, &config }, { "config/save", ACCESS_ADMIN, api_idnode_save_simple, &config }, { "tvhlog/config/load", ACCESS_ADMIN, api_idnode_load_simple, &tvhlog_conf }, diff --git a/src/htsp_server.c b/src/htsp_server.c index 2a934fdde..7fdf1e10c 100644 --- a/src/htsp_server.c +++ b/src/htsp_server.c @@ -19,6 +19,7 @@ #include "tvheadend.h" #include "atomic.h" #include "config.h" +#include "api.h" #include "channels.h" #include "subscriptions.h" #include "tcp.h" @@ -1195,6 +1196,7 @@ htsp_method_hello(htsp_connection_t *htsp, htsmsg_t *in) /* Capabilities */ htsmsg_add_msg(r, "servercapability", tvheadend_capabilities_list(1)); + htsmsg_add_u32(r, "api_version", TVH_API_VERSION); /* Set version to lowest num */ htsp->htsp_version = MIN(HTSP_PROTO_VERSION, v); @@ -1217,6 +1219,50 @@ htsp_method_authenticate(htsp_connection_t *htsp, htsmsg_t *in) return r; } +/** + * Try to authenticate + */ +static htsmsg_t * +htsp_method_api(htsp_connection_t *htsp, htsmsg_t *in) +{ + htsmsg_t *resp = NULL, *ret = htsmsg_create_map(); + htsmsg_t *args, *args2 = NULL; + const char *remain; + int r; + + args = htsmsg_get_map(in, "args"); + remain = htsmsg_get_str(in, "path"); + + if (args == NULL) + args = args2 = htsmsg_create_map(); + + /* Call */ + r = api_exec(htsp->htsp_granted_access, remain, args, &resp); + + /* Convert error */ + if (r) { + switch (r) { + case EPERM: + case EACCES: + htsmsg_add_u32(ret, "noaccess", 1); + break; + case ENOENT: + case ENOSYS: + break; + default: + htsmsg_destroy(args2); + htsmsg_destroy(ret); + return htsp_error("Bad request"); + } + } else if (resp) { + /* Output response */ + htsmsg_add_msg(ret, "response", resp); + } + + htsmsg_destroy(args2); + return ret; +} + /** * Get total and free disk space on configured path */ @@ -2716,6 +2762,7 @@ struct { } htsp_methods[] = { { "hello", htsp_method_hello, ACCESS_ANONYMOUS}, { "authenticate", htsp_method_authenticate, ACCESS_ANONYMOUS}, + { "api", htsp_method_api, ACCESS_ANONYMOUS}, { "getDiskSpace", htsp_method_getDiskSpace, ACCESS_HTSP_STREAMING}, { "getSysTime", htsp_method_getSysTime, ACCESS_HTSP_STREAMING}, { "enableAsyncMetadata", htsp_method_async, ACCESS_HTSP_STREAMING}, @@ -2785,6 +2832,7 @@ htsp_authenticate(htsp_connection_t *htsp, htsmsg_t *m) return 0; } + rights->aa_rights |= ACCESS_HTSP_INTERFACE; privgain = (rights->aa_rights | htsp->htsp_granted_access->aa_rights) != htsp->htsp_granted_access->aa_rights; @@ -2899,6 +2947,7 @@ htsp_read_loop(htsp_connection_t *htsp) htsp->htsp_granted_access = access_get_by_addr((struct sockaddr *)htsp->htsp_peer); + htsp->htsp_granted_access->aa_rights |= ACCESS_HTSP_INTERFACE; tcp_id = tcp_connection_launch(htsp->htsp_fd, htsp_server_status, htsp->htsp_granted_access);