1 // Copyright 2023 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/spdy/spdy_http_utils.h"
6
7 #include "base/memory/ref_counted.h"
8 #include "net/http/http_request_headers.h"
9 #include "net/http/http_request_info.h"
10 #include "net/http/http_response_headers.h"
11 #include "net/third_party/quiche/src/quiche/spdy/core/http2_header_block.h"
12 #include "third_party/google_benchmark/src/include/benchmark/benchmark.h"
13 #include "url/gurl.h"
14
15 namespace net {
16
17 namespace {
18
MakeHeaderBlock()19 spdy::Http2HeaderBlock MakeHeaderBlock() {
20 spdy::Http2HeaderBlock headers;
21 headers[":status"] = "200";
22 headers["date"] = "Thu, 14 Sep 2023 12:40:24 GMT";
23 headers["server"] = "server1234.example.com";
24 headers["x-content-type-options"] = "nosniff";
25 headers["content-language"] = "en";
26 headers["accept-ch"] = "";
27 headers["vary"] = "Accept-Encoding,Cookie";
28 headers["last-modified"] = "Thu, 14 Sep 2023 12:40:22 GMT";
29 headers["content-type"] = "text/html; charset=UTF-8";
30 headers["age"] = "1984";
31 headers["x-cache"] = "server1234 miss, server1235 hit/6664";
32 headers["x-cache-status"] = "hit-front";
33 headers["server-timing"] = "cache;desc=\"hit-front\", host;desc=\"cp5023\"";
34 headers["strict-transport-security"] =
35 "max-age=106384710; includeSubDomains; preload";
36 headers["report-to"] =
37 "{ \"group\": \"wm_nel\", \"max_age\": 604800, \"endpoints\": [{ "
38 "\"url\": "
39 "\"https://nel.example.net/v1/"
40 "events?stream=w3c.reportingapi.network_error&schema_uri=/w3c/"
41 "reportingapi/network_error/1.0.0\" }] }";
42 headers["nel"] =
43 "{ \"report_to\": \"wm_nel\", \"max_age\": 604800, \"failure_fraction\": "
44 "0.05, \"success_fraction\": 0.0}";
45 headers.AppendValueOrAddHeader(
46 "set-cookie",
47 "WMF-DP=ba9;Path=/;HttpOnly;secure;Expires=Fri, 15 Sep 2023 00:00:00 "
48 "GMT");
49 headers["x-client-ip"] = "0102:0203:04:405:0506:0708:0609:090a";
50 headers["cache-control"] = "private, s-maxage=0, max-age=0, must-revalidate";
51 headers.AppendValueOrAddHeader(
52 "set-cookie", "NetworkProbeLimit=0.001;Path=/;Secure;Max-Age=3600");
53 headers["accept-ranges"] = "bytes";
54 headers["content-length"] = "99545";
55 return headers;
56 }
57
58 using SpdyHeadersToHttpResponseHeadersFunctionPtrType =
59 base::expected<scoped_refptr<HttpResponseHeaders>, int> (*)(
60 const spdy::Http2HeaderBlock&);
61
62 // The benchmark code is templated on the function to force it to be specialized
63 // at compile time so there is no indirection via a function pointer at runtime
64 // sllowing it down.
65 template <SpdyHeadersToHttpResponseHeadersFunctionPtrType convert>
Benchmark(::benchmark::State & state)66 void Benchmark(::benchmark::State& state) {
67 const auto header_block = MakeHeaderBlock();
68 for (auto _ : state) {
69 auto headers = convert(header_block);
70 ::benchmark::DoNotOptimize(headers);
71 }
72 }
73
74 BENCHMARK(Benchmark<SpdyHeadersToHttpResponseHeadersUsingRawString>)
75 ->MinWarmUpTime(1.0);
76 BENCHMARK(Benchmark<SpdyHeadersToHttpResponseHeadersUsingBuilder>)
77 ->MinWarmUpTime(1.0);
78
BM_CreateSpdyHeadersFromHttpRequest(::benchmark::State & state)79 void BM_CreateSpdyHeadersFromHttpRequest(::benchmark::State& state) {
80 HttpRequestInfo info;
81 info.url = GURL("https://en.wikipedia.org/wiki/HTTP");
82 info.method = "GET";
83 HttpRequestHeaders http_request_headers;
84 http_request_headers.SetHeader(
85 "Accept",
86 "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/"
87 "webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7");
88 http_request_headers.SetHeader("Accept-Encoding", "gzip, deflate, br");
89 http_request_headers.SetHeader("Accept-Language", "en-GB,en;q=0.9");
90 http_request_headers.SetHeader("Cache-Control", "max-age=0");
91 http_request_headers.SetHeader(
92 "Cookie",
93 "WMF-Last-Access=xxxxxxxxxxx; WMF-Last-Access-Global=xxxxxxxxxxx; "
94 "GeoIP=xxxxxxxxxxxxxxxxxxxxxxxxxxx; NetworkProbeLimit=0.001; "
95 "enwikimwuser-sessionId=xxxxxxxxxxxxxxxxxxxx");
96 http_request_headers.SetHeader(
97 "Sec-Ch-Ua",
98 "\"Google Chrome\";v=\"117\", \"Not;A=Brand\";v=\"8\", "
99 "\"Chromium\";v=\"117\"");
100 http_request_headers.SetHeader("Sec-Ch-Ua-Mobile", "?0");
101 http_request_headers.SetHeader("Sec-Ch-Ua-Platform", "\"Linux\"");
102 http_request_headers.SetHeader("Sec-Fetch-Dest", "document");
103 http_request_headers.SetHeader("Sec-Fetch-Mode", "navigate");
104 http_request_headers.SetHeader("Sec-Fetch-Site", "none");
105 http_request_headers.SetHeader("Sec-Fetch-User", "?1");
106 http_request_headers.SetHeader("Upgrade-Insecure-Requests", "1");
107 http_request_headers.SetHeader(
108 "User-Agent",
109 "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) "
110 "Chrome/117.0.0.0 Safari/537.36");
111
112 for (auto _ : state) {
113 spdy::Http2HeaderBlock headers;
114 CreateSpdyHeadersFromHttpRequest(info, RequestPriority::DEFAULT_PRIORITY,
115 http_request_headers, &headers);
116 ::benchmark::DoNotOptimize(headers);
117 }
118 }
119
120 BENCHMARK(BM_CreateSpdyHeadersFromHttpRequest)->MinWarmUpTime(1.0);
121
122 } // namespace
123
124 } // namespace net
125