mirror of
https://github.com/weechat/weechat.git
synced 2026-06-12 14:14:48 +02:00
relay/api: return HTTP error 405 (Method Not Allowed) when the method received is not allowed
This commit is contained in:
@@ -15,6 +15,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||
- core: write configuration files on disk only if there are changes ([#2250](https://github.com/weechat/weechat/issues/2250))
|
||||
- core: always enable partial completion for templates in option weechat.completion.partial_completion_templates, add option weechat.completion.partial_completion_auto_expand to expand word on new completion ([#2253](https://github.com/weechat/weechat/issues/2253))
|
||||
- core: add script name in output of `/debug hooks <plugin>`
|
||||
- relay/api: return HTTP error 405 (Method Not Allowed) when the method received is not allowed
|
||||
|
||||
### Added
|
||||
|
||||
|
||||
@@ -374,7 +374,7 @@ RELAY_API_PROTOCOL_CALLBACK(options)
|
||||
relay_api_msg_send_json (
|
||||
client,
|
||||
RELAY_HTTP_204_NO_CONTENT,
|
||||
"Access-Control-Allow-Methods: GET, POST, PUT, DELETE\r\n"
|
||||
"Access-Control-Allow-Methods: " RELAY_API_ALLOWED_METHODS "\r\n"
|
||||
"Access-Control-Allow-Headers: origin, content-type, accept, authorization",
|
||||
NULL, /* body_type */
|
||||
NULL); /* json_body */
|
||||
@@ -1197,7 +1197,7 @@ relay_api_protocol_recv_json (struct t_relay_client *client, const char *json)
|
||||
void
|
||||
relay_api_protocol_recv_http (struct t_relay_client *client)
|
||||
{
|
||||
int i, num_args;
|
||||
int i, num_args, match_method, match_resource;
|
||||
char str_error[1024];
|
||||
enum t_relay_api_protocol_rc return_code;
|
||||
struct t_relay_api_protocol_cb protocol_cb[] = {
|
||||
@@ -1238,18 +1238,22 @@ relay_api_protocol_recv_http (struct t_relay_client *client)
|
||||
|| !client->http_req->path_items[1]
|
||||
|| (strcmp (client->http_req->path_items[0], "api") != 0))
|
||||
{
|
||||
goto error_not_found;
|
||||
goto resource_not_found;
|
||||
}
|
||||
|
||||
num_args = client->http_req->num_path_items - 2;
|
||||
|
||||
for (i = 0; protocol_cb[i].resource; i++)
|
||||
{
|
||||
if (strcmp (protocol_cb[i].method, client->http_req->method) != 0)
|
||||
continue;
|
||||
match_method = (strcmp (protocol_cb[i].method, client->http_req->method) == 0);
|
||||
|
||||
if ((strcmp (protocol_cb[i].resource, "*") != 0)
|
||||
&& (strcmp (protocol_cb[i].resource, client->http_req->path_items[1]) != 0))
|
||||
match_resource = ((strcmp (protocol_cb[i].resource, "*") == 0)
|
||||
|| (strcmp (protocol_cb[i].resource, client->http_req->path_items[1]) == 0));
|
||||
|
||||
if (!match_method && (strcmp (protocol_cb[i].resource, "*") != 0) && match_resource)
|
||||
goto error_method_not_allowed;
|
||||
|
||||
if (!match_method || !match_resource)
|
||||
continue;
|
||||
|
||||
if (protocol_cb[i].auth_required
|
||||
@@ -1331,7 +1335,18 @@ relay_api_protocol_recv_http (struct t_relay_client *client)
|
||||
}
|
||||
}
|
||||
|
||||
goto error_not_found;
|
||||
resource_not_found:
|
||||
if ((strcmp (client->http_req->method, "GET") != 0)
|
||||
&& (strcmp (client->http_req->method, "POST") != 0)
|
||||
&& (strcmp (client->http_req->method, "PUT") != 0)
|
||||
&& (strcmp (client->http_req->method, "DELETE") != 0))
|
||||
{
|
||||
goto error_method_not_allowed;
|
||||
}
|
||||
else
|
||||
{
|
||||
goto error_not_found;
|
||||
}
|
||||
|
||||
error_bad_request:
|
||||
relay_api_msg_send_error_json (client, RELAY_HTTP_400_BAD_REQUEST,
|
||||
@@ -1343,6 +1358,12 @@ error_not_found:
|
||||
NULL, RELAY_HTTP_ERROR_NOT_FOUND);
|
||||
goto error;
|
||||
|
||||
error_method_not_allowed:
|
||||
relay_api_msg_send_error_json (client, RELAY_HTTP_405_METHOD_NOT_ALLOWED,
|
||||
"Allow: " RELAY_API_ALLOWED_METHODS,
|
||||
RELAY_HTTP_ERROR_METHOD_NOT_ALLOWED);
|
||||
goto error;
|
||||
|
||||
error_memory:
|
||||
relay_api_msg_send_error_json (client, RELAY_HTTP_503_SERVICE_UNAVAILABLE,
|
||||
NULL, RELAY_HTTP_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
#ifndef WEECHAT_PLUGIN_RELAY_API_PROTOCOL_H
|
||||
#define WEECHAT_PLUGIN_RELAY_API_PROTOCOL_H
|
||||
|
||||
#define RELAY_API_ALLOWED_METHODS "GET, POST, PUT, DELETE"
|
||||
|
||||
#define RELAY_API_CB(__command) &relay_api_protocol_cb_##__command
|
||||
#define RELAY_API_PROTOCOL_CALLBACK(__command) \
|
||||
enum t_relay_api_protocol_rc \
|
||||
|
||||
@@ -40,6 +40,7 @@ enum t_relay_client_http_status
|
||||
#define RELAY_HTTP_401_UNAUTHORIZED 401, "Unauthorized"
|
||||
#define RELAY_HTTP_403_FORBIDDEN 403, "Forbidden"
|
||||
#define RELAY_HTTP_404_NOT_FOUND 404, "Not Found"
|
||||
#define RELAY_HTTP_405_METHOD_NOT_ALLOWED 405, "Method Not Allowed"
|
||||
#define RELAY_HTTP_500_INTERNAL_SERVER_ERROR 500, "Internal Server Error"
|
||||
#define RELAY_HTTP_503_SERVICE_UNAVAILABLE 503, "Service Unavailable"
|
||||
|
||||
@@ -53,6 +54,7 @@ enum t_relay_client_http_status
|
||||
#define RELAY_HTTP_ERROR_INVALID_ITERATIONS "Invalid number of iterations"
|
||||
#define RELAY_HTTP_ERROR_BAD_REQUEST "Bad request"
|
||||
#define RELAY_HTTP_ERROR_NOT_FOUND "Resource not found"
|
||||
#define RELAY_HTTP_ERROR_METHOD_NOT_ALLOWED "Method Not Allowed"
|
||||
#define RELAY_HTTP_ERROR_OUT_OF_MEMORY "Out of memory"
|
||||
|
||||
struct t_relay_http_request
|
||||
|
||||
@@ -1052,3 +1052,44 @@ TEST(RelayApiProtocolWithClient, RecvHttpInvalidPassword)
|
||||
"{\"error\":\"Invalid password\"}",
|
||||
data_sent[0]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests functions:
|
||||
* relay_api_protocol_recv_http (method not allowed)
|
||||
*/
|
||||
|
||||
TEST(RelayApiProtocolWithClient, RecvHttpMethodNotAllowed)
|
||||
{
|
||||
/* method not allowed (PATCH) with existing resource (/api/ping) */
|
||||
test_client_recv_http ("PATCH /api/ping", NULL, "{\"data\": \"abcdef\"}");
|
||||
STRCMP_EQUAL("HTTP/1.1 405 Method Not Allowed\r\n"
|
||||
"Allow: GET, POST, PUT, DELETE\r\n"
|
||||
"Access-Control-Allow-Origin: *\r\n"
|
||||
"Content-Type: application/json; charset=utf-8\r\n"
|
||||
"Content-Length: 30\r\n"
|
||||
"\r\n"
|
||||
"{\"error\":\"Method Not Allowed\"}",
|
||||
data_sent[0]);
|
||||
|
||||
/* method not allowed (PATCH) with unknown resource (/api/unknown) */
|
||||
test_client_recv_http ("PATCH /api/unknown", NULL, "{\"data\": \"abcdef\"}");
|
||||
STRCMP_EQUAL("HTTP/1.1 405 Method Not Allowed\r\n"
|
||||
"Allow: GET, POST, PUT, DELETE\r\n"
|
||||
"Access-Control-Allow-Origin: *\r\n"
|
||||
"Content-Type: application/json; charset=utf-8\r\n"
|
||||
"Content-Length: 30\r\n"
|
||||
"\r\n"
|
||||
"{\"error\":\"Method Not Allowed\"}",
|
||||
data_sent[0]);
|
||||
|
||||
/* method not allowed (PATCH) with unknown resource (/unknown) */
|
||||
test_client_recv_http ("PATCH /unknown", NULL, "{\"data\": \"abcdef\"}");
|
||||
STRCMP_EQUAL("HTTP/1.1 405 Method Not Allowed\r\n"
|
||||
"Allow: GET, POST, PUT, DELETE\r\n"
|
||||
"Access-Control-Allow-Origin: *\r\n"
|
||||
"Content-Type: application/json; charset=utf-8\r\n"
|
||||
"Content-Length: 30\r\n"
|
||||
"\r\n"
|
||||
"{\"error\":\"Method Not Allowed\"}",
|
||||
data_sent[0]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user