kore

a fork of the worlds most advanced web framework
Log | Files | Refs | README | LICENSE

commit dda2e1fb2c08d5d45903d024ff7349d1305d845a
parent fc246e55526585fc10c9851d95043977b09b8f80
Author: Joris Vink <joris@coders.se>
Date:   Fri, 26 Oct 2018 21:24:51 +0200

Some things still talk http/1.0.

Diffstat:
Minclude/kore/http.h | 3+++
Msrc/http.c | 47++++++++++++++++++++++++++++++++++++-----------
2 files changed, 39 insertions(+), 11 deletions(-)

diff --git a/include/kore/http.h b/include/kore/http.h @@ -210,6 +210,9 @@ struct http_file { #define HTTP_REQUEST_NO_CONTENT_LENGTH 0x0080 #define HTTP_REQUEST_AUTHED 0x0100 +#define HTTP_VERSION_1_1 0x1000 +#define HTTP_VERSION_1_0 0x2000 + #define HTTP_VALIDATOR_IS_REQUEST 0x8000 #define HTTP_BODY_DIGEST_LEN 32 diff --git a/src/http.c b/src/http.c @@ -1388,8 +1388,15 @@ http_request_new(struct connection *c, const char *host, } if (strcasecmp(version, "http/1.1")) { - http_error_response(c, 505); - return (NULL); + if (strcasecmp(version, "http/1.0")) { + http_error_response(c, 505); + return (NULL); + } + + flags = HTTP_VERSION_1_0; + c->flags |= CONN_CLOSE_EMPTY; + } else { + flags = HTTP_VERSION_1_1; } if ((p = strchr(path, '?')) != NULL) { @@ -1434,30 +1441,38 @@ http_request_new(struct connection *c, const char *host, if (!strcasecmp(method, "get")) { m = HTTP_METHOD_GET; - flags = HTTP_REQUEST_COMPLETE; + flags |= HTTP_REQUEST_COMPLETE; } else if (!strcasecmp(method, "delete")) { m = HTTP_METHOD_DELETE; - flags = HTTP_REQUEST_COMPLETE; + flags |= HTTP_REQUEST_COMPLETE; } else if (!strcasecmp(method, "post")) { m = HTTP_METHOD_POST; - flags = HTTP_REQUEST_EXPECT_BODY; + flags |= HTTP_REQUEST_EXPECT_BODY; } else if (!strcasecmp(method, "put")) { m = HTTP_METHOD_PUT; - flags = HTTP_REQUEST_EXPECT_BODY; + flags |= HTTP_REQUEST_EXPECT_BODY; } else if (!strcasecmp(method, "head")) { m = HTTP_METHOD_HEAD; - flags = HTTP_REQUEST_COMPLETE; + flags |= HTTP_REQUEST_COMPLETE; } else if (!strcasecmp(method, "options")) { m = HTTP_METHOD_OPTIONS; - flags = HTTP_REQUEST_COMPLETE; + flags |= HTTP_REQUEST_COMPLETE; } else if (!strcasecmp(method, "patch")) { m = HTTP_METHOD_PATCH; - flags = HTTP_REQUEST_EXPECT_BODY; + flags |= HTTP_REQUEST_EXPECT_BODY; } else { http_error_response(c, 400); return (NULL); } + if (flags & HTTP_VERSION_1_0) { + if (m != HTTP_METHOD_GET && m != HTTP_METHOD_POST && + m != HTTP_METHOD_HEAD) { + http_error_response(c, HTTP_STATUS_METHOD_NOT_ALLOWED); + return (NULL); + } + } + if (!(hdlr->methods & m)) { http_error_response(c, HTTP_STATUS_METHOD_NOT_ALLOWED); return (NULL); @@ -1816,12 +1831,22 @@ http_response_normal(struct http_request *req, struct connection *c, struct http_cookie *ck; struct http_header *hdr; const char *conn; + char version; int connection_close; kore_buf_reset(header_buf); - kore_buf_appendf(header_buf, "HTTP/1.1 %d %s\r\n", - status, http_status_text(status)); + if (req != NULL) { + if (req->flags & HTTP_VERSION_1_0) + version = '0'; + else + version = '1'; + } else { + version = '1'; + } + + kore_buf_appendf(header_buf, "HTTP/1.%c %d %s\r\n", + version, status, http_status_text(status)); kore_buf_append(header_buf, http_version, http_version_len); if (c->flags & CONN_CLOSE_EMPTY)