blob: c4c80f7878511a85c72025281bc205640a547d68 [file] [log] [blame]
[email protected]d8a5e9f92012-11-15 08:20:211// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]b6e5b6c62013-05-07 17:50:265#include "net/test/embedded_test_server/http_response.h"
[email protected]d8a5e9f92012-11-15 08:20:216
David Benjamin34627872019-11-27 20:11:327#include <utility>
8
Eric Robinsonc93faeb2018-05-14 02:38:009#include "base/bind.h"
Hans Wennborg0924470b2020-04-27 21:08:0510#include "base/check.h"
[email protected]d8a5e9f92012-11-15 08:20:2111#include "base/format_macros.h"
jam29f1aed42017-06-06 21:37:4312#include "base/strings/string_util.h"
[email protected]4dc3ad4f2013-06-11 07:15:5013#include "base/strings/stringprintf.h"
Eric Robinsonc93faeb2018-05-14 02:38:0014#include "base/threading/sequenced_task_runner_handle.h"
[email protected]c1dffe82013-06-26 20:59:0515#include "net/http/http_status_code.h"
[email protected]d8a5e9f92012-11-15 08:20:2116
[email protected]eb7388f2013-05-09 17:00:2617namespace net {
[email protected]d8a5e9f92012-11-15 08:20:2118namespace test_server {
19
Chris Watkins7a41d3552017-12-01 02:13:2720HttpResponse::~HttpResponse() = default;
[email protected]d8a5e9f92012-11-15 08:20:2121
svaldez6e7e82a22015-10-28 19:39:5322RawHttpResponse::RawHttpResponse(const std::string& headers,
23 const std::string& contents)
24 : headers_(headers), contents_(contents) {}
25
Chris Watkins7a41d3552017-12-01 02:13:2726RawHttpResponse::~RawHttpResponse() = default;
svaldez6e7e82a22015-10-28 19:39:5327
28void RawHttpResponse::SendResponse(const SendBytesCallback& send,
David Benjamin34627872019-11-27 20:11:3229 SendCompleteCallback done) {
svaldez6e7e82a22015-10-28 19:39:5330 std::string response;
jam29f1aed42017-06-06 21:37:4331 if (!headers_.empty()) {
32 response = headers_;
Min Qin32c60fd2017-10-02 23:38:2333 // LocateEndOfHeadersHelper() searches for the first "\n\n" and "\n\r\n" as
34 // the end of the header.
35 std::size_t index = response.find_last_not_of("\r\n");
36 if (index != std::string::npos)
37 response.erase(index + 1);
38 response += "\n\n";
39 response += contents_;
jam29f1aed42017-06-06 21:37:4340 } else {
svaldez6e7e82a22015-10-28 19:39:5341 response = contents_;
jam29f1aed42017-06-06 21:37:4342 }
David Benjamin34627872019-11-27 20:11:3243 send.Run(response, std::move(done));
svaldez6e7e82a22015-10-28 19:39:5344}
45
46void RawHttpResponse::AddHeader(const std::string& key_value_pair) {
47 headers_.append(base::StringPrintf("%s\r\n", key_value_pair.c_str()));
48}
49
[email protected]c1dffe82013-06-26 20:59:0550BasicHttpResponse::BasicHttpResponse() : code_(HTTP_OK) {
[email protected]0d31fbc2013-05-28 17:00:3751}
52
Chris Watkins7a41d3552017-12-01 02:13:2753BasicHttpResponse::~BasicHttpResponse() = default;
[email protected]0d31fbc2013-05-28 17:00:3754
55std::string BasicHttpResponse::ToResponseString() const {
[email protected]d8a5e9f92012-11-15 08:20:2156 // Response line with headers.
57 std::string response_builder;
58
[email protected]c1dffe82013-06-26 20:59:0559 std::string http_reason_phrase(GetHttpReasonPhrase(code_));
60
[email protected]d8a5e9f92012-11-15 08:20:2161 // TODO(mtomasz): For http/1.0 requests, send http/1.0.
[email protected]c1dffe82013-06-26 20:59:0562 base::StringAppendF(&response_builder,
63 "HTTP/1.1 %d %s\r\n",
64 code_,
65 http_reason_phrase.c_str());
66 base::StringAppendF(&response_builder, "Connection: close\r\n");
svaldez6e7e82a22015-10-28 19:39:5367
68 base::StringAppendF(&response_builder, "Content-Length: %" PRIuS "\r\n",
[email protected]d8a5e9f92012-11-15 08:20:2169 content_.size());
svaldez6e7e82a22015-10-28 19:39:5370 base::StringAppendF(&response_builder, "Content-Type: %s\r\n",
[email protected]d8a5e9f92012-11-15 08:20:2171 content_type_.c_str());
[email protected]c1dffe82013-06-26 20:59:0572 for (size_t i = 0; i < custom_headers_.size(); ++i) {
73 const std::string& header_name = custom_headers_[i].first;
74 const std::string& header_value = custom_headers_[i].second;
[email protected]d8a5e9f92012-11-15 08:20:2175 DCHECK(header_value.find_first_of("\n\r") == std::string::npos) <<
76 "Malformed header value.";
77 base::StringAppendF(&response_builder,
78 "%s: %s\r\n",
79 header_name.c_str(),
80 header_value.c_str());
81 }
82 base::StringAppendF(&response_builder, "\r\n");
83
84 return response_builder + content_;
85}
86
svaldez6e7e82a22015-10-28 19:39:5387void BasicHttpResponse::SendResponse(const SendBytesCallback& send,
David Benjamin34627872019-11-27 20:11:3288 SendCompleteCallback done) {
89 send.Run(ToResponseString(), std::move(done));
svaldez6e7e82a22015-10-28 19:39:5390}
91
Eric Robinsonc93faeb2018-05-14 02:38:0092DelayedHttpResponse::DelayedHttpResponse(const base::TimeDelta delay)
93 : delay_(delay) {}
94
95DelayedHttpResponse::~DelayedHttpResponse() = default;
96
97void DelayedHttpResponse::SendResponse(const SendBytesCallback& send,
David Benjamin34627872019-11-27 20:11:3298 SendCompleteCallback done) {
Eric Robinsonc93faeb2018-05-14 02:38:0099 base::SequencedTaskRunnerHandle::Get()->PostDelayedTask(
David Benjamin34627872019-11-27 20:11:32100 FROM_HERE, base::BindOnce(send, ToResponseString(), std::move(done)),
101 delay_);
Eric Robinsonc93faeb2018-05-14 02:38:00102}
103
mmenke173a6aa2016-10-17 19:14:09104void HungResponse::SendResponse(const SendBytesCallback& send,
David Benjamin34627872019-11-27 20:11:32105 SendCompleteCallback done) {}
mmenke173a6aa2016-10-17 19:14:09106
[email protected]d8a5e9f92012-11-15 08:20:21107} // namespace test_server
[email protected]eb7388f2013-05-09 17:00:26108} // namespace net