Matthias Pressfreund(m...@fn.de) on 2021.10.23 17:16:18 +0200: > On 2021-10-21 16:38, Sebastian Benoit wrote: > > > > This diff makes httpd return "505 HTTP Version Not Supported" > > for < 0.9 and > 1.9 http versions. Anything from 1.1 to 1.9 is > > interpreted as 1.1. This is what nginx does too. > > > I don't understand why an invalid HTTP version sent by the client > should result in a server error while the problem actually is on > the other side, isn't it? Wouldn't a "400 Bad Request" response > instead of a "505 HTTP Version Not Supported" be more appropriate?
because 505 HTTP Version Not Supported means The server does not support the HTTP protocol version used in the request. I think its appropiate, nginx responds the same. > Second, the latest version correctly detects "HTTP/4.0" (for > example) as an unsupported version while "HTTP/123" wrongly is > accepted as "HTTP/1.1". i might add that indeed, thx. > > The suggestion below changes both of the above. > > Index: usr.sbin/httpd/server_http.c > =================================================================== > RCS file: /cvs/src/usr.sbin/httpd/server_http.c,v > retrieving revision 1.145 > diff -u -p -r1.145 server_http.c > --- usr.sbin/httpd/server_http.c 22 Oct 2021 08:51:50 -0000 1.145 > +++ usr.sbin/httpd/server_http.c 23 Oct 2021 14:39:50 -0000 > @@ -206,8 +206,12 @@ http_version_num(char *version) > return (9); > if (strcmp(version, "HTTP/1.0") == 0) > return (10); > + /* version strings other than 8 chars long are invalid */ > + if (strlen(version) != 8) > + return (0); > /* any other version 1.x gets downgraded to 1.1 */ > - if (strncmp(version, "HTTP/1", 6) == 0) > + if (strncmp(version, "HTTP/1.", 7) == 0 && > + version[7] >= '1' && version[7] <= '9') > return (11); > > return (0); > @@ -350,13 +354,13 @@ server_read_http(struct bufferevent *bev > * be changed independently by the filters later. > * Allow HTTP version 0.9 to 1.1. > * Downgrade http version > 1.1 <= 1.9 to version 1.1. > - * Return HTTP Version Not Supported for anything else. > + * Anything else is a client error (malformed version). > */ > > version = http_version_num(http_version); > > if (version == 0) { > - server_abort_http(clt, 505, "bad http version"); > + server_abort_http(clt, 400, "malformed"); > goto abort; > } else if (version == 11) { > if ((desc->http_version = > > > > > > > ok? > > > > diff --git usr.sbin/httpd/server_http.c usr.sbin/httpd/server_http.c > > index 6a74f3e45c5..52aaf3711c2 100644 > > --- usr.sbin/httpd/server_http.c > > +++ usr.sbin/httpd/server_http.c > > @@ -51,6 +51,7 @@ int server_http_authenticate(struct > > server_config *, > > struct client *); > > char *server_expand_http(struct client *, const char *, > > char *, size_t); > > +int http_version_num(char *); > > > > static struct http_method http_methods[] = HTTP_METHODS; > > static struct http_error http_errors[] = HTTP_ERRORS; > > @@ -198,6 +199,19 @@ done: > > return (ret); > > } > > > > +int http_version_num(char *version) > > +{ > > + if (strcmp(version, "HTTP/0.9") == 0) > > + return (9); > > + if (strcmp(version, "HTTP/1.0") == 0) > > + return (10); > > + /* any other version 1.x gets downgraded to 1.1 */ > > + if (strncmp(version, "HTTP/1", 6) == 0) > > + return (11); > > + > > + return (0); > > +} > > + > > void > > server_read_http(struct bufferevent *bev, void *arg) > > { > > @@ -207,6 +221,7 @@ server_read_http(struct bufferevent *bev, void *arg) > > char *line = NULL, *key, *value; > > const char *errstr; > > size_t size, linelen; > > + int version; > > struct kv *hdr = NULL; > > > > getmonotime(&clt->clt_tv_last); > > @@ -329,12 +344,29 @@ server_read_http(struct bufferevent *bev, void *arg) > > *desc->http_query++ = '\0'; > > > > /* > > - * Have to allocate the strings because they could > > + * We have to allocate the strings because they could > > * be changed independently by the filters later. > > + * Allow HTTP version 0.9 to 1.1. > > + * Downgrade http version > 1.1 <= 1.9 to version 1.1. > > + * Return HTTP Version Not Supported for anything else. > > */ > > - if ((desc->http_version = > > - strdup(desc->http_version)) == NULL) > > - goto fail; > > + > > + version = http_version_num(desc->http_version); > > + if (version == 11) { > > + if ((desc->http_version = > > + strdup("HTTP/1.1")) == NULL) > > + goto fail; > > + } else { > > + if ((desc->http_version = > > + strdup(desc->http_version)) == NULL) > > + goto fail; > > + } > > + > > + if (version == 0) { > > + server_abort_http(clt, 505, "bad http version"); > > + goto abort; > > + } > > + > > > > if (desc->http_query != NULL && > > (desc->http_query = > > > --