Browse Source

Splitted worker from server; removed "server *srv" from most function which also have "connection *con"

personal/stbuehler/wip
Stefan Bühler 14 years ago
parent
commit
0fe9176d6f
  1. 12
      src/actions.c
  2. 4
      src/actions.h
  3. 1
      src/base.h
  4. 24
      src/chunk.c
  5. 4
      src/chunk.h
  6. 14
      src/chunk_parser.c
  7. 6
      src/chunk_parser.h
  8. 58
      src/condition.c
  9. 2
      src/condition.h
  10. 232
      src/connection.c
  11. 32
      src/connection.h
  12. 6
      src/filter_chunked.c
  13. 4
      src/filter_chunked.h
  14. 2
      src/http_request_parser.h
  15. 8
      src/http_request_parser.rl
  16. 1
      src/log.c
  17. 12
      src/log.h
  18. 10
      src/network.c
  19. 16
      src/network.h
  20. 12
      src/network_linux_sendfile.c
  21. 6
      src/network_write.c
  22. 6
      src/network_writev.c
  23. 6
      src/plugin.c
  24. 10
      src/plugin.h
  25. 22
      src/plugin_core.c
  26. 43
      src/request.c
  27. 2
      src/request.h
  28. 8
      src/response.c
  29. 2
      src/response.h
  30. 172
      src/server.c
  31. 24
      src/server.h
  32. 146
      src/worker.c
  33. 46
      src/worker.h
  34. 1
      src/wscript

12
src/actions.c

@ -145,7 +145,7 @@ static action* action_stack_element_action(action_stack_element *ase) {
}
}
action_result action_execute(server *srv, connection *con) {
action_result action_execute(connection *con) {
action *a;
action_stack *as = &con->action_stack;
action_stack_element *ase;
@ -154,31 +154,31 @@ action_result action_execute(server *srv, connection *con) {
while (NULL != (ase = action_stack_top(as))) {
a = action_stack_element_action(ase);
if (!a) {
action_stack_pop(srv, as);
action_stack_pop(con->srv, as);
continue;
}
srv->stats.actions_executed++;
con->srv->stats.actions_executed++;
switch (a->type) {
case ACTION_TSETTING:
con->options[a->value.setting.ndx] = a->value.setting.value;
break;
case ACTION_TFUNCTION:
res = a->value.function.func(srv, con, a->value.function.param);
res = a->value.function.func(con, a->value.function.param);
switch (res) {
case ACTION_GO_ON:
case ACTION_FINISHED:
break;
case ACTION_ERROR:
action_stack_reset(srv, as);
action_stack_reset(con->srv, as);
return res;
case ACTION_WAIT_FOR_EVENT:
return ACTION_WAIT_FOR_EVENT;
}
break;
case ACTION_TCONDITION:
if (condition_check(srv, con, a->value.condition.cond)) {
if (condition_check(con, a->value.condition.cond)) {
action_enter(con, a->value.condition.target);
}
else if (a->value.condition.target_else) {

4
src/actions.h

@ -29,7 +29,7 @@ struct action_stack {
};
struct server; struct connection;
typedef action_result (*ActionFunc)(struct server *srv, struct connection *con, gpointer param);
typedef action_result (*ActionFunc)(struct connection *con, gpointer param);
typedef void (*ActionFree)(struct server *srv, gpointer param);
struct action_func {
@ -69,7 +69,7 @@ LI_API void action_stack_clear(server *srv, action_stack *as);
/** handle sublist now, remember current position (stack) */
LI_API void action_enter(connection *con, action *a);
LI_API action_result action_execute(server *srv, connection *con);
LI_API action_result action_execute(connection *con);
LI_API void action_release(server *srv, action *a);

1
src/base.h

@ -38,6 +38,7 @@ typedef struct connection connection;
#include "server.h"
#include "worker.h"
#include "actions.h"
#include "options.h"
#include "plugin.h"

24
src/chunk.c

@ -42,16 +42,16 @@ static void chunkfile_release(chunkfile *cf) {
/* open the file cf->name if it is not already opened for reading
* may return HANDLER_GO_ON, HANDLER_ERROR, HANDLER_WAIT_FOR_FD
*/
handler_t chunkfile_open(server *srv, connection *con, chunkfile *cf) {
handler_t chunkfile_open(connection *con, chunkfile *cf) {
if (!cf) return HANDLER_ERROR;
if (-1 != cf->fd) return HANDLER_GO_ON;
if (!cf->name) {
CON_ERROR(srv, con, "%s", "Missing filename for FILE_CHUNK");
CON_ERROR(con, "%s", "Missing filename for FILE_CHUNK");
return HANDLER_ERROR;
}
if (-1 == (cf->fd = open(cf->name->str, O_RDONLY))) {
if (EMFILE == errno) return HANDLER_WAIT_FOR_FD;
CON_ERROR(srv, con, "Couldn't open file '%s': %s", GSTR_SAFE_STR(cf->name), g_strerror(errno));
CON_ERROR(con, "Couldn't open file '%s': %s", GSTR_SAFE_STR(cf->name), g_strerror(errno));
return HANDLER_ERROR;
}
#ifdef FD_CLOEXEC
@ -61,7 +61,7 @@ handler_t chunkfile_open(server *srv, connection *con, chunkfile *cf) {
/* tell the kernel that we want to stream the file */
if (-1 == posix_fadvise(cf->fd, 0, 0, POSIX_FADV_SEQUENTIAL)) {
if (ENOSYS != errno) {
CON_ERROR(srv, con, "posix_fadvise failed for '%s': %s (%i)", GSTR_SAFE_STR(cf->name), g_strerror(errno), cf->fd);
CON_ERROR(con, "posix_fadvise failed for '%s': %s (%i)", GSTR_SAFE_STR(cf->name), g_strerror(errno), cf->fd);
}
}
#endif
@ -82,7 +82,7 @@ handler_t chunkfile_open(server *srv, connection *con, chunkfile *cf) {
* the data is _not_ marked as "done"
* may return HANDLER_GO_ON, HANDLER_ERROR, HANDLER_WAIT_FOR_FD
*/
handler_t chunkiter_read(server *srv, connection *con, chunkiter iter, off_t start, off_t length, char **data_start, off_t *data_len) {
handler_t chunkiter_read(connection *con, chunkiter iter, off_t start, off_t length, char **data_start, off_t *data_len) {
chunk *c = chunkiter_chunk(iter);
off_t we_want, we_have, our_start, our_offset;
handler_t res = HANDLER_GO_ON;
@ -102,7 +102,7 @@ handler_t chunkiter_read(server *srv, connection *con, chunkiter iter, off_t sta
*data_len = length;
break;
case FILE_CHUNK:
if (HANDLER_GO_ON != (res = chunkfile_open(srv, con, c->file.file))) return res;
if (HANDLER_GO_ON != (res = chunkfile_open(con, c->file.file))) return res;
if (length > MAX_MMAP_CHUNK) length = MAX_MMAP_CHUNK;
@ -139,11 +139,11 @@ handler_t chunkiter_read(server *srv, connection *con, chunkiter iter, off_t sta
if (-1 == lseek(c->file.file->fd, our_start, SEEK_SET)) {
/* prefer the error of the first syscall */
if (0 != mmap_errno) {
CON_ERROR(srv, con, "mmap failed for '%s' (fd = %i): %s",
CON_ERROR(con, "mmap failed for '%s' (fd = %i): %s",
GSTR_SAFE_STR(c->file.file->name), c->file.file->fd,
g_strerror(mmap_errno));
} else {
CON_ERROR(srv, con, "lseek failed for '%s' (fd = %i): %s",
CON_ERROR(con, "lseek failed for '%s' (fd = %i): %s",
GSTR_SAFE_STR(c->file.file->name), c->file.file->fd,
g_strerror(errno));
}
@ -156,11 +156,11 @@ read_chunk:
if (EINTR == errno) goto read_chunk;
/* prefer the error of the first syscall */
if (0 != mmap_errno) {
CON_ERROR(srv, con, "mmap failed for '%s' (fd = %i): %s",
CON_ERROR(con, "mmap failed for '%s' (fd = %i): %s",
GSTR_SAFE_STR(c->file.file->name), c->file.file->fd,
g_strerror(mmap_errno));
} else {
CON_ERROR(srv, con, "read failed for '%s' (fd = %i): %s",
CON_ERROR(con, "read failed for '%s' (fd = %i): %s",
GSTR_SAFE_STR(c->file.file->name), c->file.file->fd,
g_strerror(errno));
}
@ -169,7 +169,7 @@ read_chunk:
return HANDLER_ERROR;
} else if (we_have != we_want) {
/* may return less than requested bytes due to signals */
/* CON_TRACE(srv, con, "read return unexpected number of bytes"); */
/* CON_TRACE(srv, "read return unexpected number of bytes"); */
we_want = we_have;
if (length > we_have) length = we_have;
c->file.mmap.length = we_want;
@ -180,7 +180,7 @@ read_chunk:
/* don't advise files < 64Kb */
if (c->file.mmap.length > (64*1024) &&
0 != madvise(c->file.mmap.data, c->file.mmap.length, MADV_WILLNEED)) {
CON_ERROR(srv, con, "madvise failed for '%s' (fd = %i): %s",
CON_ERROR(con, "madvise failed for '%s' (fd = %i): %s",
GSTR_SAFE_STR(c->file.file->name), c->file.file->fd,
g_strerror(errno));
}

4
src/chunk.h

@ -76,7 +76,7 @@ struct chunkiter {
/* open the file cf->name if it is not already opened for reading
* may return HANDLER_GO_ON, HANDLER_ERROR, HANDLER_WAIT_FOR_FD
*/
LI_API handler_t chunkfile_open(struct server *srv, struct connection *con, chunkfile *cf);
LI_API handler_t chunkfile_open(struct connection *con, chunkfile *cf);
/******************
* chunk iterator *
@ -92,7 +92,7 @@ INLINE goffset chunkiter_length(chunkiter iter);
* the data is _not_ marked as "done"
* may return HANDLER_GO_ON, HANDLER_ERROR, HANDLER_WAIT_FOR_FD
*/
LI_API handler_t chunkiter_read(struct server *srv, struct connection *con, chunkiter iter, off_t start, off_t length, char **data_start, off_t *data_len);
LI_API handler_t chunkiter_read(struct connection *con, chunkiter iter, off_t start, off_t length, char **data_start, off_t *data_len);
/******************
* chunk *

14
src/chunk_parser.c

@ -23,7 +23,7 @@ handler_t chunk_parser_prepare(chunk_parser_ctx *ctx) {
return HANDLER_GO_ON;
}
handler_t chunk_parser_next(server *srv, connection *con, chunk_parser_ctx *ctx, char **p, char **pe) {
handler_t chunk_parser_next(connection *con, chunk_parser_ctx *ctx, char **p, char **pe) {
off_t l;
handler_t res;
@ -39,7 +39,7 @@ handler_t chunk_parser_next(server *srv, connection *con, chunk_parser_ctx *ctx,
if (NULL == ctx->curi.element) return HANDLER_WAIT_FOR_EVENT;
if (HANDLER_GO_ON != (res = chunkiter_read(srv, con, ctx->curi, ctx->start, l - ctx->start, &ctx->buf, &ctx->length))) {
if (HANDLER_GO_ON != (res = chunkiter_read(con, ctx->curi, ctx->start, l - ctx->start, &ctx->buf, &ctx->length))) {
return res;
}
@ -53,7 +53,7 @@ void chunk_parser_done(chunk_parser_ctx *ctx, goffset len) {
ctx->start += len;
}
gboolean chunk_extract_to(server *srv, connection *con, chunk_parser_mark from, chunk_parser_mark to, GString *dest) {
gboolean chunk_extract_to(connection *con, chunk_parser_mark from, chunk_parser_mark to, GString *dest) {
g_string_set_size(dest, 0);
chunk_parser_mark i;
@ -62,7 +62,7 @@ gboolean chunk_extract_to(server *srv, connection *con, chunk_parser_mark from,
while (i.pos < len) {
char *buf;
off_t we_have;
if (HANDLER_GO_ON != chunkiter_read(srv, con, i.ci, i.pos, len - i.pos, &buf, &we_have)) goto error;
if (HANDLER_GO_ON != chunkiter_read(con, i.ci, i.pos, len - i.pos, &buf, &we_have)) goto error;
g_string_append_len(dest, buf, we_have);
i.pos += we_have;
}
@ -71,7 +71,7 @@ gboolean chunk_extract_to(server *srv, connection *con, chunk_parser_mark from,
while (i.pos < to.pos) {
char *buf;
off_t we_have;
if (HANDLER_GO_ON != chunkiter_read(srv, con, i.ci, i.pos, to.pos - i.pos, &buf, &we_have)) goto error;
if (HANDLER_GO_ON != chunkiter_read(con, i.ci, i.pos, to.pos - i.pos, &buf, &we_have)) goto error;
g_string_append_len(dest, buf, we_have);
i.pos += we_have;
}
@ -83,9 +83,9 @@ error:
return FALSE;
}
GString* chunk_extract(server *srv, connection *con, chunk_parser_mark from, chunk_parser_mark to) {
GString* chunk_extract(connection *con, chunk_parser_mark from, chunk_parser_mark to) {
GString *str = g_string_sized_new(0);
if (chunk_extract_to(srv, con, from, to, str)) return str;
if (chunk_extract_to(con, from, to, str)) return str;
g_string_free(str, TRUE);
return NULL;
}

6
src/chunk_parser.h

@ -32,11 +32,11 @@ struct chunk_parser_mark {
LI_API void chunk_parser_init(chunk_parser_ctx *ctx, chunkqueue *cq);
LI_API void chunk_parser_reset(chunk_parser_ctx *ctx);
LI_API handler_t chunk_parser_prepare(chunk_parser_ctx *ctx);
LI_API handler_t chunk_parser_next(struct server *srv, struct connection *con, chunk_parser_ctx *ctx, char **p, char **pe);
LI_API handler_t chunk_parser_next(struct connection *con, chunk_parser_ctx *ctx, char **p, char **pe);
LI_API void chunk_parser_done(chunk_parser_ctx *ctx, goffset len);
LI_API gboolean chunk_extract_to(struct server *srv, struct connection *con, chunk_parser_mark from, chunk_parser_mark to, GString *dest);
LI_API GString* chunk_extract(struct server *srv, struct connection *con, chunk_parser_mark from, chunk_parser_mark to);
LI_API gboolean chunk_extract_to(struct connection *con, chunk_parser_mark from, chunk_parser_mark to, GString *dest);
LI_API GString* chunk_extract(struct connection *con, chunk_parser_mark from, chunk_parser_mark to);
INLINE chunk_parser_mark chunk_parser_getmark(chunk_parser_ctx *ctx, const char *fpc);

58
src/condition.c

@ -248,11 +248,9 @@ const char* cond_lvalue_to_string(cond_lvalue_t t) {
}
/* COND_VALUE_STRING and COND_VALUE_REGEXP only */
static gboolean condition_check_eval_string(server *srv, connection *con, condition *cond) {
static gboolean condition_check_eval_string(connection *con, condition *cond) {
const char *value = "";
gboolean result = FALSE;
UNUSED(srv);
UNUSED(con);
switch (cond->lvalue->type) {
case COMP_REQUEST_LOCALIP:
@ -283,17 +281,17 @@ static gboolean condition_check_eval_string(server *srv, connection *con, condit
/* TODO: physical path exists */
break;
case COMP_REQUEST_HEADER:
http_header_get_fast(srv->tmp_str, con->request.headers, GSTR_LEN(cond->lvalue->key));
value = srv->tmp_str->str;
http_header_get_fast(con->wrk->tmp_str, con->request.headers, GSTR_LEN(cond->lvalue->key));
value = con->wrk->tmp_str->str;
break;
case COMP_PHYSICAL_SIZE:
/* TODO: physical size */
g_string_printf(srv->tmp_str, "%"L_GOFFSET_FORMAT, (goffset) 0);
value = srv->tmp_str->str;
g_string_printf(con->wrk->tmp_str, "%"L_GOFFSET_FORMAT, (goffset) 0);
value = con->wrk->tmp_str->str;
break;
case COMP_REQUEST_CONTENT_LENGTH:
g_string_printf(srv->tmp_str, "%"L_GOFFSET_FORMAT, con->request.content_length);
value = srv->tmp_str->str;
g_string_printf(con->wrk->tmp_str, "%"L_GOFFSET_FORMAT, con->request.content_length);
value = con->wrk->tmp_str->str;
break;
}
@ -320,9 +318,9 @@ static gboolean condition_check_eval_string(server *srv, connection *con, condit
case CONFIG_COND_NOMATCH:
#ifdef HAVE_PCRE_H
/* TODO: pcre */
ERROR(srv, "%s", "regexp match not supported yet");
CON_ERROR(con, "%s", "regexp match not supported yet");
#else
ERROR(srv, "compiled without pcre, cannot use '%s'", comp_op_to_string(cond->op));
CON_ERROR(con, "compiled without pcre, cannot use '%s'", comp_op_to_string(cond->op));
#endif
break;
case CONFIG_COND_IP:
@ -331,7 +329,7 @@ static gboolean condition_check_eval_string(server *srv, connection *con, condit
case CONFIG_COND_GT:
case CONFIG_COND_LE:
case CONFIG_COND_LT:
ERROR(srv, "cannot compare string/regexp with '%s'", comp_op_to_string(cond->op));
CON_ERROR(con, "cannot compare string/regexp with '%s'", comp_op_to_string(cond->op));
break;
}
@ -339,9 +337,7 @@ static gboolean condition_check_eval_string(server *srv, connection *con, condit
}
static gboolean condition_check_eval_int(server *srv, connection *con, condition *cond) {
UNUSED(srv);
UNUSED(con);
static gboolean condition_check_eval_int(connection *con, condition *cond) {
gint64 value;
switch (cond->lvalue->type) {
@ -351,7 +347,7 @@ static gboolean condition_check_eval_int(server *srv, connection *con, condition
value = con->physical.size;
break;
default:
CON_ERROR(srv, con, "couldn't get int value for '%s', using -1", cond_lvalue_to_string(cond->lvalue->type));
CON_ERROR(con, "couldn't get int value for '%s', using -1", cond_lvalue_to_string(cond->lvalue->type));
value = -1;
}
@ -376,7 +372,7 @@ static gboolean condition_check_eval_int(server *srv, connection *con, condition
case CONFIG_COND_NOMATCH:
case CONFIG_COND_IP:
case CONFIG_COND_NOTIP:
ERROR(srv, "cannot compare int with '%s'", comp_op_to_string(cond->op));
CON_ERROR(con, "cannot compare int with '%s'", comp_op_to_string(cond->op));
return FALSE;
}
@ -425,12 +421,10 @@ static gboolean ip_in_net(condition_rvalue *target, condition_rvalue *network) {
}
/* CONFIG_COND_IP and CONFIG_COND_NOTIP only */
static gboolean condition_check_eval_ip(server *srv, connection *con, condition *cond) {
static gboolean condition_check_eval_ip(connection *con, condition *cond) {
condition_rvalue ipval;
const char *value = NULL;
gboolean result = FALSE;
UNUSED(srv);
UNUSED(con);
ipval.type = COND_VALUE_INT;
@ -444,34 +438,34 @@ static gboolean condition_check_eval_ip(server *srv, connection *con, condition
return (cond->op == CONFIG_COND_NOTIP);
break;
case COMP_REQUEST_PATH:
ERROR(srv, "%s", "Cannot parse request.path as ip");
CON_ERROR(con, "%s", "Cannot parse request.path as ip");
return (cond->op == CONFIG_COND_NOTIP);
break;
case COMP_REQUEST_HOST:
value = con->request.uri.host->str;
break;
case COMP_REQUEST_SCHEME:
ERROR(srv, "%s", "Cannot parse request.scheme as ip");
CON_ERROR(con, "%s", "Cannot parse request.scheme as ip");
return (cond->op == CONFIG_COND_NOTIP);
case COMP_REQUEST_QUERY_STRING:
value = con->request.uri.query->str;
break;
case COMP_REQUEST_METHOD:
ERROR(srv, "%s", "Cannot request.method as ip");
CON_ERROR(con, "%s", "Cannot request.method as ip");
return (cond->op == CONFIG_COND_NOTIP);
break;
case COMP_PHYSICAL_PATH:
case COMP_PHYSICAL_PATH_EXISTS:
ERROR(srv, "%s", "Cannot physical.path(-exists) as ip");
CON_ERROR(con, "%s", "Cannot physical.path(-exists) as ip");
return (cond->op == CONFIG_COND_NOTIP);
break;
case COMP_REQUEST_HEADER:
http_header_get_fast(srv->tmp_str, con->request.headers, GSTR_LEN(cond->lvalue->key));
value = srv->tmp_str->str;
http_header_get_fast(con->wrk->tmp_str, con->request.headers, GSTR_LEN(cond->lvalue->key));
value = con->wrk->tmp_str->str;
break;
case COMP_PHYSICAL_SIZE:
case COMP_REQUEST_CONTENT_LENGTH:
ERROR(srv, "%s", "Cannot parse integers as ip");
CON_ERROR(con, "%s", "Cannot parse integers as ip");
return (cond->op == CONFIG_COND_NOTIP);
break;
}
@ -498,25 +492,25 @@ static gboolean condition_check_eval_ip(server *srv, connection *con, condition
case CONFIG_COND_GT:
case CONFIG_COND_LE:
case CONFIG_COND_LT:
ERROR(srv, "cannot match ips with '%s'", comp_op_to_string(cond->op));
CON_ERROR(con, "cannot match ips with '%s'", comp_op_to_string(cond->op));
break;
}
return result;
}
gboolean condition_check(server *srv, connection *con, condition *cond) {
gboolean condition_check(connection *con, condition *cond) {
switch (cond->rvalue.type) {
case COND_VALUE_STRING:
#ifdef HAVE_PCRE_H
case COND_VALUE_REGEXP:
#endif
return condition_check_eval_string(srv, con, cond);
return condition_check_eval_string(con, cond);
case COND_VALUE_INT:
return condition_check_eval_int(srv, con, cond);
return condition_check_eval_int(con, cond);
case COND_VALUE_SOCKET_IPV4:
case COND_VALUE_SOCKET_IPV6:
return condition_check_eval_ip(srv, con, cond);
return condition_check_eval_ip(con, cond);
}
return FALSE;
}

2
src/condition.h

@ -125,7 +125,7 @@ LI_API void condition_release(server *srv, condition* c);
LI_API const char* comp_op_to_string(comp_operator_t op);
LI_API const char* cond_lvalue_to_string(cond_lvalue_t t);
LI_API gboolean condition_check(server *srv, connection *con, condition *cond);
LI_API gboolean condition_check(connection *con, condition *cond);
/* parser */
/** parse an IPv4 (if netmask is not NULL with cidr netmask) */

232
src/connection.c

@ -1,25 +1,24 @@
#include "connection.h"
#include "base.h"
#include "network.h"
#include "utils.h"
#include "plugin_core.h"
void con_put(server *srv, connection *con); /* server.c */
void con_put(connection *con); /* server.c */
void internal_error(server *srv, connection *con) {
void internal_error(connection *con) {
if (con->response_headers_sent) {
CON_ERROR(srv, con, "%s", "Couldn't send '500 Internal Error': headers already sent");
connection_set_state(srv, con, CON_STATE_ERROR);
CON_ERROR(con, "%s", "Couldn't send '500 Internal Error': headers already sent");
connection_set_state(con, CON_STATE_ERROR);
} else {
http_headers_reset(con->response.headers);
con->response.http_status = 500;
con->content_handler = NULL;
connection_set_state(srv, con, CON_STATE_WRITE_RESPONSE);
connection_set_state(con, CON_STATE_WRITE_RESPONSE);
}
}
static void parse_request_body(server *srv, connection *con) {
UNUSED(srv);
static void parse_request_body(connection *con) {
if ( con->state >= CON_STATE_READ_REQUEST_CONTENT
&& con->state <= CON_STATE_WRITE_RESPONSE
&& !con->in->is_closed) {
@ -35,8 +34,7 @@ static void parse_request_body(server *srv, connection *con) {
}
}
static void forward_response_body(server *srv, connection *con) {
UNUSED(srv);
static void forward_response_body(connection *con) {
if (con->state == CON_STATE_WRITE_RESPONSE && !con->raw_out->is_closed) {
if (con->out->length > 0) {
/* TODO: chunked encoding, filters */
@ -45,17 +43,15 @@ static void forward_response_body(server *srv, connection *con) {
if (con->in->is_closed && 0 == con->raw_out->length)
con->raw_out->is_closed = TRUE;
if (con->raw_out->length > 0) {
ev_io_add_events(srv->loop, &con->sock.watcher, EV_WRITE);
ev_io_add_events(con->wrk->loop, &con->sock_watcher, EV_WRITE);
} else {
ev_io_rem_events(srv->loop, &con->sock.watcher, EV_WRITE);
ev_io_rem_events(con->wrk->loop, &con->sock_watcher, EV_WRITE);
}
}
}
static void connection_cb(struct ev_loop *loop, ev_io *w, int revents) {
connection_socket *con_sock = (connection_socket*) w->data;
server *srv = con_sock->srv;
connection *con = con_sock->con;
connection *con = (connection*) w->data;
gboolean dojoblist = FALSE;
UNUSED(loop);
@ -64,19 +60,19 @@ static void connection_cb(struct ev_loop *loop, ev_io *w, int revents) {
/* don't read the next request before current one is done */
ev_io_rem_events(loop, w, EV_READ);
} else {
switch (network_read(srv, con, w->fd, con->raw_in)) {
switch (network_read(con, w->fd, con->raw_in)) {
case NETWORK_STATUS_SUCCESS:
dojoblist = TRUE;
break;
case NETWORK_STATUS_FATAL_ERROR:
CON_ERROR(srv, con, "%s", "network read fatal error");
connection_set_state(srv, con, CON_STATE_ERROR);
CON_ERROR(con, "%s", "network read fatal error");
connection_set_state(con, CON_STATE_ERROR);
dojoblist = TRUE;
break;
case NETWORK_STATUS_CONNECTION_CLOSE:
con->raw_in->is_closed = TRUE;
shutdown(w->fd, SHUT_RD);
connection_set_state(srv, con, CON_STATE_CLOSE);
connection_set_state(con, CON_STATE_CLOSE);
dojoblist = TRUE;
break;
case NETWORK_STATUS_WAIT_FOR_EVENT:
@ -95,17 +91,17 @@ static void connection_cb(struct ev_loop *loop, ev_io *w, int revents) {
if (revents & EV_WRITE) {
if (con->raw_out->length > 0) {
switch (network_write(srv, con, w->fd, con->raw_out)) {
switch (network_write(con, w->fd, con->raw_out)) {
case NETWORK_STATUS_SUCCESS:
dojoblist = TRUE;
break;
case NETWORK_STATUS_FATAL_ERROR:
CON_ERROR(srv, con, "%s", "network write fatal error");
connection_set_state(srv, con, CON_STATE_ERROR);
CON_ERROR(con, "%s", "network write fatal error");
connection_set_state(con, CON_STATE_ERROR);
dojoblist = TRUE;
break;
case NETWORK_STATUS_CONNECTION_CLOSE:
connection_set_state(srv, con, CON_STATE_CLOSE);
connection_set_state(con, CON_STATE_CLOSE);
dojoblist = TRUE;
break;
case NETWORK_STATUS_WAIT_FOR_EVENT:
@ -127,26 +123,26 @@ static void connection_cb(struct ev_loop *loop, ev_io *w, int revents) {
}
if (dojoblist)
joblist_append(srv, con);
joblist_append(con);
}
static void connection_keepalive_cb(struct ev_loop *loop, ev_timer *w, int revents) {
connection *con = (connection*) w->data;
UNUSED(loop); UNUSED(revents);
con_put(con->sock.srv, con);
con_put(con);
}
connection* connection_new(server *srv) {
connection *con = g_slice_new0(connection);
UNUSED(srv);
con->srv = srv;
con->state = CON_STATE_DEAD;
con->response_headers_sent = FALSE;
con->expect_100_cont = FALSE;
ev_init(&con->sock.watcher, connection_cb);
ev_io_set(&con->sock.watcher, -1, 0);
con->sock.srv = srv; con->sock.con = con; con->sock.watcher.data = &con->sock;
ev_init(&con->sock_watcher, connection_cb);
ev_io_set(&con->sock_watcher, -1, 0);
con->sock_watcher.data = con;
con->remote_addr_str = g_string_sized_new(0);
con->local_addr_str = g_string_sized_new(0);
con->keep_alive = TRUE;
@ -173,21 +169,21 @@ connection* connection_new(server *srv) {
return con;
}
void connection_reset(server *srv, connection *con) {
void connection_reset(connection *con) {
con->state = CON_STATE_DEAD;
con->response_headers_sent = FALSE;
con->expect_100_cont = FALSE;
ev_io_stop(srv->loop, &con->sock.watcher);
if (con->sock.watcher.fd != -1) {
ev_io_stop(con->wrk->loop, &con->sock_watcher);
if (con->sock_watcher.fd != -1) {
if (con->raw_in->is_closed) { /* read already shutdown */
shutdown(con->sock.watcher.fd, SHUT_WR);
close(con->sock.watcher.fd);
shutdown(con->sock_watcher.fd, SHUT_WR);
close(con->sock_watcher.fd);
} else {
server_add_closing_socket(srv, con->sock.watcher.fd);
worker_add_closing_socket(con->wrk, con->sock_watcher.fd);
}
}
ev_io_set(&con->sock.watcher, -1, 0);
ev_io_set(&con->sock_watcher, -1, 0);
g_string_truncate(con->remote_addr_str, 0);
g_string_truncate(con->local_addr_str, 0);
con->keep_alive = TRUE;
@ -197,43 +193,43 @@ void connection_reset(server *srv, connection *con) {
chunkqueue_reset(con->in);
chunkqueue_reset(con->out);
action_stack_reset(srv, &con->action_stack);
action_stack_reset(con->srv, &con->action_stack);
memcpy(con->options, srv->option_def_values, srv->option_count * sizeof(*srv->option_def_values));
memcpy(con->options, con->srv->option_def_values, con->srv->option_count * sizeof(*con->srv->option_def_values));
request_reset(&con->request);
physical_reset(&con->physical);
response_reset(&con->response);
if (con->keep_alive_data.link) {
g_queue_delete_link(&srv->keep_alive_queue, con->keep_alive_data.link);
g_queue_delete_link(&con->wrk->keep_alive_queue, con->keep_alive_data.link);
con->keep_alive_data.link = NULL;
}
con->keep_alive_data.timeout = 0;
con->keep_alive_data.max_idle = 0;
ev_timer_stop(srv->loop, &con->keep_alive_data.watcher);
ev_timer_stop(con->wrk->loop, &con->keep_alive_data.watcher);
}
void server_check_keepalive(server *srv);
void connection_reset_keep_alive(server *srv, connection *con) {
ev_timer_stop(srv->loop, &con->keep_alive_data.watcher);
void connection_reset_keep_alive(connection *con) {
ev_timer_stop(con->wrk->loop, &con->keep_alive_data.watcher);
{
con->keep_alive_data.max_idle = GPOINTER_TO_INT(CORE_OPTION(CORE_OPTION_MAX_KEEP_ALIVE_IDLE));
if (con->keep_alive_data.max_idle == 0) {
con_put(srv, con);
con_put(con);
return;
}
if (con->keep_alive_data.max_idle >= srv->keep_alive_queue_timeout) {
if (con->keep_alive_data.max_idle >= con->srv->keep_alive_queue_timeout) {
/* queue is sorted by con->keep_alive_data.timeout */
gboolean need_start = (0 == srv->keep_alive_queue.length);
con->keep_alive_data.timeout = ev_now((srv)->loop) + srv->keep_alive_queue_timeout;
g_queue_push_tail(&srv->keep_alive_queue, con);
con->keep_alive_data.link = g_queue_peek_tail_link(&srv->keep_alive_queue);
gboolean need_start = (0 == con->wrk->keep_alive_queue.length);
con->keep_alive_data.timeout = ev_now(con->wrk->loop) + con->srv->keep_alive_queue_timeout;
g_queue_push_tail(&con->wrk->keep_alive_queue, con);
con->keep_alive_data.link = g_queue_peek_tail_link(&con->wrk->keep_alive_queue);
if (need_start)
server_check_keepalive(srv);
worker_check_keepalive(con->wrk);
} else {
ev_timer_set(&con->keep_alive_data.watcher, con->keep_alive_data.max_idle, 0);
ev_timer_start(srv->loop, &con->keep_alive_data.watcher);
ev_timer_start(con->wrk->loop, &con->keep_alive_data.watcher);
}
}
@ -241,7 +237,7 @@ void connection_reset_keep_alive(server *srv, connection *con) {
con->response_headers_sent = FALSE;
con->expect_100_cont = FALSE;
ev_io_set_events(srv->loop, &con->sock.watcher, EV_READ);
ev_io_set_events(con->wrk->loop, &con->sock_watcher, EV_READ);
g_string_truncate(con->remote_addr_str, 0);
g_string_truncate(con->local_addr_str, 0);
con->keep_alive = TRUE;
@ -250,30 +246,30 @@ void connection_reset_keep_alive(server *srv, connection *con) {
chunkqueue_reset(con->in);
chunkqueue_reset(con->out);
action_stack_reset(srv, &con->action_stack);
action_stack_reset(con->srv, &con->action_stack);
memcpy(con->options, srv->option_def_values, srv->option_count * sizeof(*srv->option_def_values));
memcpy(con->options, con->srv->option_def_values, con->srv->option_count * sizeof(*con->srv->option_def_values));
request_reset(&con->request);
physical_reset(&con->physical);
response_reset(&con->response);
}
void connection_free(server *srv, connection *con) {
void connection_free(connection *con) {
con->state = CON_STATE_DEAD;
con->response_headers_sent = FALSE;
con->expect_100_cont = FALSE;
ev_io_stop(srv->loop, &con->sock.watcher);
if (con->sock.watcher.fd != -1) {
ev_io_stop(con->wrk->loop, &con->sock_watcher);
if (con->sock_watcher.fd != -1) {
if (con->raw_in->is_closed) { /* read already shutdown */
shutdown(con->sock.watcher.fd, SHUT_WR);
close(con->sock.watcher.fd);
shutdown(con->sock_watcher.fd, SHUT_WR);
close(con->sock_watcher.fd);
} else {
server_add_closing_socket(srv, con->sock.watcher.fd);
worker_add_closing_socket(con->wrk, con->sock_watcher.fd);
}
}
ev_io_set(&con->sock.watcher, -1, 0);
ev_io_set(&con->sock_watcher, -1, 0);
g_string_free(con->remote_addr_str, TRUE);
g_string_free(con->local_addr_str, TRUE);
con->keep_alive = TRUE;
@ -283,34 +279,34 @@ void connection_free(server *srv, connection *con) {
chunkqueue_free(con->in);
chunkqueue_free(con->out);
action_stack_clear(srv, &con->action_stack);
action_stack_clear(con->srv, &con->action_stack);
g_slice_free1(srv->option_count * sizeof(*srv->option_def_values), con->options);
g_slice_free1(con->srv->option_count * sizeof(*con->srv->option_def_values), con->options);
request_clear(&con->request);
physical_clear(&con->physical);
response_clear(&con->response);
if (con->keep_alive_data.link) {
g_queue_delete_link(&srv->keep_alive_queue, con->keep_alive_data.link);
g_queue_delete_link(&con->wrk->keep_alive_queue, con->keep_alive_data.link);
con->keep_alive_data.link = NULL;
}
con->keep_alive_data.timeout = 0;
con->keep_alive_data.max_idle = 0;
ev_timer_stop(srv->loop, &con->keep_alive_data.watcher);
ev_timer_stop(con->wrk->loop, &con->keep_alive_data.watcher);
g_slice_free(connection, con);
}
void connection_set_state(server *srv, connection *con, connection_state_t state) {
void connection_set_state(connection *con, connection_state_t state) {
if (state < con->state) {
CON_ERROR(srv, con, "Cannot move into requested state: %i => %i, move to error state", con->state, state);
CON_ERROR(con, "Cannot move into requested state: %i => %i, move to error state", con->state, state);
state = CON_STATE_ERROR;
}
con->state = state;
}
void connection_state_machine(server *srv, connection *con) {
void connection_state_machine(connection *con) {
gboolean done = FALSE;
do {
switch (con->state) {
@ -322,31 +318,31 @@ void connection_state_machine(server *srv, connection *con) {
if (con->raw_in->length > 0) {
/* stop keep alive timeout watchers */
if (con->keep_alive_data.link) {
g_queue_delete_link(&srv->keep_alive_queue, con->keep_alive_data.link);
g_queue_delete_link(&con->wrk->keep_alive_queue, con->keep_alive_data.link);
con->keep_alive_data.link = NULL;
}
con->keep_alive_data.timeout = 0;
ev_timer_stop(srv->loop, &con->keep_alive_data.watcher);
ev_timer_stop(con->wrk->loop, &con->keep_alive_data.watcher);
connection_set_state(srv, con, CON_STATE_REQUEST_START);
connection_set_state(con, CON_STATE_REQUEST_START);
} else
done = TRUE;
break;
case CON_STATE_REQUEST_START:
connection_set_state(srv, con, CON_STATE_READ_REQUEST_HEADER);
action_enter(con, srv->mainaction);
connection_set_state(con, CON_STATE_READ_REQUEST_HEADER);
action_enter(con, con->srv->mainaction);
break;
case CON_STATE_READ_REQUEST_HEADER:
if (CORE_OPTION(CORE_OPTION_DEBUG_REQUEST_HANDLING)) {
TRACE(srv, "%s", "reading request header");
CON_TRACE(con, "%s", "reading request header");
}
switch(http_request_parse(srv, con, &con->request.parser_ctx)) {
switch(http_request_parse(con, &con->request.parser_ctx)) {
case HANDLER_FINISHED:
case HANDLER_GO_ON:
connection_set_state(srv, con, CON_STATE_VALIDATE_REQUEST_HEADER);
connection_set_state(con, CON_STATE_VALIDATE_REQUEST_HEADER);
break;
case HANDLER_WAIT_FOR_FD:
/* TODO: wait for fd */
@ -358,37 +354,37 @@ void connection_state_machine(server *srv, connection *con) {
case HANDLER_ERROR:
case HANDLER_COMEBACK: /* unexpected */
/* unparsable header */
connection_set_state(srv, con, CON_STATE_ERROR);
connection_set_state(con, CON_STATE_ERROR);
break;
}
break;
case CON_STATE_VALIDATE_REQUEST_HEADER:
if (CORE_OPTION(CORE_OPTION_DEBUG_REQUEST_HANDLING)) {
TRACE(srv, "%s", "validating request header");
CON_TRACE(con, "%s", "validating request header");
}
connection_set_state(srv, con, CON_STATE_HANDLE_REQUEST_HEADER);
request_validate_header(srv, con);
srv->stats.requests++;
connection_set_state(con, CON_STATE_HANDLE_REQUEST_HEADER);
request_validate_header(con);
con->srv->stats.requests++;
break;
case CON_STATE_HANDLE_REQUEST_HEADER:
if (CORE_OPTION(CORE_OPTION_DEBUG_REQUEST_HANDLING)) {
TRACE(srv, "%s", "handle request header");
CON_TRACE(con, "%s", "handle request header");
}
switch (action_execute(srv, con)) {
switch (action_execute(con)) {
case ACTION_WAIT_FOR_EVENT:
done = TRUE;
break;
case ACTION_GO_ON:
case ACTION_FINISHED:
if (con->state == CON_STATE_HANDLE_REQUEST_HEADER) {
internal_error(srv, con);
internal_error(con);
}
connection_set_state(srv, con, CON_STATE_WRITE_RESPONSE);
connection_set_state(con, CON_STATE_WRITE_RESPONSE);
break;
case ACTION_ERROR:
internal_error(srv, con);
internal_error(con);
break;
}
break;
@ -396,62 +392,62 @@ void connection_state_machine(server *srv, connection *con) {
case CON_STATE_READ_REQUEST_CONTENT:
case CON_STATE_HANDLE_RESPONSE_HEADER:
if (CORE_OPTION(CORE_OPTION_DEBUG_REQUEST_HANDLING)) {
TRACE(srv, "%s", "read request/handle response header");
CON_TRACE(con, "%s", "read request/handle response header");
}
if (con->expect_100_cont) {
if (CORE_OPTION(CORE_OPTION_DEBUG_REQUEST_HANDLING)) {
TRACE(srv, "%s", "send 100 Continue");
CON_TRACE(con, "%s", "send 100 Continue");
}
chunkqueue_append_mem(con->raw_out, CONST_STR_LEN("HTTP/1.1 100 Continue\r\n\r\n"));
con->expect_100_cont = FALSE;
ev_io_add_events(srv->loop, &con->sock.watcher, EV_WRITE);
ev_io_add_events(con->wrk->loop, &con->sock_watcher, EV_WRITE);
}
parse_request_body(srv, con);
parse_request_body(con);
if (con->content_handler)
con->content_handler->handle_content(srv, con, con->content_handler);
con->content_handler->handle_content(con, con->content_handler);
switch (action_execute(srv, con)) {
switch (action_execute(con)) {
case ACTION_WAIT_FOR_EVENT:
done = TRUE;
break;
case ACTION_GO_ON:
case ACTION_FINISHED:
connection_set_state(srv, con, CON_STATE_WRITE_RESPONSE);
connection_set_state(con, CON_STATE_WRITE_RESPONSE);
break;
case ACTION_ERROR:
internal_error(srv, con);
internal_error(con);
break;
}
break;
case CON_STATE_WRITE_RESPONSE:
if (con->in->is_closed && con->raw_out->is_closed) {
connection_set_state(srv, con, CON_STATE_RESPONSE_END);
connection_set_state(con, CON_STATE_RESPONSE_END);
break;
}
if (!con->response_headers_sent) {
con->response_headers_sent = TRUE;
if (CORE_OPTION(CORE_OPTION_DEBUG_REQUEST_HANDLING)) {
TRACE(srv, "%s", "write response headers");
CON_TRACE(con, "%s", "write response headers");
}
response_send_headers(srv, con);
response_send_headers(con);
}
if (CORE_OPTION(CORE_OPTION_DEBUG_REQUEST_HANDLING)) {
TRACE(srv, "%s", "write response");
CON_TRACE(con, "%s", "write response");
}
parse_request_body(srv, con);
parse_request_body(con);
if (con->content_handler)
con->content_handler->handle_content(srv, con, con->content_handler);
con->content_handler->handle_content(con, con->content_handler);
forward_response_body(srv, con);
forward_response_body(con);
if (con->in->is_closed && con->raw_out->is_closed) {
connection_set_state(srv, con, CON_STATE_RESPONSE_END);
connection_set_state(con, CON_STATE_RESPONSE_END);
break;
}
if (con->state == CON_STATE_WRITE_RESPONSE) done = TRUE;
@ -459,57 +455,57 @@ void connection_state_machine(server *srv, connection *con) {
case CON_STATE_RESPONSE_END:
if (CORE_OPTION(CORE_OPTION_DEBUG_REQUEST_HANDLING)) {
TRACE(srv, "response end (keep_alive = %i)", con->keep_alive);
CON_TRACE(con, "response end (keep_alive = %i)", con->keep_alive);
}
plugins_handle_close(srv, con);
plugins_handle_close(con);
if (con->keep_alive) {
connection_reset_keep_alive(srv, con);
connection_reset_keep_alive(con);
} else {
con_put(srv, con);
con_put(con);
done = TRUE;
}
break;
case CON_STATE_CLOSE:
if (CORE_OPTION(CORE_OPTION_DEBUG_REQUEST_HANDLING)) {
TRACE(srv, "%s", "connection closed");
CON_TRACE(con, "%s", "connection closed");
}
plugins_handle_close(srv, con);
plugins_handle_close(con);
con_put(srv, con);
con_put(con);
done = TRUE;
break;
case CON_STATE_ERROR:
if (CORE_OPTION(CORE_OPTION_DEBUG_REQUEST_HANDLING)) {
TRACE(srv, "%s", "connection closed (error)");
CON_TRACE(con, "%s", "connection closed (error)");
}
plugins_handle_close(srv, con);
plugins_handle_close(con);
con_put(srv, con);
con_put(con);
done = TRUE;
break;
}
} while (!done);
}
void connection_handle_direct(server *srv, connection *con) {
connection_set_state(srv, con, CON_STATE_WRITE_RESPONSE);
void connection_handle_direct(connection *con) {
connection_set_state(con, CON_STATE_WRITE_RESPONSE);
con->out->is_closed = TRUE;
}
void connection_handle_indirect(server *srv, connection *con, plugin *p) {
void connection_handle_indirect(connection *con, plugin *p) {
if (!p) {
connection_handle_direct(srv, con);
connection_handle_direct(con);
} else if (p->handle_content) {
connection_set_state(srv, con, CON_STATE_READ_REQUEST_CONTENT);
connection_set_state(con, CON_STATE_READ_REQUEST_CONTENT);
con->content_handler = p;
} else {
CON_ERROR(srv, con, "Indirect plugin '%s' handler has no handle_content callback", p->name);
internal_error(srv, con);
CON_ERROR(con, "Indirect plugin '%s' handler has no handle_content callback", p->name);
internal_error(con);
}
}

32
src/connection.h

@ -22,15 +22,15 @@ typedef enum {
* - direct response: for things like errors/auth/redirect
* just set the status code, perhaps fill in some headers,
* append your content (if any) to the queue and do:
* connection_handle_direct(srv, con);
* connection_handle_direct(con);
* this moves into the CON_STATE_HANDLE_RESPONSE_HEADER
* request body gets dropped
* - indirect response: you register your plugin as the content handler:
* connection_handle_indirect(srv, con, plugin);
* connection_handle_indirect(con, plugin);
* this moves into the CON_STATE_READ_REQUEST_CONTENT state automatically
* as soon as you build the response headers (e.g. from a backend),
* change to the CON_STATE_HANDLE_RESPONSE_HEADER state:
* connection_set_state(srv, con, CON_STATE_HANDLE_RESPONSE_HEADER);
* connection_set_state(con, CON_STATE_HANDLE_RESPONSE_HEADER);
*/
CON_STATE_HANDLE_REQUEST_HEADER,
@ -60,24 +60,18 @@ typedef enum {
CON_STATE_ERROR
} connection_state_t;
struct connection_socket;
typedef struct connection_socket connection_socket;
struct connection_socket {
server *srv;
connection *con;
ev_io watcher;
};
struct connection {
guint idx; /** index in connection table */
server *srv;
worker *wrk;
connection_state_t state;
gboolean response_headers_sent, expect_100_cont;
chunkqueue *raw_in, *raw_out;
chunkqueue *in, *out;
connection_socket sock;
ev_io sock_watcher;
sock_addr remote_addr, local_addr;
GString *remote_addr_str, *local_addr_str;
gboolean is_ssl, keep_alive;
@ -106,13 +100,13 @@ struct connection {
};
LI_API connection* connection_new(server *srv);
LI_API void connection_reset(server *srv, connection *con);
LI_API void connection_free(server *srv, connection *con);
LI_API void connection_reset(connection *con);
LI_API void connection_free(connection *con);
LI_API void connection_set_state(server *srv, connection *con, connection_state_t state);
LI_API void connection_state_machine(server *srv, connection *con);
LI_API void connection_set_state(connection *con, connection_state_t state);
LI_API void connection_state_machine(connection *con);
LI_API void connection_handle_direct(server *srv, connection *con);
LI_API void connection_handle_indirect(server *srv, connection *con, plugin *p);
LI_API void connection_handle_direct(connection *con);
LI_API void connection_handle_indirect(connection *con, plugin *p);
#endif

6
src/filter_chunked.c

@ -25,8 +25,7 @@ static void http_chunk_append_len(chunkqueue *cq, size_t len) {
}
handler_t filter_chunked_encode(server *srv, connection *con, chunkqueue *out, chunkqueue *in) {
UNUSED(srv);
handler_t filter_chunked_encode(connection *con, chunkqueue *out, chunkqueue *in) {
UNUSED(con);
if (in->length > 0) {
@ -43,8 +42,7 @@ handler_t filter_chunked_encode(server *srv, connection *con, chunkqueue *out, c
return HANDLER_GO_ON;
}
handler_t filter_chunked_decode(server *srv, connection *con, chunkqueue *out, chunkqueue *in) {
UNUSED(srv);
handler_t filter_chunked_decode(connection *con, chunkqueue *out, chunkqueue *in) {
UNUSED(con);
UNUSED(out);
UNUSED(in);

4
src/filter_chunked.h

@ -3,7 +3,7 @@
#include "base.h"
LI_API handler_t filter_chunked_encode(server *srv, connection *con, chunkqueue *out, chunkqueue *in);
LI_API handler_t filter_chunked_decode(server *srv, connection *con, chunkqueue *out, chunkqueue *in);
LI_API handler_t filter_chunked_encode(connection *con, chunkqueue *out, chunkqueue *in);
LI_API handler_t filter_chunked_decode(connection *con, chunkqueue *out, chunkqueue *in);
#endif

2
src/http_request_parser.h

@ -22,7 +22,7 @@ LI_API void http_request_parser_init(http_request_ctx* ctx, request *req, chunkq
LI_API void http_request_parser_reset(http_request_ctx* ctx);
LI_API void http_request_parser_clear(http_request_ctx *ctx);
LI_API handler_t http_request_parse(struct server *srv, struct connection *con, http_request_ctx *ctx);
LI_API handler_t http_request_parse(struct connection *con, http_request_ctx *ctx);
#endif

8
src/http_request_parser.rl

@ -4,10 +4,10 @@
/** Machine **/
#define _getString(M, FPC) (chunk_extract(srv, con, ctx->M, GETMARK(FPC)))
#define _getString(M, FPC) (chunk_extract(con, ctx->M, GETMARK(FPC)))
#define getString(FPC) _getString(mark, FPC)
#define _getStringTo(M, FPC, s) (chunk_extract_to(srv, con, ctx->M, GETMARK(FPC), s))
#define _getStringTo(M, FPC, s) (chunk_extract_to(con, ctx->M, GETMARK(FPC), s))
#define getStringTo(FPC, s) _getStringTo(mark, FPC, s)
@ -148,7 +148,7 @@ void http_request_parser_clear(http_request_ctx *ctx) {
g_string_free(ctx->h_value, TRUE);
}
handler_t http_request_parse(server *srv, connection *con, http_request_ctx *ctx) {
handler_t http_request_parse(connection *con, http_request_ctx *ctx) {
handler_t res;
if (http_request_parser_is_finished(ctx)) return HANDLER_GO_ON;
@ -158,7 +158,7 @@ handler_t http_request_parse(server *srv, connection *con, http_request_ctx *ctx
while (!http_request_parser_has_error(ctx) && !http_request_parser_is_finished(ctx)) {