1 // Copyright 2012 The Chromium Authors 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_TEST_EMBEDDED_TEST_SERVER_HTTP_RESPONSE_H_ 6 #define NET_TEST_EMBEDDED_TEST_SERVER_HTTP_RESPONSE_H_ 7 8 #include <string> 9 10 #include "base/compiler_specific.h" 11 #include "base/functional/bind.h" 12 #include "base/functional/callback.h" 13 #include "base/functional/callback_helpers.h" 14 #include "base/memory/weak_ptr.h" 15 #include "base/strings/string_number_conversions.h" 16 #include "base/strings/string_piece.h" 17 #include "base/strings/string_split.h" 18 #include "base/time/time.h" 19 #include "net/http/http_status_code.h" 20 #include "third_party/abseil-cpp/absl/types/optional.h" 21 22 namespace net::test_server { 23 24 class HttpResponse; 25 26 // Delegate that actually sends the response bytes. Any response created should 27 // be owned by the delegate that passed in via HttpResponse::SendResponse(). 28 class HttpResponseDelegate { 29 public: 30 HttpResponseDelegate(); 31 virtual ~HttpResponseDelegate(); 32 HttpResponseDelegate(HttpResponseDelegate&) = delete; 33 HttpResponseDelegate& operator=(const HttpResponseDelegate&) = delete; 34 35 // The delegate needs to take ownership of the response to ensure the 36 // response can stay alive until the delegate has finished sending it. 37 virtual void AddResponse(std::unique_ptr<HttpResponse> response) = 0; 38 39 // Builds and sends header block. Should only be called once. 40 virtual void SendResponseHeaders(HttpStatusCode status, 41 const std::string& status_reason, 42 const base::StringPairs& headers) = 0; 43 // Sends a raw header block, in the form of an HTTP1.1 response header block 44 // (separated by "\r\n". Best effort will be maintained to preserve the raw 45 // headers. 46 virtual void SendRawResponseHeaders(const std::string& headers) = 0; 47 48 // Sends a content block, then calls the closure. 49 virtual void SendContents(const std::string& contents, 50 base::OnceClosure callback = base::DoNothing()) = 0; 51 52 // Called after the last content block or after the header block. The response 53 // will hang until this is called. 54 virtual void FinishResponse() = 0; 55 56 // The following functions are essentially shorthand for common combinations 57 // of function calls that may have a more efficient layout than just calling 58 // one after the other. 59 virtual void SendContentsAndFinish(const std::string& contents) = 0; 60 virtual void SendHeadersContentAndFinish(HttpStatusCode status, 61 const std::string& status_reason, 62 const base::StringPairs& headers, 63 const std::string& contents) = 0; 64 }; 65 66 // Interface for HTTP response implementations. The response should be owned by 67 // the HttpResponseDelegate passed into SendResponse(), and should stay alive 68 // until FinishResponse() is called on the delegate (or the owning delegate is 69 // destroyed). 70 class HttpResponse { 71 public: 72 virtual ~HttpResponse(); 73 74 // Note that this is a WeakPtr. WeakPtrs can not be dereferenced or 75 // invalidated outside of the thread that created them, so any use of the 76 // delegate must either be from the same thread or posted to the original 77 // task runner 78 virtual void SendResponse(base::WeakPtr<HttpResponseDelegate> delegate) = 0; 79 }; 80 81 // This class is used to handle basic HTTP responses with commonly used 82 // response headers such as "Content-Type". Sends the response immediately. 83 class BasicHttpResponse : public HttpResponse { 84 public: 85 BasicHttpResponse(); 86 87 BasicHttpResponse(const BasicHttpResponse&) = delete; 88 BasicHttpResponse& operator=(const BasicHttpResponse&) = delete; 89 90 ~BasicHttpResponse() override; 91 92 // The response code. code()93 HttpStatusCode code() const { return code_; } set_code(HttpStatusCode code)94 void set_code(HttpStatusCode code) { code_ = code; } 95 reason()96 std::string reason() const { 97 return reason_.value_or(GetHttpReasonPhrase(code_)); 98 } set_reason(absl::optional<std::string> reason)99 void set_reason(absl::optional<std::string> reason) { 100 reason_ = std::move(reason); 101 } 102 103 // The content of the response. content()104 const std::string& content() const { return content_; } set_content(base::StringPiece content)105 void set_content(base::StringPiece content) { 106 content_ = std::string{content}; 107 } 108 109 // The content type. content_type()110 const std::string& content_type() const { return content_type_; } set_content_type(base::StringPiece content_type)111 void set_content_type(base::StringPiece content_type) { 112 content_type_ = std::string{content_type}; 113 } 114 115 // Adds a custom header. AddCustomHeader(base::StringPiece key,base::StringPiece value)116 void AddCustomHeader(base::StringPiece key, base::StringPiece value) { 117 custom_headers_.emplace_back(key, value); 118 } 119 120 // Generates and returns a http response string. 121 std::string ToResponseString() const; 122 123 base::StringPairs BuildHeaders() const; 124 125 void SendResponse(base::WeakPtr<HttpResponseDelegate> delegate) override; 126 127 private: 128 HttpStatusCode code_ = HTTP_OK; 129 absl::optional<std::string> reason_; 130 std::string content_; 131 std::string content_type_; 132 base::StringPairs custom_headers_; 133 base::WeakPtrFactory<BasicHttpResponse> weak_factory_{this}; 134 }; 135 136 class DelayedHttpResponse : public BasicHttpResponse { 137 public: 138 explicit DelayedHttpResponse(const base::TimeDelta delay); 139 140 DelayedHttpResponse(const DelayedHttpResponse&) = delete; 141 DelayedHttpResponse& operator=(const DelayedHttpResponse&) = delete; 142 143 ~DelayedHttpResponse() override; 144 145 // Issues a delayed send to the to the task runner. 146 void SendResponse(base::WeakPtr<HttpResponseDelegate> delegate) override; 147 148 private: 149 // The delay time for the response. 150 const base::TimeDelta delay_; 151 }; 152 153 class RawHttpResponse : public HttpResponse { 154 public: 155 RawHttpResponse(const std::string& headers, const std::string& contents); 156 157 RawHttpResponse(const RawHttpResponse&) = delete; 158 RawHttpResponse& operator=(const RawHttpResponse&) = delete; 159 160 ~RawHttpResponse() override; 161 162 void SendResponse(base::WeakPtr<HttpResponseDelegate> delegate) override; 163 164 void AddHeader(const std::string& key_value_pair); 165 166 private: 167 std::string headers_; 168 const std::string contents_; 169 }; 170 171 // "Response" where the server doesn't actually respond until the server is 172 // destroyed. 173 class HungResponse : public HttpResponse { 174 public: 175 HungResponse() = default; 176 177 HungResponse(const HungResponse&) = delete; 178 HungResponse& operator=(const HungResponse&) = delete; 179 180 ~HungResponse() override = default; 181 182 void SendResponse(base::WeakPtr<HttpResponseDelegate> delegate) override; 183 }; 184 185 // Return headers, then hangs. 186 class HungAfterHeadersHttpResponse : public HttpResponse { 187 public: 188 explicit HungAfterHeadersHttpResponse(base::StringPairs headers = {}); 189 ~HungAfterHeadersHttpResponse() override; 190 191 void SendResponse(base::WeakPtr<HttpResponseDelegate> delegate) override; 192 193 private: 194 base::StringPairs headers_; 195 }; 196 197 } // namespace net::test_server 198 199 #endif // NET_TEST_EMBEDDED_TEST_SERVER_HTTP_RESPONSE_H_ 200