Subject: lws_stats: fix compile error on VS2013
[platform/upstream/libwebsockets.git] / lib / hpack.c
index 09c6e7b..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;
 }
 
@@ -241,14 +245,15 @@ static void lws_dump_header(struct lws *wsi, int hdr)
        lwsl_info("  hdr tok %d (%s) = '%s'\n", hdr, lws_token_to_string(hdr), s);
 }
 
-static int lws_token_from_index(struct lws *wsi, int index, char **arg, int *len)
+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))
@@ -256,24 +261,25 @@ static int 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;
 }
 
-static int lws_hpack_add_dynamic_header(struct lws *wsi, int token, char *arg, int len)
+static int
+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;
 
@@ -282,7 +288,7 @@ static int lws_hpack_add_dynamic_header(struct lws *wsi, int token, char *arg, i
                if (!dyn)
                        return 1;
                wsi->u.http2.hpack_dyn_table = dyn;
-               
+
                dyn->args = lws_malloc(1024);
                if (!dyn->args)
                        goto bail1;
@@ -292,24 +298,25 @@ static int lws_hpack_add_dynamic_header(struct lws *wsi, int token, char *arg, i
                        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);
-       
+
+       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:
@@ -326,7 +333,8 @@ static int lws_write_indexed_hdr(struct lws *wsi, int idx)
        const char *p;
        int tok = lws_token_from_index(wsi, idx, NULL, 0);
 
-       lwsl_info("writing indexed hdr %d (tok %d '%s')\n", idx, tok, lws_token_to_string(tok));
+       lwsl_info("writing indexed hdr %d (tok %d '%s')\n", idx, tok,
+                 lws_token_to_string(tok));
 
        if (lws_frag_start(wsi, tok))
                return 1;
@@ -339,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;
@@ -374,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;
@@ -392,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 */
@@ -403,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;
@@ -418,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;
@@ -426,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
                         */
@@ -436,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;
@@ -445,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;
@@ -465,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;
@@ -492,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 (lws_frag_start(wsi,
-                                       lws_token_from_index(wsi,
-                                               wsi->u.http2.header_index, NULL, NULL)))
+                               if (wsi->u.http2.header_index)
+                               if (lws_frag_start(wsi, lws_token_from_index(wsi,
+                                                  wsi->u.http2.header_index,
+                                                  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;
@@ -504,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;
@@ -518,10 +539,9 @@ pre_data:
                for (n = 0; n < 8; n++) {
                        if (wsi->u.http2.huff) {
                                prev = wsi->u.http2.hpack_pos;
-                               wsi->u.http2.hpack_pos = 
-                                       huftable_decode(
+                               wsi->u.http2.hpack_pos = huftable_decode(
                                                wsi->u.http2.hpack_pos,
-                                                       (c >> 7) & 1);
+                                               (c >> 7) & 1);
                                c <<= 1;
                                if (wsi->u.http2.hpack_pos == 0xffff)
                                        return 1;
@@ -529,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 {
@@ -537,39 +557,46 @@ 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: // !!!
-                               if (lws_hpack_add_dynamic_header(wsi, lws_token_from_index(wsi, wsi->u.http2.header_index, NULL, NULL), NULL, 0))
+                               if (lws_hpack_add_dynamic_header(wsi,
+                                    lws_token_from_index(wsi,
+                                                wsi->u.http2.header_index,
+                                                        NULL, NULL), NULL, 0))
                                        return 1;
                                break;
                        default:
                                break;
                        }
-                       
+
                        n = 8;
                        if (wsi->u.http2.value) {
                                if (lws_frag_end(wsi))
                                        return 1;
-
-                               lws_dump_header(wsi, lws_token_from_index(wsi, wsi->u.http2.header_index, NULL, NULL));
-                               if (wsi->u.http2.count + wsi->u.http2.padding == wsi->u.http2.length)
+                               // lwsl_err("data\n");
+                               lws_dump_header(wsi, lws_token_from_index(
+                                               wsi, wsi->u.http2.header_index,
+                                               NULL, NULL));
+                               if (wsi->u.http2.count + wsi->u.http2.padding ==
+                                   wsi->u.http2.length)
                                        wsi->u.http2.hpack = HKPS_OPT_DISCARD_PADDING;
                                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;
                        }
@@ -581,7 +608,7 @@ pre_data:
                        wsi->u.http2.hpack = HPKS_TYPE;
                break;
        }
-       
+
        return 0;
 }
 
@@ -594,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);
@@ -606,22 +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)
+                                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] == ':')
@@ -641,41 +665,39 @@ int lws_add_http2_header_by_name(struct lws_context *context,
        *(*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,
-                           const unsigned char *value, int length,
-                           unsigned char **p, unsigned char *end)
+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)
 {
        const unsigned char *name;
 
        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;