http POST support
authorflorian <florian@openbsd.org>
Wed, 6 Aug 2014 15:08:04 +0000 (15:08 +0000)
committerflorian <florian@openbsd.org>
Wed, 6 Aug 2014 15:08:04 +0000 (15:08 +0000)
with & OK reyk@

usr.sbin/httpd/httpd.h
usr.sbin/httpd/server.c
usr.sbin/httpd/server_fcgi.c
usr.sbin/httpd/server_http.c

index 449c10f..4190970 100644 (file)
@@ -1,4 +1,4 @@
-/*     $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>
@@ -60,6 +60,8 @@
 #define CONFIG_SERVERS         0x02
 #define CONFIG_ALL             0xff
 
+#define FCGI_CONTENT_SIZE      65535
+
 enum httpchunk {
        TOREAD_UNLIMITED                = -1,
        TOREAD_HTTP_HEADER              = -2,
@@ -521,6 +523,7 @@ void         server_file_error(struct bufferevent *, short, void *);
 
 /* 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,
index 523becc..6671b69 100644 (file)
@@ -1,4 +1,4 @@
-/*     $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>
@@ -668,6 +668,8 @@ server_input(struct client *clt)
        /* 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);
index d1c9355..f2d14f4 100644 (file)
@@ -1,4 +1,4 @@
-/*     $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>
@@ -45,7 +45,6 @@
 #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)
@@ -323,18 +322,19 @@ server_fcgi(struct httpd *env, struct client *clt)
 
        /* send "no more params" message */
        h->content_len = 0;
-       bufferevent_write(clt->clt_srvbev, &param.buf,
-           sizeof(struct fcgi_record_header));
-
-       h->type = FCGI_STDIN;
-
        bufferevent_write(clt->clt_srvbev, &param.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
@@ -353,6 +353,30 @@ server_fcgi(struct httpd *env, struct client *clt)
        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)
index 1d3df76..f221e5a 100644 (file)
@@ -1,4 +1,4 @@
-/*     $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>
@@ -322,10 +322,10 @@ server_read_http(struct bufferevent *bev, void *arg)
                }
 
  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");
@@ -361,12 +361,11 @@ server_read_httpcontent(struct bufferevent *bev, void *arg)
                /* 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;
                }
@@ -374,17 +373,19 @@ server_read_httpcontent(struct bufferevent *bev, void *arg)
                    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));