| // Copyright 2013 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "quiche/quic/tools/quic_memory_cache_backend.h" |
| |
| #include <vector> |
| |
| #include "absl/strings/match.h" |
| #include "absl/strings/str_cat.h" |
| #include "quiche/quic/platform/api/quic_test.h" |
| #include "quiche/quic/tools/quic_backend_response.h" |
| #include "quiche/common/platform/api/quiche_file_utils.h" |
| #include "quiche/common/platform/api/quiche_test.h" |
| |
| namespace quic { |
| namespace test { |
| |
| namespace { |
| using Response = QuicBackendResponse; |
| } // namespace |
| |
| class QuicMemoryCacheBackendTest : public QuicTest { |
| protected: |
| void CreateRequest(std::string host, std::string path, |
| spdy::Http2HeaderBlock* headers) { |
| (*headers)[":method"] = "GET"; |
| (*headers)[":path"] = path; |
| (*headers)[":authority"] = host; |
| (*headers)[":scheme"] = "https"; |
| } |
| |
| std::string CacheDirectory() { |
| return quiche::test::QuicheGetTestMemoryCachePath(); |
| } |
| |
| QuicMemoryCacheBackend cache_; |
| }; |
| |
| TEST_F(QuicMemoryCacheBackendTest, GetResponseNoMatch) { |
| const Response* response = |
| cache_.GetResponse("mail.google.com", "/index.html"); |
| ASSERT_FALSE(response); |
| } |
| |
| TEST_F(QuicMemoryCacheBackendTest, AddSimpleResponseGetResponse) { |
| std::string response_body("hello response"); |
| cache_.AddSimpleResponse("www.google.com", "/", 200, response_body); |
| |
| spdy::Http2HeaderBlock request_headers; |
| CreateRequest("www.google.com", "/", &request_headers); |
| const Response* response = cache_.GetResponse("www.google.com", "/"); |
| ASSERT_TRUE(response); |
| ASSERT_TRUE(response->headers().contains(":status")); |
| EXPECT_EQ("200", response->headers().find(":status")->second); |
| EXPECT_EQ(response_body.size(), response->body().length()); |
| } |
| |
| TEST_F(QuicMemoryCacheBackendTest, AddResponse) { |
| const std::string kRequestHost = "www.foo.com"; |
| const std::string kRequestPath = "/"; |
| const std::string kResponseBody("hello response"); |
| |
| spdy::Http2HeaderBlock response_headers; |
| response_headers[":status"] = "200"; |
| response_headers["content-length"] = absl::StrCat(kResponseBody.size()); |
| |
| spdy::Http2HeaderBlock response_trailers; |
| response_trailers["key-1"] = "value-1"; |
| response_trailers["key-2"] = "value-2"; |
| response_trailers["key-3"] = "value-3"; |
| |
| cache_.AddResponse(kRequestHost, "/", response_headers.Clone(), kResponseBody, |
| response_trailers.Clone()); |
| |
| const Response* response = cache_.GetResponse(kRequestHost, kRequestPath); |
| EXPECT_EQ(response->headers(), response_headers); |
| EXPECT_EQ(response->body(), kResponseBody); |
| EXPECT_EQ(response->trailers(), response_trailers); |
| } |
| |
| // TODO(crbug.com/1249712) This test is failing on iOS. |
| #if defined(OS_IOS) |
| #define MAYBE_ReadsCacheDir DISABLED_ReadsCacheDir |
| #else |
| #define MAYBE_ReadsCacheDir ReadsCacheDir |
| #endif |
| TEST_F(QuicMemoryCacheBackendTest, MAYBE_ReadsCacheDir) { |
| cache_.InitializeBackend(CacheDirectory()); |
| const Response* response = |
| cache_.GetResponse("test.example.com", "/index.html"); |
| ASSERT_TRUE(response); |
| ASSERT_TRUE(response->headers().contains(":status")); |
| EXPECT_EQ("200", response->headers().find(":status")->second); |
| // Connection headers are not valid in HTTP/2. |
| EXPECT_FALSE(response->headers().contains("connection")); |
| EXPECT_LT(0U, response->body().length()); |
| } |
| |
| // TODO(crbug.com/1249712) This test is failing on iOS. |
| #if defined(OS_IOS) |
| #define MAYBE_UsesOriginalUrl DISABLED_UsesOriginalUrl |
| #else |
| #define MAYBE_UsesOriginalUrl UsesOriginalUrl |
| #endif |
| TEST_F(QuicMemoryCacheBackendTest, MAYBE_UsesOriginalUrl) { |
| cache_.InitializeBackend(CacheDirectory()); |
| const Response* response = |
| cache_.GetResponse("test.example.com", "/site_map.html"); |
| ASSERT_TRUE(response); |
| ASSERT_TRUE(response->headers().contains(":status")); |
| EXPECT_EQ("200", response->headers().find(":status")->second); |
| // Connection headers are not valid in HTTP/2. |
| EXPECT_FALSE(response->headers().contains("connection")); |
| EXPECT_LT(0U, response->body().length()); |
| } |
| |
| // TODO(crbug.com/1249712) This test is failing on iOS. |
| #if defined(OS_IOS) |
| #define MAYBE_UsesOriginalUrlOnly DISABLED_UsesOriginalUrlOnly |
| #else |
| #define MAYBE_UsesOriginalUrlOnly UsesOriginalUrlOnly |
| #endif |
| TEST_F(QuicMemoryCacheBackendTest, MAYBE_UsesOriginalUrlOnly) { |
| // Tests that if the URL cannot be inferred correctly from the path |
| // because the directory does not include the hostname, that the |
| // X-Original-Url header's value will be used. |
| std::string dir; |
| std::string path = "map.html"; |
| std::vector<std::string> files; |
| ASSERT_TRUE(quiche::EnumerateDirectoryRecursively(CacheDirectory(), files)); |
| for (const std::string& file : files) { |
| if (absl::EndsWithIgnoreCase(file, "map.html")) { |
| dir = file; |
| dir.erase(dir.length() - path.length() - 1); |
| break; |
| } |
| } |
| ASSERT_NE("", dir); |
| |
| cache_.InitializeBackend(dir); |
| const Response* response = |
| cache_.GetResponse("test.example.com", "/site_map.html"); |
| ASSERT_TRUE(response); |
| ASSERT_TRUE(response->headers().contains(":status")); |
| EXPECT_EQ("200", response->headers().find(":status")->second); |
| // Connection headers are not valid in HTTP/2. |
| EXPECT_FALSE(response->headers().contains("connection")); |
| EXPECT_LT(0U, response->body().length()); |
| } |
| |
| TEST_F(QuicMemoryCacheBackendTest, DefaultResponse) { |
| // Verify GetResponse returns nullptr when no default is set. |
| const Response* response = cache_.GetResponse("www.google.com", "/"); |
| ASSERT_FALSE(response); |
| |
| // Add a default response. |
| spdy::Http2HeaderBlock response_headers; |
| response_headers[":status"] = "200"; |
| response_headers["content-length"] = "0"; |
| Response* default_response = new Response; |
| default_response->set_headers(std::move(response_headers)); |
| cache_.AddDefaultResponse(default_response); |
| |
| // Now we should get the default response for the original request. |
| response = cache_.GetResponse("www.google.com", "/"); |
| ASSERT_TRUE(response); |
| ASSERT_TRUE(response->headers().contains(":status")); |
| EXPECT_EQ("200", response->headers().find(":status")->second); |
| |
| // Now add a set response for / and make sure it is returned |
| cache_.AddSimpleResponse("www.google.com", "/", 302, ""); |
| response = cache_.GetResponse("www.google.com", "/"); |
| ASSERT_TRUE(response); |
| ASSERT_TRUE(response->headers().contains(":status")); |
| EXPECT_EQ("302", response->headers().find(":status")->second); |
| |
| // We should get the default response for other requests. |
| response = cache_.GetResponse("www.google.com", "/asd"); |
| ASSERT_TRUE(response); |
| ASSERT_TRUE(response->headers().contains(":status")); |
| EXPECT_EQ("200", response->headers().find(":status")->second); |
| } |
| |
| } // namespace test |
| } // namespace quic |