Home | History | Annotate | Download | only in http
      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 
     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 
     25 Connection::~Connection() {
     26   VLOG(1) << "fake::Connection destroyed";
     27 }
     28 
     29 bool Connection::SendHeaders(const HeaderList& headers,
     30                              brillo::ErrorPtr* /* error */) {
     31   request_.AddHeaders(headers);
     32   return true;
     33 }
     34 
     35 bool Connection::SetRequestData(StreamPtr stream,
     36                                 brillo::ErrorPtr* /* error */) {
     37   request_.SetData(std::move(stream));
     38   return true;
     39 }
     40 
     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 
     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 = [](std::shared_ptr<Connection> connection,
     67                      const SuccessCallback& success_callback,
     68                      const ErrorCallback& error_callback) {
     69     connection->FinishRequestAsyncHelper(success_callback, error_callback);
     70   };
     71   transport_->RunCallbackAsync(FROM_HERE,
     72                                base::Bind(callback,
     73                                           base::Passed(&connection),
     74                                           success_callback,
     75                                           error_callback));
     76   return 1;
     77 }
     78 
     79 void Connection::FinishRequestAsyncHelper(
     80     const SuccessCallback& success_callback,
     81     const ErrorCallback& error_callback) {
     82   brillo::ErrorPtr error;
     83   if (!FinishRequest(&error)) {
     84     error_callback.Run(1, error.get());
     85   } else {
     86     std::unique_ptr<Response> response{new Response{shared_from_this()}};
     87     success_callback.Run(1, std::move(response));
     88   }
     89 }
     90 
     91 int Connection::GetResponseStatusCode() const {
     92   return response_.GetStatusCode();
     93 }
     94 
     95 std::string Connection::GetResponseStatusText() const {
     96   return response_.GetStatusText();
     97 }
     98 
     99 std::string Connection::GetProtocolVersion() const {
    100   return response_.GetProtocolVersion();
    101 }
    102 
    103 std::string Connection::GetResponseHeader(
    104     const std::string& header_name) const {
    105   return response_.GetHeader(header_name);
    106 }
    107 
    108 StreamPtr Connection::ExtractDataStream(brillo::ErrorPtr* error) {
    109   // HEAD requests must not return body.
    110   if (request_.GetMethod() != request_type::kHead) {
    111     return MemoryStream::OpenRef(response_.GetData(), error);
    112   } else {
    113     // Return empty data stream for HEAD requests.
    114     return MemoryStream::OpenCopyOf(nullptr, 0, error);
    115   }
    116 }
    117 
    118 }  // namespace fake
    119 }  // namespace http
    120 }  // namespace brillo
    121