diff --git a/CMakeLists.txt b/CMakeLists.txt index 59d6c3ad..f7fc82bf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -296,6 +296,7 @@ endif() if (LWS_WITH_HTTP2) list(APPEND SOURCES lib/http2.c + lib/hpack.c lib/ssl-http2.c ) endif() diff --git a/lib/hpack.c b/lib/hpack.c index 0d198155..1bda8104 100644 --- a/lib/hpack.c +++ b/lib/hpack.c @@ -1,3 +1,26 @@ +/* + * lib/hpack.c + * + * Copyright (C) 2014 Andy Green + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation: + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "private-libwebsockets.h" + /* * Official static header table for HPACK * +-------+-----------------------------+---------------+ @@ -104,7 +127,7 @@ static const unsigned char static_token[] = { WSI_TOKEN_HTTP_EXPECT, WSI_TOKEN_HTTP_EXPIRES, WSI_TOKEN_HTTP_FROM, - WSI_TOKEN_HTTP_HOST, + WSI_TOKEN_HOST, WSI_TOKEN_HTTP_IF_MATCH, WSI_TOKEN_HTTP_IF_MODIFIED_SINCE, WSI_TOKEN_HTTP_IF_NONE_MATCH, @@ -130,6 +153,8 @@ static const unsigned char static_token[] = { WSI_TOKEN_HTTP_WWW_AUTHENTICATE, }; +/* some of the entries imply values as well as header names */ + static const char * const http2_canned[] = { "", "", @@ -142,7 +167,6 @@ static const char * const http2_canned[] = { "200", "204", "206", - "300", "304", "400", "404", @@ -151,9 +175,11 @@ static const char * const http2_canned[] = { "gzip, deflate" }; +/* see minihuf.c */ + #include "huftable.h" -int lextable_decode(int pos, char c) +static int huftable_decode(int pos, char c) { int q = pos + !!c; @@ -163,77 +189,282 @@ int lextable_decode(int pos, char c) return pos + (lextable[q] << 1); } -static int lws_add_header(int header, const char *payload, int len) +static int lws_hpack_update_table_size(struct libwebsocket *wsi, int idx) { - wsi->u.ah.frag_index[header] + lwsl_info("hpack set table size %d\n", idx); + return 0; } -int lws_hpack_interpret(struct libwebsocket *wsi, unsigned char c) +static int lws_frag_start(struct libwebsocket *wsi, int hdr_token_idx) { + struct allocated_headers * ah = wsi->u.http2.http.ah; + + if (!hdr_token_idx) + return 1; + + if (ah->next_frag_index >= ARRAY_SIZE(ah->frag_index)) + 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->frag_index[hdr_token_idx] = ah->next_frag_index; + + return 0; +} + +static int lws_frag_append(struct libwebsocket *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); +} + +static int lws_frag_end(struct libwebsocket *wsi) +{ + if (lws_frag_append(wsi, 0)) + return 1; + + wsi->u.http2.http.ah->next_frag_index++; + return 0; +} + +static void lws_dump_header(struct libwebsocket *wsi, int hdr) +{ + char s[200]; + int len = lws_hdr_copy(wsi, s, sizeof(s) - 1, hdr); + s[len] = '\0'; + lwsl_info(" hdr tok %d '%s'\n", hdr, s); +} + +static int lws_token_from_index(struct libwebsocket *wsi, int index) +{ + if (index < ARRAY_SIZE(static_token)) + return static_token[index]; + + // dynamic indexes + + return 0; +} + +static int lws_add_indexed_hdr(struct libwebsocket *wsi, int idx) +{ + const char *p; + int tok = lws_token_from_index(wsi, idx); + + lwsl_info("adding indexed hdr %d (tok %d)\n", idx, tok); + + if (lws_frag_start(wsi, tok)) + return 1; + + if (idx < ARRAY_SIZE(http2_canned)) { + p = http2_canned[idx]; + while (*p) + if (lws_frag_append(wsi, *p++)) + return 1; + } + if (lws_frag_end(wsi)) + return 1; + + lws_dump_header(wsi, tok); + + return 0; +} + +int lws_hpack_interpret(struct libwebsocket_context *context, + struct libwebsocket *wsi, unsigned char c) +{ + unsigned int prev; + unsigned char c1; + int n; + switch (wsi->u.http2.hpack) { case HPKS_TYPE: if (c & 0x80) { /* indexed header field only */ + /* just a possibly-extended integer */ + wsi->u.http2.hpack_type = HPKT_INDEXED_HDR_7; wsi->u.http2.header_index = c & 0x7f; + if ((c & 0x7f) == 0x7f) { + wsi->u.http2.hpack_len = c & 0x7f; + wsi->u.http2.hpack_m = 0; + wsi->u.http2.hpack = HPKS_IDX_EXT; + break; + } + if (lws_add_indexed_hdr(wsi, c & 0x7f)) + return 1; /* stay at same state */ break; } if (c & 0x40) { /* literal header incr idx */ + /* + * [possibly-extended hdr idx (6) | new literal hdr name] + * H + possibly-extended value length + * literal value + */ + wsi->u.http2.header_index = 0; if (c == 0x40) { /* literal name */ - wsi->u.http2.header_index = 0; - wsi->u.http2.hpack + wsi->u.http2.hpack_type = HPKT_LITERAL_HDR_VALUE_INCR; + wsi->u.http2.value = 0; wsi->u.http2.hpack = HPKS_HLEN; break; } /* indexed name */ + wsi->u.http2.hpack_type = HPKT_INDEXED_HDR_6_VALUE_INCR; + if ((c & 0x3f) == 0x3f) { + wsi->u.http2.hpack_len = c & 0x3f; + wsi->u.http2.hpack_m = 0; + wsi->u.http2.hpack = HPKS_IDX_EXT; + break; + } wsi->u.http2.header_index = c & 0x3f; + wsi->u.http2.value = 1; wsi->u.http2.hpack = HPKS_HLEN; break; } 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 + */ if (c == 0) { /* literal name */ - wsi->u.http2.hpack = HPKS_NAME_HLEN; + wsi->u.http2.hpack_type = HPKT_LITERAL_HDR_VALUE; + wsi->u.http2.hpack = HPKS_HLEN; + wsi->u.http2.value = 0; break; } /* indexed name */ - wsi->u.http2.header_index = c & 0xf; - wsi->u.http2.hpack = HPKS_VALUE_HLEN; - break; - case 0x10: /* literal header never indexed */ - if (c == 0x10) { /* literal name */ - wsi->u.http2.header_index = 0; - wsi->u.http2.hpack = HPKS_NAME_HLEN; + wsi->u.http2.hpack_type = HPKT_INDEXED_HDR_4_VALUE; + wsi->u.http2.header_index = 0; + if ((c & 0xf) == 0xf) { + wsi->u.http2.hpack_len = c & 0xf; + wsi->u.http2.hpack_m = 0; + wsi->u.http2.hpack = HPKS_IDX_EXT; break; } - /* indexed name */ wsi->u.http2.header_index = c & 0xf; - wsi->u.http2.hpack = HPKS_NAME_HLEN; + wsi->u.http2.value = 1; + wsi->u.http2.hpack = HPKS_HLEN; break; + case 0x20: case 0x30: /* header table size update */ - /* = c & 0x1f */ - /* stay at same state */ + /* possibly-extended size value (5) */ + wsi->u.http2.hpack_type = HPKT_SIZE_5; + if ((c & 0x1f) == 0x1f) { + wsi->u.http2.hpack_len = c & 0x1f; + wsi->u.http2.hpack_m = 0; + wsi->u.http2.hpack = HPKS_IDX_EXT; + break; + } + lws_hpack_update_table_size(wsi, c & 0x1f); + /* stay at HPKS_TYPE state */ break; } - break; - case HPKS_HLEN: + 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: + if (lws_add_indexed_hdr(wsi, wsi->u.http2.hpack_len)) + return 1; + wsi->u.http2.hpack = HPKS_TYPE; + break; + default: + wsi->u.http2.header_index = wsi->u.http2.hpack_len; + wsi->u.http2.value = 1; + wsi->u.http2.hpack = HPKS_HLEN; + break; + } + } + break; + + case HPKS_HLEN: /* [ H | 7+ ] */ wsi->u.http2.huff = !!(c & 0x80); + wsi->u.http2.hpack_pos = 0; wsi->u.http2.hpack_len = c & 0x7f; - if (wsi->u.http2.hpack_len < 127) { - wsi->u.http2.hpack = HPKS_NAME_DATA; + 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))) + return 1; + } else + wsi->u.hdr.parser_state = WSI_TOKEN_NAME_PART; + wsi->u.http2.hpack = HPKS_DATA; break; } wsi->u.http2.hpack_m = 0; - wsi->u.http2.hpack = HPKS_NAME_HLEN_EXT; + wsi->u.http2.hpack = HPKS_HLEN_EXT; break; + case HPKS_HLEN_EXT: - wsi->u.http2.hpack_len += (c & 0x7f) << wsi->u.http2.hpack_m; + wsi->u.http2.hpack_len += (c & 0x7f) << + wsi->u.http2.hpack_m; wsi->u.http2.hpack_m += 7; if (!(c & 0x80)) - wsi->u.http2.hpack = HPKS_NAME_DATA; + goto pre_data; + break; case HPKS_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, + (c >> 7) & 1); + c <<= 1; + if (wsi->u.http2.hpack_pos == 0xffff) + return 1; + if (!(wsi->u.http2.hpack_pos & 0x8000)) + continue; + c1 = wsi->u.http2.hpack_pos & 0x7fff; + wsi->u.http2.hpack_pos = 0; + + if (!c1 && prev == HUFTABLE_0x100_PREV) + ; /* EOT */ + } else { + n = 8; + c1 = c; + } + if (wsi->u.http2.value) { /* value */ + if (lws_frag_append(wsi, c1)) + return 1; + } else { /* name */ + if (libwebsocket_parse(context, wsi, c1)) + return 1; + + } + } + if (--wsi->u.http2.hpack_len == 0) { + 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)); + + wsi->u.http2.hpack = HPKS_TYPE; + } else { /* name */ + if (wsi->u.hdr.parser_state < WSI_TOKEN_COUNT) + + wsi->u.http2.value = 1; + wsi->u.http2.hpack = HPKS_HLEN; + } + } + break; } + + return 0; } diff --git a/lib/http2.c b/lib/http2.c index b9bed878..61d9d076 100644 --- a/lib/http2.c +++ b/lib/http2.c @@ -66,6 +66,7 @@ lws_create_server_child_wsi(struct libwebsocket_context *context, struct libwebs lws_http2_init(&wsi->u.http2.peer_settings); lws_http2_init(&wsi->u.http2.my_settings); wsi->u.http2.stream_id = sid; + wsi->u.http2.my_stream_id = sid; wsi->u.http2.parent_wsi = parent_wsi; wsi->u.http2.next_child_wsi = parent_wsi->u.http2.next_child_wsi; @@ -129,8 +130,12 @@ lws_http2_interpret_settings_payload(struct http2_settings *settings, unsigned c int lws_http2_frame_write(struct libwebsocket *wsi, int type, int flags, unsigned int sid, unsigned int len, unsigned char *buf) { + struct libwebsocket *wsi_eff = wsi; unsigned char *p = &buf[-LWS_HTTP2_FRAME_HEADER_LENGTH]; int n; + + while (wsi_eff->u.http2.parent_wsi) + wsi_eff = wsi_eff->u.http2.parent_wsi; *p++ = len >> 16; *p++ = len >> 8; @@ -142,10 +147,10 @@ int lws_http2_frame_write(struct libwebsocket *wsi, int type, int flags, unsigne *p++ = sid >> 8; *p++ = sid; - lwsl_info("%s: %p. type %d, flags 0x%x, sid=%d, len=%d\n", - __func__, wsi, type, flags, sid, len); + lwsl_info("%s: %p (eff %p). type %d, flags 0x%x, sid=%d, len=%d\n", + __func__, wsi, wsi_eff, type, flags, sid, len); - n = lws_issue_raw(wsi, &buf[-LWS_HTTP2_FRAME_HEADER_LENGTH], len + LWS_HTTP2_FRAME_HEADER_LENGTH); + n = lws_issue_raw(wsi_eff, &buf[-LWS_HTTP2_FRAME_HEADER_LENGTH], len + LWS_HTTP2_FRAME_HEADER_LENGTH); if (n >= LWS_HTTP2_FRAME_HEADER_LENGTH) return n - LWS_HTTP2_FRAME_HEADER_LENGTH; @@ -169,7 +174,8 @@ int lws_http2_parser(struct libwebsocket_context *context, struct libwebsocket *wsi, unsigned char c) { - struct libwebsocket *wsi_new; + int n; + //dstruct libwebsocket *wsi_new; switch (wsi->state) { case WSI_STATE_HTTP2_AWAIT_CLIENT_PREFACE: @@ -206,19 +212,31 @@ lws_http2_parser(struct libwebsocket_context *context, return 1; break; case LWS_HTTP2_FRAME_TYPE_HEADERS: - + if (lws_hpack_interpret(context, wsi->u.http2.stream_wsi, c)) + return 1; break; } wsi->u.http2.count++; - if (wsi->u.http2.count == wsi->u.http2.length) { - wsi->u.http2.frame_state = 0; - wsi->u.http2.count = 0; - /* set our initial window size */ - if (!wsi->u.http2.initialized) { - wsi->u.http2.tx_credit = wsi->u.http2.peer_settings.setting[LWS_HTTP2_SETTINGS__INITIAL_WINDOW_SIZE]; - lwsl_info("initial tx credit on master conn %p: %d\n", wsi, wsi->u.http2.tx_credit); - wsi->u.http2.initialized = 1; - } + if (wsi->u.http2.count != wsi->u.http2.length) + break; + + /* end of frame */ + + wsi->u.http2.frame_state = 0; + wsi->u.http2.count = 0; + /* set our initial window size */ + if (!wsi->u.http2.initialized) { + wsi->u.http2.tx_credit = wsi->u.http2.peer_settings.setting[LWS_HTTP2_SETTINGS__INITIAL_WINDOW_SIZE]; + lwsl_info("initial tx credit on master conn %p: %d\n", wsi, wsi->u.http2.tx_credit); + wsi->u.http2.initialized = 1; + } + switch (wsi->u.http2.type) { + case LWS_HTTP2_FRAME_TYPE_HEADERS: + /* service the http request itself */ + lwsl_info("servicing initial http request\n"); + n = lws_http_action(context, wsi->u.http2.stream_wsi); + lwsl_info(" action result %d\n", n); + break; } break; } @@ -264,6 +282,7 @@ lws_http2_parser(struct libwebsocket_context *context, } break; case LWS_HTTP2_FRAME_TYPE_HEADERS: + lwsl_info("LWS_HTTP2_FRAME_TYPE_HEADERS: stream_id = %d\n", wsi->u.http2.stream_id); if (!wsi->u.http2.stream_id) return 1; wsi->u.http2.stream_wsi = lws_http2_wsi_from_id(wsi, wsi->u.http2.stream_id); @@ -318,10 +337,6 @@ int lws_http2_do_pps_send(struct libwebsocket_context *context, struct libwebsoc wsi->state = WSI_STATE_HTTP2_ESTABLISHED; wsi->u.http.fd = LWS_INVALID_FILE; - - /* service the http request itself */ - //lwsl_info("servicing initial http request\n"); - //n = lws_http_action(context, wsi); return 0; } diff --git a/lib/huftable.h b/lib/huftable.h index b7eb426f..385a83be 100644 --- a/lib/huftable.h +++ b/lib/huftable.h @@ -525,3 +525,6 @@ static unsigned char lextable[] = { 0xcc, 0x30, 0xfc, 0xcf, 0x3c, 0xf0, 0x0c, 0xcf, 0xd0, 0x03, 0x3f, 0x33, 0xff, 0xff, 0xc3, 0xf3, }; + +/* state that points to 0x100 for disambiguation with 0x0 */ +#define HUFTABLE_0x100_PREV 118 diff --git a/lib/libwebsockets.h b/lib/libwebsockets.h index 84c1e955..50b8ff49 100644 --- a/lib/libwebsockets.h +++ b/lib/libwebsockets.h @@ -326,7 +326,18 @@ enum lws_token_indexes { WSI_TOKEN_KEY, WSI_TOKEN_VERSION, WSI_TOKEN_SWORIGIN, + + WSI_TOKEN_HTTP_URI_ARGS, + /* use token storage to stash these */ + + _WSI_TOKEN_CLIENT_SENT_PROTOCOLS, + _WSI_TOKEN_CLIENT_PEER_ADDRESS, + _WSI_TOKEN_CLIENT_URI, + _WSI_TOKEN_CLIENT_HOST, + _WSI_TOKEN_CLIENT_ORIGIN, + +#ifdef LWS_USE_HTTP2 WSI_TOKEN_HTTP_COLON_AUTHORITY, WSI_TOKEN_HTTP_COLON_METHOD, WSI_TOKEN_HTTP_COLON_PATH, @@ -366,17 +377,8 @@ enum lws_token_indexes { WSI_TOKEN_HTTP_VARY, WSI_TOKEN_HTTP_VIA, WSI_TOKEN_HTTP_WWW_AUTHENTICATE, +#endif - WSI_TOKEN_HTTP_URI_ARGS, - - /* use token storage to stash these */ - - _WSI_TOKEN_CLIENT_SENT_PROTOCOLS, - _WSI_TOKEN_CLIENT_PEER_ADDRESS, - _WSI_TOKEN_CLIENT_URI, - _WSI_TOKEN_CLIENT_HOST, - _WSI_TOKEN_CLIENT_ORIGIN, - /* always last real token index*/ WSI_TOKEN_COUNT, /* parser state additions */ diff --git a/lib/minihuf.c b/lib/minihuf.c index 9f7b970e..06d7b70f 100644 --- a/lib/minihuf.c +++ b/lib/minihuf.c @@ -482,6 +482,7 @@ again: fprintf(stderr, " trying %d\n", n); while (m < huf_literal[n].len) { + prev = walk; walk = lextable_decode(walk, code_bit(n, m)); if (walk == 0xffff) { @@ -491,8 +492,15 @@ again: if (walk & 0x8000) { y = walk & 0x7fff; - if (y == 0 && m == 29) + if (y == 0 && m == 29) { y |= 0x100; + fprintf(stdout, + "\n/* state that points to " + "0x100 for disambiguation with " + "0x0 */\n" + "#define HUFTABLE_0x100_PREV " + "%d\n", prev); + } break; } m++; diff --git a/lib/output.c b/lib/output.c index 40bb1435..be1e5445 100644 --- a/lib/output.c +++ b/lib/output.c @@ -434,10 +434,14 @@ send_raw: case LWS_WRITE_PING: #ifdef LWS_USE_HTTP2 if (wsi->mode == LWS_CONNMODE_HTTP2_SERVING) { + unsigned char flags = 0; + n = LWS_HTTP2_FRAME_TYPE_DATA; - if (protocol == LWS_WRITE_HTTP_HEADERS) + if (protocol == LWS_WRITE_HTTP_HEADERS) { n = LWS_HTTP2_FRAME_TYPE_HEADERS; - return lws_http2_frame_write(wsi, n, 0, wsi->u.http2.my_stream_id, len, buf); + flags = LWS_HTTP2_FLAGS__HEADER__END_HEADER; + } + return lws_http2_frame_write(wsi, n, flags, wsi->u.http2.my_stream_id, len, buf); } #endif return lws_issue_raw(wsi, (unsigned char *)buf - pre, diff --git a/lib/private-libwebsockets.h b/lib/private-libwebsockets.h index cac681b7..9d5f1b47 100755 --- a/lib/private-libwebsockets.h +++ b/lib/private-libwebsockets.h @@ -578,6 +578,7 @@ struct _lws_http_mode_related { int content_remain; }; + #ifdef LWS_USE_HTTP2 enum lws_http2_settings { @@ -610,6 +611,8 @@ enum lws_http2_wellknown_frame_types { #define LWS_HTTP2_FRAME_HEADER_LENGTH 9 #define LWS_HTTP2_SETTINGS_LENGTH 6 +#define LWS_HTTP2_FLAGS__HEADER__END_HEADER 4 + struct http2_settings { unsigned int setting[LWS_HTTP2_SETTINGS__COUNT]; }; @@ -617,12 +620,23 @@ struct http2_settings { enum http2_hpack_state { HPKS_TYPE, + HPKS_IDX_EXT, + HPKS_HLEN, HPKS_HLEN_EXT, HPKS_DATA, }; +enum http2_hpack_type { + HPKT_INDEXED_HDR_7, + HPKT_INDEXED_HDR_6_VALUE_INCR, + HPKT_LITERAL_HDR_VALUE_INCR, + HPKT_INDEXED_HDR_4_VALUE, + HPKT_LITERAL_HDR_VALUE, + HPKT_SIZE_5 +}; + struct _lws_http2_related { /* * having this first lets us also re-use all HTTP union code @@ -649,8 +663,10 @@ struct _lws_http2_related { /* hpack */ enum http2_hpack_state hpack; + enum http2_hpack_type hpack_type; unsigned int header_index; unsigned int hpack_len; + unsigned short hpack_pos; unsigned char hpack_m; unsigned int huff:1; unsigned int value:1; @@ -904,6 +920,9 @@ LWS_EXTERN int lws_http2_do_pps_send(struct libwebsocket_context *context, struc LWS_EXTERN int lws_http2_frame_write(struct libwebsocket *wsi, int type, int flags, unsigned int sid, unsigned int len, unsigned char *buf); LWS_EXTERN struct libwebsocket * lws_http2_wsi_from_id(struct libwebsocket *wsi, unsigned int sid); +LWS_EXTERN int lws_hpack_interpret(struct libwebsocket_context *context, + struct libwebsocket *wsi, + unsigned char c); #endif LWS_EXTERN int diff --git a/lib/server.c b/lib/server.c index 4d036a96..8563a43d 100644 --- a/lib/server.c +++ b/lib/server.c @@ -183,6 +183,9 @@ int lws_http_action(struct libwebsocket_context *context, if (!lws_hdr_total_length(wsi, WSI_TOKEN_GET_URI) && !lws_hdr_total_length(wsi, WSI_TOKEN_POST_URI) && +#ifdef LWS_USE_HTTP2 + !lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_COLON_PATH) && +#endif !lws_hdr_total_length(wsi, WSI_TOKEN_OPTIONS_URI)) { lwsl_warn("Missing URI in HTTP request\n"); goto bail_nuke_ah; @@ -197,25 +200,33 @@ int lws_http_action(struct libwebsocket_context *context, if (libwebsocket_ensure_user_space(wsi)) goto bail_nuke_ah; +#ifdef LWS_USE_HTTP2 + if (lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_COLON_PATH)) { + uri_ptr = lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_COLON_PATH); + uri_len = lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_COLON_PATH); + lwsl_info("HTTP2 request for '%s'\n", uri_ptr); + goto got_uri; + } +#endif + if (lws_hdr_total_length(wsi, WSI_TOKEN_OPTIONS_URI)) { + uri_ptr = lws_hdr_simple_ptr(wsi, WSI_TOKEN_OPTIONS_URI); + uri_len = lws_hdr_total_length(wsi, WSI_TOKEN_OPTIONS_URI); + lwsl_info("HTTP OPTIONS request for '%s'\n", uri_ptr); + goto got_uri; + } + if (lws_hdr_total_length(wsi, WSI_TOKEN_POST_URI)) { + uri_ptr = lws_hdr_simple_ptr(wsi, WSI_TOKEN_POST_URI); + uri_len = lws_hdr_total_length(wsi, WSI_TOKEN_POST_URI); + lwsl_info("HTTP POST request for '%s'\n", uri_ptr); + goto got_uri; + } if (lws_hdr_total_length(wsi, WSI_TOKEN_GET_URI)) { uri_ptr = lws_hdr_simple_ptr(wsi, WSI_TOKEN_GET_URI); uri_len = lws_hdr_total_length(wsi, WSI_TOKEN_GET_URI); - lwsl_info("HTTP GET request for '%s'\n", - lws_hdr_simple_ptr(wsi, WSI_TOKEN_GET_URI)); - } - if (lws_hdr_total_length(wsi, WSI_TOKEN_POST_URI)) { - lwsl_info("HTTP POST request for '%s'\n", - lws_hdr_simple_ptr(wsi, WSI_TOKEN_POST_URI)); - uri_ptr = lws_hdr_simple_ptr(wsi, WSI_TOKEN_POST_URI); - uri_len = lws_hdr_total_length(wsi, WSI_TOKEN_POST_URI); - } - if (lws_hdr_total_length(wsi, WSI_TOKEN_OPTIONS_URI)) { - lwsl_info("HTTP OPTIONS request for '%s'\n", - lws_hdr_simple_ptr(wsi, WSI_TOKEN_OPTIONS_URI)); - uri_ptr = lws_hdr_simple_ptr(wsi, WSI_TOKEN_OPTIONS_URI); - uri_len = lws_hdr_total_length(wsi, WSI_TOKEN_OPTIONS_URI); + lwsl_info("HTTP GET request for '%s'\n", uri_ptr); } +got_uri: /* HTTP header had a content length? */ wsi->u.http.content_length = 0; diff --git a/test-server/test-server.c b/test-server/test-server.c index b89d014d..24438d18 100644 --- a/test-server/test-server.c +++ b/test-server/test-server.c @@ -112,21 +112,16 @@ dump_handshake_info(struct libwebsocket *wsi) /*[WSI_TOKEN_OPTIONS_URI] =*/ "options uri", /*[WSI_TOKEN_HOST] =*/ "Host", /*[WSI_TOKEN_CONNECTION] =*/ "Connection", - /*[WSI_TOKEN_KEY1] =*/ "key 1", - /*[WSI_TOKEN_KEY2] =*/ "key 2", - /*[WSI_TOKEN_PROTOCOL] =*/ "Protocol", /*[WSI_TOKEN_UPGRADE] =*/ "Upgrade", /*[WSI_TOKEN_ORIGIN] =*/ "Origin", /*[WSI_TOKEN_DRAFT] =*/ "Draft", /*[WSI_TOKEN_CHALLENGE] =*/ "Challenge", - - /* new for 04 */ - /*[WSI_TOKEN_KEY] =*/ "Key", - /*[WSI_TOKEN_VERSION] =*/ "Version", - /*[WSI_TOKEN_SWORIGIN] =*/ "Sworigin", - /* new for 05 */ /*[WSI_TOKEN_EXTENSIONS] =*/ "Extensions", + /*[WSI_TOKEN_KEY1] =*/ "key 1", + /*[WSI_TOKEN_KEY2] =*/ "key 2", + + /*[WSI_TOKEN_PROTOCOL] =*/ "Protocol", /* client receives these */ /*[WSI_TOKEN_ACCEPT] =*/ "Accept", @@ -148,9 +143,12 @@ dump_handshake_info(struct libwebsocket *wsi) "Date:", "Range:", "Referer:", + /* new for 04 */ + /*[WSI_TOKEN_KEY] =*/ "Key", + /*[WSI_TOKEN_VERSION] =*/ "Version", + /*[WSI_TOKEN_SWORIGIN] =*/ "Sworigin", "Uri-Args:", - /*[WSI_TOKEN_MUXURL] =*/ "MuxURL", }; char buf[256];