blob: ff76c9ad41b30467685d5457b16eb08608553bbc [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// 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 QUICHE_QUIC_TOOLS_QUIC_MEMORY_CACHE_BACKEND_H_
6#define QUICHE_QUIC_TOOLS_QUIC_MEMORY_CACHE_BACKEND_H_
7
8#include <list>
9#include <map>
10#include <memory>
11#include <vector>
12
13#include "net/third_party/quiche/src/quic/core/http/spdy_utils.h"
14#include "net/third_party/quiche/src/quic/platform/api/quic_containers.h"
15#include "net/third_party/quiche/src/quic/platform/api/quic_mutex.h"
16#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
17#include "net/third_party/quiche/src/quic/tools/quic_backend_response.h"
18#include "net/third_party/quiche/src/quic/tools/quic_simple_server_backend.h"
19#include "net/third_party/quiche/src/quic/tools/quic_url.h"
20#include "net/third_party/quiche/src/spdy/core/spdy_framer.h"
21
22namespace quic {
23
24// In-memory cache for HTTP responses.
25// Reads from disk cache generated by:
26// `wget -p --save_headers <url>`
27class QuicMemoryCacheBackend : public QuicSimpleServerBackend {
28 public:
29 // Class to manage loading a resource file into memory. There are
30 // two uses: called by InitializeBackend to load resources
31 // from files, and recursively called when said resources specify
32 // server push associations.
33 class ResourceFile {
34 public:
vasilvvc48c8712019-03-11 13:38:16 -070035 explicit ResourceFile(const std::string& file_name);
QUICHE teama6ef0a62019-03-07 20:34:33 -050036 ResourceFile(const ResourceFile&) = delete;
37 ResourceFile& operator=(const ResourceFile&) = delete;
38 virtual ~ResourceFile();
39
40 void Read();
41
42 // |base| is |file_name_| with |cache_directory| prefix stripped.
43 void SetHostPathFromBase(QuicStringPiece base);
44
vasilvvc48c8712019-03-11 13:38:16 -070045 const std::string& file_name() { return file_name_; }
QUICHE teama6ef0a62019-03-07 20:34:33 -050046
47 QuicStringPiece host() { return host_; }
48
49 QuicStringPiece path() { return path_; }
50
51 const spdy::SpdyHeaderBlock& spdy_headers() { return spdy_headers_; }
52
53 QuicStringPiece body() { return body_; }
54
55 const std::vector<QuicStringPiece>& push_urls() { return push_urls_; }
56
57 protected:
58 void HandleXOriginalUrl();
59 QuicStringPiece RemoveScheme(QuicStringPiece url);
60
vasilvvc48c8712019-03-11 13:38:16 -070061 std::string file_name_;
62 std::string file_contents_;
QUICHE teama6ef0a62019-03-07 20:34:33 -050063 QuicStringPiece body_;
64 spdy::SpdyHeaderBlock spdy_headers_;
65 QuicStringPiece x_original_url_;
66 std::vector<QuicStringPiece> push_urls_;
67
68 private:
69 QuicStringPiece host_;
70 QuicStringPiece path_;
71 };
72
73 QuicMemoryCacheBackend();
74 QuicMemoryCacheBackend(const QuicMemoryCacheBackend&) = delete;
75 QuicMemoryCacheBackend& operator=(const QuicMemoryCacheBackend&) = delete;
76 ~QuicMemoryCacheBackend() override;
77
78 // Retrieve a response from this cache for a given host and path..
79 // If no appropriate response exists, nullptr is returned.
80 const QuicBackendResponse* GetResponse(QuicStringPiece host,
81 QuicStringPiece path) const;
82
83 // Adds a simple response to the cache. The response headers will
84 // only contain the "content-length" header with the length of |body|.
85 void AddSimpleResponse(QuicStringPiece host,
86 QuicStringPiece path,
87 int response_code,
88 QuicStringPiece body);
89
90 // Add a simple response to the cache as AddSimpleResponse() does, and add
91 // some server push resources(resource path, corresponding response status and
92 // path) associated with it.
93 // Push resource implicitly come from the same host.
94 void AddSimpleResponseWithServerPushResources(
95 QuicStringPiece host,
96 QuicStringPiece path,
97 int response_code,
98 QuicStringPiece body,
99 std::list<QuicBackendResponse::ServerPushInfo> push_resources);
100
101 // Add a response to the cache.
102 void AddResponse(QuicStringPiece host,
103 QuicStringPiece path,
104 spdy::SpdyHeaderBlock response_headers,
105 QuicStringPiece response_body);
106
107 // Add a response, with trailers, to the cache.
108 void AddResponse(QuicStringPiece host,
109 QuicStringPiece path,
110 spdy::SpdyHeaderBlock response_headers,
111 QuicStringPiece response_body,
112 spdy::SpdyHeaderBlock response_trailers);
113
114 // Simulate a special behavior at a particular path.
115 void AddSpecialResponse(
116 QuicStringPiece host,
117 QuicStringPiece path,
118 QuicBackendResponse::SpecialResponseType response_type);
119
120 void AddSpecialResponse(
121 QuicStringPiece host,
122 QuicStringPiece path,
123 spdy::SpdyHeaderBlock response_headers,
124 QuicStringPiece response_body,
125 QuicBackendResponse::SpecialResponseType response_type);
126
127 void AddStopSendingResponse(QuicStringPiece host,
128 QuicStringPiece path,
129 spdy::SpdyHeaderBlock response_headers,
130 QuicStringPiece response_body,
131 uint16_t stop_sending_code);
132
133 // Sets a default response in case of cache misses. Takes ownership of
134 // 'response'.
135 void AddDefaultResponse(QuicBackendResponse* response);
136
137 // |cache_cirectory| can be generated using `wget -p --save-headers <url>`.
vasilvvc48c8712019-03-11 13:38:16 -0700138 void InitializeFromDirectory(const std::string& cache_directory);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500139
140 // Find all the server push resources associated with |request_url|.
141 std::list<QuicBackendResponse::ServerPushInfo> GetServerPushResources(
vasilvvc48c8712019-03-11 13:38:16 -0700142 std::string request_url);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500143
144 // Implements the functions for interface QuicSimpleServerBackend
145 // |cache_cirectory| can be generated using `wget -p --save-headers <url>`.
vasilvvc48c8712019-03-11 13:38:16 -0700146 bool InitializeBackend(const std::string& cache_directory) override;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500147 bool IsBackendInitialized() const override;
148 void FetchResponseFromBackend(
149 const spdy::SpdyHeaderBlock& request_headers,
vasilvvc48c8712019-03-11 13:38:16 -0700150 const std::string& request_body,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500151 QuicSimpleServerBackend::RequestHandler* quic_server_stream) override;
152 void CloseBackendResponseStream(
153 QuicSimpleServerBackend::RequestHandler* quic_server_stream) override;
154
155 private:
156 void AddResponseImpl(QuicStringPiece host,
157 QuicStringPiece path,
158 QuicBackendResponse::SpecialResponseType response_type,
159 spdy::SpdyHeaderBlock response_headers,
160 QuicStringPiece response_body,
161 spdy::SpdyHeaderBlock response_trailers,
162 uint16_t stop_sending_code);
163
vasilvvc48c8712019-03-11 13:38:16 -0700164 std::string GetKey(QuicStringPiece host, QuicStringPiece path) const;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500165
166 // Add some server push urls with given responses for specified
167 // request if these push resources are not associated with this request yet.
168 void MaybeAddServerPushResources(
169 QuicStringPiece request_host,
170 QuicStringPiece request_path,
171 std::list<QuicBackendResponse::ServerPushInfo> push_resources);
172
173 // Check if push resource(push_host/push_path) associated with given request
174 // url already exists in server push map.
vasilvvc48c8712019-03-11 13:38:16 -0700175 bool PushResourceExistsInCache(std::string original_request_url,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500176 QuicBackendResponse::ServerPushInfo resource);
177
178 // Cached responses.
vasilvvc48c8712019-03-11 13:38:16 -0700179 QuicUnorderedMap<std::string, std::unique_ptr<QuicBackendResponse>> responses_
QUICHE teama6ef0a62019-03-07 20:34:33 -0500180 GUARDED_BY(response_mutex_);
181
182 // The default response for cache misses, if set.
183 std::unique_ptr<QuicBackendResponse> default_response_
184 GUARDED_BY(response_mutex_);
185
186 // A map from request URL to associated server push responses (if any).
vasilvvc48c8712019-03-11 13:38:16 -0700187 std::multimap<std::string, QuicBackendResponse::ServerPushInfo>
QUICHE teama6ef0a62019-03-07 20:34:33 -0500188 server_push_resources_ GUARDED_BY(response_mutex_);
189
190 // Protects against concurrent access from test threads setting responses, and
191 // server threads accessing those responses.
192 mutable QuicMutex response_mutex_;
193 bool cache_initialized_;
194};
195
196} // namespace quic
197
198#endif // QUICHE_QUIC_TOOLS_QUIC_MEMORY_CACHE_BACKEND_H_