if (LWS_WITH_HTTP2)
list(APPEND SOURCES
lib/http2.c
+ lib/hpack.c
lib/ssl-http2.c
)
endif()
/*
+ * lib/hpack.c
+ *
+ * Copyright (C) 2014 Andy Green <andy@warmcat.com>
+ *
+ * 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
* +-------+-----------------------------+---------------+
| 1 | :authority | |
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,
WSI_TOKEN_HTTP_WWW_AUTHENTICATE,
};
+/* some of the entries imply values as well as header names */
+
static const char * const http2_canned[] = {
"",
"",
"200",
"204",
"206",
- "300",
"304",
"400",
"404",
"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;
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;
}
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;
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;
*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;
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:
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;
}
}
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);
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;
}
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
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,
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 */
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) {
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++;
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,
int content_remain;
};
+
#ifdef LWS_USE_HTTP2
enum lws_http2_settings {
#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];
};
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
/* 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;
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
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;
if (libwebsocket_ensure_user_space(wsi))
goto bail_nuke_ah;
- 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));
+#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)) {
- 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);
+ lwsl_info("HTTP POST request for '%s'\n", uri_ptr);
+ goto got_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);
+ 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", uri_ptr);
}
+got_uri:
/* HTTP header had a content length? */
wsi->u.http.content_length = 0;
/*[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",
"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];