|
|
|
@ -315,12 +315,10 @@ static int connection_handle_read(server *srv, connection *con) {
|
|
|
|
|
} else if (len == 0) {
|
|
|
|
|
con->is_readable = 0;
|
|
|
|
|
/* the other end close the connection -> KEEP-ALIVE */
|
|
|
|
|
#if 0
|
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "s",
|
|
|
|
|
"connection closed: remote site closed unexpectedly");
|
|
|
|
|
#endif
|
|
|
|
|
connection_set_state(srv, con, CON_STATE_ERROR);
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
/* pipelining */
|
|
|
|
|
|
|
|
|
|
return -2;
|
|
|
|
|
} else if ((size_t)len < b->size - 1) {
|
|
|
|
|
/* we got less then expected, wait for the next fd-event */
|
|
|
|
|
|
|
|
|
@ -602,7 +600,7 @@ connection *connection_init(server *srv) {
|
|
|
|
|
|
|
|
|
|
/* init plugin specific connection structures */
|
|
|
|
|
|
|
|
|
|
con->plugin_ctx = calloc(srv->plugins.used + 1, sizeof(void *));
|
|
|
|
|
con->plugin_ctx = calloc(1, (srv->plugins.used + 1) * sizeof(void *));
|
|
|
|
|
|
|
|
|
|
con->cond_cache = calloc(srv->config_context->used, sizeof(cond_cache_t));
|
|
|
|
|
config_setup_connection(srv, con);
|
|
|
|
@ -751,6 +749,8 @@ int connection_reset(server *srv, connection *con) {
|
|
|
|
|
plugin *p = ((plugin **)(srv->plugins.ptr))[i];
|
|
|
|
|
plugin_data *pd = p->data;
|
|
|
|
|
|
|
|
|
|
if (!pd) continue;
|
|
|
|
|
|
|
|
|
|
if (con->plugin_ctx[pd->id] != NULL) {
|
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "sb", "missing cleanup in", p->name);
|
|
|
|
|
}
|
|
|
|
@ -818,7 +818,11 @@ char *buffer_search_rnrn(buffer *b) {
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* handle all header and content read
|
|
|
|
|
*
|
|
|
|
|
* we get called by the state-engine and by the fdevent-handler
|
|
|
|
|
*/
|
|
|
|
|
int connection_handle_read_state(server *srv, connection *con) {
|
|
|
|
|
int ostate = con->state;
|
|
|
|
|
char *h_term = NULL;
|
|
|
|
@ -829,25 +833,56 @@ int connection_handle_read_state(server *srv, connection *con) {
|
|
|
|
|
if (con->is_readable) {
|
|
|
|
|
con->read_idle_ts = srv->cur_ts;
|
|
|
|
|
|
|
|
|
|
if (0 != connection_handle_read(srv, con)) {
|
|
|
|
|
switch(connection_handle_read(srv, con)) {
|
|
|
|
|
case -1:
|
|
|
|
|
return -1;
|
|
|
|
|
case -2:
|
|
|
|
|
/* remote side closed the connection
|
|
|
|
|
* if we still have content, handle it, if not leave here */
|
|
|
|
|
|
|
|
|
|
if (cq->first == cq->last &&
|
|
|
|
|
cq->first->mem->used == 0) {
|
|
|
|
|
|
|
|
|
|
/* conn-closed, leave here */
|
|
|
|
|
connection_set_state(srv, con, CON_STATE_ERROR);
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* move the empty chunks out of the way */
|
|
|
|
|
for (c = cq->first; c; c = cq->first) {
|
|
|
|
|
assert(c != c->next);
|
|
|
|
|
|
|
|
|
|
if (c->mem->used == 0) {
|
|
|
|
|
/* the last chunk might be empty */
|
|
|
|
|
for (c = cq->first; c;) {
|
|
|
|
|
if (cq->first == c && c->mem->used == 0) {
|
|
|
|
|
/* the first node is empty */
|
|
|
|
|
/* ... and it is empty, move it to unused */
|
|
|
|
|
|
|
|
|
|
cq->first = c->next;
|
|
|
|
|
if (cq->first == NULL) cq->last = NULL;
|
|
|
|
|
|
|
|
|
|
c->next = cq->unused;
|
|
|
|
|
cq->unused = c;
|
|
|
|
|
|
|
|
|
|
if (cq->first == NULL) cq->last = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
c = cq->first;
|
|
|
|
|
} else if (c->next && c->next->mem->used == 0) {
|
|
|
|
|
chunk *fc;
|
|
|
|
|
/* next node is the last one */
|
|
|
|
|
/* ... and it is empty, move it to unused */
|
|
|
|
|
|
|
|
|
|
fc = c->next;
|
|
|
|
|
c->next = fc->next;
|
|
|
|
|
|
|
|
|
|
fc->next = cq->unused;
|
|
|
|
|
cq->unused = fc;
|
|
|
|
|
|
|
|
|
|
/* the last node was empty */
|
|
|
|
|
if (c->next == NULL) {
|
|
|
|
|
cq->last = c;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
c = c->next;
|
|
|
|
|
} else {
|
|
|
|
|
break;
|
|
|
|
|
c = c->next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|