Project import generated by Copybara.
PiperOrigin-RevId: 237361882
Change-Id: I109a68f44db867b20f8c6a7732b0ce657133e52a
diff --git a/quic/tools/quic_memory_cache_backend.h b/quic/tools/quic_memory_cache_backend.h
new file mode 100644
index 0000000..1417349
--- /dev/null
+++ b/quic/tools/quic_memory_cache_backend.h
@@ -0,0 +1,198 @@
+// Copyright (c) 2012 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.
+
+#ifndef QUICHE_QUIC_TOOLS_QUIC_MEMORY_CACHE_BACKEND_H_
+#define QUICHE_QUIC_TOOLS_QUIC_MEMORY_CACHE_BACKEND_H_
+
+#include <list>
+#include <map>
+#include <memory>
+#include <vector>
+
+#include "net/third_party/quiche/src/quic/core/http/spdy_utils.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_containers.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_mutex.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
+#include "net/third_party/quiche/src/quic/tools/quic_backend_response.h"
+#include "net/third_party/quiche/src/quic/tools/quic_simple_server_backend.h"
+#include "net/third_party/quiche/src/quic/tools/quic_url.h"
+#include "net/third_party/quiche/src/spdy/core/spdy_framer.h"
+
+namespace quic {
+
+// In-memory cache for HTTP responses.
+// Reads from disk cache generated by:
+// `wget -p --save_headers <url>`
+class QuicMemoryCacheBackend : public QuicSimpleServerBackend {
+ public:
+ // Class to manage loading a resource file into memory. There are
+ // two uses: called by InitializeBackend to load resources
+ // from files, and recursively called when said resources specify
+ // server push associations.
+ class ResourceFile {
+ public:
+ explicit ResourceFile(const QuicString& file_name);
+ ResourceFile(const ResourceFile&) = delete;
+ ResourceFile& operator=(const ResourceFile&) = delete;
+ virtual ~ResourceFile();
+
+ void Read();
+
+ // |base| is |file_name_| with |cache_directory| prefix stripped.
+ void SetHostPathFromBase(QuicStringPiece base);
+
+ const QuicString& file_name() { return file_name_; }
+
+ QuicStringPiece host() { return host_; }
+
+ QuicStringPiece path() { return path_; }
+
+ const spdy::SpdyHeaderBlock& spdy_headers() { return spdy_headers_; }
+
+ QuicStringPiece body() { return body_; }
+
+ const std::vector<QuicStringPiece>& push_urls() { return push_urls_; }
+
+ protected:
+ void HandleXOriginalUrl();
+ QuicStringPiece RemoveScheme(QuicStringPiece url);
+
+ QuicString file_name_;
+ QuicString file_contents_;
+ QuicStringPiece body_;
+ spdy::SpdyHeaderBlock spdy_headers_;
+ QuicStringPiece x_original_url_;
+ std::vector<QuicStringPiece> push_urls_;
+
+ private:
+ QuicStringPiece host_;
+ QuicStringPiece path_;
+ };
+
+ QuicMemoryCacheBackend();
+ QuicMemoryCacheBackend(const QuicMemoryCacheBackend&) = delete;
+ QuicMemoryCacheBackend& operator=(const QuicMemoryCacheBackend&) = delete;
+ ~QuicMemoryCacheBackend() override;
+
+ // Retrieve a response from this cache for a given host and path..
+ // If no appropriate response exists, nullptr is returned.
+ const QuicBackendResponse* GetResponse(QuicStringPiece host,
+ QuicStringPiece path) const;
+
+ // Adds a simple response to the cache. The response headers will
+ // only contain the "content-length" header with the length of |body|.
+ void AddSimpleResponse(QuicStringPiece host,
+ QuicStringPiece path,
+ int response_code,
+ QuicStringPiece body);
+
+ // Add a simple response to the cache as AddSimpleResponse() does, and add
+ // some server push resources(resource path, corresponding response status and
+ // path) associated with it.
+ // Push resource implicitly come from the same host.
+ void AddSimpleResponseWithServerPushResources(
+ QuicStringPiece host,
+ QuicStringPiece path,
+ int response_code,
+ QuicStringPiece body,
+ std::list<QuicBackendResponse::ServerPushInfo> push_resources);
+
+ // Add a response to the cache.
+ void AddResponse(QuicStringPiece host,
+ QuicStringPiece path,
+ spdy::SpdyHeaderBlock response_headers,
+ QuicStringPiece response_body);
+
+ // Add a response, with trailers, to the cache.
+ void AddResponse(QuicStringPiece host,
+ QuicStringPiece path,
+ spdy::SpdyHeaderBlock response_headers,
+ QuicStringPiece response_body,
+ spdy::SpdyHeaderBlock response_trailers);
+
+ // Simulate a special behavior at a particular path.
+ void AddSpecialResponse(
+ QuicStringPiece host,
+ QuicStringPiece path,
+ QuicBackendResponse::SpecialResponseType response_type);
+
+ void AddSpecialResponse(
+ QuicStringPiece host,
+ QuicStringPiece path,
+ spdy::SpdyHeaderBlock response_headers,
+ QuicStringPiece response_body,
+ QuicBackendResponse::SpecialResponseType response_type);
+
+ void AddStopSendingResponse(QuicStringPiece host,
+ QuicStringPiece path,
+ spdy::SpdyHeaderBlock response_headers,
+ QuicStringPiece response_body,
+ uint16_t stop_sending_code);
+
+ // Sets a default response in case of cache misses. Takes ownership of
+ // 'response'.
+ void AddDefaultResponse(QuicBackendResponse* response);
+
+ // |cache_cirectory| can be generated using `wget -p --save-headers <url>`.
+ void InitializeFromDirectory(const QuicString& cache_directory);
+
+ // Find all the server push resources associated with |request_url|.
+ std::list<QuicBackendResponse::ServerPushInfo> GetServerPushResources(
+ QuicString request_url);
+
+ // Implements the functions for interface QuicSimpleServerBackend
+ // |cache_cirectory| can be generated using `wget -p --save-headers <url>`.
+ bool InitializeBackend(const QuicString& cache_directory) override;
+ bool IsBackendInitialized() const override;
+ void FetchResponseFromBackend(
+ const spdy::SpdyHeaderBlock& request_headers,
+ const QuicString& request_body,
+ QuicSimpleServerBackend::RequestHandler* quic_server_stream) override;
+ void CloseBackendResponseStream(
+ QuicSimpleServerBackend::RequestHandler* quic_server_stream) override;
+
+ private:
+ void AddResponseImpl(QuicStringPiece host,
+ QuicStringPiece path,
+ QuicBackendResponse::SpecialResponseType response_type,
+ spdy::SpdyHeaderBlock response_headers,
+ QuicStringPiece response_body,
+ spdy::SpdyHeaderBlock response_trailers,
+ uint16_t stop_sending_code);
+
+ QuicString GetKey(QuicStringPiece host, QuicStringPiece path) const;
+
+ // Add some server push urls with given responses for specified
+ // request if these push resources are not associated with this request yet.
+ void MaybeAddServerPushResources(
+ QuicStringPiece request_host,
+ QuicStringPiece request_path,
+ std::list<QuicBackendResponse::ServerPushInfo> push_resources);
+
+ // Check if push resource(push_host/push_path) associated with given request
+ // url already exists in server push map.
+ bool PushResourceExistsInCache(QuicString original_request_url,
+ QuicBackendResponse::ServerPushInfo resource);
+
+ // Cached responses.
+ QuicUnorderedMap<QuicString, std::unique_ptr<QuicBackendResponse>> responses_
+ GUARDED_BY(response_mutex_);
+
+ // The default response for cache misses, if set.
+ std::unique_ptr<QuicBackendResponse> default_response_
+ GUARDED_BY(response_mutex_);
+
+ // A map from request URL to associated server push responses (if any).
+ std::multimap<QuicString, QuicBackendResponse::ServerPushInfo>
+ server_push_resources_ GUARDED_BY(response_mutex_);
+
+ // Protects against concurrent access from test threads setting responses, and
+ // server threads accessing those responses.
+ mutable QuicMutex response_mutex_;
+ bool cache_initialized_;
+};
+
+} // namespace quic
+
+#endif // QUICHE_QUIC_TOOLS_QUIC_MEMORY_CACHE_BACKEND_H_