]> git.pld-linux.org Git - packages/lighttpd.git/commitdiff
1.4.51
authorElan Ruusamäe <glen@pld-linux.org>
Sat, 27 Oct 2018 16:11:05 +0000 (19:11 +0300)
committerElan Ruusamäe <glen@pld-linux.org>
Fri, 30 Nov 2018 13:13:04 +0000 (15:13 +0200)
a9e131..df8e4f.patch [deleted file]
lighttpd.spec

diff --git a/a9e131..df8e4f.patch b/a9e131..df8e4f.patch
deleted file mode 100644 (file)
index 12ea77c..0000000
+++ /dev/null
@@ -1,976 +0,0 @@
-From: =?UTF-8?Q?Stefan_B=c3=bchler?= <stbuehler@web.de>
-To: lighttpd-announce@lists.lighttpd.net
-Message-ID: <8cbf0c87-1037-8f70-aa24-b2f14c95170d@web.de>
-Date: Sun, 26 Aug 2018 19:06:30 +0200
-Subject: use-after-free bug in header folding
-
-Hi,
-
-Or Peles reported some use-after-free scenarios related to header 
-folding (continuing a header value on a whitespace indented line).
-
-The fix required some preparation and therefor consists of a series of 4 
-patches, see git:
-
-https://git.lighttpd.net/lighttpd/lighttpd1.4.git/log/?qt=range&q=a9e131..df8e4f&showmsg=1
-
-There are currently no plans for a new release.
-
-cheers,
-Stefan
-
-diff --git a/src/request.c b/src/request.c
-index 213a87e1..e94d8591 100644
---- a/src/request.c
-+++ b/src/request.c
-@@ -408,26 +408,179 @@ static int request_uri_is_valid_char(unsigned char c) {
-       return 1;
- }
--static int http_request_missing_CR_before_LF(server *srv, connection *con) {
-+static void http_request_missing_CR_before_LF(server *srv, connection *con) {
-       if (srv->srvconf.log_request_header_on_error) {
-               log_error_write(srv, __FILE__, __LINE__, "s", "missing CR before LF in header -> 400");
-               log_error_write(srv, __FILE__, __LINE__, "Sb", "request-header:\n", con->request.request);
-       }
-+}
--      con->http_status = 400;
--      con->keep_alive = 0;
--      con->response.keep_alive = 0;
-+enum keep_alive_set {
-+      HTTP_CONNECTION_UNSET,
-+      HTTP_CONNECTION_KEEPALIVE,
-+      HTTP_CONNECTION_CLOSE,
-+};
-+
-+typedef struct {
-+      enum keep_alive_set keep_alive_set;
-+      char con_length_set;
-+      char *reqline_host;
-+      int reqline_hostlen;
-+} parse_header_state;
-+
-+static void init_parse_header_state(parse_header_state* state) {
-+      state->keep_alive_set = HTTP_CONNECTION_UNSET;
-+      state->con_length_set = 0;
-+      state->reqline_host = NULL;
-+      state->reqline_hostlen = 0;
-+}
-+
-+/* add a header to the list of headers; certain headers are also parsed in this state.
-+ *
-+ * Also might drop a header if deemed unnecessary/broken.
-+ *
-+ * returns 0 on error
-+ */
-+static int parse_single_header(server *srv, connection *con, parse_header_state *state, data_string *ds) {
-+      int cmp = 0;
-+
-+      /* empty header-fields are not allowed by HTTP-RFC, we just ignore them */
-+      if (buffer_string_is_empty(ds->value)) {
-+              goto drop_header;
-+      }
-+
-+      /* retreive values
-+       *
-+       *
-+       * the list of options is sorted to simplify the search
-+       */
-+
-+      if (0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("Connection")))) {
-+              array *vals;
-+              size_t vi;
-+
-+              /* split on , */
-+
-+              vals = srv->split_vals;
-+
-+              array_reset(vals);
-+
-+              http_request_split_value(vals, ds->value);
-+
-+              for (vi = 0; vi < vals->used; vi++) {
-+                      data_string *dsv = (data_string *)vals->data[vi];
-+
-+                      if (0 == buffer_caseless_compare(CONST_BUF_LEN(dsv->value), CONST_STR_LEN("keep-alive"))) {
-+                              state->keep_alive_set = HTTP_CONNECTION_KEEPALIVE;
-+
-+                              break;
-+                      } else if (0 == buffer_caseless_compare(CONST_BUF_LEN(dsv->value), CONST_STR_LEN("close"))) {
-+                              state->keep_alive_set = HTTP_CONNECTION_CLOSE;
-+
-+                              break;
-+                      }
-+              }
-+
-+      } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("Content-Length")))) {
-+              char *err;
-+              off_t r;
-+
-+              if (state->con_length_set) {
-+                      if (srv->srvconf.log_request_header_on_error) {
-+                              log_error_write(srv, __FILE__, __LINE__, "s",
-+                                              "duplicate Content-Length-header -> 400");
-+                              log_error_write(srv, __FILE__, __LINE__, "Sb",
-+                                              "request-header:\n",
-+                                              con->request.request);
-+                      }
-+                      goto invalid_header;
-+              }
-+
-+              r = strtoll(ds->value->ptr, &err, 10);
-+
-+              if (*err == '\0' && r >= 0) {
-+                      state->con_length_set = 1;
-+                      con->request.content_length = r;
-+              } else {
-+                      log_error_write(srv, __FILE__, __LINE__, "sbs",
-+                                      "content-length broken:", ds->value, "-> 400");
-+                      goto invalid_header;
-+              }
-+      } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("Content-Type")))) {
-+              /* if dup, only the first one will survive */
-+              if (!con->request.http_content_type) {
-+                      con->request.http_content_type = ds->value->ptr;
-+              } else {
-+                      if (srv->srvconf.log_request_header_on_error) {
-+                              log_error_write(srv, __FILE__, __LINE__, "s",
-+                                              "duplicate Content-Type-header -> 400");
-+                              log_error_write(srv, __FILE__, __LINE__, "Sb",
-+                                              "request-header:\n",
-+                                              con->request.request);
-+                      }
-+                      goto invalid_header;
-+              }
-+      } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("Host")))) {
-+              if (state->reqline_host) {
-+                      /* ignore all host: headers as we got the host in the request line */
-+                      goto drop_header;
-+              } else if (!con->request.http_host) {
-+                      con->request.http_host = ds->value;
-+              } else {
-+                      if (srv->srvconf.log_request_header_on_error) {
-+                              log_error_write(srv, __FILE__, __LINE__, "s",
-+                                              "duplicate Host-header -> 400");
-+                              log_error_write(srv, __FILE__, __LINE__, "Sb",
-+                                              "request-header:\n",
-+                                              con->request.request);
-+                      }
-+                      goto invalid_header;
-+              }
-+      } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("If-Modified-Since")))) {
-+              /* Proxies sometimes send dup headers
-+               * if they are the same we ignore the second
-+               * if not, we raise an error */
-+              if (!con->request.http_if_modified_since) {
-+                      con->request.http_if_modified_since = ds->value->ptr;
-+              } else if (0 == strcasecmp(con->request.http_if_modified_since, ds->value->ptr)) {
-+                      /* ignore it if they are the same */
-+                      goto drop_header;
-+              } else {
-+                      if (srv->srvconf.log_request_header_on_error) {
-+                              log_error_write(srv, __FILE__, __LINE__, "s",
-+                                              "duplicate If-Modified-Since header -> 400");
-+                              log_error_write(srv, __FILE__, __LINE__, "Sb",
-+                                              "request-header:\n",
-+                                              con->request.request);
-+                      }
-+                      goto invalid_header;
-+              }
-+      } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("If-None-Match")))) {
-+              /* if dup, only the first one will survive */
-+              if (!con->request.http_if_none_match) {
-+                      con->request.http_if_none_match = ds->value->ptr;
-+              } else {
-+                      goto drop_header;
-+              }
-+      }
-+
-+      array_insert_unique(con->request.headers, (data_unset *)ds);
-+      return 1;
-+
-+drop_header:
-+      ds->free((data_unset *)ds);
-+      return 1;
-+
-+invalid_header:
-+      ds->free((data_unset *)ds);
-       return 0;
- }
- int http_request_parse(server *srv, connection *con) {
--      char *uri = NULL, *proto = NULL, *method = NULL, con_length_set;
-+      char *uri = NULL, *proto = NULL, *method = NULL;
-       int is_key = 1, key_len = 0, is_ws_after_key = 0, in_folding;
-       char *value = NULL, *key = NULL;
--      char *reqline_host = NULL;
--      int reqline_hostlen = 0;
--
--      enum { HTTP_CONNECTION_UNSET, HTTP_CONNECTION_KEEPALIVE, HTTP_CONNECTION_CLOSE } keep_alive_set = HTTP_CONNECTION_UNSET;
-+      data_string *current_header = NULL;
-       int line = 0;
-@@ -437,6 +590,9 @@ int http_request_parse(server *srv, connection *con) {
-       int done = 0;
-       const unsigned int http_header_strict = (con->conf.http_parseopts & HTTP_PARSEOPT_HEADER_STRICT);
-+      parse_header_state state;
-+      init_parse_header_state(&state);
-+
-       /*
-        * Request: "^(GET|POST|HEAD) ([^ ]+(\\?[^ ]+|)) (HTTP/1\\.[01])$"
-        * Option : "^([-a-zA-Z]+): (.+)$"
-@@ -457,9 +613,7 @@ int http_request_parse(server *srv, connection *con) {
-             #ifdef __COVERITY__
-               if (buffer_string_length(con->request.request) < 2) {
--                      con->keep_alive = 0;
--                      con->http_status = 400;
--                      return 0;
-+                      goto failure;
-               }
-             #endif
-               /* coverity[overflow_sink : FALSE] */
-@@ -467,12 +621,13 @@ int http_request_parse(server *srv, connection *con) {
-       } else if (con->request_count > 0 &&
-           con->request.request->ptr[1] == '\n') {
-               /* we are in keep-alive and might get \n after a previous POST request.*/
--              if (http_header_strict) return http_request_missing_CR_before_LF(srv, con);
-+              if (http_header_strict) {
-+                      http_request_missing_CR_before_LF(srv, con);
-+                      goto failure;
-+              }
-             #ifdef __COVERITY__
-               if (buffer_string_length(con->request.request) < 1) {
--                      con->keep_alive = 0;
--                      con->http_status = 400;
--                      return 0;
-+                      goto failure;
-               }
-             #endif
-               /* coverity[overflow_sink : FALSE] */
-@@ -482,9 +637,6 @@ int http_request_parse(server *srv, connection *con) {
-               buffer_copy_buffer(con->parse_request, con->request.request);
-       }
--      keep_alive_set = 0;
--      con_length_set = 0;
--
-       /* parse the first line of the request
-        *
-        * should be:
-@@ -510,22 +662,19 @@ int http_request_parse(server *srv, connection *con) {
-                                       con->parse_request->ptr[i] = '\0';
-                                       ++i;
-                               } else if (http_header_strict) { /* '\n' */
--                                      return http_request_missing_CR_before_LF(srv, con);
-+                                      http_request_missing_CR_before_LF(srv, con);
-+                                      goto failure;
-                               }
-                               con->parse_request->ptr[i] = '\0';
-                               if (request_line_stage != 2) {
--                                      con->http_status = 400;
--                                      con->response.keep_alive = 0;
--                                      con->keep_alive = 0;
--
-                                       if (srv->srvconf.log_request_header_on_error) {
-                                               log_error_write(srv, __FILE__, __LINE__, "s", "incomplete request line -> 400");
-                                               log_error_write(srv, __FILE__, __LINE__, "Sb",
-                                                               "request-header:\n",
-                                                               con->request.request);
-                                       }
--                                      return 0;
-+                                      goto failure;
-                               }
-                               proto = con->parse_request->ptr + first;
-@@ -536,8 +685,6 @@ int http_request_parse(server *srv, connection *con) {
-                               /* we got the first one :) */
-                               if (HTTP_METHOD_UNSET == (r = get_http_method_key(method))) {
-                                       con->http_status = 501;
--                                      con->response.keep_alive = 0;
--                                      con->keep_alive = 0;
-                                       if (srv->srvconf.log_request_header_on_error) {
-                                               log_error_write(srv, __FILE__, __LINE__, "s", "unknown http-method -> 501");
-@@ -546,7 +693,7 @@ int http_request_parse(server *srv, connection *con) {
-                                                               con->request.request);
-                                       }
--                                      return 0;
-+                                      goto failure;
-                               }
-                               con->request.http_method = r;
-@@ -582,16 +729,13 @@ int http_request_parse(server *srv, connection *con) {
-                                       }
-                                       if (invalid_version) {
--                                              con->http_status = 400;
--                                              con->keep_alive = 0;
--
-                                               if (srv->srvconf.log_request_header_on_error) {
-                                                       log_error_write(srv, __FILE__, __LINE__, "s", "unknown protocol -> 400");
-                                                       log_error_write(srv, __FILE__, __LINE__, "Sb",
-                                                                       "request-header:\n",
-                                                                       con->request.request);
-                                               }
--                                              return 0;
-+                                              goto failure;
-                                       }
-                                       if (major_num == 1 && minor_num == 1) {
-@@ -607,19 +751,16 @@ int http_request_parse(server *srv, connection *con) {
-                                                                       "request-header:\n",
-                                                                       con->request.request);
-                                               }
--                                              return 0;
-+                                              goto failure;
-                                       }
-                               } else {
--                                      con->http_status = 400;
--                                      con->keep_alive = 0;
--
-                                       if (srv->srvconf.log_request_header_on_error) {
-                                               log_error_write(srv, __FILE__, __LINE__, "s", "unknown protocol -> 400");
-                                               log_error_write(srv, __FILE__, __LINE__, "Sb",
-                                                               "request-header:\n",
-                                                               con->request.request);
-                                       }
--                                      return 0;
-+                                      goto failure;
-                               }
-                               if (*uri == '/') {
-@@ -627,14 +768,14 @@ int http_request_parse(server *srv, connection *con) {
-                                       buffer_copy_string_len(con->request.uri, uri, proto - uri - 1);
-                               } else if (0 == strncasecmp(uri, "http://", 7) &&
-                                   NULL != (nuri = strchr(uri + 7, '/'))) {
--                                      reqline_host = uri + 7;
--                                      reqline_hostlen = nuri - reqline_host;
-+                                      state.reqline_host = uri + 7;
-+                                      state.reqline_hostlen = nuri - state.reqline_host;
-                                       buffer_copy_string_len(con->request.uri, nuri, proto - nuri - 1);
-                               } else if (0 == strncasecmp(uri, "https://", 8) &&
-                                   NULL != (nuri = strchr(uri + 8, '/'))) {
--                                      reqline_host = uri + 8;
--                                      reqline_hostlen = nuri - reqline_host;
-+                                      state.reqline_host = uri + 8;
-+                                      state.reqline_hostlen = nuri - state.reqline_host;
-                                       buffer_copy_string_len(con->request.uri, nuri, proto - nuri - 1);
-                               } else if (!http_header_strict
-@@ -643,10 +784,8 @@ int http_request_parse(server *srv, connection *con) {
-                                       /* everything looks good so far */
-                                       buffer_copy_string_len(con->request.uri, uri, proto - uri - 1);
-                               } else {
--                                      con->http_status = 400;
--                                      con->keep_alive = 0;
-                                       log_error_write(srv, __FILE__, __LINE__, "ss", "request-URI parse error -> 400 for:", uri);
--                                      return 0;
-+                                      goto failure;
-                               }
-                               /* check uri for invalid characters */
-@@ -660,33 +799,30 @@ int http_request_parse(server *srv, connection *con) {
-                                       j = (NULL == z) ? jlen : (size_t)(z - con->request.uri->ptr);
-                               }
-                               if (j < jlen) {
--                                              con->http_status = 400;
--                                              con->keep_alive = 0;
--
--                                              if (srv->srvconf.log_request_header_on_error) {
--                                                      unsigned char buf[2];
--                                                      buf[0] = con->request.uri->ptr[j];
--                                                      buf[1] = '\0';
--
--                                                      if (con->request.uri->ptr[j] > 32 &&
--                                                          con->request.uri->ptr[j] != 127) {
--                                                              /* the character is printable -> print it */
--                                                              log_error_write(srv, __FILE__, __LINE__, "ss",
--                                                                              "invalid character in URI -> 400",
--                                                                              buf);
--                                                      } else {
--                                                              /* a control-character, print ascii-code */
--                                                              log_error_write(srv, __FILE__, __LINE__, "sd",
--                                                                              "invalid character in URI -> 400",
--                                                                              con->request.uri->ptr[j]);
--                                                      }
--
--                                                      log_error_write(srv, __FILE__, __LINE__, "Sb",
--                                                                      "request-header:\n",
--                                                                      con->request.request);
-+                                      if (srv->srvconf.log_request_header_on_error) {
-+                                              unsigned char buf[2];
-+                                              buf[0] = con->request.uri->ptr[j];
-+                                              buf[1] = '\0';
-+
-+                                              if (con->request.uri->ptr[j] > 32 &&
-+                                                      con->request.uri->ptr[j] != 127) {
-+                                                      /* the character is printable -> print it */
-+                                                      log_error_write(srv, __FILE__, __LINE__, "ss",
-+                                                                      "invalid character in URI -> 400",
-+                                                                      buf);
-+                                              } else {
-+                                                      /* a control-character, print ascii-code */
-+                                                      log_error_write(srv, __FILE__, __LINE__, "sd",
-+                                                                      "invalid character in URI -> 400",
-+                                                                      con->request.uri->ptr[j]);
-                                               }
--                                              return 0;
-+                                              log_error_write(srv, __FILE__, __LINE__, "Sb",
-+                                                              "request-header:\n",
-+                                                              con->request.request);
-+                                      }
-+
-+                                      goto failure;
-                               }
-                               buffer_copy_buffer(con->request.orig_uri, con->request.uri);
-@@ -711,17 +847,13 @@ int http_request_parse(server *srv, connection *con) {
-                               break;
-                       default:
-                               /* ERROR, one space to much */
--                              con->http_status = 400;
--                              con->response.keep_alive = 0;
--                              con->keep_alive = 0;
--
-                               if (srv->srvconf.log_request_header_on_error) {
-                                       log_error_write(srv, __FILE__, __LINE__, "s", "overlong request line -> 400");
-                                       log_error_write(srv, __FILE__, __LINE__, "Sb",
-                                                       "request-header:\n",
-                                                       con->request.request);
-                               }
--                              return 0;
-+                              goto failure;
-                       }
-                       request_line_stage++;
-@@ -732,20 +864,16 @@ int http_request_parse(server *srv, connection *con) {
-       in_folding = 0;
-       if (buffer_string_is_empty(con->request.uri)) {
--              con->http_status = 400;
--              con->response.keep_alive = 0;
--              con->keep_alive = 0;
--
-               if (srv->srvconf.log_request_header_on_error) {
-                       log_error_write(srv, __FILE__, __LINE__, "s", "no uri specified -> 400");
-                       log_error_write(srv, __FILE__, __LINE__, "Sb",
-                                                       "request-header:\n",
-                                                       con->request.request);
-               }
--              return 0;
-+              goto failure;
-       }
--      if (reqline_host) {
-+      if (state.reqline_host) {
-               /* Insert as host header */
-               data_string *ds;
-@@ -754,7 +882,7 @@ int http_request_parse(server *srv, connection *con) {
-               }
-               buffer_copy_string_len(ds->key, CONST_STR_LEN("Host"));
--              buffer_copy_string_len(ds->value, reqline_host, reqline_hostlen);
-+              buffer_copy_string_len(ds->value, state.reqline_host, state.reqline_hostlen);
-               array_insert_unique(con->request.headers, (data_unset *)ds);
-               con->request.http_host = ds->value;
-       }
-@@ -799,10 +927,6 @@ int http_request_parse(server *srv, connection *con) {
-                       case '=':
-                       case '{':
-                       case '}':
--                              con->http_status = 400;
--                              con->keep_alive = 0;
--                              con->response.keep_alive = 0;
--
-                               if (srv->srvconf.log_request_header_on_error) {
-                                       log_error_write(srv, __FILE__, __LINE__, "sbsds",
-                                               "invalid character in key", con->request.request, cur, *cur, "-> 400");
-@@ -811,7 +935,7 @@ int http_request_parse(server *srv, connection *con) {
-                                               "request-header:\n",
-                                               con->request.request);
-                               }
--                              return 0;
-+                              goto failure;
-                       case ' ':
-                       case '\t':
-                               if (i == first) {
-@@ -850,11 +974,7 @@ int http_request_parse(server *srv, connection *con) {
-                                                               con->request.request);
-                                               }
--                                              con->http_status = 400;
--                                              con->response.keep_alive = 0;
--                                              con->keep_alive = 0;
--
--                                              return 0;
-+                                              goto failure;
-                                       }
-                               }
-@@ -876,15 +996,13 @@ int http_request_parse(server *srv, connection *con) {
-                                                       con->request.request);
-                                       }
--                                      con->http_status = 400;
--                                      con->keep_alive = 0;
--                                      con->response.keep_alive = 0;
--                                      return 0;
-+                                      goto failure;
-                               }
-                               break;
-                       case '\n':
-                               if (http_header_strict) {
--                                      return http_request_missing_CR_before_LF(srv, con);
-+                                      http_request_missing_CR_before_LF(srv, con);
-+                                      goto failure;
-                               } else if (i == first) {
-                                       con->parse_request->ptr[i] = '\0';
-                                       done = 1;
-@@ -893,10 +1011,6 @@ int http_request_parse(server *srv, connection *con) {
-                               /* fall through */
-                       default:
-                               if (http_header_strict ? (*cur < 32 || ((unsigned char)*cur) >= 127) : *cur == '\0') {
--                                      con->http_status = 400;
--                                      con->keep_alive = 0;
--                                      con->response.keep_alive = 0;
--
-                                       if (srv->srvconf.log_request_header_on_error) {
-                                               log_error_write(srv, __FILE__, __LINE__, "sbsds",
-                                                       "invalid character in key", con->request.request, cur, *cur, "-> 400");
-@@ -906,7 +1020,7 @@ int http_request_parse(server *srv, connection *con) {
-                                                       con->request.request);
-                                       }
--                                      return 0;
-+                                      goto failure;
-                               }
-                               /* ok */
-                               break;
-@@ -916,9 +1030,13 @@ int http_request_parse(server *srv, connection *con) {
-                       case '\r':
-                       case '\n':
-                               if (*cur == '\n' || con->parse_request->ptr[i+1] == '\n') {
--                                      data_string *ds = NULL;
-+                                      int value_len;
-+
-                                       if (*cur == '\n') {
--                                              if (http_header_strict) return http_request_missing_CR_before_LF(srv, con);
-+                                              if (http_header_strict) {
-+                                                      http_request_missing_CR_before_LF(srv, con);
-+                                                      goto failure;
-+                                              }
-                                       } else { /* (con->parse_request->ptr[i+1] == '\n') */
-                                               con->parse_request->ptr[i] = '\0';
-                                               ++i;
-@@ -927,17 +1045,15 @@ int http_request_parse(server *srv, connection *con) {
-                                       /* End of Headerline */
-                                       con->parse_request->ptr[i] = '\0';
-+                                      value_len = cur - value;
-+
-+                                      /* strip trailing white-spaces */
-+                                      while (value_len > 0 && (value[value_len - 1] == ' ' || value[value_len - 1] == '\t')) {
-+                                              --value_len;
-+                                      }
-+
-                                       if (in_folding) {
--                                              /**
--                                               * we use a evil hack to handle the line-folding
--                                               * 
--                                               * As array_insert_unique() deletes 'ds' in the case of a duplicate
--                                               * ds points somewhere and we get a evil crash. As a solution we keep the old
--                                               * "key" and get the current value from the hash and append us
--                                               *
--                                               * */
--
--                                              if (!key || !key_len) {
-+                                              if (!current_header) {
-                                                       /* 400 */
-                                                       if (srv->srvconf.log_request_header_on_error) {
-@@ -948,193 +1064,35 @@ int http_request_parse(server *srv, connection *con) {
-                                                                       con->request.request);
-                                                       }
--
--                                                      con->http_status = 400;
--                                                      con->keep_alive = 0;
--                                                      con->response.keep_alive = 0;
--                                                      return 0;
-+                                                      goto failure;
-                                               }
--                                              if (NULL != (ds = (data_string *)array_get_element_klen(con->request.headers, key, key_len))) {
--                                                      buffer_append_string(ds->value, value);
--                                              }
-+                                              buffer_append_string_len(current_header->value, value, value_len);
-                                       } else {
--                                              int s_len;
--                                              key = con->parse_request->ptr + first;
--
--                                              s_len = cur - value;
--
--                                              /* strip trailing white-spaces */
--                                              for (; s_len > 0 && 
--                                                              (value[s_len - 1] == ' ' || 
--                                                               value[s_len - 1] == '\t'); s_len--);
--
--                                              value[s_len] = '\0';
--
--                                              if (s_len > 0) {
--                                                      int cmp = 0;
--                                                      if (NULL == (ds = (data_string *)array_get_unused_element(con->request.headers, TYPE_STRING))) {
--                                                              ds = data_string_init();
--                                                      }
--                                                      buffer_copy_string_len(ds->key, key, key_len);
--                                                      buffer_copy_string_len(ds->value, value, s_len);
--
--                                                      /* retreive values
--                                                       *
--                                                       *
--                                                       * the list of options is sorted to simplify the search
--                                                       */
--
--                                                      if (0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("Connection")))) {
--                                                              array *vals;
--                                                              size_t vi;
--
--                                                              /* split on , */
--
--                                                              vals = srv->split_vals;
--
--                                                              array_reset(vals);
--
--                                                              http_request_split_value(vals, ds->value);
--
--                                                              for (vi = 0; vi < vals->used; vi++) {
--                                                                      data_string *dsv = (data_string *)vals->data[vi];
--
--                                                                      if (0 == buffer_caseless_compare(CONST_BUF_LEN(dsv->value), CONST_STR_LEN("keep-alive"))) {
--                                                                              keep_alive_set = HTTP_CONNECTION_KEEPALIVE;
--
--                                                                              break;
--                                                                      } else if (0 == buffer_caseless_compare(CONST_BUF_LEN(dsv->value), CONST_STR_LEN("close"))) {
--                                                                              keep_alive_set = HTTP_CONNECTION_CLOSE;
--
--                                                                              break;
--                                                                      }
--                                                              }
--
--                                                      } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("Content-Length")))) {
--                                                              char *err;
--                                                              off_t r;
--
--                                                              if (con_length_set) {
--                                                                      con->http_status = 400;
--                                                                      con->keep_alive = 0;
--
--                                                                      if (srv->srvconf.log_request_header_on_error) {
--                                                                              log_error_write(srv, __FILE__, __LINE__, "s",
--                                                                                              "duplicate Content-Length-header -> 400");
--                                                                              log_error_write(srv, __FILE__, __LINE__, "Sb",
--                                                                                              "request-header:\n",
--                                                                                              con->request.request);
--                                                                      }
--                                                                      array_insert_unique(con->request.headers, (data_unset *)ds);
--                                                                      return 0;
--                                                              }
--
--                                                              r = strtoll(ds->value->ptr, &err, 10);
--
--                                                              if (*err == '\0' && r >= 0) {
--                                                                      con_length_set = 1;
--                                                                      con->request.content_length = r;
--                                                              } else {
--                                                                      log_error_write(srv, __FILE__, __LINE__, "sbs",
--                                                                                      "content-length broken:", ds->value, "-> 400");
--
--                                                                      con->http_status = 400;
--                                                                      con->keep_alive = 0;
--
--                                                                      array_insert_unique(con->request.headers, (data_unset *)ds);
--                                                                      return 0;
--                                                              }
--                                                      } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("Content-Type")))) {
--                                                              /* if dup, only the first one will survive */
--                                                              if (!con->request.http_content_type) {
--                                                                      con->request.http_content_type = ds->value->ptr;
--                                                              } else {
--                                                                      con->http_status = 400;
--                                                                      con->keep_alive = 0;
--
--                                                                      if (srv->srvconf.log_request_header_on_error) {
--                                                                              log_error_write(srv, __FILE__, __LINE__, "s",
--                                                                                              "duplicate Content-Type-header -> 400");
--                                                                              log_error_write(srv, __FILE__, __LINE__, "Sb",
--                                                                                              "request-header:\n",
--                                                                                              con->request.request);
--                                                                      }
--                                                                      array_insert_unique(con->request.headers, (data_unset *)ds);
--                                                                      return 0;
--                                                              }
--                                                      } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("Host")))) {
--                                                              if (reqline_host) {
--                                                                      /* ignore all host: headers as we got the host in the request line */
--                                                                      ds->free((data_unset*) ds);
--                                                                      ds = NULL;
--                                                              } else if (!con->request.http_host) {
--                                                                      con->request.http_host = ds->value;
--                                                              } else {
--                                                                      con->http_status = 400;
--                                                                      con->keep_alive = 0;
--
--                                                                      if (srv->srvconf.log_request_header_on_error) {
--                                                                              log_error_write(srv, __FILE__, __LINE__, "s",
--                                                                                              "duplicate Host-header -> 400");
--                                                                              log_error_write(srv, __FILE__, __LINE__, "Sb",
--                                                                                              "request-header:\n",
--                                                                                              con->request.request);
--                                                                      }
--                                                                      array_insert_unique(con->request.headers, (data_unset *)ds);
--                                                                      return 0;
--                                                              }
--                                                      } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("If-Modified-Since")))) {
--                                                              /* Proxies sometimes send dup headers
--                                                               * if they are the same we ignore the second
--                                                               * if not, we raise an error */
--                                                              if (!con->request.http_if_modified_since) {
--                                                                      con->request.http_if_modified_since = ds->value->ptr;
--                                                              } else if (0 == strcasecmp(con->request.http_if_modified_since,
--                                                                                      ds->value->ptr)) {
--                                                                      /* ignore it if they are the same */
--
--                                                                      ds->free((data_unset *)ds);
--                                                                      ds = NULL;
--                                                              } else {
--                                                                      con->http_status = 400;
--                                                                      con->keep_alive = 0;
--
--                                                                      if (srv->srvconf.log_request_header_on_error) {
--                                                                              log_error_write(srv, __FILE__, __LINE__, "s",
--                                                                                              "duplicate If-Modified-Since header -> 400");
--                                                                              log_error_write(srv, __FILE__, __LINE__, "Sb",
--                                                                                              "request-header:\n",
--                                                                                              con->request.request);
--                                                                      }
--                                                                      array_insert_unique(con->request.headers, (data_unset *)ds);
--                                                                      return 0;
--                                                              }
--                                                      } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("If-None-Match")))) {
--                                                              /* if dup, only the first one will survive */
--                                                              if (!con->request.http_if_none_match) {
--                                                                      con->request.http_if_none_match = ds->value->ptr;
--                                                              } else {
--                                                                      ds->free((data_unset*) ds);
--                                                                      ds = NULL;
--                                                              }
-+                                              /* process previous header */
-+                                              if (current_header) {
-+                                                      data_string *ds = current_header;
-+                                                      current_header = NULL;
-+                                                      if (!parse_single_header(srv, con, &state, ds)) {
-+                                                              /* parse_single_header should already have logged it */
-+                                                              goto failure;
-                                                       }
-+                                              }
--                                                      if (ds) array_insert_unique(con->request.headers, (data_unset *)ds);
--                                              } else {
--                                                      /* empty header-fields are not allowed by HTTP-RFC, we just ignore them */
-+                                              key = con->parse_request->ptr + first;
-+
-+                                              if (NULL == (current_header = (data_string *)array_get_unused_element(con->request.headers, TYPE_STRING))) {
-+                                                      current_header = data_string_init();
-                                               }
-+
-+                                              buffer_copy_string_len(current_header->key, key, key_len);
-+                                              buffer_copy_string_len(current_header->value, value, value_len);
-                                       }
-                                       first = i+1;
-                                       is_key = 1;
-                                       value = NULL;
--#if 0
--                                      /**
--                                       * for Bug 1230 keep the key_len a live
--                                       */
-                                       key_len = 0; 
--#endif
-                                       in_folding = 0;
-                               } else {
-                                       if (srv->srvconf.log_request_header_on_error) {
-@@ -1142,10 +1100,7 @@ int http_request_parse(server *srv, connection *con) {
-                                                               "CR without LF", con->request.request, "-> 400");
-                                       }
--                                      con->http_status = 400;
--                                      con->keep_alive = 0;
--                                      con->response.keep_alive = 0;
--                                      return 0;
-+                                      goto failure;
-                               }
-                               break;
-                       case ' ':
-@@ -1160,22 +1115,29 @@ int http_request_parse(server *srv, connection *con) {
-                                                               "invalid char in header", (int)*cur, "-> 400");
-                                       }
--                                      con->http_status = 400;
--                                      con->keep_alive = 0;
--
--                                      return 0;
-+                                      goto failure;
-                               }
-                               break;
-                       }
-               }
-       }
-+      /* process last header */
-+      if (current_header) {
-+              data_string* ds = current_header;
-+              current_header = NULL;
-+              if (!parse_single_header(srv, con, &state, ds)) {
-+                      /* parse_single_header should already have logged it */
-+                      goto failure;
-+              }
-+      }
-+
-       con->header_len = i;
-       /* do some post-processing */
-       if (con->request.http_version == HTTP_VERSION_1_1) {
--              if (keep_alive_set != HTTP_CONNECTION_CLOSE) {
-+              if (state.keep_alive_set != HTTP_CONNECTION_CLOSE) {
-                       /* no Connection-Header sent */
-                       /* HTTP/1.1 -> keep-alive default TRUE */
-@@ -1187,9 +1149,6 @@ int http_request_parse(server *srv, connection *con) {
-               /* RFC 2616, 14.23 */
-               if (con->request.http_host == NULL ||
-                   buffer_string_is_empty(con->request.http_host)) {
--                      con->http_status = 400;
--                      con->response.keep_alive = 0;
--                      con->keep_alive = 0;
-                       if (srv->srvconf.log_request_header_on_error) {
-                               log_error_write(srv, __FILE__, __LINE__, "s", "HTTP/1.1 but Host missing -> 400");
-@@ -1197,10 +1156,10 @@ int http_request_parse(server *srv, connection *con) {
-                                               "request-header:\n",
-                                               con->request.request);
-                       }
--                      return 0;
-+                      goto failure;
-               }
-       } else {
--              if (keep_alive_set == HTTP_CONNECTION_KEEPALIVE) {
-+              if (state.keep_alive_set == HTTP_CONNECTION_KEEPALIVE) {
-                       /* no Connection-Header sent */
-                       /* HTTP/1.0 -> keep-alive default FALSE  */
-@@ -1222,11 +1181,7 @@ int http_request_parse(server *srv, connection *con) {
-                                       con->request.request);
-               }
--              con->http_status = 400;
--              con->response.keep_alive = 0;
--              con->keep_alive = 0;
--
--              return 0;
-+              goto failure;
-       }
-       {
-@@ -1235,24 +1190,21 @@ int http_request_parse(server *srv, connection *con) {
-                       if (con->request.http_version == HTTP_VERSION_1_0) {
-                               log_error_write(srv, __FILE__, __LINE__, "s",
-                                               "HTTP/1.0 with Transfer-Encoding (bad HTTP/1.0 proxy?) -> 400");
--                              con->keep_alive = 0;
--                              con->http_status = 400; /* Bad Request */
--                              return 0;
-+                              goto failure;
-                       }
-                       if (0 != strcasecmp(ds->value->ptr, "chunked")) {
-                               /* Transfer-Encoding might contain additional encodings,
-                                * which are not currently supported by lighttpd */
--                              con->keep_alive = 0;
-                               con->http_status = 501; /* Not Implemented */
--                              return 0;
-+                              goto failure;
-                       }
-                       /* reset value for Transfer-Encoding, a hop-by-hop header,
-                        * which must not be blindly forwarded to backends */
-                       buffer_reset(ds->value); /* headers with empty values are ignored */
--                      con_length_set = 1;
-+                      state.con_length_set = 1;
-                       con->request.content_length = -1;
-                       /*(note: ignore whether or not Content-Length was provided)*/
-@@ -1265,27 +1217,23 @@ int http_request_parse(server *srv, connection *con) {
-       case HTTP_METHOD_GET:
-       case HTTP_METHOD_HEAD:
-               /* content-length is forbidden for those */
--              if (con_length_set && con->request.content_length != 0) {
-+              if (state.con_length_set && con->request.content_length != 0) {
-                       /* content-length is missing */
-                       log_error_write(srv, __FILE__, __LINE__, "s",
-                                       "GET/HEAD with content-length -> 400");
--                      con->keep_alive = 0;
--                      con->http_status = 400;
--                      return 0;
-+                      goto failure;
-               }
-               break;
-       case HTTP_METHOD_POST:
-               /* content-length is required for them */
--              if (!con_length_set) {
-+              if (!state.con_length_set) {
-                       /* content-length is missing */
-                       log_error_write(srv, __FILE__, __LINE__, "s",
-                                       "POST-request, but content-length missing -> 411");
--                      con->keep_alive = 0;
-                       con->http_status = 411;
--                      return 0;
--
-+                      goto failure;
-               }
-               break;
-       default:
-@@ -1294,12 +1242,21 @@ int http_request_parse(server *srv, connection *con) {
-       /* check if we have read post data */
--      if (con_length_set) {
-+      if (state.con_length_set) {
-               /* we have content */
-               if (con->request.content_length != 0) {
-                       return 1;
-               }
-       }
-+      return 0;
-+
-+failure:
-+      if (current_header) current_header->free((data_unset *)current_header);
-+
-+      con->keep_alive = 0;
-+      con->response.keep_alive = 0;
-+      if (!con->http_status) con->http_status = 400;
-+
-       return 0;
- }
index fb659bd64bf361146a284cd7d755ce74040fee02..ed41295e8c3b99957c298117bd453b7616ed2202 100644 (file)
 Summary:       Fast and light HTTP server
 Summary(pl.UTF-8):     Szybki i lekki serwer HTTP
 Name:          lighttpd
-Version:       1.4.50
-Release:       5
+Version:       1.4.51
+Release:       1
 License:       BSD
 Group:         Networking/Daemons/HTTP
 Source0:       https://download.lighttpd.net/lighttpd/releases-1.4.x/%{name}-%{version}.tar.xz
-# Source0-md5: 0547831efda8492648b7f0c652865dfd
+# Source0-md5: 6e68c19601af332fa3c5f174245f59bf
 Source1:       %{name}.init
 Source2:       %{name}.conf
 Source3:       %{name}.user
@@ -120,7 +120,6 @@ Patch2:             %{name}-mod_h264_streaming.patch
 Patch3:                %{name}-branding.patch
 Patch4:                systemd.patch
 Patch5:                test-port-setup.patch
-Patch6:                a9e131..df8e4f.patch
 URL:           https://www.lighttpd.net/
 %{?with_geoip:BuildRequires:   GeoIP-devel}
 %{?with_xattr:BuildRequires:   attr-devel}
@@ -953,7 +952,6 @@ Plik monitrc do monitorowania serwera www lighttpd.
 %patch3 -p1
 %patch4 -p1
 %patch5 -p1
-%patch6 -p1
 
 rm -f src/mod_ssi_exprparser.h # bad patching: should be removed by is emptied instead
 
This page took 0.083911 seconds and 4 git commands to generate.