• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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