1// Copyright 2014 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_QUIC_QUIC_IN_MEMORY_CACHE_H_ 6#define NET_QUIC_QUIC_IN_MEMORY_CACHE_H_ 7 8#include <string> 9 10#include "base/containers/hash_tables.h" 11#include "base/memory/singleton.h" 12#include "base/strings/string_piece.h" 13#include "net/base/net_export.h" 14#include "net/tools/balsa/balsa_frame.h" 15#include "net/tools/balsa/balsa_headers.h" 16#include "net/tools/balsa/noop_balsa_visitor.h" 17 18template <typename T> struct DefaultSingletonTraits; 19 20namespace net { 21 22namespace test { 23class QuicInMemoryCachePeer; 24} // namespace 25 26class QuicServer; 27 28// In-memory cache for HTTP responses. 29// Reads from disk cache generated by: 30// `wget -p --save_headers <url>` 31class QuicInMemoryCache { 32 public: 33 enum SpecialResponseType { 34 REGULAR_RESPONSE, // Send the headers and body like a server should. 35 CLOSE_CONNECTION, // Close the connection (sending the close packet). 36 IGNORE_REQUEST, // Do nothing, expect the client to time out. 37 }; 38 39 // Container for response header/body pairs. 40 class Response { 41 public: 42 Response() : response_type_(REGULAR_RESPONSE) {} 43 ~Response() {} 44 45 SpecialResponseType response_type() const { return response_type_; } 46 const BalsaHeaders& headers() const { return headers_; } 47 const base::StringPiece body() const { return base::StringPiece(body_); } 48 49 private: 50 friend class QuicInMemoryCache; 51 52 void set_headers(const BalsaHeaders& headers) { 53 headers_.CopyFrom(headers); 54 } 55 void set_body(base::StringPiece body) { 56 body.CopyToString(&body_); 57 } 58 59 SpecialResponseType response_type_; 60 BalsaHeaders headers_; 61 std::string body_; 62 63 DISALLOW_COPY_AND_ASSIGN(Response); 64 }; 65 66 // Returns the singleton instance of the cache. 67 static QuicInMemoryCache* GetInstance(); 68 69 // Retrieve a response from this cache for a given request. 70 // If no appropriate response exists, NULL is returned. 71 // Currently, responses are selected based on request URI only. 72 const Response* GetResponse(const BalsaHeaders& request_headers) const; 73 74 // Adds a simple response to the cache. The response headers will 75 // only contain the "content-length" header with the lenght of |body|. 76 void AddSimpleResponse(base::StringPiece method, 77 base::StringPiece path, 78 base::StringPiece version, 79 base::StringPiece response_code, 80 base::StringPiece response_detail, 81 base::StringPiece body); 82 83 // Add a response to the cache. 84 void AddResponse(const BalsaHeaders& request_headers, 85 const BalsaHeaders& response_headers, 86 base::StringPiece response_body); 87 88 // Simulate a special behavior at a particular path. 89 void AddSpecialResponse(base::StringPiece method, 90 base::StringPiece path, 91 base::StringPiece version, 92 SpecialResponseType response_type); 93 94 private: 95 typedef base::hash_map<std::string, Response*> ResponseMap; 96 friend struct DefaultSingletonTraits<QuicInMemoryCache>; 97 friend class test::QuicInMemoryCachePeer; 98 99 QuicInMemoryCache(); 100 ~QuicInMemoryCache(); 101 102 void ResetForTests(); 103 104 void Initialize(); 105 106 std::string GetKey(const BalsaHeaders& response_headers) const; 107 108 // Cached responses. 109 ResponseMap responses_; 110 111 DISALLOW_COPY_AND_ASSIGN(QuicInMemoryCache); 112}; 113 114} // namespace net 115 116#endif // NET_QUIC_QUIC_IN_MEMORY_CACHE_H_ 117