[core] http_header_str_contains_token()
parent
6f803af03c
commit
e2b4c309f6
|
@ -57,6 +57,24 @@ enum http_header_e http_header_hkey_get(const char *s, size_t slen) {
|
|||
}
|
||||
|
||||
|
||||
int http_header_str_contains_token (const char * const s, const size_t slen, const char * const m, const size_t mlen)
|
||||
{
|
||||
/*if (slen < mlen) return 0;*//*(possible optimizations for caller)*/
|
||||
/*if (slen == mlen && buffer_eq_icase_ssn(s, m, mlen)) return 1;*/
|
||||
size_t i = 0;
|
||||
do {
|
||||
while (i < slen && (s[i]==' ' || s[i]=='\t' || s[i]==',')) ++i;
|
||||
if (i == slen) return 0;
|
||||
if (buffer_eq_icase_ssn(s+i, m, mlen)) {
|
||||
i += mlen;
|
||||
if (i == slen || s[i]==' ' || s[i]=='\t' || s[i]==',' || s[i]==';')
|
||||
return 1;
|
||||
}
|
||||
while (i < slen && s[i]!=',') ++i;
|
||||
} while (i < slen);
|
||||
return 0;
|
||||
}
|
||||
|
||||
buffer * http_header_response_get(connection *con, enum http_header_e id, const char *k, size_t klen) {
|
||||
data_string * const ds =
|
||||
(id <= HTTP_HEADER_OTHER || (con->response.htags & id))
|
||||
|
|
|
@ -42,6 +42,9 @@ enum http_header_e {
|
|||
__attribute_pure__
|
||||
enum http_header_e http_header_hkey_get(const char *s, size_t slen);
|
||||
|
||||
__attribute_pure__
|
||||
int http_header_str_contains_token (const char *s, size_t slen, const char *m, size_t mlen);
|
||||
|
||||
buffer * http_header_response_get(connection *con, enum http_header_e id, const char *k, size_t klen);
|
||||
void http_header_response_unset(connection *con, enum http_header_e id, const char *k, size_t klen);
|
||||
void http_header_response_set(connection *con, enum http_header_e id, const char *k, size_t klen, const char *v, size_t vlen);
|
||||
|
|
|
@ -407,19 +407,6 @@ static void mod_wstunnel_patch_connection(server *srv, connection *con, plugin_d
|
|||
#undef PATCH_GW
|
||||
#undef PATCH
|
||||
|
||||
static int header_contains_token (buffer *b, const char *m, size_t mlen)
|
||||
{
|
||||
for (char *s = b->ptr; s; s = strchr(s, ',')) {
|
||||
while (*s == ' ' || *s == '\t' || *s == ',') ++s;
|
||||
if (buffer_eq_icase_ssn(s, m, mlen)) {
|
||||
s += mlen;
|
||||
if (*s == '\0' || *s == ' ' || *s == '\t' || *s == ',' || *s == ';')
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wstunnel_is_allowed_origin(connection *con, handler_ctx *hctx) {
|
||||
/* If allowed origins is set (and not empty list), fail closed if no match.
|
||||
* Note that origin provided in request header has not been normalized, so
|
||||
|
@ -594,11 +581,11 @@ static handler_t mod_wstunnel_check_extension(server *srv, connection *con, void
|
|||
*/
|
||||
vb = http_header_request_get(con, HTTP_HEADER_UPGRADE, CONST_STR_LEN("Upgrade"));
|
||||
if (NULL == vb
|
||||
|| !header_contains_token(vb, CONST_STR_LEN("websocket")))
|
||||
|| !http_header_str_contains_token(CONST_BUF_LEN(vb), CONST_STR_LEN("websocket")))
|
||||
return HANDLER_GO_ON;
|
||||
vb = http_header_request_get(con, HTTP_HEADER_CONNECTION, CONST_STR_LEN("Connection"));
|
||||
if (NULL == vb
|
||||
|| !header_contains_token(vb, CONST_STR_LEN("upgrade")))
|
||||
|| !http_header_str_contains_token(CONST_BUF_LEN(vb), CONST_STR_LEN("upgrade")))
|
||||
return HANDLER_GO_ON;
|
||||
|
||||
mod_wstunnel_patch_connection(srv, con, p);
|
||||
|
|
|
@ -345,57 +345,6 @@ int http_request_host_policy (connection *con, buffer *b, const buffer *scheme)
|
|||
&& 0 != http_request_host_normalize(b, scheme_port(scheme))));
|
||||
}
|
||||
|
||||
static int http_request_split_value(array *vals, const char *current, size_t len) {
|
||||
int state = 0;
|
||||
const char *token_start = NULL, *token_end = NULL;
|
||||
/*
|
||||
* parse
|
||||
*
|
||||
* val1, val2, val3, val4
|
||||
*
|
||||
* into a array (more or less a explode() incl. stripping of whitespaces
|
||||
*/
|
||||
|
||||
for (size_t i = 0; i <= len; ++i, ++current) {
|
||||
switch (state) {
|
||||
case 0: /* find start of a token */
|
||||
switch (*current) {
|
||||
case ' ':
|
||||
case '\t': /* skip white space */
|
||||
case ',': /* skip empty token */
|
||||
break;
|
||||
case '\0': /* end of string */
|
||||
return 0;
|
||||
default:
|
||||
/* found real data, switch to state 1 to find the end of the token */
|
||||
token_start = token_end = current;
|
||||
state = 1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 1: /* find end of token and last non white space character */
|
||||
switch (*current) {
|
||||
case ' ':
|
||||
case '\t':
|
||||
/* space - don't update token_end */
|
||||
break;
|
||||
case ',':
|
||||
case '\0': /* end of string also marks the end of a token */
|
||||
array_insert_value(vals, token_start, token_end-token_start+1);
|
||||
state = 0;
|
||||
break;
|
||||
default:
|
||||
/* no white space, update token_end to include current character */
|
||||
token_end = current;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int request_uri_is_valid_char(unsigned char c) {
|
||||
return (c > 32 && c != 127 && c != 255);
|
||||
}
|
||||
|
@ -479,23 +428,15 @@ static int parse_single_header(server *srv, connection *con, parse_header_state
|
|||
}
|
||||
break;
|
||||
case HTTP_HEADER_CONNECTION:
|
||||
{
|
||||
array * const vals = srv->split_vals;
|
||||
array_reset_data_strings(vals);
|
||||
http_request_split_value(vals, v, vlen); /* split on , */
|
||||
for (size_t vi = 0; vi < vals->used; ++vi) {
|
||||
data_string *dsv = (data_string *)vals->data[vi];
|
||||
if (buffer_eq_icase_slen(dsv->value,
|
||||
CONST_STR_LEN("keep-alive"))) {
|
||||
state->keep_alive_set = HTTP_CONNECTION_KEEPALIVE;
|
||||
break;
|
||||
}
|
||||
else if (buffer_eq_icase_slen(dsv->value,
|
||||
CONST_STR_LEN("close"))) {
|
||||
state->keep_alive_set = HTTP_CONNECTION_CLOSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* "Connection: close" is common case if header is present */
|
||||
if ((vlen == 5 && buffer_eq_icase_ssn(v, CONST_STR_LEN("close")))
|
||||
|| http_header_str_contains_token(v,vlen,CONST_STR_LEN("close"))) {
|
||||
state->keep_alive_set = HTTP_CONNECTION_CLOSE;
|
||||
break;
|
||||
}
|
||||
if (http_header_str_contains_token(v,vlen,CONST_STR_LEN("keep-alive"))){
|
||||
state->keep_alive_set = HTTP_CONNECTION_KEEPALIVE;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case HTTP_HEADER_CONTENT_TYPE:
|
||||
|
|
Loading…
Reference in New Issue