OLD | NEW |
| (Empty) |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | |
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 <string> | |
6 | |
7 #include "base/files/file_path.h" | |
8 #include "base/memory/singleton.h" | |
9 #include "base/path_service.h" | |
10 #include "base/stl_util.h" | |
11 #include "base/strings/string_number_conversions.h" | |
12 #include "base/strings/string_piece.h" | |
13 #include "net/spdy/spdy_framer.h" | |
14 #include "net/tools/quic/quic_in_memory_cache.h" | |
15 #include "testing/gtest/include/gtest/gtest.h" | |
16 | |
17 using base::ContainsKey; | |
18 using base::IntToString; | |
19 using base::StringPiece; | |
20 using net::SpdyHeaderBlock; | |
21 using std::list; | |
22 using std::string; | |
23 | |
24 namespace net { | |
25 namespace test { | |
26 | |
27 namespace { | |
28 typedef QuicInMemoryCache::Response Response; | |
29 typedef QuicInMemoryCache::ServerPushInfo ServerPushInfo; | |
30 }; // namespace | |
31 | |
32 class QuicInMemoryCacheTest : public ::testing::Test { | |
33 protected: | |
34 void CreateRequest(string host, string path, SpdyHeaderBlock* headers) { | |
35 (*headers)[":method"] = "GET"; | |
36 (*headers)[":path"] = path; | |
37 (*headers)[":authority"] = host; | |
38 (*headers)[":scheme"] = "https"; | |
39 } | |
40 | |
41 string CacheDirectory() { | |
42 base::FilePath path; | |
43 PathService::Get(base::DIR_SOURCE_ROOT, &path); | |
44 path = path.AppendASCII("net").AppendASCII("data").AppendASCII( | |
45 "quic_in_memory_cache_data"); | |
46 // The file path is known to be an ascii string. | |
47 return path.MaybeAsASCII(); | |
48 } | |
49 | |
50 QuicInMemoryCache cache_; | |
51 }; | |
52 | |
53 TEST_F(QuicInMemoryCacheTest, GetResponseNoMatch) { | |
54 const QuicInMemoryCache::Response* response = | |
55 cache_.GetResponse("mail.google.com", "/index.html"); | |
56 ASSERT_FALSE(response); | |
57 } | |
58 | |
59 TEST_F(QuicInMemoryCacheTest, AddSimpleResponseGetResponse) { | |
60 string response_body("hello response"); | |
61 cache_.AddSimpleResponse("www.google.com", "/", 200, response_body); | |
62 | |
63 SpdyHeaderBlock request_headers; | |
64 CreateRequest("www.google.com", "/", &request_headers); | |
65 const QuicInMemoryCache::Response* response = | |
66 cache_.GetResponse("www.google.com", "/"); | |
67 ASSERT_TRUE(response); | |
68 ASSERT_TRUE(ContainsKey(response->headers(), ":status")); | |
69 EXPECT_EQ("200", response->headers().find(":status")->second); | |
70 EXPECT_EQ(response_body.size(), response->body().length()); | |
71 } | |
72 | |
73 TEST_F(QuicInMemoryCacheTest, AddResponse) { | |
74 const string kRequestHost = "www.foo.com"; | |
75 const string kRequestPath = "/"; | |
76 const string kResponseBody("hello response"); | |
77 | |
78 SpdyHeaderBlock response_headers; | |
79 response_headers[":version"] = "HTTP/1.1"; | |
80 response_headers[":status"] = "200"; | |
81 response_headers["content-length"] = IntToString(kResponseBody.size()); | |
82 | |
83 SpdyHeaderBlock response_trailers; | |
84 response_trailers["key-1"] = "value-1"; | |
85 response_trailers["key-2"] = "value-2"; | |
86 response_trailers["key-3"] = "value-3"; | |
87 | |
88 cache_.AddResponse(kRequestHost, "/", response_headers.Clone(), kResponseBody, | |
89 response_trailers.Clone()); | |
90 | |
91 const QuicInMemoryCache::Response* response = | |
92 cache_.GetResponse(kRequestHost, kRequestPath); | |
93 EXPECT_EQ(response->headers(), response_headers); | |
94 EXPECT_EQ(response->body(), kResponseBody); | |
95 EXPECT_EQ(response->trailers(), response_trailers); | |
96 } | |
97 | |
98 TEST_F(QuicInMemoryCacheTest, ReadsCacheDir) { | |
99 cache_.InitializeFromDirectory(CacheDirectory()); | |
100 const QuicInMemoryCache::Response* response = | |
101 cache_.GetResponse("quic.test.url", "/index.html"); | |
102 ASSERT_TRUE(response); | |
103 ASSERT_TRUE(ContainsKey(response->headers(), ":status")); | |
104 EXPECT_EQ("200", response->headers().find(":status")->second); | |
105 // Connection headers are not valid in HTTP/2. | |
106 EXPECT_FALSE(ContainsKey(response->headers(), "connection")); | |
107 EXPECT_LT(0U, response->body().length()); | |
108 } | |
109 | |
110 TEST_F(QuicInMemoryCacheTest, ReadsCacheDirWithServerPushResource) { | |
111 cache_.InitializeFromDirectory(CacheDirectory() + "_with_push"); | |
112 list<ServerPushInfo> resources = | |
113 cache_.GetServerPushResources("quic.test.url/"); | |
114 ASSERT_EQ(1UL, resources.size()); | |
115 } | |
116 | |
117 TEST_F(QuicInMemoryCacheTest, ReadsCacheDirWithServerPushResources) { | |
118 cache_.InitializeFromDirectory(CacheDirectory() + "_with_push"); | |
119 list<ServerPushInfo> resources = | |
120 cache_.GetServerPushResources("quic.test.url/index2.html"); | |
121 ASSERT_EQ(2UL, resources.size()); | |
122 } | |
123 | |
124 TEST_F(QuicInMemoryCacheTest, UsesOriginalUrl) { | |
125 cache_.InitializeFromDirectory(CacheDirectory()); | |
126 const QuicInMemoryCache::Response* response = | |
127 cache_.GetResponse("quic.test.url", "/index.html"); | |
128 ASSERT_TRUE(response); | |
129 ASSERT_TRUE(ContainsKey(response->headers(), ":status")); | |
130 EXPECT_EQ("200", response->headers().find(":status")->second); | |
131 // Connection headers are not valid in HTTP/2. | |
132 EXPECT_FALSE(ContainsKey(response->headers(), "connection")); | |
133 EXPECT_LT(0U, response->body().length()); | |
134 } | |
135 | |
136 TEST_F(QuicInMemoryCacheTest, DefaultResponse) { | |
137 // Verify GetResponse returns nullptr when no default is set. | |
138 const QuicInMemoryCache::Response* response = | |
139 cache_.GetResponse("www.google.com", "/"); | |
140 ASSERT_FALSE(response); | |
141 | |
142 // Add a default response. | |
143 SpdyHeaderBlock response_headers; | |
144 response_headers[":version"] = "HTTP/1.1"; | |
145 response_headers[":status"] = "200"; | |
146 response_headers["content-length"] = "0"; | |
147 QuicInMemoryCache::Response* default_response = | |
148 new QuicInMemoryCache::Response; | |
149 default_response->set_headers(std::move(response_headers)); | |
150 cache_.AddDefaultResponse(default_response); | |
151 | |
152 // Now we should get the default response for the original request. | |
153 response = cache_.GetResponse("www.google.com", "/"); | |
154 ASSERT_TRUE(response); | |
155 ASSERT_TRUE(ContainsKey(response->headers(), ":status")); | |
156 EXPECT_EQ("200", response->headers().find(":status")->second); | |
157 | |
158 // Now add a set response for / and make sure it is returned | |
159 cache_.AddSimpleResponse("www.google.com", "/", 302, ""); | |
160 response = cache_.GetResponse("www.google.com", "/"); | |
161 ASSERT_TRUE(response); | |
162 ASSERT_TRUE(ContainsKey(response->headers(), ":status")); | |
163 EXPECT_EQ("302", response->headers().find(":status")->second); | |
164 | |
165 // We should get the default response for other requests. | |
166 response = cache_.GetResponse("www.google.com", "/asd"); | |
167 ASSERT_TRUE(response); | |
168 ASSERT_TRUE(ContainsKey(response->headers(), ":status")); | |
169 EXPECT_EQ("200", response->headers().find(":status")->second); | |
170 } | |
171 | |
172 TEST_F(QuicInMemoryCacheTest, AddSimpleResponseWithServerPushResources) { | |
173 string request_host = "www.foo.com"; | |
174 string response_body("hello response"); | |
175 const size_t kNumResources = 5; | |
176 int NumResources = 5; | |
177 list<QuicInMemoryCache::ServerPushInfo> push_resources; | |
178 string scheme = "http"; | |
179 for (int i = 0; i < NumResources; ++i) { | |
180 string path = "/server_push_src" + base::IntToString(i); | |
181 string url = scheme + "://" + request_host + path; | |
182 GURL resource_url(url); | |
183 string body = "This is server push response body for " + path; | |
184 SpdyHeaderBlock response_headers; | |
185 response_headers[":version"] = "HTTP/1.1"; | |
186 response_headers[":status"] = "200"; | |
187 response_headers["content-length"] = base::UintToString(body.size()); | |
188 push_resources.push_back( | |
189 ServerPushInfo(resource_url, response_headers.Clone(), i, body)); | |
190 } | |
191 | |
192 cache_.AddSimpleResponseWithServerPushResources( | |
193 request_host, "/", 200, response_body, push_resources); | |
194 string request_url = request_host + "/"; | |
195 list<ServerPushInfo> resources = cache_.GetServerPushResources(request_url); | |
196 ASSERT_EQ(kNumResources, resources.size()); | |
197 for (const auto& push_resource : push_resources) { | |
198 ServerPushInfo resource = resources.front(); | |
199 EXPECT_EQ(resource.request_url.spec(), push_resource.request_url.spec()); | |
200 EXPECT_EQ(resource.priority, push_resource.priority); | |
201 resources.pop_front(); | |
202 } | |
203 } | |
204 | |
205 TEST_F(QuicInMemoryCacheTest, GetServerPushResourcesAndPushResponses) { | |
206 string request_host = "www.foo.com"; | |
207 string response_body("hello response"); | |
208 const size_t kNumResources = 4; | |
209 int NumResources = 4; | |
210 string scheme = "http"; | |
211 string push_response_status[kNumResources] = {"200", "200", "301", "404"}; | |
212 list<QuicInMemoryCache::ServerPushInfo> push_resources; | |
213 for (int i = 0; i < NumResources; ++i) { | |
214 string path = "/server_push_src" + base::IntToString(i); | |
215 string url = scheme + "://" + request_host + path; | |
216 GURL resource_url(url); | |
217 string body = "This is server push response body for " + path; | |
218 SpdyHeaderBlock response_headers; | |
219 response_headers[":version"] = "HTTP/1.1"; | |
220 response_headers[":status"] = push_response_status[i]; | |
221 response_headers["content-length"] = base::UintToString(body.size()); | |
222 push_resources.push_back( | |
223 ServerPushInfo(resource_url, response_headers.Clone(), i, body)); | |
224 } | |
225 cache_.AddSimpleResponseWithServerPushResources( | |
226 request_host, "/", 200, response_body, push_resources); | |
227 string request_url = request_host + "/"; | |
228 list<ServerPushInfo> resources = cache_.GetServerPushResources(request_url); | |
229 ASSERT_EQ(kNumResources, resources.size()); | |
230 int i = 0; | |
231 for (const auto& push_resource : push_resources) { | |
232 GURL url = resources.front().request_url; | |
233 string host = url.host(); | |
234 string path = url.path(); | |
235 const QuicInMemoryCache::Response* response = | |
236 cache_.GetResponse(host, path); | |
237 ASSERT_TRUE(response); | |
238 ASSERT_TRUE(ContainsKey(response->headers(), ":status")); | |
239 EXPECT_EQ(push_response_status[i++], | |
240 response->headers().find(":status")->second); | |
241 EXPECT_EQ(push_resource.body, response->body()); | |
242 resources.pop_front(); | |
243 } | |
244 } | |
245 | |
246 } // namespace test | |
247 } // namespace net | |
OLD | NEW |