Subject: lws_stats: fix compile error on VS2013
[platform/upstream/libwebsockets.git] / lib / hpack.c
index ba69374..a205cbc 100644 (file)
@@ -199,18 +199,22 @@ static int lws_frag_start(struct lws *wsi, int hdr_token_idx)
 {
        struct allocated_headers * ah = wsi->u.http2.http.ah;
 
-       if (!hdr_token_idx)
+       if (!hdr_token_idx) {
+               lwsl_err("%s: zero hdr_token_idx\n", __func__);
                return 1;
-       
-       if (ah->next_frag_index >= ARRAY_SIZE(ah->frag_index))
+       }
+
+       if (ah->nfrag >= ARRAY_SIZE(ah->frag_index)) {
+               lwsl_err("%s: frag index %d too big\n", __func__, ah->nfrag);
                return 1;
-       
-       ah->frags[ah->next_frag_index].offset = ah->pos;
-       ah->frags[ah->next_frag_index].len = 0;
-       ah->frags[ah->next_frag_index].next_frag_index = 0;
+       }
+
+       ah->frags[ah->nfrag].offset = ah->pos;
+       ah->frags[ah->nfrag].len = 0;
+       ah->frags[ah->nfrag].nfrag = 0;
+
+       ah->frag_index[hdr_token_idx] = ah->nfrag;
 
-       ah->frag_index[hdr_token_idx] = ah->next_frag_index;
-       
        return 0;
 }
 
@@ -219,9 +223,9 @@ static int lws_frag_append(struct lws *wsi, unsigned char c)
        struct allocated_headers * ah = wsi->u.http2.http.ah;
 
        ah->data[ah->pos++] = c;
-       ah->frags[ah->next_frag_index].len++;
-       
-       return ah->pos >= sizeof(ah->data);
+       ah->frags[ah->nfrag].len++;
+
+       return ah->pos >= wsi->context->max_http_header_data;
 }
 
 static int lws_frag_end(struct lws *wsi)
@@ -229,7 +233,7 @@ static int lws_frag_end(struct lws *wsi)
        if (lws_frag_append(wsi, 0))
                return 1;
 
-       wsi->u.http2.http.ah->next_frag_index++;
+       wsi->u.http2.http.ah->nfrag++;
        return 0;
 }
 
@@ -245,11 +249,11 @@ static int
 lws_token_from_index(struct lws *wsi, int index, char **arg, int *len)
 {
        struct hpack_dynamic_table *dyn;
-       
+
        /* dynamic table only belongs to network wsi */
-       
+
        wsi = lws_http2_get_network_wsi(wsi);
-       
+
        dyn = wsi->u.http2.hpack_dyn_table;
 
        if (index < ARRAY_SIZE(static_token))
@@ -257,16 +261,16 @@ lws_token_from_index(struct lws *wsi, int index, char **arg, int *len)
 
        if (!dyn)
                return 0;
-       
+
        index -= ARRAY_SIZE(static_token);
        if (index >= dyn->num_entries)
                return 0;
-       
+
        if (arg && len) {
                *arg = dyn->args + dyn->entries[index].arg_offset;
                *len = dyn->entries[index].arg_len;
        }
-       
+
        return dyn->entries[index].token;
 }
 
@@ -275,7 +279,7 @@ lws_hpack_add_dynamic_header(struct lws *wsi, int token, char *arg, int len)
 {
        struct hpack_dynamic_table *dyn;
        int ret = 1;
-       
+
        wsi = lws_http2_get_network_wsi(wsi);
        dyn = wsi->u.http2.hpack_dyn_table;
 
@@ -284,7 +288,7 @@ lws_hpack_add_dynamic_header(struct lws *wsi, int token, char *arg, int len)
                if (!dyn)
                        return 1;
                wsi->u.http2.hpack_dyn_table = dyn;
-               
+
                dyn->args = lws_malloc(1024);
                if (!dyn->args)
                        goto bail1;
@@ -294,25 +298,25 @@ lws_hpack_add_dynamic_header(struct lws *wsi, int token, char *arg, int len)
                        goto bail2;
                dyn->num_entries = 20;
        }
-       
+
        if (dyn->next == dyn->num_entries)
                return 1;
-       
+
        if (dyn->args_length - dyn->pos < len)
                return 1;
-       
+
        dyn->entries[dyn->next].token = token;
        dyn->entries[dyn->next].arg_offset = dyn->pos;
        if (len)
                memcpy(dyn->args + dyn->pos, arg, len);
        dyn->entries[dyn->next].arg_len = len;
-       
+
        lwsl_info("%s: added dynamic hdr %d, token %d (%s), len %d\n",
                  __func__, dyn->next, token, lws_token_to_string(token), len);
-       
+
        dyn->pos += len;
        dyn->next++;
-       
+
        return 0;
 
 bail2:
@@ -343,19 +347,20 @@ static int lws_write_indexed_hdr(struct lws *wsi, int idx)
        }
        if (lws_frag_end(wsi))
                return 1;
-       
+
        lws_dump_header(wsi, tok);
 
        return 0;
 }
 
-int lws_hpack_interpret(struct lws_context *context,
-                       struct lws *wsi, unsigned char c)
+int lws_hpack_interpret(struct lws *wsi, unsigned char c)
 {
        unsigned int prev;
        unsigned char c1;
        int n;
 
+       lwsl_debug("   state %d\n", wsi->u.http2.hpack);
+
        switch (wsi->u.http2.hpack) {
        case HPKS_OPT_PADDING:
                wsi->u.http2.padding = c;
@@ -378,17 +383,18 @@ int lws_hpack_interpret(struct lws_context *context,
                /* weight */
                wsi->u.http2.hpack = HPKS_TYPE;
                break;
-                       
+
        case HPKS_TYPE:
-               
+
                if (wsi->u.http2.count > (wsi->u.http2.length - wsi->u.http2.padding)) {
                        lwsl_info("padding eat\n");
                        break;
                }
-               
+
                if (c & 0x80) { /* indexed header field only */
                        /* just a possibly-extended integer */
                        wsi->u.http2.hpack_type = HPKT_INDEXED_HDR_7;
+                       lwsl_debug("HKPS_TYPE setting header_index %d\n", c & 0x7f);
                        wsi->u.http2.header_index = c & 0x7f;
                        if ((c & 0x7f) == 0x7f) {
                                wsi->u.http2.hpack_len = c & 0x7f;
@@ -396,6 +402,7 @@ int lws_hpack_interpret(struct lws_context *context,
                                wsi->u.http2.hpack = HPKS_IDX_EXT;
                                break;
                        }
+                       lwsl_debug("HKPS_TYPE: %d\n", c & 0x7f);
                        if (lws_write_indexed_hdr(wsi, c & 0x7f))
                                return 1;
                        /* stay at same state */
@@ -407,6 +414,7 @@ int lws_hpack_interpret(struct lws_context *context,
                         * H + possibly-extended value length
                         * literal value
                         */
+                       lwsl_debug("HKPS_TYPE 2 setting header_index %d\n", 0);
                        wsi->u.http2.header_index = 0;
                        if (c == 0x40) { /* literal name */
                                wsi->u.http2.hpack_type = HPKT_LITERAL_HDR_VALUE_INCR;
@@ -422,6 +430,7 @@ int lws_hpack_interpret(struct lws_context *context,
                                wsi->u.http2.hpack = HPKS_IDX_EXT;
                                break;
                        }
+                       lwsl_debug("HKPS_TYPE 3 setting header_index %d\n", c & 0x3f);
                        wsi->u.http2.header_index = c & 0x3f;
                        wsi->u.http2.value = 1;
                        wsi->u.http2.hpack = HPKS_HLEN;
@@ -430,7 +439,7 @@ int lws_hpack_interpret(struct lws_context *context,
                switch(c & 0xf0) {
                case 0x10: /* literal header never index */
                case 0: /* literal header without indexing */
-                       /* 
+                       /*
                         * follows 0x40 except 4-bit hdr idx
                         * and don't add to index
                         */
@@ -440,6 +449,7 @@ int lws_hpack_interpret(struct lws_context *context,
                                wsi->u.http2.value = 0;
                                break;
                        }
+                       //lwsl_debug("indexed\n");
                        /* indexed name */
                        wsi->u.http2.hpack_type = HPKT_INDEXED_HDR_4_VALUE;
                        wsi->u.http2.header_index = 0;
@@ -449,6 +459,7 @@ int lws_hpack_interpret(struct lws_context *context,
                                wsi->u.http2.hpack = HPKS_IDX_EXT;
                                break;
                        }
+                       //lwsl_err("HKPS_TYPE 5 setting header_index %d\n", c & 0xf);
                        wsi->u.http2.header_index = c & 0xf;
                        wsi->u.http2.value = 1;
                        wsi->u.http2.hpack = HPKS_HLEN;
@@ -469,18 +480,21 @@ int lws_hpack_interpret(struct lws_context *context,
                        break;
                }
                break;
-               
+
        case HPKS_IDX_EXT:
                wsi->u.http2.hpack_len += (c & 0x7f) << wsi->u.http2.hpack_m;
                wsi->u.http2.hpack_m += 7;
                if (!(c & 0x80)) {
                        switch (wsi->u.http2.hpack_type) {
                        case HPKT_INDEXED_HDR_7:
+                               //lwsl_err("HKPS_IDX_EXT hdr idx %d\n", wsi->u.http2.hpack_len);
                                if (lws_write_indexed_hdr(wsi, wsi->u.http2.hpack_len))
                                        return 1;
                                wsi->u.http2.hpack = HPKS_TYPE;
                                break;
                        default:
+                               // lwsl_err("HKPS_IDX_EXT setting header_index %d\n",
+                               //              wsi->u.http2.hpack_len);
                                wsi->u.http2.header_index = wsi->u.http2.hpack_len;
                                wsi->u.http2.value = 1;
                                wsi->u.http2.hpack = HPKS_HLEN;
@@ -496,10 +510,13 @@ int lws_hpack_interpret(struct lws_context *context,
                if (wsi->u.http2.hpack_len < 0x7f) {
 pre_data:
                        if (wsi->u.http2.value) {
+                               if (wsi->u.http2.header_index)
                                if (lws_frag_start(wsi, lws_token_from_index(wsi,
                                                   wsi->u.http2.header_index,
-                                                  NULL, NULL)))
+                                                  NULL, NULL))) {
+                               //      lwsl_notice("%s: hlen failed\n", __func__);
                                        return 1;
+                               }
                        } else
                                wsi->u.hdr.parser_state = WSI_TOKEN_NAME_PART;
                        wsi->u.http2.hpack = HPKS_DATA;
@@ -508,7 +525,7 @@ pre_data:
                wsi->u.http2.hpack_m = 0;
                wsi->u.http2.hpack = HPKS_HLEN_EXT;
                break;
-               
+
        case HPKS_HLEN_EXT:
                wsi->u.http2.hpack_len += (c & 0x7f) <<
                                        wsi->u.http2.hpack_m;
@@ -532,7 +549,7 @@ pre_data:
                                        continue;
                                c1 = wsi->u.http2.hpack_pos & 0x7fff;
                                wsi->u.http2.hpack_pos = 0;
-       
+
                                if (!c1 && prev == HUFTABLE_0x100_PREV)
                                        ; /* EOT */
                        } else {
@@ -540,16 +557,17 @@ pre_data:
                                c1 = c;
                        }
                        if (wsi->u.http2.value) { /* value */
-                               if (lws_frag_append(wsi, c1))
-                                       return 1;
+                               if (wsi->u.http2.header_index)
+                                       if (lws_frag_append(wsi, c1))
+                                               return 1;
                        } else { /* name */
-                               if (lws_parse(context, wsi, c1))
+                               if (lws_parse(wsi, c1))
                                        return 1;
-                               
+
                        }
                }
                if (--wsi->u.http2.hpack_len == 0) {
-                       
+
                        switch (wsi->u.http2.hpack_type) {
                        case HPKT_LITERAL_HDR_VALUE_INCR:
                        case HPKT_INDEXED_HDR_6_VALUE_INCR: // !!!
@@ -562,12 +580,12 @@ pre_data:
                        default:
                                break;
                        }
-                       
+
                        n = 8;
                        if (wsi->u.http2.value) {
                                if (lws_frag_end(wsi))
                                        return 1;
-
+                               // lwsl_err("data\n");
                                lws_dump_header(wsi, lws_token_from_index(
                                                wsi, wsi->u.http2.header_index,
                                                NULL, NULL));
@@ -577,8 +595,8 @@ pre_data:
                                else
                                        wsi->u.http2.hpack = HPKS_TYPE;
                        } else { /* name */
-                               if (wsi->u.hdr.parser_state < WSI_TOKEN_COUNT)
-                                       
+                               //if (wsi->u.hdr.parser_state < WSI_TOKEN_COUNT)
+
                                wsi->u.http2.value = 1;
                                wsi->u.http2.hpack = HPKS_HLEN;
                        }
@@ -590,7 +608,7 @@ pre_data:
                        wsi->u.http2.hpack = HPKS_TYPE;
                break;
        }
-       
+
        return 0;
 }
 
@@ -603,11 +621,11 @@ static int lws_http2_num(int starting_bits, unsigned long num,
                *((*p)++) |= num;
                return *p >= end;
        }
-       
+
        *((*p)++) |= mask;
        if (*p >= end)
                return 1;
-       
+
        num -= mask;
        while (num >= 128) {
                *((*p)++) = 0x80 | (num & 0x7f);
@@ -615,19 +633,19 @@ static int lws_http2_num(int starting_bits, unsigned long num,
                        return 1;
                num >>= 7;
        }
-       
+
        return 0;
 }
 
-int lws_add_http2_header_by_name(struct lws_context *context, struct lws *wsi,
+int lws_add_http2_header_by_name(struct lws *wsi,
                                 const unsigned char *name,
                                 const unsigned char *value, int length,
                                 unsigned char **p, unsigned char *end)
 {
        int len;
-       
+
        lwsl_info("%s: %p  %s:%s\n", __func__, *p, name, value);
-       
+
        len = strlen((char *)name);
        if (len)
                if (name[len - 1] == ':')
@@ -647,15 +665,14 @@ int lws_add_http2_header_by_name(struct lws_context *context, struct lws *wsi,
        *(*p) = 0; /* non-HUF */
        if (lws_http2_num(7, length, p, end))
                return 1;
-       
+
        memcpy(*p, value, length);
        *p += length;
-       
+
        return 0;
 }
 
-int lws_add_http2_header_by_token(struct lws_context *context, struct lws *wsi,
-                                 enum lws_token_indexes token,
+int lws_add_http2_header_by_token(struct lws *wsi, enum lws_token_indexes token,
                                  const unsigned char *value, int length,
                                  unsigned char **p, unsigned char *end)
 {
@@ -664,24 +681,23 @@ int lws_add_http2_header_by_token(struct lws_context *context, struct lws *wsi,
        name = lws_token_to_string(token);
        if (!name)
                return 1;
-       
-       return lws_add_http2_header_by_name(context, wsi, name, value,
-                                           length, p, end);
+
+       return lws_add_http2_header_by_name(wsi, name, value, length, p, end);
 }
 
-int lws_add_http2_header_status(struct lws_context *context, struct lws *wsi,
+int lws_add_http2_header_status(struct lws *wsi,
                                unsigned int code, unsigned char **p,
                                unsigned char *end)
 {
        unsigned char status[10];
        int n;
-       
+
        wsi->u.http2.send_END_STREAM = !!(code >= 400);
-       
+
        n = sprintf((char *)status, "%u", code);
-       if (lws_add_http2_header_by_token(context, wsi,
-                                         WSI_TOKEN_HTTP_COLON_STATUS, status,
-                                         n, p, end))
+       if (lws_add_http2_header_by_token(wsi, WSI_TOKEN_HTTP_COLON_STATUS,
+                                         status, n, p, end))
+
                return 1;
 
        return 0;