diff --git a/src/acl.c b/src/acl.c index 42c4dc48..b8fa0393 100644 --- a/src/acl.c +++ b/src/acl.c @@ -101,7 +101,7 @@ acl_t *acl_new(void) ret->refcount = 1; acl_set_method_str(ret, ACL_POLICY_DENY, "*"); - acl_set_method_str(ret, ACL_POLICY_ALLOW, "get"); + acl_set_method_str(ret, ACL_POLICY_ALLOW, "get,options"); acl_set_admin_str(ret, ACL_POLICY_DENY, "*"); acl_set_admin_str(ret, ACL_POLICY_ALLOW, "buildm3u"); diff --git a/src/admin.c b/src/admin.c index e1823306..b4edcf12 100644 --- a/src/admin.c +++ b/src/admin.c @@ -540,7 +540,19 @@ void admin_handle_request(client_t *client, const char *uri) format = handler->format; } - handler->function(client, source, format); + switch (client->parser->req_type) { + case httpp_req_get: + handler->function(client, source, format); + break; + case httpp_req_options: + client_send_204(client); + break; + default: + ICECAST_LOG_ERROR("Wrong request type from client"); + client_send_error_by_id(client, ICECAST_ERROR_CON_UNKNOWN_REQUEST); + break; + } + if (source) { avl_tree_unlock(global.source_tree); } diff --git a/src/cfgfile.c b/src/cfgfile.c index ebe3a378..fcf5b183 100644 --- a/src/cfgfile.c +++ b/src/cfgfile.c @@ -399,9 +399,9 @@ static void __append_old_style_urlauth(auth_stack_t **stack, xmlSetProp(role, XMLSTR("allow-web"), XMLSTR("*")); xmlSetProp(role, XMLSTR("allow-admin"), XMLSTR("*")); } else { - xmlSetProp(role, XMLSTR("method"), XMLSTR("get,post,head")); + xmlSetProp(role, XMLSTR("method"), XMLSTR("get,post,head,options")); xmlSetProp(role, XMLSTR("deny-method"), XMLSTR("*")); - xmlSetProp(role, XMLSTR("allow-method"), XMLSTR("get,post,head")); + xmlSetProp(role, XMLSTR("allow-method"), XMLSTR("get,post,head,options")); xmlSetProp(role, XMLSTR("allow-web"), XMLSTR("*")); xmlSetProp(role, XMLSTR("deny-admin"), XMLSTR("*")); } @@ -1188,7 +1188,7 @@ static void _parse_mount_oldstyle_authentication(mount_proxy *mount, } __append_old_style_auth(authstack, NULL, AUTH_TYPE_ANONYMOUS, - NULL, NULL, "get,head,post", NULL, 0, NULL); + NULL, NULL, "get,head,post,options", NULL, 0, NULL); } else if (strcmp(type, AUTH_TYPE_URL) == 0) { /* This block is super fun! Attention! Super fun ahead! Ladies and Gentlemen take care and watch your children! */ /* Stuff that was of help: @@ -1280,7 +1280,7 @@ static void _parse_mount_oldstyle_authentication(mount_proxy *mount, headers, header_prefix); if (listener_add) __append_old_style_auth(authstack, NULL, AUTH_TYPE_ANONYMOUS, NULL, - NULL, "get,put,head", NULL, 0, NULL); + NULL, "get,put,head,options", NULL, 0, NULL); if (stream_auth) __append_old_style_auth(authstack, NULL, AUTH_TYPE_ANONYMOUS, NULL, NULL, "source,put", NULL, 0, NULL); @@ -1841,7 +1841,7 @@ static void _parse_authentication(xmlDocPtr doc, xmlNodePtr node, if (admin_password && admin_username) __append_old_style_auth(&old_style, "legacy-admin", AUTH_TYPE_STATIC, - admin_username, admin_password, NULL, "get,post,head,stats", 1, "*"); + admin_username, admin_password, NULL, "get,post,head,stats,options", 1, "*"); if (relay_password && relay_username) __append_old_style_auth(&old_style, "legacy-relay", AUTH_TYPE_STATIC, @@ -1865,7 +1865,7 @@ static void _parse_authentication(xmlDocPtr doc, xmlNodePtr node, /* default unauthed anonymous account */ __append_old_style_auth(&old_style, "anonymous", AUTH_TYPE_ANONYMOUS, - NULL, NULL, NULL, "get,post,head", 1, NULL); + NULL, NULL, NULL, "get,post,head,options", 1, NULL); if (!old_style) ICECAST_LOG_ERROR("BAD. old_style=NULL"); diff --git a/src/client.c b/src/client.c index d7b17d1a..a8863246 100644 --- a/src/client.c +++ b/src/client.c @@ -319,6 +319,29 @@ void client_send_101(client_t *client, reuse_t reuse) fserve_add_client(client, NULL); } +void client_send_204(client_t *client) +{ + ssize_t ret; + + if (!client) + return; + + client->reuse = ICECAST_REUSE_KEEPALIVE; + + ret = util_http_build_header(client->refbuf->data, PER_CLIENT_REFBUF_SIZE, 0, + 0, 204, NULL, + NULL, NULL, + NULL, NULL, client); + + snprintf(client->refbuf->data + ret, PER_CLIENT_REFBUF_SIZE - ret, + "Content-Length: 0\r\n\r\n"); + + client->respcode = 204; + client->refbuf->len = strlen(client->refbuf->data); + + fserve_add_client(client, NULL); +} + void client_send_426(client_t *client, reuse_t reuse) { ssize_t ret; diff --git a/src/client.h b/src/client.h index f619e391..c4bab286 100644 --- a/src/client.h +++ b/src/client.h @@ -115,6 +115,7 @@ int client_create (client_t **c_ptr, connection_t *con, http_parser_t *parser); void client_destroy(client_t *client); void client_send_error_by_id(client_t *client, icecast_error_id_t id); void client_send_101(client_t *client, reuse_t reuse); +void client_send_204(client_t *client); void client_send_426(client_t *client, reuse_t reuse); admin_format_t client_get_admin_format_by_content_negotiation(client_t *client); int client_send_bytes (client_t *client, const void *buf, unsigned len); diff --git a/src/connection.c b/src/connection.c index 38cfb58c..734aeece 100644 --- a/src/connection.c +++ b/src/connection.c @@ -926,6 +926,11 @@ static void _handle_get_request(client_t *client, char *uri) { return; } + if (client->parser->req_type == httpp_req_options) { + client_send_204(client); + return; + } + if (util_check_valid_extension(uri) == XSLT_CONTENT) { /* If the file exists, then transform it, otherwise, write a 404 */ ICECAST_LOG_DEBUG("Stats request, sending XSL transformed stats"); @@ -1157,15 +1162,7 @@ static void _handle_admin_request(client_t *client, char *adminuri) stats_event_inc(NULL, "client_connections"); - switch (client->parser->req_type) { - case httpp_req_get: - admin_handle_request(client, adminuri); - break; - default: - ICECAST_LOG_ERROR("Wrong request type from client"); - client_send_error_by_id(client, ICECAST_ERROR_CON_UNKNOWN_REQUEST); - break; - } + admin_handle_request(client, adminuri); } /* Handle any client that passed the authing process. @@ -1209,6 +1206,7 @@ static void _handle_authed_client(client_t *client, void *uri, auth_result resul _handle_stats_request(client, uri); break; case httpp_req_get: + case httpp_req_options: _handle_get_request(client, uri); break; default: @@ -1413,6 +1411,11 @@ static void _handle_connection(void) continue; } + if (strcmp(rawuri, "*") == 0) { + client_send_204(client); + continue; + } + uri = util_normalise_uri(rawuri); if (!uri) { diff --git a/src/util.c b/src/util.c index b0d7586d..abc2aaad 100644 --- a/src/util.c +++ b/src/util.c @@ -710,6 +710,7 @@ ssize_t util_http_build_header(char * out, size_t len, ssize_t offset, case 100: statusmsg = "Continue"; http_version = "1.1"; break; case 101: statusmsg = "Switching Protocols"; http_version = "1.1"; break; case 200: statusmsg = "OK"; break; + case 204: statusmsg = "No Content"; break; case 206: statusmsg = "Partial Content"; http_version = "1.1"; break; case 400: statusmsg = "Bad Request"; break; case 401: statusmsg = "Authentication Required"; break; @@ -766,7 +767,7 @@ ssize_t util_http_build_header(char * out, size_t len, ssize_t offset, config->server_id, connection_header, (client && client->admin_command == ADMIN_COMMAND_ERROR ? - "GET, SOURCE" : "GET"), + "GET, SOURCE, OPTIONS" : "GET, OPTIONS"), upgrade_header, currenttime_buffer, contenttype_buffer,