• 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 <optional>
9 #include <string>
10 #include <string_view>
11 
12 #include "base/compiler_specific.h"
13 #include "base/functional/bind.h"
14 #include "base/functional/callback.h"
15 #include "base/functional/callback_helpers.h"
16 #include "base/memory/weak_ptr.h"
17 #include "base/strings/string_number_conversions.h"
18 #include "base/strings/string_split.h"
19 #include "base/time/time.h"
20 #include "net/http/http_status_code.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     if (reason_) {
98       return *reason_;
99     } else {
100       return GetHttpReasonPhrase(code_);
101     }
102   }
set_reason(std::optional<std::string> reason)103   void set_reason(std::optional<std::string> reason) {
104     reason_ = std::move(reason);
105   }
106 
107   // The content of the response.
content()108   const std::string& content() const { return content_; }
set_content(std::string_view content)109   void set_content(std::string_view content) {
110     content_ = std::string{content};
111   }
112 
113   // The content type.
content_type()114   const std::string& content_type() const { return content_type_; }
set_content_type(std::string_view content_type)115   void set_content_type(std::string_view content_type) {
116     content_type_ = std::string{content_type};
117   }
118 
119   // Adds a custom header.
AddCustomHeader(std::string_view key,std::string_view value)120   void AddCustomHeader(std::string_view key, std::string_view value) {
121     custom_headers_.emplace_back(key, value);
122   }
123 
124   // Generates and returns a http response string.
125   std::string ToResponseString() const;
126 
127   base::StringPairs BuildHeaders() const;
128 
129   void SendResponse(base::WeakPtr<HttpResponseDelegate> delegate) override;
130 
131  private:
132   HttpStatusCode code_ = HTTP_OK;
133   std::optional<std::string> reason_;
134   std::string content_;
135   std::string content_type_;
136   base::StringPairs custom_headers_;
137   base::WeakPtrFactory<BasicHttpResponse> weak_factory_{this};
138 };
139 
140 class DelayedHttpResponse : public BasicHttpResponse {
141  public:
142   explicit DelayedHttpResponse(const base::TimeDelta delay);
143 
144   DelayedHttpResponse(const DelayedHttpResponse&) = delete;
145   DelayedHttpResponse& operator=(const DelayedHttpResponse&) = delete;
146 
147   ~DelayedHttpResponse() override;
148 
149   // Issues a delayed send to the to the task runner.
150   void SendResponse(base::WeakPtr<HttpResponseDelegate> delegate) override;
151 
152  private:
153   // The delay time for the response.
154   const base::TimeDelta delay_;
155 };
156 
157 class RawHttpResponse : public HttpResponse {
158  public:
159   RawHttpResponse(const std::string& headers, const std::string& contents);
160 
161   RawHttpResponse(const RawHttpResponse&) = delete;
162   RawHttpResponse& operator=(const RawHttpResponse&) = delete;
163 
164   ~RawHttpResponse() override;
165 
166   void SendResponse(base::WeakPtr<HttpResponseDelegate> delegate) override;
167 
168   void AddHeader(const std::string& key_value_pair);
169 
170  private:
171   std::string headers_;
172   const std::string contents_;
173 };
174 
175 // "Response" where the server doesn't actually respond until the server is
176 // destroyed.
177 class HungResponse : public HttpResponse {
178  public:
179   HungResponse() = default;
180 
181   HungResponse(const HungResponse&) = delete;
182   HungResponse& operator=(const HungResponse&) = delete;
183 
184   ~HungResponse() override = default;
185 
186   void SendResponse(base::WeakPtr<HttpResponseDelegate> delegate) override;
187 };
188 
189 // Return headers, then hangs.
190 class HungAfterHeadersHttpResponse : public HttpResponse {
191  public:
192   explicit HungAfterHeadersHttpResponse(base::StringPairs headers = {});
193   ~HungAfterHeadersHttpResponse() override;
194 
195   void SendResponse(base::WeakPtr<HttpResponseDelegate> delegate) override;
196 
197  private:
198   base::StringPairs headers_;
199 };
200 
201 }  // namespace net::test_server
202 
203 #endif  // NET_TEST_EMBEDDED_TEST_SERVER_HTTP_RESPONSE_H_
204