nghttp: Use same priority anchor nodes as Firefox does
This commit is contained in:
parent
e6ad2eb14f
commit
e23225689f
|
@ -75,22 +75,23 @@ void start_element_func(void *user_data, const xmlChar *name,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (util::strieq(rel_attr, "shortcut icon")) {
|
if (util::strieq(rel_attr, "shortcut icon")) {
|
||||||
add_link(parser_data, href_attr, REQ_PRI_LOWEST);
|
add_link(parser_data, href_attr, REQ_OTHERS);
|
||||||
} else if (util::strieq(rel_attr, "stylesheet")) {
|
} else if (util::strieq(rel_attr, "stylesheet")) {
|
||||||
add_link(parser_data, href_attr, REQ_PRI_MEDIUM);
|
add_link(parser_data, href_attr, REQ_CSS);
|
||||||
}
|
}
|
||||||
} else if (util::strieq(reinterpret_cast<const char *>(name), "img")) {
|
} else if (util::strieq(reinterpret_cast<const char *>(name), "img")) {
|
||||||
auto src_attr = get_attr(attrs, "src");
|
auto src_attr = get_attr(attrs, "src");
|
||||||
if (!src_attr) {
|
if (!src_attr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
add_link(parser_data, src_attr, REQ_PRI_LOWEST);
|
add_link(parser_data, src_attr, REQ_IMG);
|
||||||
} else if (util::strieq(reinterpret_cast<const char *>(name), "script")) {
|
} else if (util::strieq(reinterpret_cast<const char *>(name), "script")) {
|
||||||
auto src_attr = get_attr(attrs, "src");
|
auto src_attr = get_attr(attrs, "src");
|
||||||
if (!src_attr) {
|
if (!src_attr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
add_link(parser_data, src_attr, REQ_PRI_LOW);
|
// TODO if script is inside in head, this should be REQ_LEADERS.
|
||||||
|
add_link(parser_data, src_attr, REQ_UNBLOCK_JS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -38,11 +38,12 @@
|
||||||
|
|
||||||
namespace nghttp2 {
|
namespace nghttp2 {
|
||||||
|
|
||||||
|
// Lower value has higher priority
|
||||||
enum RequestPriority {
|
enum RequestPriority {
|
||||||
REQ_PRI_HIGH = 0,
|
REQ_CSS = 1,
|
||||||
REQ_PRI_MEDIUM = 1,
|
REQ_UNBLOCK_JS,
|
||||||
REQ_PRI_LOW = 2,
|
REQ_IMG,
|
||||||
REQ_PRI_LOWEST = 3
|
REQ_OTHERS,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ParserData {
|
struct ParserData {
|
||||||
|
|
|
@ -61,17 +61,33 @@
|
||||||
|
|
||||||
namespace nghttp2 {
|
namespace nghttp2 {
|
||||||
|
|
||||||
// stream ID of anchor stream node when --dep-idle is enabled. These
|
// The anchor stream nodes when --dep-idle is enabled. The stream ID
|
||||||
// * portion of ANCHOR_ID_* matches RequestPriority in HtmlParser.h.
|
// = 1 is excluded since it is used as first stream in upgrade case.
|
||||||
// The stream ID = 1 is excluded since it is used as first stream in
|
// We follows the same dependency anchor nodes as Firefox does.
|
||||||
// upgrade case.
|
struct Anchor {
|
||||||
enum {
|
int32_t stream_id;
|
||||||
ANCHOR_ID_HIGH = 3,
|
// stream ID this anchor depends on
|
||||||
ANCHOR_ID_MEDIUM = 5,
|
int32_t dep_stream_id;
|
||||||
ANCHOR_ID_LOW = 7,
|
// .. with this weight.
|
||||||
ANCHOR_ID_LOWEST = 9,
|
int32_t weight;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// This is index into anchors. Firefox uses ANCHOR_FOLLOWERS for html
|
||||||
|
// file.
|
||||||
|
enum {
|
||||||
|
ANCHOR_LEADERS,
|
||||||
|
ANCHOR_UNBLOCKED,
|
||||||
|
ANCHOR_BACKGROUND,
|
||||||
|
ANCHOR_SPECULATIVE,
|
||||||
|
ANCHOR_FOLLOWERS,
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
auto anchors = std::array<Anchor, 5>{{
|
||||||
|
{3, 0, 201}, {5, 0, 101}, {7, 0, 1}, {9, 7, 1}, {11, 3, 1},
|
||||||
|
}};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
Config::Config()
|
Config::Config()
|
||||||
: output_upper_thres(1024 * 1024), padding(0),
|
: output_upper_thres(1024 * 1024), padding(0),
|
||||||
peer_max_concurrent_streams(NGHTTP2_INITIAL_MAX_CONCURRENT_STREAMS),
|
peer_max_concurrent_streams(NGHTTP2_INITIAL_MAX_CONCURRENT_STREAMS),
|
||||||
|
@ -176,22 +192,27 @@ nghttp2_priority_spec Request::resolve_dep(int32_t pri) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.dep_idle) {
|
if (config.dep_idle) {
|
||||||
int32_t anchor_id = 0;
|
int32_t anchor_id;
|
||||||
|
int32_t weight;
|
||||||
switch (pri) {
|
switch (pri) {
|
||||||
case REQ_PRI_HIGH:
|
case REQ_CSS:
|
||||||
anchor_id = ANCHOR_ID_HIGH;
|
anchor_id = anchors[ANCHOR_LEADERS].stream_id;
|
||||||
|
weight = 2;
|
||||||
break;
|
break;
|
||||||
case REQ_PRI_MEDIUM:
|
case REQ_UNBLOCK_JS:
|
||||||
anchor_id = ANCHOR_ID_MEDIUM;
|
anchor_id = anchors[ANCHOR_UNBLOCKED].stream_id;
|
||||||
|
weight = 2;
|
||||||
break;
|
break;
|
||||||
case REQ_PRI_LOW:
|
case REQ_IMG:
|
||||||
anchor_id = ANCHOR_ID_LOW;
|
anchor_id = anchors[ANCHOR_FOLLOWERS].stream_id;
|
||||||
break;
|
weight = 12;
|
||||||
case REQ_PRI_LOWEST:
|
|
||||||
anchor_id = ANCHOR_ID_LOWEST;
|
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
anchor_id = anchors[ANCHOR_FOLLOWERS].stream_id;
|
||||||
|
weight = 2;
|
||||||
}
|
}
|
||||||
nghttp2_priority_spec_init(&pri_spec, anchor_id, NGHTTP2_DEFAULT_WEIGHT, 0);
|
|
||||||
|
nghttp2_priority_spec_init(&pri_spec, anchor_id, weight, 0);
|
||||||
return pri_spec;
|
return pri_spec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -980,23 +1001,19 @@ int HttpClient::connection_made() {
|
||||||
if (!config.no_dep && config.dep_idle) {
|
if (!config.no_dep && config.dep_idle) {
|
||||||
// Create anchor stream nodes
|
// Create anchor stream nodes
|
||||||
nghttp2_priority_spec pri_spec;
|
nghttp2_priority_spec pri_spec;
|
||||||
int32_t dep_stream_id = 0;
|
|
||||||
|
|
||||||
for (auto stream_id :
|
for (auto &anchor : anchors) {
|
||||||
{ANCHOR_ID_HIGH, ANCHOR_ID_MEDIUM, ANCHOR_ID_LOW, ANCHOR_ID_LOWEST}) {
|
nghttp2_priority_spec_init(&pri_spec, anchor.dep_stream_id, anchor.weight,
|
||||||
|
0);
|
||||||
nghttp2_priority_spec_init(&pri_spec, dep_stream_id,
|
rv = nghttp2_submit_priority(session, NGHTTP2_FLAG_NONE, anchor.stream_id,
|
||||||
NGHTTP2_DEFAULT_WEIGHT, 0);
|
|
||||||
rv = nghttp2_submit_priority(session, NGHTTP2_FLAG_NONE, stream_id,
|
|
||||||
&pri_spec);
|
&pri_spec);
|
||||||
if (rv != 0) {
|
if (rv != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
dep_stream_id = stream_id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = nghttp2_session_set_next_stream_id(session, ANCHOR_ID_LOWEST + 2);
|
rv = nghttp2_session_set_next_stream_id(
|
||||||
|
session, anchors[ANCHOR_FOLLOWERS].stream_id + 2);
|
||||||
if (rv != 0) {
|
if (rv != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1004,7 +1021,8 @@ int HttpClient::connection_made() {
|
||||||
if (need_upgrade()) {
|
if (need_upgrade()) {
|
||||||
// Amend the priority because we cannot send priority in
|
// Amend the priority because we cannot send priority in
|
||||||
// HTTP/1.1 Upgrade.
|
// HTTP/1.1 Upgrade.
|
||||||
nghttp2_priority_spec_init(&pri_spec, ANCHOR_ID_HIGH, config.weight, 0);
|
auto &anchor = anchors[ANCHOR_FOLLOWERS];
|
||||||
|
nghttp2_priority_spec_init(&pri_spec, anchor.stream_id, config.weight, 0);
|
||||||
|
|
||||||
rv = nghttp2_submit_priority(session, NGHTTP2_FLAG_NONE, 1, &pri_spec);
|
rv = nghttp2_submit_priority(session, NGHTTP2_FLAG_NONE, 1, &pri_spec);
|
||||||
if (rv != 0) {
|
if (rv != 0) {
|
||||||
|
@ -1272,14 +1290,6 @@ void HttpClient::record_connect_end_time() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void HttpClient::request_done(Request *req) {
|
void HttpClient::request_done(Request *req) {
|
||||||
if (req->pri == 0 && req->dep) {
|
|
||||||
assert(req->dep->deps.empty());
|
|
||||||
|
|
||||||
req->dep->deps.push_back(std::vector<Request *>{req});
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (req->stream_id % 2 == 0) {
|
if (req->stream_id % 2 == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2059,7 +2069,7 @@ int communicate(
|
||||||
int32_t dep_stream_id = 0;
|
int32_t dep_stream_id = 0;
|
||||||
|
|
||||||
if (!config.no_dep && config.dep_idle) {
|
if (!config.no_dep && config.dep_idle) {
|
||||||
dep_stream_id = ANCHOR_ID_HIGH;
|
dep_stream_id = anchors[ANCHOR_FOLLOWERS].stream_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
nghttp2_priority_spec_init(&pri_spec, dep_stream_id, config.weight, 0);
|
nghttp2_priority_spec_init(&pri_spec, dep_stream_id, config.weight, 0);
|
||||||
|
|
Loading…
Reference in New Issue