xref: /aosp_15_r20/external/cronet/net/test/embedded_test_server/http_response.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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