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 202 203
|
// Copyright 2012 The Chromium Authors
// 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 <optional>
#include <string>
#include <string_view>
#include "base/compiler_specific.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/time/time.h"
#include "net/http/http_status_code.h"
namespace net::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 {
if (reason_) {
return *reason_;
} else {
return GetHttpReasonPhrase(code_);
}
}
void set_reason(std::optional<std::string> reason) {
reason_ = std::move(reason);
}
// The content of the response.
const std::string& content() const { return content_; }
void set_content(std::string_view content) {
content_ = std::string{content};
}
// The content type.
const std::string& content_type() const { return content_type_; }
void set_content_type(std::string_view content_type) {
content_type_ = std::string{content_type};
}
// Adds a custom header.
void AddCustomHeader(std::string_view key, std::string_view 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;
std::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:
explicit 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() = default;
HungResponse(const HungResponse&) = delete;
HungResponse& operator=(const HungResponse&) = delete;
~HungResponse() override = default;
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 net::test_server
#endif // NET_TEST_EMBEDDED_TEST_SERVER_HTTP_RESPONSE_H_
|