summaryrefslogtreecommitdiff
path: root/chromium/net/test/embedded_test_server/http_response.h
blob: de2ffe071708ce9433ad0ceb305f7abb59847c13 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
// 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 NET_TEST_EMBEDDED_TEST_SERVER_HTTP_RESPONSE_H_
#define NET_TEST_EMBEDDED_TEST_SERVER_HTTP_RESPONSE_H_

#include <string>

#include "absl/types/optional.h"
#include "base/bind.h"
#include "base/callback.h"
#include "base/callback_helpers.h"
#include "base/compiler_specific.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_split.h"
#include "base/time/time.h"
#include "net/http/http_status_code.h"

namespace net {
namespace test_server {

class HttpResponse;

// Delegate that actually sends the response bytes. Any response created should
// be owned by the delegate that passed in via HttpResponse::SendResponse().
class HttpResponseDelegate {
 public:
  HttpResponseDelegate();
  virtual ~HttpResponseDelegate();
  HttpResponseDelegate(HttpResponseDelegate&) = delete;
  HttpResponseDelegate& operator=(const HttpResponseDelegate&) = delete;

  // The delegate needs to take ownership of the response to ensure the
  // response can stay alive until the delegate has finished sending it.
  virtual void AddResponse(std::unique_ptr<HttpResponse> response) = 0;

  // Builds and sends header block. Should only be called once.
  virtual void SendResponseHeaders(HttpStatusCode status,
                                   const std::string& status_reason,
                                   const base::StringPairs& headers) = 0;
  // Sends a raw header block, in the form of an HTTP1.1 response header block
  // (separated by "\r\n". Best effort will be maintained to preserve the raw
  // headers.
  virtual void SendRawResponseHeaders(const std::string& headers) = 0;

  // Sends a content block, then calls the closure.
  virtual void SendContents(const std::string& contents,
                            base::OnceClosure callback = base::DoNothing()) = 0;

  // Called after the last content block or after the header block. The response
  // will hang until this is called.
  virtual void FinishResponse() = 0;

  // The following functions are essentially shorthand for common combinations
  // of function calls that may have a more efficient layout than just calling
  // one after the other.
  virtual void SendContentsAndFinish(const std::string& contents) = 0;
  virtual void SendHeadersContentAndFinish(HttpStatusCode status,
                                           const std::string& status_reason,
                                           const base::StringPairs& headers,
                                           const std::string& contents) = 0;
};

// Interface for HTTP response implementations. The response should be owned by
// the HttpResponseDelegate passed into SendResponse(), and should stay alive
// until FinishResponse() is called on the delegate (or the owning delegate is
// destroyed).
class HttpResponse {
 public:
  virtual ~HttpResponse();

  // Note that this is a WeakPtr. WeakPtrs can not be dereferenced or
  // invalidated outside of the thread that created them, so any use of the
  // delegate must either be from the same thread or posted to the original
  // task runner
  virtual void SendResponse(base::WeakPtr<HttpResponseDelegate> delegate) = 0;
};

// This class is used to handle basic HTTP responses with commonly used
// response headers such as "Content-Type". Sends the response immediately.
class BasicHttpResponse : public HttpResponse {
 public:
  BasicHttpResponse();

  BasicHttpResponse(const BasicHttpResponse&) = delete;
  BasicHttpResponse& operator=(const BasicHttpResponse&) = delete;

  ~BasicHttpResponse() override;

  // The response code.
  HttpStatusCode code() const { return code_; }
  void set_code(HttpStatusCode code) { code_ = code; }

  std::string reason() const {
    return reason_.value_or(GetHttpReasonPhrase(code_));
  }
  void set_reason(absl::optional<std::string> reason) {
    reason_ = std::move(reason);
  }

  // The content of the response.
  const std::string& content() const { return content_; }
  void set_content(base::StringPiece content) {
    content_ = std::string{content};
  }

  // The content type.
  const std::string& content_type() const { return content_type_; }
  void set_content_type(base::StringPiece content_type) {
    content_type_ = std::string{content_type};
  }

  // Adds a custom header.
  void AddCustomHeader(base::StringPiece key, base::StringPiece value) {
    custom_headers_.emplace_back(key, value);
  }

  // Generates and returns a http response string.
  std::string ToResponseString() const;

  base::StringPairs BuildHeaders() const;

  void SendResponse(base::WeakPtr<HttpResponseDelegate> delegate) override;

 private:
  HttpStatusCode code_ = HTTP_OK;
  absl::optional<std::string> reason_;
  std::string content_;
  std::string content_type_;
  base::StringPairs custom_headers_;
  base::WeakPtrFactory<BasicHttpResponse> weak_factory_{this};
};

class DelayedHttpResponse : public BasicHttpResponse {
 public:
  DelayedHttpResponse(const base::TimeDelta delay);

  DelayedHttpResponse(const DelayedHttpResponse&) = delete;
  DelayedHttpResponse& operator=(const DelayedHttpResponse&) = delete;

  ~DelayedHttpResponse() override;

  // Issues a delayed send to the to the task runner.
  void SendResponse(base::WeakPtr<HttpResponseDelegate> delegate) override;

 private:
  // The delay time for the response.
  const base::TimeDelta delay_;
};

class RawHttpResponse : public HttpResponse {
 public:
  RawHttpResponse(const std::string& headers, const std::string& contents);

  RawHttpResponse(const RawHttpResponse&) = delete;
  RawHttpResponse& operator=(const RawHttpResponse&) = delete;

  ~RawHttpResponse() override;

  void SendResponse(base::WeakPtr<HttpResponseDelegate> delegate) override;

  void AddHeader(const std::string& key_value_pair);

 private:
  std::string headers_;
  const std::string contents_;
};

// "Response" where the server doesn't actually respond until the server is
// destroyed.
class HungResponse : public HttpResponse {
 public:
  HungResponse() {}

  HungResponse(const HungResponse&) = delete;
  HungResponse& operator=(const HungResponse&) = delete;

  ~HungResponse() override {}

  void SendResponse(base::WeakPtr<HttpResponseDelegate> delegate) override;
};

// Return headers, then hangs.
class HungAfterHeadersHttpResponse : public HttpResponse {
 public:
  explicit HungAfterHeadersHttpResponse(base::StringPairs headers = {});
  ~HungAfterHeadersHttpResponse() override;

  void SendResponse(base::WeakPtr<HttpResponseDelegate> delegate) override;

 private:
  base::StringPairs headers_;
};

}  // namespace test_server
}  // namespace net

#endif  // NET_TEST_EMBEDDED_TEST_SERVER_HTTP_RESPONSE_H_