200 lines
6.8 KiB
C++
200 lines
6.8 KiB
C++
// 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 <string>
|
|
|
|
#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_piece.h"
|
|
#include "base/strings/string_split.h"
|
|
#include "base/time/time.h"
|
|
#include "net/http/http_status_code.h"
|
|
#include "third_party/abseil-cpp/absl/types/optional.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 {
|
|
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:
|
|
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_
|