fixed assertion if a read() returned with EGAIN in POST-read

and fixed pipelining + keep-alive


git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-merge-1.4.x@854 152afb58-edef-0310-8abb-c4023f1b3aa9
svn/tags/lighttpd-1.4.8
Jan Kneschke 2005-11-17 14:08:58 +00:00
parent 7d46051907
commit aa7e634b75
1 changed files with 53 additions and 18 deletions

View File

@ -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;
}
}