1 // Copyright 2014 The Chromium OS 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
5 #include <brillo/http/http_connection_fake.h>
6
7 #include <base/logging.h>
8 #include <brillo/bind_lambda.h>
9 #include <brillo/http/http_request.h>
10 #include <brillo/mime_utils.h>
11 #include <brillo/streams/memory_stream.h>
12 #include <brillo/strings/string_utils.h>
13
14 namespace brillo {
15 namespace http {
16 namespace fake {
17
Connection(const std::string & url,const std::string & method,const std::shared_ptr<http::Transport> & transport)18 Connection::Connection(const std::string& url,
19 const std::string& method,
20 const std::shared_ptr<http::Transport>& transport)
21 : http::Connection(transport), request_(url, method) {
22 VLOG(1) << "fake::Connection created: " << method;
23 }
24
~Connection()25 Connection::~Connection() {
26 VLOG(1) << "fake::Connection destroyed";
27 }
28
SendHeaders(const HeaderList & headers,brillo::ErrorPtr *)29 bool Connection::SendHeaders(const HeaderList& headers,
30 brillo::ErrorPtr* /* error */) {
31 request_.AddHeaders(headers);
32 return true;
33 }
34
SetRequestData(StreamPtr stream,brillo::ErrorPtr *)35 bool Connection::SetRequestData(StreamPtr stream,
36 brillo::ErrorPtr* /* error */) {
37 request_.SetData(std::move(stream));
38 return true;
39 }
40
FinishRequest(brillo::ErrorPtr *)41 bool Connection::FinishRequest(brillo::ErrorPtr* /* error */) {
42 using brillo::string_utils::ToString;
43 request_.AddHeaders(
44 {{request_header::kContentLength, ToString(request_.GetData().size())}});
45 fake::Transport* transport = static_cast<fake::Transport*>(transport_.get());
46 CHECK(transport) << "Expecting a fake transport";
47 auto handler = transport->GetHandler(request_.GetURL(), request_.GetMethod());
48 if (handler.is_null()) {
49 LOG(ERROR) << "Received unexpected " << request_.GetMethod()
50 << " request at " << request_.GetURL();
51 response_.ReplyText(status_code::NotFound,
52 "<html><body>Not found</body></html>",
53 brillo::mime::text::kHtml);
54 } else {
55 handler.Run(request_, &response_);
56 }
57 return true;
58 }
59
FinishRequestAsync(const SuccessCallback & success_callback,const ErrorCallback & error_callback)60 RequestID Connection::FinishRequestAsync(
61 const SuccessCallback& success_callback,
62 const ErrorCallback& error_callback) {
63 // Make sure the produced Closure holds a reference to the instance of this
64 // connection.
65 auto connection = std::static_pointer_cast<Connection>(shared_from_this());
66 auto callback = [connection, success_callback, error_callback] {
67 connection->FinishRequestAsyncHelper(success_callback, error_callback);
68 };
69 transport_->RunCallbackAsync(FROM_HERE, base::Bind(callback));
70 return 1;
71 }
72
FinishRequestAsyncHelper(const SuccessCallback & success_callback,const ErrorCallback & error_callback)73 void Connection::FinishRequestAsyncHelper(
74 const SuccessCallback& success_callback,
75 const ErrorCallback& error_callback) {
76 brillo::ErrorPtr error;
77 if (!FinishRequest(&error)) {
78 error_callback.Run(1, error.get());
79 } else {
80 std::unique_ptr<Response> response{new Response{shared_from_this()}};
81 success_callback.Run(1, std::move(response));
82 }
83 }
84
GetResponseStatusCode() const85 int Connection::GetResponseStatusCode() const {
86 return response_.GetStatusCode();
87 }
88
GetResponseStatusText() const89 std::string Connection::GetResponseStatusText() const {
90 return response_.GetStatusText();
91 }
92
GetProtocolVersion() const93 std::string Connection::GetProtocolVersion() const {
94 return response_.GetProtocolVersion();
95 }
96
GetResponseHeader(const std::string & header_name) const97 std::string Connection::GetResponseHeader(
98 const std::string& header_name) const {
99 return response_.GetHeader(header_name);
100 }
101
ExtractDataStream(brillo::ErrorPtr * error)102 StreamPtr Connection::ExtractDataStream(brillo::ErrorPtr* error) {
103 // HEAD requests must not return body.
104 if (request_.GetMethod() != request_type::kHead) {
105 return MemoryStream::OpenRef(response_.GetData(), error);
106 } else {
107 // Return empty data stream for HEAD requests.
108 return MemoryStream::OpenCopyOf(nullptr, 0, error);
109 }
110 }
111
112 } // namespace fake
113 } // namespace http
114 } // namespace brillo
115