| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012 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 #ifndef NET_TOOLS_QUIC_QUIC_IN_MEMORY_CACHE_H_ | |
| 6 #define NET_TOOLS_QUIC_QUIC_IN_MEMORY_CACHE_H_ | |
| 7 | |
| 8 #include <list> | |
| 9 #include <map> | |
| 10 #include <memory> | |
| 11 #include <string> | |
| 12 #include <unordered_map> | |
| 13 #include <vector> | |
| 14 | |
| 15 #include "base/files/file_path.h" | |
| 16 #include "base/macros.h" | |
| 17 #include "base/strings/string_piece.h" | |
| 18 #include "net/http/http_response_headers.h" | |
| 19 #include "net/quic/core/spdy_utils.h" | |
| 20 #include "net/spdy/spdy_framer.h" | |
| 21 #include "url/gurl.h" | |
| 22 | |
| 23 namespace net { | |
| 24 | |
| 25 // In-memory cache for HTTP responses. | |
| 26 // Reads from disk cache generated by: | |
| 27 // `wget -p --save_headers <url>` | |
| 28 class QuicInMemoryCache { | |
| 29 public: | |
| 30 // A ServerPushInfo contains path of the push request and everything needed in | |
| 31 // comprising a response for the push request. | |
| 32 struct ServerPushInfo { | |
| 33 ServerPushInfo(GURL request_url, | |
| 34 SpdyHeaderBlock headers, | |
| 35 SpdyPriority priority, | |
| 36 std::string body); | |
| 37 ServerPushInfo(const ServerPushInfo& other); | |
| 38 GURL request_url; | |
| 39 SpdyHeaderBlock headers; | |
| 40 SpdyPriority priority; | |
| 41 std::string body; | |
| 42 }; | |
| 43 | |
| 44 enum SpecialResponseType { | |
| 45 REGULAR_RESPONSE, // Send the headers and body like a server should. | |
| 46 CLOSE_CONNECTION, // Close the connection (sending the close packet). | |
| 47 IGNORE_REQUEST, // Do nothing, expect the client to time out. | |
| 48 }; | |
| 49 | |
| 50 // Container for response header/body pairs. | |
| 51 class Response { | |
| 52 public: | |
| 53 Response(); | |
| 54 ~Response(); | |
| 55 | |
| 56 SpecialResponseType response_type() const { return response_type_; } | |
| 57 const SpdyHeaderBlock& headers() const { return headers_; } | |
| 58 const SpdyHeaderBlock& trailers() const { return trailers_; } | |
| 59 const base::StringPiece body() const { return base::StringPiece(body_); } | |
| 60 | |
| 61 void set_response_type(SpecialResponseType response_type) { | |
| 62 response_type_ = response_type; | |
| 63 } | |
| 64 void set_headers(SpdyHeaderBlock headers) { headers_ = std::move(headers); } | |
| 65 void set_trailers(SpdyHeaderBlock trailers) { | |
| 66 trailers_ = std::move(trailers); | |
| 67 } | |
| 68 void set_body(base::StringPiece body) { body.CopyToString(&body_); } | |
| 69 | |
| 70 private: | |
| 71 SpecialResponseType response_type_; | |
| 72 SpdyHeaderBlock headers_; | |
| 73 SpdyHeaderBlock trailers_; | |
| 74 std::string body_; | |
| 75 | |
| 76 DISALLOW_COPY_AND_ASSIGN(Response); | |
| 77 }; | |
| 78 | |
| 79 // Class to manage loading a resource file into memory. There are | |
| 80 // two uses: called by InitializeFromDirectory to load resources | |
| 81 // from files, and recursively called when said resources specify | |
| 82 // server push associations. | |
| 83 class ResourceFile { | |
| 84 public: | |
| 85 explicit ResourceFile(const base::FilePath& file_name); | |
| 86 virtual ~ResourceFile(); | |
| 87 | |
| 88 void Read(); | |
| 89 | |
| 90 void SetHostPathFromBase(base::StringPiece base); | |
| 91 | |
| 92 base::StringPiece host() { return host_; } | |
| 93 void set_host(base::StringPiece host) { host_ = host; } | |
| 94 | |
| 95 base::StringPiece path() { return path_; } | |
| 96 void set_path(base::StringPiece path) { path_ = path; } | |
| 97 | |
| 98 const SpdyHeaderBlock& spdy_headers() { return spdy_headers_; } | |
| 99 | |
| 100 base::StringPiece body() { return body_; } | |
| 101 | |
| 102 const std::vector<base::StringPiece>& push_urls() { return push_urls_; } | |
| 103 | |
| 104 const std::string& file_name() { return file_name_string_; } | |
| 105 | |
| 106 protected: | |
| 107 void HandleXOriginalUrl(); | |
| 108 void HandlePushUrls(const std::vector<base::StringPiece>& push_urls); | |
| 109 base::StringPiece RemoveScheme(base::StringPiece url); | |
| 110 | |
| 111 const std::string cache_directory_; | |
| 112 const base::FilePath file_name_; | |
| 113 const std::string file_name_string_; | |
| 114 std::string file_contents_; | |
| 115 base::StringPiece body_; | |
| 116 SpdyHeaderBlock spdy_headers_; | |
| 117 base::StringPiece x_original_url_; | |
| 118 std::vector<base::StringPiece> push_urls_; | |
| 119 | |
| 120 private: | |
| 121 base::StringPiece host_; | |
| 122 base::StringPiece path_; | |
| 123 QuicInMemoryCache* cache_; | |
| 124 | |
| 125 DISALLOW_COPY_AND_ASSIGN(ResourceFile); | |
| 126 }; | |
| 127 | |
| 128 QuicInMemoryCache(); | |
| 129 ~QuicInMemoryCache(); | |
| 130 | |
| 131 // Retrieve a response from this cache for a given host and path.. | |
| 132 // If no appropriate response exists, nullptr is returned. | |
| 133 const Response* GetResponse(base::StringPiece host, | |
| 134 base::StringPiece path) const; | |
| 135 | |
| 136 // Adds a simple response to the cache. The response headers will | |
| 137 // only contain the "content-length" header with the length of |body|. | |
| 138 void AddSimpleResponse(base::StringPiece host, | |
| 139 base::StringPiece path, | |
| 140 int response_code, | |
| 141 base::StringPiece body); | |
| 142 | |
| 143 // Add a simple response to the cache as AddSimpleResponse() does, and add | |
| 144 // some server push resources(resource path, corresponding response status and | |
| 145 // path) associated with it. | |
| 146 // Push resource implicitly come from the same host. | |
| 147 void AddSimpleResponseWithServerPushResources( | |
| 148 base::StringPiece host, | |
| 149 base::StringPiece path, | |
| 150 int response_code, | |
| 151 base::StringPiece body, | |
| 152 std::list<ServerPushInfo> push_resources); | |
| 153 | |
| 154 // Add a response to the cache. | |
| 155 void AddResponse(base::StringPiece host, | |
| 156 base::StringPiece path, | |
| 157 SpdyHeaderBlock response_headers, | |
| 158 base::StringPiece response_body); | |
| 159 | |
| 160 // Add a response, with trailers, to the cache. | |
| 161 void AddResponse(base::StringPiece host, | |
| 162 base::StringPiece path, | |
| 163 SpdyHeaderBlock response_headers, | |
| 164 base::StringPiece response_body, | |
| 165 SpdyHeaderBlock response_trailers); | |
| 166 | |
| 167 // Simulate a special behavior at a particular path. | |
| 168 void AddSpecialResponse(base::StringPiece host, | |
| 169 base::StringPiece path, | |
| 170 SpecialResponseType response_type); | |
| 171 | |
| 172 // Sets a default response in case of cache misses. Takes ownership of | |
| 173 // 'response'. | |
| 174 void AddDefaultResponse(Response* response); | |
| 175 | |
| 176 // |cache_cirectory| can be generated using `wget -p --save-headers <url>`. | |
| 177 void InitializeFromDirectory(const std::string& cache_directory); | |
| 178 | |
| 179 // Find all the server push resources associated with |request_url|. | |
| 180 std::list<ServerPushInfo> GetServerPushResources(std::string request_url); | |
| 181 | |
| 182 private: | |
| 183 void AddResponseImpl(base::StringPiece host, | |
| 184 base::StringPiece path, | |
| 185 SpecialResponseType response_type, | |
| 186 SpdyHeaderBlock response_headers, | |
| 187 base::StringPiece response_body, | |
| 188 SpdyHeaderBlock response_trailers); | |
| 189 | |
| 190 std::string GetKey(base::StringPiece host, base::StringPiece path) const; | |
| 191 | |
| 192 // Add some server push urls with given responses for specified | |
| 193 // request if these push resources are not associated with this request yet. | |
| 194 void MaybeAddServerPushResources(base::StringPiece request_host, | |
| 195 base::StringPiece request_path, | |
| 196 std::list<ServerPushInfo> push_resources); | |
| 197 | |
| 198 // Check if push resource(push_host/push_path) associated with given request | |
| 199 // url already exists in server push map. | |
| 200 bool PushResourceExistsInCache(std::string original_request_url, | |
| 201 ServerPushInfo resource); | |
| 202 | |
| 203 // Cached responses. | |
| 204 std::unordered_map<std::string, std::unique_ptr<Response>> responses_; | |
| 205 | |
| 206 // The default response for cache misses, if set. | |
| 207 std::unique_ptr<Response> default_response_; | |
| 208 | |
| 209 // A map from request URL to associated server push responses (if any). | |
| 210 std::multimap<std::string, ServerPushInfo> server_push_resources_; | |
| 211 | |
| 212 // Protects against concurrent access from test threads setting responses, and | |
| 213 // server threads accessing those responses. | |
| 214 mutable base::Lock response_mutex_; | |
| 215 | |
| 216 DISALLOW_COPY_AND_ASSIGN(QuicInMemoryCache); | |
| 217 }; | |
| 218 | |
| 219 } // namespace net | |
| 220 | |
| 221 #endif // NET_TOOLS_QUIC_QUIC_IN_MEMORY_CACHE_H_ | |
| OLD | NEW |