mirror of
https://github.com/warmcat/libwebsockets.git
synced 2025-03-09 00:00:04 +01:00
hpack: pseudoheader check improvement
This commit is contained in:
parent
6bc92f7592
commit
46ee0713de
5 changed files with 72 additions and 32 deletions
|
@ -1,5 +1,10 @@
|
|||
cmake_minimum_required(VERSION 2.8.9)
|
||||
|
||||
# General Advice
|
||||
#
|
||||
# For selecting between DEBUG / RELEASE, use -DCMAKE_BUILD_TYPE=DEBUG or =RELEASE
|
||||
# debug builds include source level debug info and extra logging
|
||||
|
||||
if(NOT DEFINED CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type")
|
||||
endif()
|
||||
|
|
|
@ -712,6 +712,38 @@ lws_hpack_use_idx_hdr(struct lws *wsi, int idx, int known_token)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static uint8_t lws_header_implies_psuedoheader_map[] = {
|
||||
0x07, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00 /* <-64 */,
|
||||
0x0e /* <- 72 */, 0x04 /* <- 80 */, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
static int
|
||||
lws_hpack_handle_pseudo_rules(struct lws *nwsi, struct lws *wsi, int m)
|
||||
{
|
||||
if (m == LWS_HPACK_IGNORE_ENTRY || m == -1)
|
||||
return 0;
|
||||
|
||||
if (wsi->seen_nonpseudoheader &&
|
||||
(lws_header_implies_psuedoheader_map[m >> 3] & (1 << (m & 7)))) {
|
||||
|
||||
lwsl_notice("lws tok %d seems to be a pseudoheader\n", m);
|
||||
|
||||
/*
|
||||
* it's not legal to see a
|
||||
* pseudoheader after normal
|
||||
* headers
|
||||
*/
|
||||
lws_h2_goaway(nwsi, H2_ERR_PROTOCOL_ERROR,
|
||||
"Pseudoheader after normal hdrs");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!(lws_header_implies_psuedoheader_map[m >> 3] & (1 << (m & 7))))
|
||||
wsi->seen_nonpseudoheader = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lws_hpack_interpret(struct lws *wsi, unsigned char c)
|
||||
{
|
||||
struct lws *nwsi = lws_get_network_wsi(wsi);
|
||||
|
@ -743,6 +775,7 @@ int lws_hpack_interpret(struct lws *wsi, unsigned char c)
|
|||
h2n->ext_count = 0;
|
||||
h2n->hpack_hdr_len = 0;
|
||||
h2n->unknown_header = 0;
|
||||
wsi->u.hdr.parser_state = 255;
|
||||
|
||||
if (c & 0x80) { /* 1.... indexed header field only */
|
||||
/* just a possibly-extended integer */
|
||||
|
@ -762,6 +795,12 @@ int lws_hpack_interpret(struct lws *wsi, unsigned char c)
|
|||
"hdr index 0 seen");
|
||||
return 1;
|
||||
}
|
||||
|
||||
m = lws_token_from_index(wsi, h2n->hdr_idx,
|
||||
NULL, NULL, NULL);
|
||||
if (lws_hpack_handle_pseudo_rules(nwsi, wsi, m))
|
||||
return 1;
|
||||
|
||||
lwsl_header("HPKT_INDEXED_HDR_7: hdr %d\n", c & 0x7f);
|
||||
if (lws_hpack_use_idx_hdr(wsi, c & 0x7f, -1)) {
|
||||
lwsl_header("%s: idx hdr wr fail\n", __func__);
|
||||
|
@ -1113,6 +1152,7 @@ swallow:
|
|||
wsi->u.hdr.parser_state == WSI_TOKEN_SKIPPING) {
|
||||
h2n->unknown_header = 1;
|
||||
wsi->u.hdr.parser_state = -1;
|
||||
wsi->seen_nonpseudoheader = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1132,6 +1172,7 @@ swallow:
|
|||
* we have got both the header and value
|
||||
*/
|
||||
|
||||
m = -1;
|
||||
switch (h2n->hpack_type) {
|
||||
/*
|
||||
* These are the only two that insert to the dyntable
|
||||
|
@ -1187,39 +1228,26 @@ add_it:
|
|||
if (h2n->hdr_idx != LWS_HPACK_IGNORE_ENTRY && lws_frag_end(wsi))
|
||||
return 1;
|
||||
|
||||
if (h2n->hpack_type == HPKT_LITERAL_HDR_VALUE ||
|
||||
h2n->hpack_type == HPKT_INDEXED_HDR_6_VALUE_INCR ||
|
||||
h2n->hpack_type == HPKT_LITERAL_HDR_VALUE_INCR ||
|
||||
h2n->hpack_type == HPKT_LITERAL_HDR_VALUE_NEVER) {
|
||||
m = wsi->u.hdr.parser_state;
|
||||
if (m == 255)
|
||||
m = -1;
|
||||
} else
|
||||
m = lws_token_from_index(wsi, h2n->hdr_idx, NULL, NULL,
|
||||
NULL);
|
||||
if (h2n->hpack_type != HPKT_INDEXED_HDR_6_VALUE_INCR) {
|
||||
|
||||
if (h2n->hpack_type == HPKT_LITERAL_HDR_VALUE ||
|
||||
h2n->hpack_type == HPKT_LITERAL_HDR_VALUE_INCR ||
|
||||
h2n->hpack_type == HPKT_LITERAL_HDR_VALUE_NEVER) {
|
||||
m = wsi->u.hdr.parser_state;
|
||||
if (m == 255)
|
||||
m = -1;
|
||||
} else {
|
||||
m = lws_token_from_index(wsi, h2n->hdr_idx, NULL, NULL,
|
||||
NULL);
|
||||
//lwsl_notice("token from index(%d) says %d\n", h2n->hdr_idx, m);
|
||||
}
|
||||
}
|
||||
|
||||
if (m != -1 && m != LWS_HPACK_IGNORE_ENTRY)
|
||||
lws_dump_header(wsi, m);
|
||||
|
||||
if (h2n->seen_nonpseudoheader && (
|
||||
m == WSI_TOKEN_HTTP_COLON_AUTHORITY ||
|
||||
m == WSI_TOKEN_HTTP_COLON_METHOD ||
|
||||
m == WSI_TOKEN_HTTP_COLON_PATH ||
|
||||
m == WSI_TOKEN_HTTP_COLON_SCHEME)) {
|
||||
/*
|
||||
* it's not legal to see a
|
||||
* pseudoheader after normal
|
||||
* headers
|
||||
*/
|
||||
lws_h2_goaway(nwsi, H2_ERR_PROTOCOL_ERROR,
|
||||
"Pseudoheader after normal hdrs");
|
||||
if (lws_hpack_handle_pseudo_rules(nwsi, wsi, m))
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (m != WSI_TOKEN_HTTP_COLON_AUTHORITY &&
|
||||
m != WSI_TOKEN_HTTP_COLON_METHOD &&
|
||||
m != WSI_TOKEN_HTTP_COLON_PATH &&
|
||||
m != WSI_TOKEN_HTTP_COLON_SCHEME)
|
||||
h2n->seen_nonpseudoheader = 1;
|
||||
|
||||
h2n->is_first_header_char = 1;
|
||||
h2n->hpack = HPKS_TYPE;
|
||||
|
@ -1229,6 +1257,8 @@ add_it:
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
lws_h2_num_start(int starting_bits, unsigned long num)
|
||||
{
|
||||
|
|
|
@ -170,6 +170,7 @@ lws_wsi_server_new(struct lws_vhost *vh, struct lws *parent_wsi,
|
|||
h2n->highest_sid_opened = sid;
|
||||
wsi->u.h2.my_sid = sid;
|
||||
wsi->http2_substream = 1;
|
||||
wsi->seen_nonpseudoheader = 0;
|
||||
|
||||
wsi->u.h2.parent_wsi = parent_wsi;
|
||||
/* new guy's sibling is whoever was the first child before */
|
||||
|
@ -1003,7 +1004,6 @@ lws_h2_parse_frame_header(struct lws *wsi)
|
|||
h2n->cont_exp = !(h2n->flags & LWS_H2_FLAG_END_HEADERS);
|
||||
h2n->cont_exp_sid = h2n->sid;
|
||||
h2n->cont_exp_headers = 1;
|
||||
h2n->seen_nonpseudoheader = 0;
|
||||
lws_header_table_reset(h2n->swsi, 0);
|
||||
|
||||
update_end_headers:
|
||||
|
|
|
@ -537,9 +537,14 @@ LWS_VISIBLE int
|
|||
lws_callback_on_writable_all_protocol(const struct lws_context *context,
|
||||
const struct lws_protocols *protocol)
|
||||
{
|
||||
struct lws_vhost *vhost = context->vhost_list;
|
||||
struct lws_vhost *vhost;
|
||||
int n;
|
||||
|
||||
if (!context)
|
||||
return 0;
|
||||
|
||||
vhost = context->vhost_list;
|
||||
|
||||
while (vhost) {
|
||||
for (n = 0; n < vhost->count_protocols; n++)
|
||||
if (protocol->callback ==
|
||||
|
|
|
@ -1681,7 +1681,6 @@ struct lws_h2_netconn {
|
|||
unsigned int pad_length:1;
|
||||
unsigned int collected_priority:1;
|
||||
unsigned int is_first_header_char:1;
|
||||
unsigned int seen_nonpseudoheader:1;
|
||||
unsigned int zero_huff_padding:1;
|
||||
unsigned int last_action_dyntable_resize:1;
|
||||
|
||||
|
@ -1970,6 +1969,7 @@ struct lws {
|
|||
unsigned int hdr_parsing_completed:1;
|
||||
unsigned int http2_substream:1;
|
||||
unsigned int upgraded_to_http2:1;
|
||||
unsigned int seen_nonpseudoheader:1;
|
||||
unsigned int listener:1;
|
||||
unsigned int user_space_externally_allocated:1;
|
||||
unsigned int socket_is_permanently_unusable:1;
|
||||
|
|
Loading…
Add table
Reference in a new issue