OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 #include "net/spdy/hpack_huffman_aggregator.h" | 4 #include "net/spdy/hpack_huffman_aggregator.h" |
5 | 5 |
6 #include "base/metrics/histogram.h" | 6 #include "base/metrics/histogram.h" |
7 #include "base/metrics/statistics_recorder.h" | 7 #include "base/metrics/statistics_recorder.h" |
8 #include "net/base/load_flags.h" | 8 #include "net/base/load_flags.h" |
9 #include "net/http/http_request_headers.h" | 9 #include "net/http/http_request_headers.h" |
10 #include "net/http/http_request_info.h" | 10 #include "net/http/http_request_info.h" |
(...skipping 12 matching lines...) Expand all Loading... |
23 const char kHistogramName[] = "Net.SpdyHpackEncodedCharacterFrequency"; | 23 const char kHistogramName[] = "Net.SpdyHpackEncodedCharacterFrequency"; |
24 } // namespace | 24 } // namespace |
25 | 25 |
26 namespace test { | 26 namespace test { |
27 | 27 |
28 class HpackHuffmanAggregatorPeer { | 28 class HpackHuffmanAggregatorPeer { |
29 public: | 29 public: |
30 explicit HpackHuffmanAggregatorPeer(HpackHuffmanAggregator* agg) | 30 explicit HpackHuffmanAggregatorPeer(HpackHuffmanAggregator* agg) |
31 : agg_(agg) {} | 31 : agg_(agg) {} |
32 | 32 |
33 std::vector<size_t>* counts() { | 33 std::vector<size_t>* counts() { return &agg_->counts_; } |
34 return &agg_->counts_; | |
35 } | |
36 HpackHuffmanAggregator::OriginEncoders* encoders() { | 34 HpackHuffmanAggregator::OriginEncoders* encoders() { |
37 return &agg_->encoders_; | 35 return &agg_->encoders_; |
38 } | 36 } |
39 size_t total_counts() { | 37 size_t total_counts() { return agg_->total_counts_; } |
40 return agg_->total_counts_; | |
41 } | |
42 void set_total_counts(size_t total_counts) { | 38 void set_total_counts(size_t total_counts) { |
43 agg_->total_counts_ = total_counts; | 39 agg_->total_counts_ = total_counts; |
44 } | 40 } |
45 void set_max_encoders(size_t max_encoders) { | 41 void set_max_encoders(size_t max_encoders) { |
46 agg_->max_encoders_ = max_encoders; | 42 agg_->max_encoders_ = max_encoders; |
47 } | 43 } |
48 static bool IsCrossOrigin(const HttpRequestInfo& request) { | 44 static bool IsCrossOrigin(const HttpRequestInfo& request) { |
49 return HpackHuffmanAggregator::IsCrossOrigin(request); | 45 return HpackHuffmanAggregator::IsCrossOrigin(request); |
50 } | 46 } |
51 static void CreateSpdyHeadersFromHttpResponse( | 47 static void CreateSpdyHeadersFromHttpResponse( |
52 const HttpResponseHeaders& headers, | 48 const HttpResponseHeaders& headers, |
53 SpdyHeaderBlock* headers_out) { | 49 SpdyHeaderBlock* headers_out) { |
54 HpackHuffmanAggregator::CreateSpdyHeadersFromHttpResponse( | 50 HpackHuffmanAggregator::CreateSpdyHeadersFromHttpResponse(headers, |
55 headers, headers_out); | 51 headers_out); |
56 } | 52 } |
57 HpackEncoder* ObtainEncoder(const SpdySessionKey& key) { | 53 HpackEncoder* ObtainEncoder(const SpdySessionKey& key) { |
58 return agg_->ObtainEncoder(key); | 54 return agg_->ObtainEncoder(key); |
59 } | 55 } |
60 void PublishCounts() { | 56 void PublishCounts() { agg_->PublishCounts(); } |
61 agg_->PublishCounts(); | |
62 } | |
63 | 57 |
64 private: | 58 private: |
65 HpackHuffmanAggregator* agg_; | 59 HpackHuffmanAggregator* agg_; |
66 }; | 60 }; |
67 | 61 |
68 } // namespace test | 62 } // namespace test |
69 | 63 |
70 class HpackHuffmanAggregatorTest : public ::testing::Test { | 64 class HpackHuffmanAggregatorTest : public ::testing::Test { |
71 protected: | 65 protected: |
72 HpackHuffmanAggregatorTest() | 66 HpackHuffmanAggregatorTest() : peer_(&agg_) {} |
73 : peer_(&agg_) {} | |
74 | 67 |
75 HpackHuffmanAggregator agg_; | 68 HpackHuffmanAggregator agg_; |
76 test::HpackHuffmanAggregatorPeer peer_; | 69 test::HpackHuffmanAggregatorPeer peer_; |
77 }; | 70 }; |
78 | 71 |
79 TEST_F(HpackHuffmanAggregatorTest, CrossOriginDetermination) { | 72 TEST_F(HpackHuffmanAggregatorTest, CrossOriginDetermination) { |
80 HttpRequestInfo request; | 73 HttpRequestInfo request; |
81 request.url = GURL("https://www.foo.com/a/page"); | 74 request.url = GURL("https://www.foo.com/a/page"); |
82 | 75 |
83 // Main load without referer. | 76 // Main load without referer. |
(...skipping 21 matching lines...) Expand all Loading... |
105 | 98 |
106 // Non-main load with same referer host but different schemes. | 99 // Non-main load with same referer host but different schemes. |
107 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer, | 100 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer, |
108 "http://www.foo.com/other/page"); | 101 "http://www.foo.com/other/page"); |
109 EXPECT_TRUE(peer_.IsCrossOrigin(request)); | 102 EXPECT_TRUE(peer_.IsCrossOrigin(request)); |
110 } | 103 } |
111 | 104 |
112 TEST_F(HpackHuffmanAggregatorTest, EncoderLRUQueue) { | 105 TEST_F(HpackHuffmanAggregatorTest, EncoderLRUQueue) { |
113 peer_.set_max_encoders(2); | 106 peer_.set_max_encoders(2); |
114 | 107 |
115 SpdySessionKey key1(HostPortPair("one.com", 443), ProxyServer::Direct(), | 108 SpdySessionKey key1(HostPortPair("one.com", 443), |
| 109 ProxyServer::Direct(), |
116 PRIVACY_MODE_ENABLED); | 110 PRIVACY_MODE_ENABLED); |
117 SpdySessionKey key2(HostPortPair("two.com", 443), ProxyServer::Direct(), | 111 SpdySessionKey key2(HostPortPair("two.com", 443), |
| 112 ProxyServer::Direct(), |
118 PRIVACY_MODE_ENABLED); | 113 PRIVACY_MODE_ENABLED); |
119 SpdySessionKey key3(HostPortPair("three.com", 443), ProxyServer::Direct(), | 114 SpdySessionKey key3(HostPortPair("three.com", 443), |
| 115 ProxyServer::Direct(), |
120 PRIVACY_MODE_ENABLED); | 116 PRIVACY_MODE_ENABLED); |
121 | 117 |
122 // Creates one.com. | 118 // Creates one.com. |
123 HpackEncoder* one = peer_.ObtainEncoder(key1); | 119 HpackEncoder* one = peer_.ObtainEncoder(key1); |
124 EXPECT_EQ(1u, peer_.encoders()->size()); | 120 EXPECT_EQ(1u, peer_.encoders()->size()); |
125 | 121 |
126 // Creates two.com. No evictions. | 122 // Creates two.com. No evictions. |
127 HpackEncoder* two = peer_.ObtainEncoder(key2); | 123 HpackEncoder* two = peer_.ObtainEncoder(key2); |
128 EXPECT_EQ(2u, peer_.encoders()->size()); | 124 EXPECT_EQ(2u, peer_.encoders()->size()); |
129 EXPECT_NE(one, two); | 125 EXPECT_NE(one, two); |
(...skipping 16 matching lines...) Expand all Loading... |
146 | 142 |
147 peer_.PublishCounts(); | 143 peer_.PublishCounts(); |
148 | 144 |
149 // Internal counts were reset after being published. | 145 // Internal counts were reset after being published. |
150 EXPECT_THAT(*peer_.counts(), Each(Eq(0u))); | 146 EXPECT_THAT(*peer_.counts(), Each(Eq(0u))); |
151 EXPECT_EQ(0u, peer_.total_counts()); | 147 EXPECT_EQ(0u, peer_.total_counts()); |
152 | 148 |
153 // Verify histogram counts match the expectation. | 149 // Verify histogram counts match the expectation. |
154 scoped_ptr<base::HistogramSamples> samples = | 150 scoped_ptr<base::HistogramSamples> samples = |
155 base::StatisticsRecorder::FindHistogram(kHistogramName) | 151 base::StatisticsRecorder::FindHistogram(kHistogramName) |
156 ->SnapshotSamples(); | 152 ->SnapshotSamples(); |
157 | 153 |
158 EXPECT_EQ(0, samples->GetCount(0)); | 154 EXPECT_EQ(0, samples->GetCount(0)); |
159 EXPECT_EQ(1, samples->GetCount(1)); | 155 EXPECT_EQ(1, samples->GetCount(1)); |
160 EXPECT_EQ(101, samples->GetCount(129)); | 156 EXPECT_EQ(101, samples->GetCount(129)); |
161 EXPECT_EQ(10, samples->GetCount(256)); | 157 EXPECT_EQ(10, samples->GetCount(256)); |
162 EXPECT_EQ(112, samples->TotalCount()); | 158 EXPECT_EQ(112, samples->TotalCount()); |
163 | 159 |
164 // Publish a second round of counts; | 160 // Publish a second round of counts; |
165 (*peer_.counts())[1] = 32; | 161 (*peer_.counts())[1] = 32; |
166 (*peer_.counts())[128] = 5; | 162 (*peer_.counts())[128] = 5; |
167 peer_.set_total_counts(37); | 163 peer_.set_total_counts(37); |
168 | 164 |
169 peer_.PublishCounts(); | 165 peer_.PublishCounts(); |
170 | 166 |
171 // Verify they've been aggregated into the previous counts. | 167 // Verify they've been aggregated into the previous counts. |
172 samples = base::StatisticsRecorder::FindHistogram(kHistogramName) | 168 samples = base::StatisticsRecorder::FindHistogram(kHistogramName) |
173 ->SnapshotSamples(); | 169 ->SnapshotSamples(); |
174 | 170 |
175 EXPECT_EQ(0, samples->GetCount(0)); | 171 EXPECT_EQ(0, samples->GetCount(0)); |
176 EXPECT_EQ(1, samples->GetCount(1)); | 172 EXPECT_EQ(1, samples->GetCount(1)); |
177 EXPECT_EQ(32, samples->GetCount(2)); | 173 EXPECT_EQ(32, samples->GetCount(2)); |
178 EXPECT_EQ(106, samples->GetCount(129)); | 174 EXPECT_EQ(106, samples->GetCount(129)); |
179 EXPECT_EQ(10, samples->GetCount(256)); | 175 EXPECT_EQ(10, samples->GetCount(256)); |
180 EXPECT_EQ(149, samples->TotalCount()); | 176 EXPECT_EQ(149, samples->TotalCount()); |
181 } | 177 } |
182 | 178 |
183 TEST_F(HpackHuffmanAggregatorTest, CreateSpdyResponseHeaders) { | 179 TEST_F(HpackHuffmanAggregatorTest, CreateSpdyResponseHeaders) { |
184 char kRawHeaders[] = | 180 char kRawHeaders[] = |
185 "HTTP/1.1 202 Accepted \0" | 181 "HTTP/1.1 202 Accepted \0" |
186 "Content-TYPE : text/html; charset=utf-8 \0" | 182 "Content-TYPE : text/html; charset=utf-8 \0" |
187 "Set-Cookie: foo=bar \0" | 183 "Set-Cookie: foo=bar \0" |
188 "Set-Cookie: baz=bing \0" | 184 "Set-Cookie: baz=bing \0" |
189 "Cache-Control: pragma=no-cache \0" | 185 "Cache-Control: pragma=no-cache \0" |
190 "Cache-CONTROL: expires=12345 \0\0"; | 186 "Cache-CONTROL: expires=12345 \0\0"; |
191 | 187 |
192 scoped_refptr<HttpResponseHeaders> parsed_headers(new HttpResponseHeaders( | 188 scoped_refptr<HttpResponseHeaders> parsed_headers(new HttpResponseHeaders( |
193 std::string(kRawHeaders, arraysize(kRawHeaders) - 1))); | 189 std::string(kRawHeaders, arraysize(kRawHeaders) - 1))); |
194 | 190 |
195 SpdyHeaderBlock headers; | 191 SpdyHeaderBlock headers; |
196 peer_.CreateSpdyHeadersFromHttpResponse(*parsed_headers, &headers); | 192 peer_.CreateSpdyHeadersFromHttpResponse(*parsed_headers, &headers); |
197 EXPECT_THAT(headers, ElementsAre( | 193 EXPECT_THAT( |
198 Pair(":status", "202"), | 194 headers, |
199 Pair("cache-control", std::string("pragma=no-cache\0expires=12345", 29)), | 195 ElementsAre(Pair(":status", "202"), |
200 Pair("content-type", "text/html; charset=utf-8"), | 196 Pair("cache-control", |
201 Pair("set-cookie", std::string("foo=bar\0baz=bing", 16)))); | 197 std::string("pragma=no-cache\0expires=12345", 29)), |
| 198 Pair("content-type", "text/html; charset=utf-8"), |
| 199 Pair("set-cookie", std::string("foo=bar\0baz=bing", 16)))); |
202 } | 200 } |
203 | 201 |
204 } // namespace net | 202 } // namespace net |
OLD | NEW |