commit - 7ecc4542fefb0ad0b7babe055da2f9ac447a906b
commit + 3ff00eade6c3b17a852658c28502edbfc83ef25b
blob - f0de1b24e2bf33d38244b293dc7316561566af60
blob + f6cb81448f5778d7872b537fd6b90838285c99ee
--- gotwebd/fcgi.c
+++ gotwebd/fcgi.c
void fcgi_parse_begin_request(uint8_t *, uint16_t, struct request *,
uint16_t);
void fcgi_parse_params(uint8_t *, uint16_t, struct request *, uint16_t);
-void fcgi_send_response(struct request *, int, const void *, size_t);
+int fcgi_send_response(struct request *, int, const void *, size_t);
void dump_fcgi_record_header(const char *, struct fcgi_record_header *);
void dump_fcgi_begin_request_body(const char *,
break;
case FCGI_STDIN:
case FCGI_ABORT_REQUEST:
+ if (c->sock->client_status != CLIENT_DISCONNECT &&
+ c->outbuf_len != 0) {
+ fcgi_send_response(c, FCGI_STDOUT, c->outbuf,
+ c->outbuf_len);
+ }
+
fcgi_create_end_record(c);
fcgi_cleanup_request(c);
return 0;
int
fcgi_gen_binary_response(struct request *c, const uint8_t *data, int len)
{
+ int r;
+
if (c->sock->client_status == CLIENT_DISCONNECT)
return -1;
if (data == NULL || len == 0)
return 0;
- fcgi_send_response(c, FCGI_STDOUT, data, len);
+ /*
+ * special case: send big replies -like blobs- directly
+ * without copying.
+ */
+ if (len > sizeof(c->outbuf)) {
+ if (c->outbuf_len > 0) {
+ fcgi_send_response(c, FCGI_STDOUT,
+ c->outbuf, c->outbuf_len);
+ c->outbuf_len = 0;
+ }
+ return fcgi_send_response(c, FCGI_STDOUT, data, len);
+ }
+
+ if (len < sizeof(c->outbuf) - c->outbuf_len) {
+ memcpy(c->outbuf + c->outbuf_len, data, len);
+ c->outbuf_len += len;
+ return 0;
+ }
+
+ r = fcgi_send_response(c, FCGI_STDOUT, c->outbuf, c->outbuf_len);
+ if (r == -1)
+ return -1;
+
+ memcpy(c->outbuf, data, len);
+ c->outbuf_len = len;
return 0;
}
return fcgi_gen_binary_response(c, data, strlen(data));
}
-static void
+static int
send_response(struct request *c, int type, const uint8_t *data,
size_t len)
{
}
log_warn("%s: write failure", __func__);
c->sock->client_status = CLIENT_DISCONNECT;
- break;
+ return -1;
}
if (nw != tot)
iov[i].iov_len = 0;
}
}
+
+ return 0;
}
-void
+int
fcgi_send_response(struct request *c, int type, const void *data,
size_t len)
{
+ if (c->sock->client_status == CLIENT_DISCONNECT)
+ return -1;
+
while (len > FCGI_CONTENT_SIZE) {
- send_response(c, type, data, len);
- if (c->sock->client_status == CLIENT_DISCONNECT)
- return;
+ if (send_response(c, type, data, len) == -1)
+ return -1;
data += FCGI_CONTENT_SIZE;
len -= FCGI_CONTENT_SIZE;
}
if (len == 0)
- return;
+ return 0;
- send_response(c, type, data, len);
+ return send_response(c, type, data, len);
}
void
blob - aafdb73fcd040caf5d1182eb5bd173b3e7bd6a95
blob + b58b1e7be0421dac9ff6c9717bacb59208ad1bbb
--- gotwebd/gotwebd.h
+++ gotwebd/gotwebd.h
#define GOTWEBD_USER "www"
+#define GOTWEBD_CACHESIZE 1024
#define GOTWEBD_MAXCLIENTS 1024
#define GOTWEBD_MAXTEXT 511
#define GOTWEBD_MAXNAME 64
uint8_t buf[FCGI_RECORD_SIZE];
size_t buf_pos;
size_t buf_len;
+
+ uint8_t outbuf[GOTWEBD_CACHESIZE];
+ size_t outbuf_len;
char querystring[MAX_QUERYSTRING];
char http_host[GOTWEBD_MAXTEXT];