1f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// Copyright 2014 The Chromium OS Authors. All rights reserved. 2f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// Use of this source code is governed by a BSD-style license that can be 3f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// found in the LICENSE file. 4f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko 59ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko#include <brillo/http/http_request.h> 6f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko 7f95a2b9e277726d8793a5849ec6e81c038c22be3Alex Vakulenko#include <base/bind.h> 8f95a2b9e277726d8793a5849ec6e81c038c22be3Alex Vakulenko#include <base/callback.h> 9f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko#include <base/logging.h> 109ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko#include <brillo/http/http_form_data.h> 119ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko#include <brillo/map_utils.h> 129ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko#include <brillo/mime_utils.h> 139ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko#include <brillo/streams/memory_stream.h> 149ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko#include <brillo/strings/string_utils.h> 15f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko 169ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenkonamespace brillo { 17f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkonamespace http { 18f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko 19f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// request_type 20f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char request_type::kOptions[] = "OPTIONS"; 21f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char request_type::kGet[] = "GET"; 22f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char request_type::kHead[] = "HEAD"; 23f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char request_type::kPost[] = "POST"; 24f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char request_type::kPut[] = "PUT"; 25f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char request_type::kPatch[] = "PATCH"; 26f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char request_type::kDelete[] = "DELETE"; 27f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char request_type::kTrace[] = "TRACE"; 28f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char request_type::kConnect[] = "CONNECT"; 29f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char request_type::kCopy[] = "COPY"; 30f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char request_type::kMove[] = "MOVE"; 31f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko 32f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// request_header 33f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char request_header::kAccept[] = "Accept"; 34f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char request_header::kAcceptCharset[] = "Accept-Charset"; 35f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char request_header::kAcceptEncoding[] = "Accept-Encoding"; 36f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char request_header::kAcceptLanguage[] = "Accept-Language"; 37f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char request_header::kAllow[] = "Allow"; 38f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char request_header::kAuthorization[] = "Authorization"; 39f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char request_header::kCacheControl[] = "Cache-Control"; 40f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char request_header::kConnection[] = "Connection"; 41f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char request_header::kContentEncoding[] = "Content-Encoding"; 42f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char request_header::kContentLanguage[] = "Content-Language"; 43f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char request_header::kContentLength[] = "Content-Length"; 44f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char request_header::kContentLocation[] = "Content-Location"; 45f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char request_header::kContentMd5[] = "Content-MD5"; 46f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char request_header::kContentRange[] = "Content-Range"; 47f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char request_header::kContentType[] = "Content-Type"; 48f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char request_header::kCookie[] = "Cookie"; 49f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char request_header::kDate[] = "Date"; 50f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char request_header::kExpect[] = "Expect"; 51f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char request_header::kExpires[] = "Expires"; 52f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char request_header::kFrom[] = "From"; 53f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char request_header::kHost[] = "Host"; 54f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char request_header::kIfMatch[] = "If-Match"; 55f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char request_header::kIfModifiedSince[] = "If-Modified-Since"; 56f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char request_header::kIfNoneMatch[] = "If-None-Match"; 57f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char request_header::kIfRange[] = "If-Range"; 58f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char request_header::kIfUnmodifiedSince[] = "If-Unmodified-Since"; 59f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char request_header::kLastModified[] = "Last-Modified"; 60f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char request_header::kMaxForwards[] = "Max-Forwards"; 61f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char request_header::kPragma[] = "Pragma"; 62f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char request_header::kProxyAuthorization[] = "Proxy-Authorization"; 63f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char request_header::kRange[] = "Range"; 64f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char request_header::kReferer[] = "Referer"; 65f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char request_header::kTE[] = "TE"; 66f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char request_header::kTrailer[] = "Trailer"; 67f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char request_header::kTransferEncoding[] = "Transfer-Encoding"; 68f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char request_header::kUpgrade[] = "Upgrade"; 69f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char request_header::kUserAgent[] = "User-Agent"; 70f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char request_header::kVia[] = "Via"; 71f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char request_header::kWarning[] = "Warning"; 72f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko 73f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// response_header 74f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char response_header::kAcceptRanges[] = "Accept-Ranges"; 75f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char response_header::kAge[] = "Age"; 76f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char response_header::kAllow[] = "Allow"; 77f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char response_header::kCacheControl[] = "Cache-Control"; 78f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char response_header::kConnection[] = "Connection"; 79f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char response_header::kContentEncoding[] = "Content-Encoding"; 80f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char response_header::kContentLanguage[] = "Content-Language"; 81f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char response_header::kContentLength[] = "Content-Length"; 82f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char response_header::kContentLocation[] = "Content-Location"; 83f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char response_header::kContentMd5[] = "Content-MD5"; 84f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char response_header::kContentRange[] = "Content-Range"; 85f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char response_header::kContentType[] = "Content-Type"; 86f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char response_header::kDate[] = "Date"; 87f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char response_header::kETag[] = "ETag"; 88f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char response_header::kExpires[] = "Expires"; 89f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char response_header::kLastModified[] = "Last-Modified"; 90f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char response_header::kLocation[] = "Location"; 91f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char response_header::kPragma[] = "Pragma"; 92f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char response_header::kProxyAuthenticate[] = "Proxy-Authenticate"; 93f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char response_header::kRetryAfter[] = "Retry-After"; 94f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char response_header::kServer[] = "Server"; 95f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char response_header::kSetCookie[] = "Set-Cookie"; 96f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char response_header::kTrailer[] = "Trailer"; 97f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char response_header::kTransferEncoding[] = "Transfer-Encoding"; 98f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char response_header::kUpgrade[] = "Upgrade"; 99f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char response_header::kVary[] = "Vary"; 100f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char response_header::kVia[] = "Via"; 101f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char response_header::kWarning[] = "Warning"; 102f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoconst char response_header::kWwwAuthenticate[] = "WWW-Authenticate"; 103f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko 104f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// *********************************************************** 105f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// ********************** Request Class ********************** 106f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// *********************************************************** 10705d29044d14a60775ed6c51c75a414eb0cb50347Alex VakulenkoRequest::Request(const std::string& url, 10805d29044d14a60775ed6c51c75a414eb0cb50347Alex Vakulenko const std::string& method, 10905d29044d14a60775ed6c51c75a414eb0cb50347Alex Vakulenko std::shared_ptr<Transport> transport) 11005d29044d14a60775ed6c51c75a414eb0cb50347Alex Vakulenko : transport_(transport), request_url_(url), method_(method) { 111f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko VLOG(1) << "http::Request created"; 112f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko if (!transport_) 1137c686ea5ca47c2b1c14df27f656ad44a59bb2646Alex Vakulenko transport_ = http::Transport::CreateDefault(); 114f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko} 115f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko 116f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex VakulenkoRequest::~Request() { 117f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko VLOG(1) << "http::Request destroyed"; 118f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko} 119f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko 120f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkovoid Request::AddRange(int64_t bytes) { 1218757d061cd87578b5b158e8efcc8a6cf4715c7a1Alex Vakulenko DCHECK(transport_) << "Request already sent"; 122f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko if (bytes < 0) { 123f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko ranges_.emplace_back(Request::range_value_omitted, -bytes); 124f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko } else { 125f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko ranges_.emplace_back(bytes, Request::range_value_omitted); 126f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko } 127f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko} 128f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko 129f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkovoid Request::AddRange(uint64_t from_byte, uint64_t to_byte) { 1308757d061cd87578b5b158e8efcc8a6cf4715c7a1Alex Vakulenko DCHECK(transport_) << "Request already sent"; 131f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko ranges_.emplace_back(from_byte, to_byte); 132f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko} 133f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko 1342e1579107504b584d59e4ab036544369321f2a58Alex Vakulenkostd::unique_ptr<Response> Request::GetResponseAndBlock( 1359ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko brillo::ErrorPtr* error) { 136f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko if (!SendRequestIfNeeded(error) || !connection_->FinishRequest(error)) 137f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko return std::unique_ptr<Response>(); 138f95a2b9e277726d8793a5849ec6e81c038c22be3Alex Vakulenko std::unique_ptr<Response> response(new Response(connection_)); 139f95a2b9e277726d8793a5849ec6e81c038c22be3Alex Vakulenko connection_.reset(); 140f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko transport_.reset(); // Indicate that the response has been received 141f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko return response; 142f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko} 143f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko 1448757d061cd87578b5b158e8efcc8a6cf4715c7a1Alex VakulenkoRequestID Request::GetResponse(const SuccessCallback& success_callback, 1458757d061cd87578b5b158e8efcc8a6cf4715c7a1Alex Vakulenko const ErrorCallback& error_callback) { 146f95a2b9e277726d8793a5849ec6e81c038c22be3Alex Vakulenko ErrorPtr error; 147f95a2b9e277726d8793a5849ec6e81c038c22be3Alex Vakulenko if (!SendRequestIfNeeded(&error)) { 148f95a2b9e277726d8793a5849ec6e81c038c22be3Alex Vakulenko transport_->RunCallbackAsync( 149ac3059d5edad2af5a75184d1e31133e712c91f60Alex Vakulenko FROM_HERE, base::Bind(error_callback, 0, base::Owned(error.release()))); 150ac3059d5edad2af5a75184d1e31133e712c91f60Alex Vakulenko return 0; 151f95a2b9e277726d8793a5849ec6e81c038c22be3Alex Vakulenko } 1528757d061cd87578b5b158e8efcc8a6cf4715c7a1Alex Vakulenko RequestID id = 1538757d061cd87578b5b158e8efcc8a6cf4715c7a1Alex Vakulenko connection_->FinishRequestAsync(success_callback, error_callback); 154f95a2b9e277726d8793a5849ec6e81c038c22be3Alex Vakulenko connection_.reset(); 155f95a2b9e277726d8793a5849ec6e81c038c22be3Alex Vakulenko transport_.reset(); // Indicate that the request has been dispatched. 156ac3059d5edad2af5a75184d1e31133e712c91f60Alex Vakulenko return id; 157f95a2b9e277726d8793a5849ec6e81c038c22be3Alex Vakulenko} 158f95a2b9e277726d8793a5849ec6e81c038c22be3Alex Vakulenko 1592e1579107504b584d59e4ab036544369321f2a58Alex Vakulenkovoid Request::SetAccept(const std::string& accept_mime_types) { 1608757d061cd87578b5b158e8efcc8a6cf4715c7a1Alex Vakulenko DCHECK(transport_) << "Request already sent"; 161f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko accept_ = accept_mime_types; 162f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko} 163f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko 164f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenkoconst std::string& Request::GetAccept() const { 165f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko return accept_; 166f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko} 167f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko 1682e1579107504b584d59e4ab036544369321f2a58Alex Vakulenkovoid Request::SetContentType(const std::string& contentType) { 1698757d061cd87578b5b158e8efcc8a6cf4715c7a1Alex Vakulenko DCHECK(transport_) << "Request already sent"; 170f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko content_type_ = contentType; 171f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko} 172f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko 173f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenkoconst std::string& Request::GetContentType() const { 174f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko return content_type_; 175f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko} 176f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko 1772e1579107504b584d59e4ab036544369321f2a58Alex Vakulenkovoid Request::AddHeader(const std::string& header, const std::string& value) { 1788757d061cd87578b5b158e8efcc8a6cf4715c7a1Alex Vakulenko DCHECK(transport_) << "Request already sent"; 179f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko headers_.emplace(header, value); 180f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko} 181f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko 182f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkovoid Request::AddHeaders(const HeaderList& headers) { 1838757d061cd87578b5b158e8efcc8a6cf4715c7a1Alex Vakulenko DCHECK(transport_) << "Request already sent"; 184f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko headers_.insert(headers.begin(), headers.end()); 185f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko} 186f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko 187f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkobool Request::AddRequestBody(const void* data, 188f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko size_t size, 1899ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko brillo::ErrorPtr* error) { 190f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko if (!SendRequestIfNeeded(error)) 191f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko return false; 19280663bf89f5ba2c0646f196371a1fa92123855c6Alex Vakulenko StreamPtr stream = MemoryStream::OpenCopyOf(data, size, error); 19380663bf89f5ba2c0646f196371a1fa92123855c6Alex Vakulenko return stream && connection_->SetRequestData(std::move(stream), error); 19447e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko} 19547e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko 1969ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenkobool Request::AddRequestBody(StreamPtr stream, brillo::ErrorPtr* error) { 19747e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko return SendRequestIfNeeded(error) && 19880663bf89f5ba2c0646f196371a1fa92123855c6Alex Vakulenko connection_->SetRequestData(std::move(stream), error); 19947e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko} 20047e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko 20147e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenkobool Request::AddRequestBodyAsFormData(std::unique_ptr<FormData> form_data, 2029ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko brillo::ErrorPtr* error) { 20347e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko AddHeader(request_header::kContentType, form_data->GetContentType()); 20447e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko if (!SendRequestIfNeeded(error)) 20547e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko return false; 20680663bf89f5ba2c0646f196371a1fa92123855c6Alex Vakulenko return connection_->SetRequestData(form_data->ExtractDataStream(), error); 207f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko} 208f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko 2099ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenkobool Request::AddResponseStream(StreamPtr stream, brillo::ErrorPtr* error) { 2102eed2f9a423b8e776b4d54530c567736c371ba48Nathan Bullock if (!SendRequestIfNeeded(error)) 2112eed2f9a423b8e776b4d54530c567736c371ba48Nathan Bullock return false; 2122eed2f9a423b8e776b4d54530c567736c371ba48Nathan Bullock connection_->SetResponseData(std::move(stream)); 2132eed2f9a423b8e776b4d54530c567736c371ba48Nathan Bullock return true; 2142eed2f9a423b8e776b4d54530c567736c371ba48Nathan Bullock} 2152eed2f9a423b8e776b4d54530c567736c371ba48Nathan Bullock 216f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenkoconst std::string& Request::GetRequestURL() const { 217f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko return request_url_; 218f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko} 219f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko 220f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenkoconst std::string& Request::GetRequestMethod() const { 221f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko return method_; 222f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko} 223f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko 2242e1579107504b584d59e4ab036544369321f2a58Alex Vakulenkovoid Request::SetReferer(const std::string& referer) { 2258757d061cd87578b5b158e8efcc8a6cf4715c7a1Alex Vakulenko DCHECK(transport_) << "Request already sent"; 226f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko referer_ = referer; 227f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko} 228f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko 229f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenkoconst std::string& Request::GetReferer() const { 230f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko return referer_; 231f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko} 232f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko 2332e1579107504b584d59e4ab036544369321f2a58Alex Vakulenkovoid Request::SetUserAgent(const std::string& user_agent) { 2348757d061cd87578b5b158e8efcc8a6cf4715c7a1Alex Vakulenko DCHECK(transport_) << "Request already sent"; 235f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko user_agent_ = user_agent; 236f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko} 237f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko 238f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenkoconst std::string& Request::GetUserAgent() const { 239f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko return user_agent_; 240f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko} 241f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko 2429ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenkobool Request::SendRequestIfNeeded(brillo::ErrorPtr* error) { 243f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko if (transport_) { 244f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko if (!connection_) { 2459ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko http::HeaderList headers = brillo::MapToVector(headers_); 246f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko std::vector<std::string> ranges; 247f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko if (method_ != request_type::kHead) { 248f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko ranges.reserve(ranges_.size()); 249f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko for (auto p : ranges_) { 250f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko if (p.first != range_value_omitted || 251f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko p.second != range_value_omitted) { 252f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko std::string range; 253f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko if (p.first != range_value_omitted) { 2549ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko range = brillo::string_utils::ToString(p.first); 255f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko } 256f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko range += '-'; 257f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko if (p.second != range_value_omitted) { 2589ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko range += brillo::string_utils::ToString(p.second); 259f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko } 260f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko ranges.push_back(range); 261f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko } 262f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko } 263f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko } 264f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko if (!ranges.empty()) 26505d29044d14a60775ed6c51c75a414eb0cb50347Alex Vakulenko headers.emplace_back( 26605d29044d14a60775ed6c51c75a414eb0cb50347Alex Vakulenko request_header::kRange, 2679ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko "bytes=" + brillo::string_utils::Join(",", ranges)); 268f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko 269f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko headers.emplace_back(request_header::kAccept, GetAccept()); 270f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko if (method_ != request_type::kGet && method_ != request_type::kHead) { 271f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko if (!content_type_.empty()) 272f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko headers.emplace_back(request_header::kContentType, content_type_); 273f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko } 27405d29044d14a60775ed6c51c75a414eb0cb50347Alex Vakulenko connection_ = transport_->CreateConnection( 27505d29044d14a60775ed6c51c75a414eb0cb50347Alex Vakulenko request_url_, method_, headers, user_agent_, referer_, error); 276f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko } 277f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko 278f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko if (connection_) 279f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko return true; 280f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko } else { 2819ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko brillo::Error::AddTo(error, 28205d29044d14a60775ed6c51c75a414eb0cb50347Alex Vakulenko FROM_HERE, 28305d29044d14a60775ed6c51c75a414eb0cb50347Alex Vakulenko http::kErrorDomain, 2842e1579107504b584d59e4ab036544369321f2a58Alex Vakulenko "response_already_received", 285f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko "HTTP response already received"); 286f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko } 287f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko return false; 288f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko} 289f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko 290f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// ************************************************************ 291f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// ********************** Response Class ********************** 292f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// ************************************************************ 293f95a2b9e277726d8793a5849ec6e81c038c22be3Alex VakulenkoResponse::Response(const std::shared_ptr<Connection>& connection) 294f95a2b9e277726d8793a5849ec6e81c038c22be3Alex Vakulenko : connection_{connection} { 295f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko VLOG(1) << "http::Response created"; 296f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko} 297f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko 298f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex VakulenkoResponse::~Response() { 299f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko VLOG(1) << "http::Response destroyed"; 300f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko} 301f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko 302f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkobool Response::IsSuccessful() const { 303f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko int code = GetStatusCode(); 304f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko return code >= status_code::Continue && code < status_code::BadRequest; 305f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko} 306f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko 307f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoint Response::GetStatusCode() const { 308f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko if (!connection_) 309f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko return -1; 310f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko 311f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko return connection_->GetResponseStatusCode(); 312f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko} 313f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko 314f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkostd::string Response::GetStatusText() const { 315f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko if (!connection_) 316f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko return std::string(); 317f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko 318f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko return connection_->GetResponseStatusText(); 319f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko} 320f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko 321f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkostd::string Response::GetContentType() const { 322f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko return GetHeader(response_header::kContentType); 323f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko} 324f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko 32520d497f58d7abdec1e011cb1efadb45e53e5af0bAlex VakulenkoStreamPtr Response::ExtractDataStream(ErrorPtr* error) { 32620d497f58d7abdec1e011cb1efadb45e53e5af0bAlex Vakulenko return connection_->ExtractDataStream(error); 327f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko} 328f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko 32920d497f58d7abdec1e011cb1efadb45e53e5af0bAlex Vakulenkostd::vector<uint8_t> Response::ExtractData() { 33020d497f58d7abdec1e011cb1efadb45e53e5af0bAlex Vakulenko std::vector<uint8_t> data; 33120d497f58d7abdec1e011cb1efadb45e53e5af0bAlex Vakulenko StreamPtr src_stream = connection_->ExtractDataStream(nullptr); 33220d497f58d7abdec1e011cb1efadb45e53e5af0bAlex Vakulenko StreamPtr dest_stream = MemoryStream::CreateRef(&data, nullptr); 33320d497f58d7abdec1e011cb1efadb45e53e5af0bAlex Vakulenko if (src_stream && dest_stream) { 33420d497f58d7abdec1e011cb1efadb45e53e5af0bAlex Vakulenko char buffer[1024]; 33520d497f58d7abdec1e011cb1efadb45e53e5af0bAlex Vakulenko size_t read = 0; 33620d497f58d7abdec1e011cb1efadb45e53e5af0bAlex Vakulenko while (src_stream->ReadBlocking(buffer, sizeof(buffer), &read, nullptr) && 33720d497f58d7abdec1e011cb1efadb45e53e5af0bAlex Vakulenko read > 0) { 33820d497f58d7abdec1e011cb1efadb45e53e5af0bAlex Vakulenko CHECK(dest_stream->WriteAllBlocking(buffer, read, nullptr)); 33920d497f58d7abdec1e011cb1efadb45e53e5af0bAlex Vakulenko } 34020d497f58d7abdec1e011cb1efadb45e53e5af0bAlex Vakulenko } 34120d497f58d7abdec1e011cb1efadb45e53e5af0bAlex Vakulenko return data; 34220d497f58d7abdec1e011cb1efadb45e53e5af0bAlex Vakulenko} 343f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko 34420d497f58d7abdec1e011cb1efadb45e53e5af0bAlex Vakulenkostd::string Response::ExtractDataAsString() { 34520d497f58d7abdec1e011cb1efadb45e53e5af0bAlex Vakulenko std::vector<uint8_t> data = ExtractData(); 34620d497f58d7abdec1e011cb1efadb45e53e5af0bAlex Vakulenko return std::string{data.begin(), data.end()}; 347f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko} 348f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko 3492e1579107504b584d59e4ab036544369321f2a58Alex Vakulenkostd::string Response::GetHeader(const std::string& header_name) const { 350f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko if (connection_) 351f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko return connection_->GetResponseHeader(header_name); 352f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko 353f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko return std::string(); 354f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko} 355f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko 356f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko} // namespace http 3579ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko} // namespace brillo 358