-/* $OpenBSD: httpd.h,v 1.48 2014/08/06 09:36:31 reyk Exp $ */
+/* $OpenBSD: httpd.h,v 1.49 2014/08/06 15:08:04 florian Exp $ */
/*
* Copyright (c) 2006 - 2014 Reyk Floeter <reyk@openbsd.org>
#define CONFIG_SERVERS 0x02
#define CONFIG_ALL 0xff
+#define FCGI_CONTENT_SIZE 65535
+
enum httpchunk {
TOREAD_UNLIMITED = -1,
TOREAD_HTTP_HEADER = -2,
/* server_fcgi.c */
int server_fcgi(struct httpd *, struct client *);
+int fcgi_add_stdin(struct client *, struct evbuffer *);
/* httpd.c */
void event_again(struct event *, int, short,
-/* $OpenBSD: server.c,v 1.35 2014/08/06 12:56:58 reyk Exp $ */
+/* $OpenBSD: server.c,v 1.36 2014/08/06 15:08:04 florian Exp $ */
/*
* Copyright (c) 2006 - 2014 Reyk Floeter <reyk@openbsd.org>
/* Adjust write watermark to the socket buffer output size */
bufferevent_setwatermark(clt->clt_bev, EV_WRITE,
clt->clt_sndbufsiz, 0);
+ /* Read at most amount of data that fits in one fcgi record. */
+ bufferevent_setwatermark(clt->clt_bev, EV_READ, 0, FCGI_CONTENT_SIZE);
bufferevent_settimeout(clt->clt_bev,
srv_conf->timeout.tv_sec, srv_conf->timeout.tv_sec);
-/* $OpenBSD: server_fcgi.c,v 1.22 2014/08/06 13:40:18 florian Exp $ */
+/* $OpenBSD: server_fcgi.c,v 1.23 2014/08/06 15:08:04 florian Exp $ */
/*
* Copyright (c) 2014 Florian Obser <florian@openbsd.org>
#include "httpd.h"
#include "http.h"
-#define FCGI_CONTENT_SIZE 65535
#define FCGI_PADDING_SIZE 255
#define FCGI_RECORD_SIZE \
(sizeof(struct fcgi_record_header) + FCGI_CONTENT_SIZE + FCGI_PADDING_SIZE)
/* send "no more params" message */
h->content_len = 0;
- bufferevent_write(clt->clt_srvbev, ¶m.buf,
- sizeof(struct fcgi_record_header));
-
- h->type = FCGI_STDIN;
-
bufferevent_write(clt->clt_srvbev, ¶m.buf,
sizeof(struct fcgi_record_header));
bufferevent_settimeout(clt->clt_srvbev,
srv_conf->timeout.tv_sec, srv_conf->timeout.tv_sec);
bufferevent_enable(clt->clt_srvbev, EV_READ|EV_WRITE);
- bufferevent_disable(clt->clt_bev, EV_READ);
+ if (clt->clt_toread != 0) {
+ server_read_httpcontent(clt->clt_bev, clt);
+ bufferevent_enable(clt->clt_bev, EV_READ);
+ } else {
+ bufferevent_disable(clt->clt_bev, EV_READ);
+ fcgi_add_stdin(clt, NULL);
+ }
/*
* persist is not supported yet because we don't get the
return (-1);
}
+int
+fcgi_add_stdin(struct client *clt, struct evbuffer *evbuf)
+{
+ struct fcgi_record_header h;
+
+ h.version = 1;
+ h.type = FCGI_STDIN;
+ h.id = htons(1);
+ h.padding_len = 0;
+
+ if (evbuf == NULL) {
+ h.content_len = 0;
+ return bufferevent_write(clt->clt_srvbev, &h,
+ sizeof(struct fcgi_record_header));
+ } else {
+ h.content_len = htons(EVBUFFER_LENGTH(evbuf));
+ if (bufferevent_write(clt->clt_srvbev, &h,
+ sizeof(struct fcgi_record_header)) == -1)
+ return -1;
+ return bufferevent_write_buffer(clt->clt_srvbev, evbuf);
+ }
+ return (0);
+}
+
int
fcgi_add_param(struct server_fcgi_param *p, const char *key,
const char *val, struct client *clt)
-/* $OpenBSD: server_http.c,v 1.40 2014/08/06 09:34:21 reyk Exp $ */
+/* $OpenBSD: server_http.c,v 1.41 2014/08/06 15:08:04 florian Exp $ */
/*
* Copyright (c) 2006 - 2014 Reyk Floeter <reyk@openbsd.org>
}
done:
- if (clt->clt_toread <= 0) {
- server_response(env, clt);
- return;
- }
+ if (clt->clt_toread != 0)
+ bufferevent_disable(bev, EV_READ);
+ server_response(env, clt);
+ return;
}
if (clt->clt_done) {
server_close(clt, "done");
/* Read content data */
if ((off_t)size > clt->clt_toread) {
size = clt->clt_toread;
- if (server_bufferevent_write_chunk(clt,
- src, size) == -1)
+ if (fcgi_add_stdin(clt, src) == -1)
goto fail;
clt->clt_toread = 0;
} else {
- if (server_bufferevent_write_buffer(clt, src) == -1)
+ if (fcgi_add_stdin(clt, src) == -1)
goto fail;
clt->clt_toread -= size;
}
size, clt->clt_toread);
}
if (clt->clt_toread == 0) {
+ fcgi_add_stdin(clt, NULL);
clt->clt_toread = TOREAD_HTTP_HEADER;
+ bufferevent_disable(bev, EV_READ);
bev->readcb = server_read_http;
+ return;
}
if (clt->clt_done)
goto done;
if (bev->readcb != server_read_httpcontent)
bev->readcb(bev, arg);
- bufferevent_enable(bev, EV_READ);
+
return;
done:
- server_close(clt, "last http content read");
return;
fail:
server_close(clt, strerror(errno));