On Fri, Sep 07, 2018 at 03:08:53AM +1200, Carlin Bingham wrote:
> If httpd is configured to do "block return" with a 1xx or 204 status, it
> sends a response with a Content-Length header and a body, which per RFC
> 7230 it must not.
> 
> The use case for this is a webapp which wants the webserver itself to be
> configured to return a 204 response for certain requests. I'm running
> httpd behind relayd, and relayd doesn't accept the 204 responses httpd
> returns.
> 
> Here's a possible patch.
> 
> 
> --
> Carlin

How about this one? That way we list all the reasons not to have a
body up front.

diff --git server_http.c server_http.c
index 4c91dea2d16..72c67c46890 100644
--- server_http.c
+++ server_http.c
@@ -846,9 +846,10 @@ server_abort_http(struct client *clt, unsigned int code, 
const char *msg)
        const char              *httperr = NULL, *style;
        char                    *httpmsg, *body = NULL, *extraheader = NULL;
        char                     tmbuf[32], hbuf[128], *hstsheader = NULL;
+       char                    *clenheader = NULL;
        char                     buf[IBUF_READ_SIZE];
        char                    *escapedmsg = NULL;
-       int                      bodylen;
+       int                      bodylen = -1;
 
        if (code == 0) {
                server_close(clt, "dropped");
@@ -924,29 +925,34 @@ server_abort_http(struct client *clt, unsigned int code, 
const char *msg)
 
        free(escapedmsg);
 
-       /* A CSS stylesheet allows minimal customization by the user */
-       style = "body { background-color: white; color: black; font-family: "
-           "'Comic Sans MS', 'Chalkboard SE', 'Comic Neue', sans-serif; }\n"
-           "hr { border: 0; border-bottom: 1px dashed; }\n";
-
-       /* Generate simple HTML error document */
-       if ((bodylen = asprintf(&body,
-           "<!DOCTYPE html>\n"
-           "<html>\n"
-           "<head>\n"
-           "<meta http-equiv=\"Content-Type\" content=\"text/html; "
-           "charset=utf-8\"/>\n"
-           "<title>%03d %s</title>\n"
-           "<style type=\"text/css\"><!--\n%s\n--></style>\n"
-           "</head>\n"
-           "<body>\n"
-           "<h1>%03d %s</h1>\n"
-           "<hr>\n<address>%s</address>\n"
-           "</body>\n"
-           "</html>\n",
-           code, httperr, style, code, httperr, HTTPD_SERVERNAME)) == -1) {
-               body = NULL;
-               goto done;
+       if (code >= 200 && code != 204 && desc->http_method !=
+           HTTP_METHOD_HEAD) {
+               /* A CSS stylesheet allows minimal customization by the user */
+               style = "body { background-color: white; color: black; "
+                   "font-family: 'Comic Sans MS', 'Chalkboard SE', "
+                   "'Comic Neue', sans-serif; }\n"
+                   "hr { border: 0; border-bottom: 1px dashed; }\n";
+
+               /* Generate simple HTML error document */
+               if ((bodylen = asprintf(&body,
+                   "<!DOCTYPE html>\n"
+                   "<html>\n"
+                   "<head>\n"
+                   "<meta http-equiv=\"Content-Type\" content=\"text/html; "
+                   "charset=utf-8\"/>\n"
+                   "<title>%03d %s</title>\n"
+                   "<style type=\"text/css\"><!--\n%s\n--></style>\n"
+                   "</head>\n"
+                   "<body>\n"
+                   "<h1>%03d %s</h1>\n"
+                   "<hr>\n<address>%s</address>\n"
+                   "</body>\n"
+                   "</html>\n",
+                   code, httperr, style, code, httperr, HTTPD_SERVERNAME)) ==
+                   -1) {
+                       body = NULL;
+                       goto done;
+               }
        }
 
        if (srv_conf->flags & SRVFLAG_SERVER_HSTS) {
@@ -961,6 +967,14 @@ server_abort_http(struct client *clt, unsigned int code, 
const char *msg)
                }
        }
 
+       if (bodylen != -1) {
+               if (asprintf(&clenheader, "Content-Length: %d\r\n",
+                   bodylen) == -1) {
+                       clenheader = NULL;
+                       goto done;
+               }
+       }
+
        /* Add basic HTTP headers */
        if (asprintf(&httpmsg,
            "HTTP/1.0 %03d %s\r\n"
@@ -968,15 +982,16 @@ server_abort_http(struct client *clt, unsigned int code, 
const char *msg)
            "Server: %s\r\n"
            "Connection: close\r\n"
            "Content-Type: text/html\r\n"
-           "Content-Length: %d\r\n"
+           "%s"
            "%s"
            "%s"
            "\r\n"
            "%s",
-           code, httperr, tmbuf, HTTPD_SERVERNAME, bodylen,
+           code, httperr, tmbuf, HTTPD_SERVERNAME,
+           bodylen == -1 ? "" : clenheader,
            extraheader == NULL ? "" : extraheader,
            hstsheader == NULL ? "" : hstsheader,
-           desc->http_method == HTTP_METHOD_HEAD ? "" : body) == -1)
+           bodylen == -1 ? "" : body) == -1)
                goto done;
 
        /* Dump the message without checking for success */
@@ -987,6 +1002,7 @@ server_abort_http(struct client *clt, unsigned int code, 
const char *msg)
        free(body);
        free(extraheader);
        free(hstsheader);
+       free(clenheader);
        if (msg == NULL)
                msg = "\"\"";
        if (asprintf(&httpmsg, "%s (%03d %s)", msg, code, httperr) == -1) {


-- 
I'm not entirely sure you are real.

Reply via email to