From 11f8da53dacd6b6d34574617d7872e8ed6b424be Mon Sep 17 00:00:00 2001 From: florian Date: Sat, 2 Aug 2014 11:59:04 +0000 Subject: [PATCH] We need to read from the fcgi bufferevent until it's empty because the event handler will not be called again if no new data arrives. Debugged with and OK reyk@ --- usr.sbin/httpd/server_fcgi.c | 80 ++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 39 deletions(-) diff --git a/usr.sbin/httpd/server_fcgi.c b/usr.sbin/httpd/server_fcgi.c index a9232a89fb2..7f19016a655 100644 --- a/usr.sbin/httpd/server_fcgi.c +++ b/usr.sbin/httpd/server_fcgi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: server_fcgi.c,v 1.9 2014/08/02 11:52:01 reyk Exp $ */ +/* $OpenBSD: server_fcgi.c,v 1.10 2014/08/02 11:59:04 florian Exp $ */ /* * Copyright (c) 2014 Florian Obser @@ -434,46 +434,48 @@ server_fcgi_read(struct bufferevent *bev, void *arg) struct fcgi_record_header *h; size_t len; - len = bufferevent_read(bev, &buf, clt->clt_fcgi_toread); - /* XXX error handling */ - evbuffer_add(clt->clt_srvevb, &buf, len); - clt->clt_fcgi_toread -= len; - DPRINTF("%s: len: %lu toread: %d state: %d", __func__, len, - clt->clt_fcgi_toread, clt->clt_fcgi_state); - - if (clt->clt_fcgi_toread != 0) - return; - - switch (clt->clt_fcgi_state) { - case FCGI_READ_HEADER: - clt->clt_fcgi_state = FCGI_READ_CONTENT; - h = (struct fcgi_record_header *) - EVBUFFER_DATA(clt->clt_srvevb); - DPRINTF("%s: record header: version %d type %d id %d " - "content len %d", __func__, h->version, h->type, - ntohs(h->id), ntohs(h->content_len)); - clt->clt_fcgi_type = h->type; - clt->clt_fcgi_toread = ntohs(h->content_len); - evbuffer_drain(clt->clt_srvevb, - EVBUFFER_LENGTH(clt->clt_srvevb)); + do { + len = bufferevent_read(bev, &buf, clt->clt_fcgi_toread); + /* XXX error handling */ + evbuffer_add(clt->clt_srvevb, &buf, len); + clt->clt_fcgi_toread -= len; + DPRINTF("%s: len: %lu toread: %d state: %d", __func__, len, + clt->clt_fcgi_toread, clt->clt_fcgi_state); + if (clt->clt_fcgi_toread != 0) - break; - - /* fallthrough if content_len == 0 */ - case FCGI_READ_CONTENT: - if (clt->clt_fcgi_type == FCGI_STDOUT && - EVBUFFER_LENGTH(clt->clt_srvevb) > 0) { - if (++clt->clt_chunk == 1) - server_fcgi_header(clt, 200); - server_bufferevent_write_buffer(clt, - clt->clt_srvevb); + return; + + switch (clt->clt_fcgi_state) { + case FCGI_READ_HEADER: + clt->clt_fcgi_state = FCGI_READ_CONTENT; + h = (struct fcgi_record_header *) + EVBUFFER_DATA(clt->clt_srvevb); + DPRINTF("%s: record header: version %d type %d id %d " + "content len %d", __func__, h->version, h->type, + ntohs(h->id), ntohs(h->content_len)); + clt->clt_fcgi_type = h->type; + clt->clt_fcgi_toread = ntohs(h->content_len); + evbuffer_drain(clt->clt_srvevb, + EVBUFFER_LENGTH(clt->clt_srvevb)); + if (clt->clt_fcgi_toread != 0) + break; + + /* fallthrough if content_len == 0 */ + case FCGI_READ_CONTENT: + if (clt->clt_fcgi_type == FCGI_STDOUT && + EVBUFFER_LENGTH(clt->clt_srvevb) > 0) { + if (++clt->clt_chunk == 1) + server_fcgi_header(clt, 200); + server_bufferevent_write_buffer(clt, + clt->clt_srvevb); + } + evbuffer_drain(clt->clt_srvevb, + EVBUFFER_LENGTH(clt->clt_srvevb)); + clt->clt_fcgi_state = FCGI_READ_HEADER; + clt->clt_fcgi_toread = + sizeof(struct fcgi_record_header); } - evbuffer_drain(clt->clt_srvevb, - EVBUFFER_LENGTH(clt->clt_srvevb)); - clt->clt_fcgi_state = FCGI_READ_HEADER; - clt->clt_fcgi_toread = - sizeof(struct fcgi_record_header); - } + } while (len > 0); } int -- 2.20.1