Add PATCH, PUT, DELETE methods
AG: rewrite method code to use method arrays
This commit is contained in:
parent
363420dff4
commit
49f72aa451
5 changed files with 795 additions and 775 deletions
|
@ -81,6 +81,10 @@ static const char *set[] = {
|
||||||
"www-authenticate:",
|
"www-authenticate:",
|
||||||
"proxy ",
|
"proxy ",
|
||||||
|
|
||||||
|
"patch",
|
||||||
|
"put",
|
||||||
|
"delete",
|
||||||
|
|
||||||
"", /* not matchable */
|
"", /* not matchable */
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
1425
lib/lextable.h
1425
lib/lextable.h
File diff suppressed because it is too large
Load diff
|
@ -389,6 +389,10 @@ enum lws_token_indexes {
|
||||||
WSI_TOKEN_HTTP_WWW_AUTHENTICATE,
|
WSI_TOKEN_HTTP_WWW_AUTHENTICATE,
|
||||||
WSI_TOKEN_PROXY,
|
WSI_TOKEN_PROXY,
|
||||||
|
|
||||||
|
WSI_TOKEN_PATCH_URI,
|
||||||
|
WSI_TOKEN_PUT_URI,
|
||||||
|
WSI_TOKEN_DELETE_URI,
|
||||||
|
|
||||||
WSI_TOKEN_HTTP_URI_ARGS,
|
WSI_TOKEN_HTTP_URI_ARGS,
|
||||||
|
|
||||||
/* use token storage to stash these */
|
/* use token storage to stash these */
|
||||||
|
|
|
@ -202,7 +202,15 @@ int libwebsocket_parse(
|
||||||
struct libwebsocket_context *context,
|
struct libwebsocket_context *context,
|
||||||
struct libwebsocket *wsi, unsigned char c)
|
struct libwebsocket *wsi, unsigned char c)
|
||||||
{
|
{
|
||||||
int n;
|
static const unsigned char methods[] = {
|
||||||
|
WSI_TOKEN_GET_URI,
|
||||||
|
WSI_TOKEN_POST_URI,
|
||||||
|
WSI_TOKEN_OPTIONS_URI,
|
||||||
|
WSI_TOKEN_PUT_URI,
|
||||||
|
WSI_TOKEN_PATCH_URI,
|
||||||
|
WSI_TOKEN_DELETE_URI,
|
||||||
|
};
|
||||||
|
int n, m;
|
||||||
|
|
||||||
switch (wsi->u.hdr.parser_state) {
|
switch (wsi->u.hdr.parser_state) {
|
||||||
default:
|
default:
|
||||||
|
@ -215,9 +223,11 @@ int libwebsocket_parse(
|
||||||
wsi->u.hdr.parser_state]].len && c == ' ')
|
wsi->u.hdr.parser_state]].len && c == ' ')
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if ((wsi->u.hdr.parser_state != WSI_TOKEN_GET_URI) &&
|
for (m = 0; m < ARRAY_SIZE(methods); m++)
|
||||||
(wsi->u.hdr.parser_state != WSI_TOKEN_POST_URI) &&
|
if (wsi->u.hdr.parser_state == methods[m])
|
||||||
(wsi->u.hdr.parser_state != WSI_TOKEN_OPTIONS_URI))
|
break;
|
||||||
|
if (m == ARRAY_SIZE(methods))
|
||||||
|
/* it was not any of the methods */
|
||||||
goto check_eol;
|
goto check_eol;
|
||||||
|
|
||||||
/* special URI processing... end at space */
|
/* special URI processing... end at space */
|
||||||
|
@ -398,17 +408,15 @@ swallow:
|
||||||
|
|
||||||
if (wsi->u.hdr.lextable_pos < 0) {
|
if (wsi->u.hdr.lextable_pos < 0) {
|
||||||
/* this is not a header we know about */
|
/* this is not a header we know about */
|
||||||
if (wsi->u.hdr.ah->frag_index[WSI_TOKEN_GET_URI] ||
|
for (m = 0; m < ARRAY_SIZE(methods); m++)
|
||||||
wsi->u.hdr.ah->frag_index[WSI_TOKEN_POST_URI] ||
|
if (wsi->u.hdr.ah->frag_index[methods[m]]) {
|
||||||
wsi->u.hdr.ah->frag_index[WSI_TOKEN_OPTIONS_URI] ||
|
/*
|
||||||
wsi->u.hdr.ah->frag_index[WSI_TOKEN_HTTP]) {
|
* already had the method, no idea what
|
||||||
/*
|
* this crap is, ignore
|
||||||
* already had the method, no idea what
|
*/
|
||||||
* this crap is, ignore
|
wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING;
|
||||||
*/
|
break;
|
||||||
wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING;
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
/*
|
/*
|
||||||
* hm it's an unknown http method in fact,
|
* hm it's an unknown http method in fact,
|
||||||
* treat as dangerous
|
* treat as dangerous
|
||||||
|
@ -418,28 +426,19 @@ swallow:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (lextable[wsi->u.hdr.lextable_pos] < FAIL_CHAR) {
|
if (lextable[wsi->u.hdr.lextable_pos] < FAIL_CHAR) {
|
||||||
|
|
||||||
/* terminal state */
|
/* terminal state */
|
||||||
|
|
||||||
n = ((unsigned int)lextable[wsi->u.hdr.lextable_pos] << 8) |
|
n = ((unsigned int)lextable[wsi->u.hdr.lextable_pos] << 8) |
|
||||||
lextable[wsi->u.hdr.lextable_pos + 1];
|
lextable[wsi->u.hdr.lextable_pos + 1];
|
||||||
|
|
||||||
lwsl_parser("known hdr %d\n", n);
|
lwsl_parser("known hdr %d\n", n);
|
||||||
if (n == WSI_TOKEN_GET_URI &&
|
for (m = 0; m < ARRAY_SIZE(methods); m++)
|
||||||
wsi->u.hdr.ah->frag_index[WSI_TOKEN_GET_URI]) {
|
if (n == methods[m] &&
|
||||||
lwsl_warn("Duplicated GET\n");
|
wsi->u.hdr.ah->frag_index[
|
||||||
return -1;
|
methods[m]]) {
|
||||||
}
|
lwsl_warn("Duplicated method\n");
|
||||||
if (n == WSI_TOKEN_POST_URI &&
|
return -1;
|
||||||
wsi->u.hdr.ah->frag_index[WSI_TOKEN_POST_URI]) {
|
}
|
||||||
lwsl_warn("Duplicated POST\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (n == WSI_TOKEN_OPTIONS_URI &&
|
|
||||||
wsi->u.hdr.ah->frag_index[WSI_TOKEN_OPTIONS_URI]) {
|
|
||||||
lwsl_warn("Duplicated OPTIONS\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* WSORIGIN is protocol equiv to ORIGIN,
|
* WSORIGIN is protocol equiv to ORIGIN,
|
||||||
|
|
72
lib/server.c
72
lib/server.c
|
@ -179,60 +179,58 @@ int lws_http_action(struct libwebsocket_context *context,
|
||||||
char content_length_str[32];
|
char content_length_str[32];
|
||||||
char http_version_str[10];
|
char http_version_str[10];
|
||||||
char http_conn_str[20];
|
char http_conn_str[20];
|
||||||
int n;
|
int n, count = 0;
|
||||||
|
static const unsigned char methods[] = {
|
||||||
|
WSI_TOKEN_GET_URI,
|
||||||
|
WSI_TOKEN_POST_URI,
|
||||||
|
WSI_TOKEN_OPTIONS_URI,
|
||||||
|
WSI_TOKEN_PUT_URI,
|
||||||
|
WSI_TOKEN_PATCH_URI,
|
||||||
|
WSI_TOKEN_DELETE_URI,
|
||||||
|
#ifdef LWS_USE_HTTP2
|
||||||
|
WSI_TOKEN_HTTP_COLON_PATH,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
static const char * const method_names[] = {
|
||||||
|
"GET", "POST", "OPTIONS", "PUT", "PATCH", "DELETE",
|
||||||
|
#ifdef LWS_USE_HTTP2
|
||||||
|
":path",
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
/* it's not websocket.... shall we accept it as http? */
|
/* it's not websocket.... shall we accept it as http? */
|
||||||
|
|
||||||
if (!lws_hdr_total_length(wsi, WSI_TOKEN_GET_URI) &&
|
for (n = 0; n < ARRAY_SIZE(methods); n++)
|
||||||
!lws_hdr_total_length(wsi, WSI_TOKEN_POST_URI) &&
|
if (lws_hdr_total_length(wsi, methods[n]))
|
||||||
#ifdef LWS_USE_HTTP2
|
count++;
|
||||||
!lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_COLON_PATH) &&
|
if (!count) {
|
||||||
#endif
|
|
||||||
!lws_hdr_total_length(wsi, WSI_TOKEN_OPTIONS_URI)) {
|
|
||||||
lwsl_warn("Missing URI in HTTP request\n");
|
lwsl_warn("Missing URI in HTTP request\n");
|
||||||
goto bail_nuke_ah;
|
goto bail_nuke_ah;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lws_hdr_total_length(wsi, WSI_TOKEN_GET_URI) &&
|
if (count != 1) {
|
||||||
lws_hdr_total_length(wsi, WSI_TOKEN_POST_URI)) {
|
lwsl_warn("multiple methods?\n");
|
||||||
lwsl_warn("GET and POST methods?\n");
|
|
||||||
goto bail_nuke_ah;
|
goto bail_nuke_ah;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (libwebsocket_ensure_user_space(wsi))
|
if (libwebsocket_ensure_user_space(wsi))
|
||||||
goto bail_nuke_ah;
|
goto bail_nuke_ah;
|
||||||
|
|
||||||
#ifdef LWS_USE_HTTP2
|
for (n = 0; n < ARRAY_SIZE(methods); n++)
|
||||||
if (lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_COLON_PATH)) {
|
if (lws_hdr_total_length(wsi, methods[n])) {
|
||||||
uri_ptr = lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_COLON_PATH);
|
uri_ptr = lws_hdr_simple_ptr(wsi, methods[n]);
|
||||||
uri_len = lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_COLON_PATH);
|
uri_len = lws_hdr_total_length(wsi, methods[n]);
|
||||||
lwsl_info("HTTP2 request for '%s'\n", uri_ptr);
|
lwsl_info("Method: %s request for '%s'\n",
|
||||||
goto got_uri;
|
method_names[n], uri_ptr);
|
||||||
}
|
break;
|
||||||
#endif
|
}
|
||||||
if (lws_hdr_total_length(wsi, WSI_TOKEN_OPTIONS_URI)) {
|
|
||||||
uri_ptr = lws_hdr_simple_ptr(wsi, WSI_TOKEN_OPTIONS_URI);
|
|
||||||
uri_len = lws_hdr_total_length(wsi, WSI_TOKEN_OPTIONS_URI);
|
|
||||||
lwsl_info("HTTP OPTIONS request for '%s'\n", uri_ptr);
|
|
||||||
goto got_uri;
|
|
||||||
}
|
|
||||||
if (lws_hdr_total_length(wsi, WSI_TOKEN_POST_URI)) {
|
|
||||||
uri_ptr = lws_hdr_simple_ptr(wsi, WSI_TOKEN_POST_URI);
|
|
||||||
uri_len = lws_hdr_total_length(wsi, WSI_TOKEN_POST_URI);
|
|
||||||
lwsl_info("HTTP POST request for '%s'\n", uri_ptr);
|
|
||||||
goto got_uri;
|
|
||||||
}
|
|
||||||
if (lws_hdr_total_length(wsi, WSI_TOKEN_GET_URI)) {
|
|
||||||
uri_ptr = lws_hdr_simple_ptr(wsi, WSI_TOKEN_GET_URI);
|
|
||||||
uri_len = lws_hdr_total_length(wsi, WSI_TOKEN_GET_URI);
|
|
||||||
lwsl_info("HTTP GET request for '%s'\n", uri_ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
got_uri:
|
|
||||||
/* HTTP header had a content length? */
|
/* HTTP header had a content length? */
|
||||||
|
|
||||||
wsi->u.http.content_length = 0;
|
wsi->u.http.content_length = 0;
|
||||||
if (lws_hdr_total_length(wsi, WSI_TOKEN_POST_URI))
|
if (lws_hdr_total_length(wsi, WSI_TOKEN_POST_URI) ||
|
||||||
|
lws_hdr_total_length(wsi, WSI_TOKEN_PATCH_URI) ||
|
||||||
|
lws_hdr_total_length(wsi, WSI_TOKEN_PUT_URI))
|
||||||
wsi->u.http.content_length = 100 * 1024 * 1024;
|
wsi->u.http.content_length = 100 * 1024 * 1024;
|
||||||
|
|
||||||
if (lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_CONTENT_LENGTH)) {
|
if (lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_CONTENT_LENGTH)) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue