diff options
-rw-r--r-- | usr.sbin/relayd/http.h | 3 | ||||
-rw-r--r-- | usr.sbin/relayd/relay_http.c | 33 |
2 files changed, 29 insertions, 7 deletions
diff --git a/usr.sbin/relayd/http.h b/usr.sbin/relayd/http.h index 1d38631310c..052bc0ce326 100644 --- a/usr.sbin/relayd/http.h +++ b/usr.sbin/relayd/http.h @@ -1,4 +1,4 @@ -/* $OpenBSD: http.h,v 1.8 2016/07/29 10:00:12 reyk Exp $ */ +/* $OpenBSD: http.h,v 1.9 2016/08/01 21:14:45 benno Exp $ */ /* * Copyright (c) 2012 - 2015 Reyk Floeter <reyk@openbsd.org> @@ -241,6 +241,7 @@ struct http_descriptor { enum httpmethod http_method; int http_chunked; char *http_version; + unsigned int http_status; /* Rewritten path remains NULL if not used */ char *http_path_alias; diff --git a/usr.sbin/relayd/relay_http.c b/usr.sbin/relayd/relay_http.c index 81e0394d357..266938c13c7 100644 --- a/usr.sbin/relayd/relay_http.c +++ b/usr.sbin/relayd/relay_http.c @@ -1,4 +1,4 @@ -/* $OpenBSD: relay_http.c,v 1.60 2016/07/29 10:09:26 reyk Exp $ */ +/* $OpenBSD: relay_http.c,v 1.61 2016/08/01 21:14:45 benno Exp $ */ /* * Copyright (c) 2006 - 2016 Reyk Floeter <reyk@openbsd.org> @@ -258,6 +258,15 @@ relay_read_http(struct bufferevent *bev, void *arg) free(line); goto fail; } + desc->http_status = strtonum(desc->http_rescode, 100, + 599, &errstr); + if (errstr) { + DPRINTF("%s: http_status %s: errno %d, %s", + __func__, desc->http_rescode, errno, + errstr); + free(line); + goto fail; + } DPRINTF("http_version %s http_rescode %s " "http_resmesg %s", desc->http_version, desc->http_rescode, desc->http_resmesg); @@ -303,16 +312,28 @@ relay_read_http(struct bufferevent *bev, void *arg) } } else if (desc->http_method != HTTP_METHOD_NONE && strcasecmp("Content-Length", key) == 0) { + /* + * These methods should not have a body + * and thus no Content-Length header. + */ if (desc->http_method == HTTP_METHOD_TRACE || desc->http_method == HTTP_METHOD_CONNECT) { - /* - * These method should not have a body - * and thus no Content-Length header. - */ relay_abort_http(con, 400, "malformed", 0); goto abort; } - + /* + * response with a status code of 1xx + * (Informational) or 204 (No Content) MUST + * not have a Content-Length (rfc 7230 3.3.3) + */ + if (desc->http_method == HTTP_METHOD_RESPONSE && ( + ((desc->http_status >= 100 && + desc->http_status < 200) || + desc->http_status == 204))) { + relay_abort_http(con, 500, + "Internal Server Error", 0); + goto abort; + } /* * Need to read data from the client after the * HTTP header. |