Browse Source

[core] pass req hdrs buffer to http_request_parse

personal/stbuehler/fix-fdevent
Glenn Strauss 3 years ago
parent
commit
25185d1de0
  1. 2
      src/base.h
  2. 3
      src/connections.c
  3. 46
      src/request.c
  4. 2
      src/request.h
  5. 7
      src/t/test_request.c

2
src/base.h

@ -247,8 +247,6 @@ struct connection {
buffer *dst_addr_buf;
/* request */
buffer *parse_request;
request request;
request_uri uri;
physical physical;

3
src/connections.c

@ -545,7 +545,6 @@ static connection *connection_init(server *srv) {
con->bytes_read = 0;
con->bytes_header = 0;
con->loops_per_request = 0;
con->parse_request = con->request.request; /* for http_request_parse() */
#define CLEAN(x) \
con->x = buffer_init();
@ -798,7 +797,7 @@ static void connection_read_header(server *srv, connection *con) {
save = buffer_init_buffer(con->request.request);
}
if (0 != http_request_parse(srv, con)) {
if (0 != http_request_parse(srv, con, con->request.request)) {
con->keep_alive = 0;
con->request.content_length = 0;

46
src/request.c

@ -570,7 +570,8 @@ static int parse_single_header(server *srv, connection *con, parse_header_state
return 1;
}
static size_t http_request_parse_reqline(server *srv, connection *con, parse_header_state *state) {
static size_t http_request_parse_reqline(server *srv, connection *con, buffer *hdrs, parse_header_state *state) {
char * const ptr = hdrs->ptr;
char *uri = NULL, *proto = NULL, *method = NULL;
int line = 0;
@ -590,11 +591,11 @@ static size_t http_request_parse_reqline(server *srv, connection *con, parse_hea
*
* <method> <uri> <protocol>\r\n
* */
ilen = buffer_string_length(con->parse_request);
ilen = buffer_string_length(hdrs);
for (i = 0, first = 0; i < ilen && line == 0; i++) {
switch(con->parse_request->ptr[i]) {
switch(ptr[i]) {
case '\r':
if (con->parse_request->ptr[i+1] != '\n') break;
if (ptr[i+1] != '\n') break;
/* fall through */
case '\n':
{
@ -602,17 +603,17 @@ static size_t http_request_parse_reqline(server *srv, connection *con, parse_hea
char *nuri = NULL;
size_t j, jlen;
buffer_copy_string_len(con->request.request_line, con->parse_request->ptr, i);
buffer_copy_string_len(con->request.request_line, ptr, i);
/* \r\n -> \0\0 */
if (con->parse_request->ptr[i] == '\r') {
con->parse_request->ptr[i] = '\0';
if (ptr[i] == '\r') {
ptr[i] = '\0';
++i;
} else if (http_header_strict) { /* '\n' */
http_request_missing_CR_before_LF(srv, con);
return 0;
}
con->parse_request->ptr[i] = '\0';
ptr[i] = '\0';
if (request_line_stage != 2) {
if (srv->srvconf.log_request_header_on_error) {
@ -621,7 +622,7 @@ static size_t http_request_parse_reqline(server *srv, connection *con, parse_hea
return 0;
}
proto = con->parse_request->ptr + first;
proto = ptr + first;
*(uri - 1) = '\0';
*(proto - 1) = '\0';
@ -765,12 +766,12 @@ static size_t http_request_parse_reqline(server *srv, connection *con, parse_hea
switch(request_line_stage) {
case 0:
/* GET|POST|... */
method = con->parse_request->ptr + first;
method = ptr + first;
first = i + 1;
break;
case 1:
/* /foobar/... */
uri = con->parse_request->ptr + first;
uri = ptr + first;
first = i + 1;
break;
default:
@ -808,7 +809,8 @@ static size_t http_request_parse_reqline(server *srv, connection *con, parse_hea
return i;
}
int http_request_parse(server *srv, connection *con) {
int http_request_parse(server *srv, connection *con, buffer *hdrs) {
char * const ptr = hdrs->ptr;
char *value = NULL;
size_t i, first, ilen;
const unsigned int http_header_strict = (con->conf.http_parseopts & HTTP_PARSEOPT_HEADER_STRICT);
@ -816,19 +818,19 @@ int http_request_parse(server *srv, connection *con) {
parse_header_state state;
init_parse_header_state(&state);
i = first = http_request_parse_reqline(srv, con, &state);
i = first = http_request_parse_reqline(srv, con, hdrs, &state);
if (0 == i) goto failure;
if (con->parse_request->ptr[i] == ' ' || con->parse_request->ptr[i] == '\t') {
if (ptr[i] == ' ' || 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");
}
goto failure;
}
ilen = buffer_string_length(con->parse_request);
ilen = buffer_string_length(hdrs);
for (int is_key = 1, key_len = 0, done = 0; i <= ilen && !done; ++i) {
char *cur = con->parse_request->ptr + i;
char *cur = ptr + i;
if (is_key) {
/**
@ -853,7 +855,7 @@ int http_request_parse(server *srv, connection *con) {
is_key = 0;
key_len = i - first;
value = cur + 1;
i = cur - con->parse_request->ptr;
i = cur - ptr;
break;
case '(':
case ')':
@ -877,10 +879,10 @@ int http_request_parse(server *srv, connection *con) {
}
goto failure;
case '\r':
if (con->parse_request->ptr[i+1] == '\n' && i == first) {
if (ptr[i+1] == '\n' && i == first) {
/* End of Header */
con->parse_request->ptr[i] = '\0';
con->parse_request->ptr[i+1] = '\0';
ptr[i] = '\0';
ptr[i+1] = '\0';
i++;
@ -898,7 +900,7 @@ int http_request_parse(server *srv, connection *con) {
http_request_missing_CR_before_LF(srv, con);
goto failure;
} else if (i == first) {
con->parse_request->ptr[i] = '\0';
ptr[i] = '\0';
done = 1;
break;
}
@ -949,7 +951,7 @@ int http_request_parse(server *srv, connection *con) {
/* End of Headerline */
*cur = '\0'; /*(for if value is further parsed and '\0' is expected at end of string)*/
if (!parse_single_header(srv, con, &state, con->parse_request->ptr + first, key_len, value, cur - value)) {
if (!parse_single_header(srv, con, &state, ptr + first, key_len, value, cur - value)) {
/* parse_single_header should already have logged it */
goto failure;
}

2
src/request.h

@ -5,7 +5,7 @@
#include "base_decls.h"
#include "buffer.h"
int http_request_parse(server *srv, connection *con);
int http_request_parse(server *srv, connection *con, buffer *hdrs);
int http_request_host_normalize(buffer *b, int scheme_port);
int http_request_host_policy(connection *con, buffer *b, const buffer *scheme);

7
src/t/test_request.c

@ -20,7 +20,6 @@ static void test_request_connection_reset(connection *con)
con->header_len = 0;
con->http_status = 0;
buffer_reset(con->proto);
buffer_reset(con->parse_request);
buffer_reset(con->request.request);
buffer_reset(con->request.request_line);
buffer_reset(con->request.orig_uri);
@ -31,8 +30,8 @@ static void test_request_connection_reset(connection *con)
static void run_http_request_parse(server *srv, connection *con, int line, int status, const char *desc, const char *req, size_t reqlen)
{
test_request_connection_reset(con);
buffer_copy_string_len(con->parse_request, req, reqlen);
http_request_parse(srv, con);
buffer_copy_string_len(con->request.request, req, reqlen);
http_request_parse(srv, con, con->request.request);
if (con->http_status != status) {
fprintf(stderr,
"%s.%d: %s() failed: expected '%d', got '%d' for test %s\n",
@ -462,7 +461,6 @@ int main (void)
memset(&con, 0, sizeof(connection));
con.proto = buffer_init();
con.parse_request = buffer_init();
con.request.request = buffer_init();
con.request.request_line = buffer_init();
con.request.orig_uri = buffer_init();
@ -476,7 +474,6 @@ int main (void)
test_request_http_request_parse(&srv, &con);
buffer_free(con.proto);
buffer_free(con.parse_request);
buffer_free(con.request.request);
buffer_free(con.request.request_line);
buffer_free(con.request.orig_uri);

Loading…
Cancel
Save