Browse Source

[core] http_request_parse_reqline() separate func

http_request_parse_reqline() separate func from http_request_parse()
600+ line http_request_parse() is now two routines with ~300 lines each
personal/stbuehler/fix-fdevent
Glenn Strauss 3 years ago
parent
commit
c8159ee5f6
  1. 65
      src/request.c

65
src/request.c

@ -578,22 +578,14 @@ static int parse_single_header(server *srv, connection *con, parse_header_state
return 1;
}
int http_request_parse(server *srv, connection *con) {
static size_t http_request_parse_reqline(server *srv, connection *con, parse_header_state *state) {
char *uri = NULL, *proto = NULL, *method = NULL;
int is_key = 1, key_len = 0;
char *value = NULL;
int line = 0;
int request_line_stage = 0;
size_t i, first, ilen;
int done = 0;
const unsigned int http_header_strict = (con->conf.http_parseopts & HTTP_PARSEOPT_HEADER_STRICT);
parse_header_state state;
init_parse_header_state(&state);
/*
* Request: "^(GET|POST|HEAD) ([^ ]+(\\?[^ ]+|)) (HTTP/1\\.[01])$"
* Option : "^([-a-zA-Z]+): (.+)$"
@ -614,7 +606,7 @@ int http_request_parse(server *srv, connection *con) {
#ifdef __COVERITY__
if (buffer_string_length(con->request.request) < 2) {
goto failure;
return 0;
}
#endif
/* coverity[overflow_sink : FALSE] */
@ -624,11 +616,11 @@ int http_request_parse(server *srv, connection *con) {
/* we are in keep-alive and might get \n after a previous POST request.*/
if (http_header_strict) {
http_request_missing_CR_before_LF(srv, con);
goto failure;
return 0;
}
#ifdef __COVERITY__
if (buffer_string_length(con->request.request) < 1) {
goto failure;
return 0;
}
#endif
/* coverity[overflow_sink : FALSE] */
@ -664,7 +656,7 @@ int http_request_parse(server *srv, connection *con) {
++i;
} else if (http_header_strict) { /* '\n' */
http_request_missing_CR_before_LF(srv, con);
goto failure;
return 0;
}
con->parse_request->ptr[i] = '\0';
@ -675,7 +667,7 @@ int http_request_parse(server *srv, connection *con) {
"request-header:\n",
con->request.request);
}
goto failure;
return 0;
}
proto = con->parse_request->ptr + first;
@ -694,7 +686,7 @@ int http_request_parse(server *srv, connection *con) {
con->request.request);
}
goto failure;
return 0;
}
con->request.http_method = r;
@ -736,7 +728,7 @@ int http_request_parse(server *srv, connection *con) {
"request-header:\n",
con->request.request);
}
goto failure;
return 0;
}
if (major_num == 1 && minor_num == 1) {
@ -752,7 +744,7 @@ int http_request_parse(server *srv, connection *con) {
"request-header:\n",
con->request.request);
}
goto failure;
return 0;
}
} else {
if (srv->srvconf.log_request_header_on_error) {
@ -761,7 +753,7 @@ int http_request_parse(server *srv, connection *con) {
"request-header:\n",
con->request.request);
}
goto failure;
return 0;
}
if (*uri == '/') {
@ -769,14 +761,14 @@ int http_request_parse(server *srv, connection *con) {
buffer_copy_string_len(con->request.uri, uri, proto - uri - 1);
} else if (0 == strncasecmp(uri, "http://", 7) &&
NULL != (nuri = strchr(uri + 7, '/'))) {
state.reqline_host = uri + 7;
state.reqline_hostlen = nuri - state.reqline_host;
state->reqline_host = uri + 7;
state->reqline_hostlen = nuri - state->reqline_host;
buffer_copy_string_len(con->request.uri, nuri, proto - nuri - 1);
} else if (0 == strncasecmp(uri, "https://", 8) &&
NULL != (nuri = strchr(uri + 8, '/'))) {
state.reqline_host = uri + 8;
state.reqline_hostlen = nuri - state.reqline_host;
state->reqline_host = uri + 8;
state->reqline_hostlen = nuri - state->reqline_host;
buffer_copy_string_len(con->request.uri, nuri, proto - nuri - 1);
} else if (!http_header_strict
@ -786,7 +778,7 @@ int http_request_parse(server *srv, connection *con) {
buffer_copy_string_len(con->request.uri, uri, proto - uri - 1);
} else {
log_error_write(srv, __FILE__, __LINE__, "ss", "request-URI parse error -> 400 for:", uri);
goto failure;
return 0;
}
/* check uri for invalid characters */
@ -823,7 +815,7 @@ int http_request_parse(server *srv, connection *con) {
con->request.request);
}
goto failure;
return 0;
}
buffer_copy_buffer(con->request.orig_uri, con->request.uri);
@ -854,7 +846,7 @@ int http_request_parse(server *srv, connection *con) {
"request-header:\n",
con->request.request);
}
goto failure;
return 0;
}
request_line_stage++;
@ -869,15 +861,29 @@ int http_request_parse(server *srv, connection *con) {
"request-header:\n",
con->request.request);
}
goto failure;
return 0;
}
if (state.reqline_host) {
if (state->reqline_host) {
/* Insert as host header */
array_insert_key_value(con->request.headers, CONST_STR_LEN("Host"), state.reqline_host, state.reqline_hostlen);
array_insert_key_value(con->request.headers, CONST_STR_LEN("Host"), state->reqline_host, state->reqline_hostlen);
con->request.http_host = ((data_string *)array_get_element_klen(con->request.headers, CONST_STR_LEN("Host")))->value;
}
return i;
}
int http_request_parse(server *srv, connection *con) {
char *value = NULL;
size_t i, first, ilen;
const unsigned int http_header_strict = (con->conf.http_parseopts & HTTP_PARSEOPT_HEADER_STRICT);
parse_header_state state;
init_parse_header_state(&state);
i = first = http_request_parse_reqline(srv, con, &state);
if (0 == i) goto failure;
if (con->parse_request->ptr[i] == ' ' || con->parse_request->ptr[i] == '\t') {
if (srv->srvconf.log_request_header_on_error) {
log_error_write(srv, __FILE__, __LINE__, "s", "WS at the start of first line -> 400");
@ -886,7 +892,8 @@ int http_request_parse(server *srv, connection *con) {
goto failure;
}
for (; i <= ilen && !done; i++) {
ilen = buffer_string_length(con->parse_request);
for (int is_key = 1, key_len = 0, done = 0; i <= ilen && !done; ++i) {
char *cur = con->parse_request->ptr + i;
if (is_key) {

Loading…
Cancel
Save