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 #include "net/test/embedded_test_server/http_response.h"
6
7 #include <iterator>
8 #include <map>
9 #include <string>
10 #include <utility>
11
12 #include "base/check.h"
13 #include "base/containers/flat_map.h"
14 #include "base/format_macros.h"
15 #include "base/functional/bind.h"
16 #include "base/functional/callback_forward.h"
17 #include "base/logging.h"
18 #include "base/ranges/algorithm.h"
19 #include "base/strings/string_number_conversions.h"
20 #include "base/strings/string_split.h"
21 #include "base/strings/string_util.h"
22 #include "base/strings/stringprintf.h"
23 #include "base/task/sequenced_task_runner.h"
24 #include "net/http/http_status_code.h"
25 #include "net/test/embedded_test_server/http_request.h"
26
27 namespace net::test_server {
28
29 HttpResponseDelegate::HttpResponseDelegate() = default;
30 HttpResponseDelegate::~HttpResponseDelegate() = default;
31
32 HttpResponse::~HttpResponse() = default;
33
RawHttpResponse(const std::string & headers,const std::string & contents)34 RawHttpResponse::RawHttpResponse(const std::string& headers,
35 const std::string& contents)
36 : headers_(headers), contents_(contents) {}
37
38 RawHttpResponse::~RawHttpResponse() = default;
39
SendResponse(base::WeakPtr<HttpResponseDelegate> delegate)40 void RawHttpResponse::SendResponse(
41 base::WeakPtr<HttpResponseDelegate> delegate) {
42 if (!headers_.empty()) {
43 std::string response = headers_;
44 // LocateEndOfHeadersHelper() searches for the first "\n\n" and "\n\r\n" as
45 // the end of the header.
46 std::size_t index = response.find_last_not_of("\r\n");
47 if (index != std::string::npos)
48 response.erase(index + 1);
49 response += "\n\n";
50 delegate->SendRawResponseHeaders(response);
51 }
52
53 delegate->SendContentsAndFinish(contents_);
54 }
55
AddHeader(const std::string & key_value_pair)56 void RawHttpResponse::AddHeader(const std::string& key_value_pair) {
57 headers_.append(base::StringPrintf("%s\r\n", key_value_pair.c_str()));
58 }
59
60 BasicHttpResponse::BasicHttpResponse() = default;
61
62 BasicHttpResponse::~BasicHttpResponse() = default;
63
ToResponseString() const64 std::string BasicHttpResponse::ToResponseString() const {
65 base::StringPairs headers = BuildHeaders();
66 // Response line with headers.
67 std::string response_builder;
68
69 // TODO(mtomasz): For http/1.0 requests, send http/1.0.
70
71 base::StringAppendF(&response_builder, "HTTP/1.1 %d %s\r\n", code_,
72 reason().c_str());
73
74 for (const auto& header : headers)
75 base::StringAppendF(&response_builder, "%s: %s\r\n", header.first.c_str(),
76 header.second.c_str());
77
78 base::StringAppendF(&response_builder, "\r\n");
79
80 return response_builder + content_;
81 }
82
BuildHeaders() const83 base::StringPairs BasicHttpResponse::BuildHeaders() const {
84 base::StringPairs headers;
85 headers.emplace_back("Connection", "close");
86 headers.emplace_back("Content-Length", base::NumberToString(content_.size()));
87 headers.emplace_back("Content-Type", content_type_);
88
89 base::ranges::copy(custom_headers_, std::back_inserter(headers));
90
91 return headers;
92 }
93
SendResponse(base::WeakPtr<HttpResponseDelegate> delegate)94 void BasicHttpResponse::SendResponse(
95 base::WeakPtr<HttpResponseDelegate> delegate) {
96 delegate->SendHeadersContentAndFinish(code_, reason(), BuildHeaders(),
97 content_);
98 }
99
DelayedHttpResponse(const base::TimeDelta delay)100 DelayedHttpResponse::DelayedHttpResponse(const base::TimeDelta delay)
101 : delay_(delay) {}
102
103 DelayedHttpResponse::~DelayedHttpResponse() = default;
104
SendResponse(base::WeakPtr<HttpResponseDelegate> delegate)105 void DelayedHttpResponse::SendResponse(
106 base::WeakPtr<HttpResponseDelegate> delegate) {
107 base::SequencedTaskRunner::GetCurrentDefault()->PostDelayedTask(
108 FROM_HERE,
109 base::BindOnce(&HttpResponseDelegate::SendHeadersContentAndFinish,
110 delegate, code(), reason(), BuildHeaders(), content()),
111 delay_);
112 }
113
SendResponse(base::WeakPtr<HttpResponseDelegate> delegate)114 void HungResponse::SendResponse(base::WeakPtr<HttpResponseDelegate> delegate) {}
115
HungAfterHeadersHttpResponse(base::StringPairs headers)116 HungAfterHeadersHttpResponse::HungAfterHeadersHttpResponse(
117 base::StringPairs headers)
118 : headers_(headers) {}
119 HungAfterHeadersHttpResponse::~HungAfterHeadersHttpResponse() = default;
120
SendResponse(base::WeakPtr<HttpResponseDelegate> delegate)121 void HungAfterHeadersHttpResponse::SendResponse(
122 base::WeakPtr<HttpResponseDelegate> delegate) {
123 delegate->SendResponseHeaders(HTTP_OK, "OK", headers_);
124 }
125
126 } // namespace net::test_server
127