struct http_hdr *hdr, unsigned int hdr_num,
struct h1m *h1m, union h1_sl *slp);
-int h1_parse_cont_len_header(struct h1m *h1m, struct ist *value);
int h1_parse_xfer_enc_header(struct h1m *h1m, struct ist value);
void h1_parse_connection_header(struct h1m *h1m, struct ist *value);
void h1_parse_upgrade_header(struct h1m *h1m, struct ist value);
*/
int h1_do_not_close_on_insecure_t_e = 0;
-/* Parse the Content-Length header field of an HTTP/1 request. The function
- * checks all possible occurrences of a comma-delimited value, and verifies
- * if any of them doesn't match a previous value. It returns <0 if a value
- * differs, 0 if the whole header can be dropped (i.e. already known), or >0
- * if the value can be indexed (first one). In the last case, the value might
- * be adjusted and the caller must only add the updated value.
- */
-int h1_parse_cont_len_header(struct h1m *h1m, struct ist *value)
-{
- char *e, *n;
- long long cl;
- int not_first = !!(h1m->flags & H1_MF_CLEN);
- struct ist word;
-
- word.ptr = value->ptr;
- e = value->ptr + value->len;
-
- while (1) {
- if (word.ptr >= e) {
- /* empty header or empty value */
- goto fail;
- }
-
- /* skip leading delimiter and blanks */
- if (unlikely(HTTP_IS_LWS(*word.ptr))) {
- word.ptr++;
- continue;
- }
-
- /* digits only now */
- for (cl = 0, n = word.ptr; n < e; n++) {
- unsigned int c = *n - '0';
- if (unlikely(c > 9)) {
- /* non-digit */
- if (unlikely(n == word.ptr)) // spaces only
- goto fail;
- break;
- }
-
- if (unlikely(!cl && n > word.ptr)) {
- /* There was a leading zero before this digit,
- * let's trim it.
- */
- word.ptr = n;
- }
-
- if (unlikely(cl > ULLONG_MAX / 10ULL))
- goto fail; /* multiply overflow */
- cl = cl * 10ULL;
- if (unlikely(cl + c < cl))
- goto fail; /* addition overflow */
- cl = cl + c;
- }
-
- /* keep a copy of the exact cleaned value */
- word.len = n - word.ptr;
-
- /* skip trailing LWS till next comma or EOL */
- for (; n < e; n++) {
- if (!HTTP_IS_LWS(*n)) {
- if (unlikely(*n != ','))
- goto fail;
- break;
- }
- }
-
- /* if duplicate, must be equal */
- if (h1m->flags & H1_MF_CLEN && cl != h1m->body_len)
- goto fail;
-
- /* OK, store this result as the one to be indexed */
- h1m->flags |= H1_MF_CLEN;
- h1m->curr_len = h1m->body_len = cl;
- *value = word;
-
- /* Now either n==e and we're done, or n points to the comma,
- * and we skip it and continue.
- */
- if (n++ == e)
- break;
-
- word.ptr = n;
- }
- /* here we've reached the end with a single value or a series of
- * identical values, all matching previous series if any. The last
- * parsed value was sent back into <value>. We just have to decide
- * if this occurrence has to be indexed (it's the first one) or
- * silently skipped (it's not the first one)
- */
- return !not_first;
- fail:
- return -1;
-}
-
/* Parse the Transfer-Encoding: header field of an HTTP/1 request, looking for
* "chunked" encoding to perform some checks (it must be the last encoding for
* the request and must not be performed twice for any message). The