Add PATCH, PUT, DELETE methods

AG: rewrite method code to use method arrays
This commit is contained in:
Quinlan Pfiffer 2015-01-10 19:01:52 -08:00 committed by Andy Green
parent 363420dff4
commit 49f72aa451
5 changed files with 795 additions and 775 deletions

View file

@ -81,6 +81,10 @@ static const char *set[] = {
"www-authenticate:", "www-authenticate:",
"proxy ", "proxy ",
"patch",
"put",
"delete",
"", /* not matchable */ "", /* not matchable */
}; };

File diff suppressed because it is too large Load diff

View file

@ -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 */

View file

@ -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,

View file

@ -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)) {