1
0
Fork 0
mirror of https://github.com/warmcat/libwebsockets.git synced 2025-03-09 00:00:04 +01:00

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

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

File diff suppressed because it is too large Load diff

View file

@ -389,8 +389,12 @@ enum lws_token_indexes {
WSI_TOKEN_HTTP_WWW_AUTHENTICATE,
WSI_TOKEN_PROXY,
WSI_TOKEN_PATCH_URI,
WSI_TOKEN_PUT_URI,
WSI_TOKEN_DELETE_URI,
WSI_TOKEN_HTTP_URI_ARGS,
/* use token storage to stash these */
_WSI_TOKEN_CLIENT_SENT_PROTOCOLS,

View file

@ -202,7 +202,15 @@ int libwebsocket_parse(
struct libwebsocket_context *context,
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) {
default:
@ -215,9 +223,11 @@ int libwebsocket_parse(
wsi->u.hdr.parser_state]].len && c == ' ')
break;
if ((wsi->u.hdr.parser_state != WSI_TOKEN_GET_URI) &&
(wsi->u.hdr.parser_state != WSI_TOKEN_POST_URI) &&
(wsi->u.hdr.parser_state != WSI_TOKEN_OPTIONS_URI))
for (m = 0; m < ARRAY_SIZE(methods); m++)
if (wsi->u.hdr.parser_state == methods[m])
break;
if (m == ARRAY_SIZE(methods))
/* it was not any of the methods */
goto check_eol;
/* special URI processing... end at space */
@ -398,17 +408,15 @@ swallow:
if (wsi->u.hdr.lextable_pos < 0) {
/* this is not a header we know about */
if (wsi->u.hdr.ah->frag_index[WSI_TOKEN_GET_URI] ||
wsi->u.hdr.ah->frag_index[WSI_TOKEN_POST_URI] ||
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
*/
wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING;
break;
}
for (m = 0; m < ARRAY_SIZE(methods); m++)
if (wsi->u.hdr.ah->frag_index[methods[m]]) {
/*
* already had the method, no idea what
* this crap is, ignore
*/
wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING;
break;
}
/*
* hm it's an unknown http method in fact,
* treat as dangerous
@ -418,28 +426,19 @@ swallow:
return -1;
}
if (lextable[wsi->u.hdr.lextable_pos] < FAIL_CHAR) {
/* terminal state */
n = ((unsigned int)lextable[wsi->u.hdr.lextable_pos] << 8) |
lextable[wsi->u.hdr.lextable_pos + 1];
lwsl_parser("known hdr %d\n", n);
if (n == WSI_TOKEN_GET_URI &&
wsi->u.hdr.ah->frag_index[WSI_TOKEN_GET_URI]) {
lwsl_warn("Duplicated GET\n");
return -1;
}
if (n == WSI_TOKEN_POST_URI &&
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;
}
for (m = 0; m < ARRAY_SIZE(methods); m++)
if (n == methods[m] &&
wsi->u.hdr.ah->frag_index[
methods[m]]) {
lwsl_warn("Duplicated method\n");
return -1;
}
/*
* 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 http_version_str[10];
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? */
if (!lws_hdr_total_length(wsi, WSI_TOKEN_GET_URI) &&
!lws_hdr_total_length(wsi, WSI_TOKEN_POST_URI) &&
#ifdef LWS_USE_HTTP2
!lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_COLON_PATH) &&
#endif
!lws_hdr_total_length(wsi, WSI_TOKEN_OPTIONS_URI)) {
for (n = 0; n < ARRAY_SIZE(methods); n++)
if (lws_hdr_total_length(wsi, methods[n]))
count++;
if (!count) {
lwsl_warn("Missing URI in HTTP request\n");
goto bail_nuke_ah;
}
if (lws_hdr_total_length(wsi, WSI_TOKEN_GET_URI) &&
lws_hdr_total_length(wsi, WSI_TOKEN_POST_URI)) {
lwsl_warn("GET and POST methods?\n");
if (count != 1) {
lwsl_warn("multiple methods?\n");
goto bail_nuke_ah;
}
if (libwebsocket_ensure_user_space(wsi))
goto bail_nuke_ah;
#ifdef LWS_USE_HTTP2
if (lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_COLON_PATH)) {
uri_ptr = lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_COLON_PATH);
uri_len = lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_COLON_PATH);
lwsl_info("HTTP2 request for '%s'\n", uri_ptr);
goto got_uri;
}
#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);
}
for (n = 0; n < ARRAY_SIZE(methods); n++)
if (lws_hdr_total_length(wsi, methods[n])) {
uri_ptr = lws_hdr_simple_ptr(wsi, methods[n]);
uri_len = lws_hdr_total_length(wsi, methods[n]);
lwsl_info("Method: %s request for '%s'\n",
method_names[n], uri_ptr);
break;
}
got_uri:
/* HTTP header had a content length? */
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;
if (lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_CONTENT_LENGTH)) {