http_request.cc revision f5effe9e46e479e6fdc4f6928da545d48dcd3997
1242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com// Copyright 2014 The Chromium OS Authors. All rights reserved.
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com// Use of this source code is governed by a BSD-style license that can be
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com// found in the LICENSE file.
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com#include <chromeos/http/http_request.h>
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
7242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com#include <base/bind.h>
8242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com#include <base/callback.h>
985302969fcf0860d451b0748da372571b2fc9f88bungeman@google.com#include <base/logging.h>
1085302969fcf0860d451b0748da372571b2fc9f88bungeman@google.com#include <chromeos/http/http_form_data.h>
111ee76510f5dbf632d30975fc3509ef4f609156d2mtklein#include <chromeos/map_utils.h>
121ee76510f5dbf632d30975fc3509ef4f609156d2mtklein#include <chromeos/mime_utils.h>
1385302969fcf0860d451b0748da372571b2fc9f88bungeman@google.com#include <chromeos/strings/string_utils.h>
1485302969fcf0860d451b0748da372571b2fc9f88bungeman@google.com
1585302969fcf0860d451b0748da372571b2fc9f88bungeman@google.comnamespace chromeos {
1685302969fcf0860d451b0748da372571b2fc9f88bungeman@google.comnamespace http {
1785302969fcf0860d451b0748da372571b2fc9f88bungeman@google.com
1885302969fcf0860d451b0748da372571b2fc9f88bungeman@google.com// request_type
1985302969fcf0860d451b0748da372571b2fc9f88bungeman@google.comconst char request_type::kOptions[]               = "OPTIONS";
2085302969fcf0860d451b0748da372571b2fc9f88bungeman@google.comconst char request_type::kGet[]                   = "GET";
2185302969fcf0860d451b0748da372571b2fc9f88bungeman@google.comconst char request_type::kHead[]                  = "HEAD";
2285302969fcf0860d451b0748da372571b2fc9f88bungeman@google.comconst char request_type::kPost[]                  = "POST";
2385302969fcf0860d451b0748da372571b2fc9f88bungeman@google.comconst char request_type::kPut[]                   = "PUT";
2485302969fcf0860d451b0748da372571b2fc9f88bungeman@google.comconst char request_type::kPatch[]                 = "PATCH";
2585302969fcf0860d451b0748da372571b2fc9f88bungeman@google.comconst char request_type::kDelete[]                = "DELETE";
2685302969fcf0860d451b0748da372571b2fc9f88bungeman@google.comconst char request_type::kTrace[]                 = "TRACE";
2785302969fcf0860d451b0748da372571b2fc9f88bungeman@google.comconst char request_type::kConnect[]               = "CONNECT";
2885302969fcf0860d451b0748da372571b2fc9f88bungeman@google.comconst char request_type::kCopy[]                  = "COPY";
2985302969fcf0860d451b0748da372571b2fc9f88bungeman@google.comconst char request_type::kMove[]                  = "MOVE";
3085302969fcf0860d451b0748da372571b2fc9f88bungeman@google.com
31ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com// request_header
32242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.comconst char request_header::kAccept[]              = "Accept";
339df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.comconst char request_header::kAcceptCharset[]       = "Accept-Charset";
34242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.comconst char request_header::kAcceptEncoding[]      = "Accept-Encoding";
35242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.comconst char request_header::kAcceptLanguage[]      = "Accept-Language";
369df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.comconst char request_header::kAllow[]               = "Allow";
37242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.comconst char request_header::kAuthorization[]       = "Authorization";
38242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.comconst char request_header::kCacheControl[]        = "Cache-Control";
399df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.comconst char request_header::kConnection[]          = "Connection";
4059bfb1240666b0f70109ac8ab04a280765ff8563robertphillips@google.comconst char request_header::kContentEncoding[]     = "Content-Encoding";
41242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.comconst char request_header::kContentLanguage[]     = "Content-Language";
42c18143e89b8ef91cb0a3f64cb490ea765da3549fbungeman@google.comconst char request_header::kContentLength[]       = "Content-Length";
43c18143e89b8ef91cb0a3f64cb490ea765da3549fbungeman@google.comconst char request_header::kContentLocation[]     = "Content-Location";
44c18143e89b8ef91cb0a3f64cb490ea765da3549fbungeman@google.comconst char request_header::kContentMd5[]          = "Content-MD5";
45c18143e89b8ef91cb0a3f64cb490ea765da3549fbungeman@google.comconst char request_header::kContentRange[]        = "Content-Range";
46c18143e89b8ef91cb0a3f64cb490ea765da3549fbungeman@google.comconst char request_header::kContentType[]         = "Content-Type";
47c18143e89b8ef91cb0a3f64cb490ea765da3549fbungeman@google.comconst char request_header::kCookie[]              = "Cookie";
48c18143e89b8ef91cb0a3f64cb490ea765da3549fbungeman@google.comconst char request_header::kDate[]                = "Date";
49c18143e89b8ef91cb0a3f64cb490ea765da3549fbungeman@google.comconst char request_header::kExpect[]              = "Expect";
50c18143e89b8ef91cb0a3f64cb490ea765da3549fbungeman@google.comconst char request_header::kExpires[]             = "Expires";
51242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.comconst char request_header::kFrom[]                = "From";
5239edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.comconst char request_header::kHost[]                = "Host";
5339edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.comconst char request_header::kIfMatch[]             = "If-Match";
5439edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.comconst char request_header::kIfModifiedSince[]     = "If-Modified-Since";
5539edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.comconst char request_header::kIfNoneMatch[]         = "If-None-Match";
5639edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.comconst char request_header::kIfRange[]             = "If-Range";
5739edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.comconst char request_header::kIfUnmodifiedSince[]   = "If-Unmodified-Since";
5839edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.comconst char request_header::kLastModified[]        = "Last-Modified";
5939edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.comconst char request_header::kMaxForwards[]         = "Max-Forwards";
6039edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.comconst char request_header::kPragma[]              = "Pragma";
6139edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.comconst char request_header::kProxyAuthorization[]  = "Proxy-Authorization";
6239edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.comconst char request_header::kRange[]               = "Range";
6339edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.comconst char request_header::kReferer[]             = "Referer";
6439edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.comconst char request_header::kTE[]                  = "TE";
6596fcdcc219d2a0d3579719b84b28bede76efba64halcanaryconst char request_header::kTrailer[]             = "Trailer";
6639edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.comconst char request_header::kTransferEncoding[]    = "Transfer-Encoding";
6739edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.comconst char request_header::kUpgrade[]             = "Upgrade";
6839edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.comconst char request_header::kUserAgent[]           = "User-Agent";
6939edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.comconst char request_header::kVia[]                 = "Via";
7039edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.comconst char request_header::kWarning[]             = "Warning";
71242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com
7236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein// response_header
7339edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.comconst char response_header::kAcceptRanges[]       = "Accept-Ranges";
7439edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.comconst char response_header::kAge[]                = "Age";
7539edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.comconst char response_header::kAllow[]              = "Allow";
7639edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.comconst char response_header::kCacheControl[]       = "Cache-Control";
7739edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.comconst char response_header::kConnection[]         = "Connection";
78242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.comconst char response_header::kContentEncoding[]    = "Content-Encoding";
79242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.comconst char response_header::kContentLanguage[]    = "Content-Language";
8039edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.comconst char response_header::kContentLength[]      = "Content-Length";
8139edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.comconst char response_header::kContentLocation[]    = "Content-Location";
8239edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.comconst char response_header::kContentMd5[]         = "Content-MD5";
8339edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.comconst char response_header::kContentRange[]       = "Content-Range";
8439edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.comconst char response_header::kContentType[]        = "Content-Type";
8539edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.comconst char response_header::kDate[]               = "Date";
8639edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.comconst char response_header::kETag[]               = "ETag";
8739edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.comconst char response_header::kExpires[]            = "Expires";
8839edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.comconst char response_header::kLastModified[]       = "Last-Modified";
8939edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.comconst char response_header::kLocation[]           = "Location";
9039edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.comconst char response_header::kPragma[]             = "Pragma";
9139edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.comconst char response_header::kProxyAuthenticate[]  = "Proxy-Authenticate";
9239edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.comconst char response_header::kRetryAfter[]         = "Retry-After";
9339edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.comconst char response_header::kServer[]             = "Server";
9439edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.comconst char response_header::kSetCookie[]          = "Set-Cookie";
9539edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.comconst char response_header::kTrailer[]            = "Trailer";
9639edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.comconst char response_header::kTransferEncoding[]   = "Transfer-Encoding";
972a1208017dd676f94a53bbb228197c3978dbdd8ascroggoconst char response_header::kUpgrade[]            = "Upgrade";
9839edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.comconst char response_header::kVary[]               = "Vary";
9939edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.comconst char response_header::kVia[]                = "Via";
10039edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.comconst char response_header::kWarning[]            = "Warning";
10139edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.comconst char response_header::kWwwAuthenticate[]    = "WWW-Authenticate";
10239edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com
10339edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com// ***********************************************************
10439edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com// ********************** Request Class **********************
10539edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com// ***********************************************************
10639edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.comRequest::Request(const std::string& url, const std::string& method,
10796fcdcc219d2a0d3579719b84b28bede76efba64halcanary                 std::shared_ptr<Transport> transport) :
10839edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com    transport_(transport), request_url_(url), method_(method) {
10939edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com  VLOG(1) << "http::Request created";
11039edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com  if (!transport_)
11139edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com    transport_ = http::Transport::CreateDefault();
112242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com}
1132e2f3f58b5b0599c776f20bb55845d3e6005a01cbungeman@google.com
1142e2f3f58b5b0599c776f20bb55845d3e6005a01cbungeman@google.comRequest::~Request() {
1152e2f3f58b5b0599c776f20bb55845d3e6005a01cbungeman@google.com  VLOG(1) << "http::Request destroyed";
1162e2f3f58b5b0599c776f20bb55845d3e6005a01cbungeman@google.com}
117d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
1182e2f3f58b5b0599c776f20bb55845d3e6005a01cbungeman@google.comvoid Request::AddRange(int64_t bytes) {
119d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com  if (bytes < 0) {
120242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com    ranges_.emplace_back(Request::range_value_omitted, -bytes);
1219df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.com  } else {
122242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com    ranges_.emplace_back(bytes, Request::range_value_omitted);
123242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com  }
124242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com}
12596fcdcc219d2a0d3579719b84b28bede76efba64halcanary
126242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.comvoid Request::AddRange(uint64_t from_byte, uint64_t to_byte) {
127242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com  ranges_.emplace_back(from_byte, to_byte);
128242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com}
129242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com
130d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.comstd::unique_ptr<Response> Request::GetResponseAndBlock(
131242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com    chromeos::ErrorPtr* error) {
1329df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.com  if (!SendRequestIfNeeded(error) || !connection_->FinishRequest(error))
133242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com    return std::unique_ptr<Response>();
1349df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.com  std::unique_ptr<Response> response(new Response(connection_));
135242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com  connection_.reset();
136d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com  transport_.reset();  // Indicate that the response has been received
137242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com  return response;
138242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com}
139242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com
14096fcdcc219d2a0d3579719b84b28bede76efba64halcanaryvoid Request::GetResponse(const SuccessCallback& success_callback,
141242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com                          const ErrorCallback& error_callback) {
142d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com  ErrorPtr error;
143242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com  if (!SendRequestIfNeeded(&error)) {
1449df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.com    transport_->RunCallbackAsync(
145242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com        FROM_HERE, base::Bind(error_callback, base::Owned(error.release())));
146242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com    return;
147242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com  }
14896fcdcc219d2a0d3579719b84b28bede76efba64halcanary  connection_->FinishRequestAsync(success_callback, error_callback);
149242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com  connection_.reset();
150242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com  transport_.reset();  // Indicate that the request has been dispatched.
151242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com}
152242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com
153d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.comvoid Request::SetAccept(const std::string& accept_mime_types) {
15439edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com  accept_ = accept_mime_types;
15596fcdcc219d2a0d3579719b84b28bede76efba64halcanary}
15639edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com
15739edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.comconst std::string& Request::GetAccept() const {
15839edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com  return accept_;
15939edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com}
16039edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com
16139edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.comvoid Request::SetContentType(const std::string& contentType) {
16239edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com  content_type_ = contentType;
16339edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com}
16439edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com
16539edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.comconst std::string& Request::GetContentType() const {
16639edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com  return content_type_;
16739edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com}
168242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com
1699df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.comvoid Request::AddHeader(const std::string& header, const std::string& value) {
170242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com  headers_.emplace(header, value);
171242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com}
172242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com
173d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.comvoid Request::AddHeaders(const HeaderList& headers) {
174242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com  headers_.insert(headers.begin(), headers.end());
1759df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.com}
176242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com
177242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.combool Request::AddRequestBody(const void* data,
178242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com                             size_t size,
179242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com                             chromeos::ErrorPtr* error) {
180242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com  if (!SendRequestIfNeeded(error))
181d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    return false;
182242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com  std::unique_ptr<DataReaderInterface> data_reader{
183242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com    new MemoryDataReader{data, size}
184242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com  };
185242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com  return connection_->SetRequestData(std::move(data_reader), error);
186242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com}
187242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com
188d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.combool Request::AddRequestBody(std::unique_ptr<DataReaderInterface> data_reader,
189242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com                             chromeos::ErrorPtr* error) {
190242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com  return SendRequestIfNeeded(error) &&
191a3264e53ee3f3c5d6a2c813df7e44b5b96d207f2commit-bot@chromium.org         connection_->SetRequestData(std::move(data_reader), error);
19239edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com}
193242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com
194242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.combool Request::AddRequestBodyAsFormData(std::unique_ptr<FormData> form_data,
19596fcdcc219d2a0d3579719b84b28bede76efba64halcanary                                       chromeos::ErrorPtr* error) {
196242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com  AddHeader(request_header::kContentType, form_data->GetContentType());
197242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com  if (!SendRequestIfNeeded(error))
198242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com    return false;
199d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com  return connection_->SetRequestData(std::move(form_data), error);
200242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com}
2019df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.com
202242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.comconst std::string& Request::GetRequestURL() const {
203242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com  return request_url_;
204242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com}
205d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
2062bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.comconst std::string& Request::GetRequestMethod() const {
2072bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.com  return method_;
2082bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.com}
2092bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.com
2102bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.comvoid Request::SetReferer(const std::string& referer) {
2112bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.com  referer_ = referer;
2122bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.com}
213242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com
214242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.comconst std::string& Request::GetReferer() const {
215242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com  return referer_;
2162bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.com}
217242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com
21896fcdcc219d2a0d3579719b84b28bede76efba64halcanaryvoid Request::SetUserAgent(const std::string& user_agent) {
219242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com  user_agent_ = user_agent;
220242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com}
221242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com
222242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.comconst std::string& Request::GetUserAgent() const {
223d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com  return user_agent_;
224242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com}
2259df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.com
226242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.combool Request::SendRequestIfNeeded(chromeos::ErrorPtr* error) {
227242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com  if (transport_) {
228242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com    if (!connection_) {
229242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com      http::HeaderList headers = chromeos::MapToVector(headers_);
230242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com      std::vector<std::string> ranges;
231d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com      if (method_ != request_type::kHead) {
232242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com        ranges.reserve(ranges_.size());
233242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com        for (auto p : ranges_) {
234955bb0751a0d48e47a341c7c0adda94977bc8170bungeman@google.com          if (p.first != range_value_omitted ||
235dbfac8a72393eaf01670aeb3244de0e18d8faf98junov@google.com              p.second != range_value_omitted) {
2368b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com            std::string range;
237242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com            if (p.first != range_value_omitted) {
23896fcdcc219d2a0d3579719b84b28bede76efba64halcanary              range = chromeos::string_utils::ToString(p.first);
239242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com            }
240242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com            range += '-';
241242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com            if (p.second != range_value_omitted) {
242242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com              range += chromeos::string_utils::ToString(p.second);
24359bfb1240666b0f70109ac8ab04a280765ff8563robertphillips@google.com            }
24459bfb1240666b0f70109ac8ab04a280765ff8563robertphillips@google.com            ranges.push_back(range);
245e7e29b7815e97e9c4db55fa9dac48b419352b2c6reed@google.com          }
246383a697692cf46951fd451f6f4c3d03634a6a1cbreed@google.com        }
247383a697692cf46951fd451f6f4c3d03634a6a1cbreed@google.com      }
248242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com      if (!ranges.empty())
249d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        headers.emplace_back(request_header::kRange,
250242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com                             "bytes=" +
251242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com                                 chromeos::string_utils::Join(',', ranges));
252242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com
253242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com      headers.emplace_back(request_header::kAccept, GetAccept());
254242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com      if (method_ != request_type::kGet && method_ != request_type::kHead) {
255b5571b3324cf18629a255ec85e189447069c9b14scroggo@google.com        if (!content_type_.empty())
2564c6adf9a089dbdd541f25d01d257ec05aedcb57dscroggo@google.com          headers.emplace_back(request_header::kContentType, content_type_);
257b5571b3324cf18629a255ec85e189447069c9b14scroggo@google.com      }
2584c6adf9a089dbdd541f25d01d257ec05aedcb57dscroggo@google.com      connection_ = transport_->CreateConnection(request_url_, method_, headers,
25996fcdcc219d2a0d3579719b84b28bede76efba64halcanary                                                 user_agent_, referer_, error);
2604c6adf9a089dbdd541f25d01d257ec05aedcb57dscroggo@google.com    }
261385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary
2624c6adf9a089dbdd541f25d01d257ec05aedcb57dscroggo@google.com    if (connection_)
2634c6adf9a089dbdd541f25d01d257ec05aedcb57dscroggo@google.com      return true;
2644c6adf9a089dbdd541f25d01d257ec05aedcb57dscroggo@google.com  } else {
265242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com    chromeos::Error::AddTo(error, FROM_HERE, http::kErrorDomain,
266242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com                           "response_already_received",
267242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com                           "HTTP response already received");
268242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com  }
269b5571b3324cf18629a255ec85e189447069c9b14scroggo@google.com  return false;
27096fcdcc219d2a0d3579719b84b28bede76efba64halcanary}
271242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com
272242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com// ************************************************************
273242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com// ********************** Response Class **********************
274242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com// ************************************************************
275242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.comResponse::Response(const std::shared_ptr<Connection>& connection)
276242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com    : connection_{connection} {
277242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com  VLOG(1) << "http::Response created";
278242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com  // Response object doesn't have streaming interface for response data (yet),
279242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com  // so read the data into a buffer and cache it.
280242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com  if (connection_) {
281242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com    size_t size = static_cast<size_t>(connection_->GetResponseDataSize());
282242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com    response_data_.reserve(size);
283242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com    uint8_t buffer[1024];
284242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com    size_t read = 0;
285242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com    while (connection_->ReadResponseData(buffer, sizeof(buffer),
286242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com                                         &read, nullptr) && read > 0) {
28722b4950f60c18d79b985bceb39784840e3d30004bungeman@google.com      response_data_.insert(response_data_.end(), buffer, buffer + read);
288242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com    }
289242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com  }
290242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com}
291242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com
2924c6adf9a089dbdd541f25d01d257ec05aedcb57dscroggo@google.comResponse::~Response() {
2934c6adf9a089dbdd541f25d01d257ec05aedcb57dscroggo@google.com  VLOG(1) << "http::Response destroyed";
2944c6adf9a089dbdd541f25d01d257ec05aedcb57dscroggo@google.com}
2954c6adf9a089dbdd541f25d01d257ec05aedcb57dscroggo@google.com
2964c6adf9a089dbdd541f25d01d257ec05aedcb57dscroggo@google.combool Response::IsSuccessful() const {
2974c6adf9a089dbdd541f25d01d257ec05aedcb57dscroggo@google.com  int code = GetStatusCode();
298242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com  return code >= status_code::Continue && code < status_code::BadRequest;
299242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com}
300242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com
301242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.comint Response::GetStatusCode() const {
302242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com  if (!connection_)
303242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com    return -1;
304242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com
305242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com  return connection_->GetResponseStatusCode();
306242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com}
307242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com
30822b4950f60c18d79b985bceb39784840e3d30004bungeman@google.comstd::string Response::GetStatusText() const {
30922b4950f60c18d79b985bceb39784840e3d30004bungeman@google.com  if (!connection_)
31022b4950f60c18d79b985bceb39784840e3d30004bungeman@google.com    return std::string();
31128fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org
31222b4950f60c18d79b985bceb39784840e3d30004bungeman@google.com  return connection_->GetResponseStatusText();
31322b4950f60c18d79b985bceb39784840e3d30004bungeman@google.com}
31428fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org
31522b4950f60c18d79b985bceb39784840e3d30004bungeman@google.comstd::string Response::GetContentType() const {
31622b4950f60c18d79b985bceb39784840e3d30004bungeman@google.com  return GetHeader(response_header::kContentType);
31722b4950f60c18d79b985bceb39784840e3d30004bungeman@google.com}
31822b4950f60c18d79b985bceb39784840e3d30004bungeman@google.com
31922b4950f60c18d79b985bceb39784840e3d30004bungeman@google.comconst std::vector<uint8_t>& Response::GetData() const {
32059bfb1240666b0f70109ac8ab04a280765ff8563robertphillips@google.com  return response_data_;
32159bfb1240666b0f70109ac8ab04a280765ff8563robertphillips@google.com}
32259bfb1240666b0f70109ac8ab04a280765ff8563robertphillips@google.com
32359bfb1240666b0f70109ac8ab04a280765ff8563robertphillips@google.comstd::string Response::GetDataAsString() const {
32459bfb1240666b0f70109ac8ab04a280765ff8563robertphillips@google.com  if (response_data_.empty())
32559bfb1240666b0f70109ac8ab04a280765ff8563robertphillips@google.com    return std::string();
32659bfb1240666b0f70109ac8ab04a280765ff8563robertphillips@google.com
32759bfb1240666b0f70109ac8ab04a280765ff8563robertphillips@google.com  const char* data_buf = reinterpret_cast<const char*>(response_data_.data());
32859bfb1240666b0f70109ac8ab04a280765ff8563robertphillips@google.com  return std::string(data_buf, data_buf + response_data_.size());
32959bfb1240666b0f70109ac8ab04a280765ff8563robertphillips@google.com}
33059bfb1240666b0f70109ac8ab04a280765ff8563robertphillips@google.com
33159bfb1240666b0f70109ac8ab04a280765ff8563robertphillips@google.comstd::string Response::GetHeader(const std::string& header_name) const {
33259bfb1240666b0f70109ac8ab04a280765ff8563robertphillips@google.com  if (connection_)
33359bfb1240666b0f70109ac8ab04a280765ff8563robertphillips@google.com    return connection_->GetResponseHeader(header_name);
33459bfb1240666b0f70109ac8ab04a280765ff8563robertphillips@google.com
33559bfb1240666b0f70109ac8ab04a280765ff8563robertphillips@google.com  return std::string();
33659bfb1240666b0f70109ac8ab04a280765ff8563robertphillips@google.com}
337242bb89c0d239662b05f5a396d45ad4f28b1596ebungeman@google.com
3382e2f3f58b5b0599c776f20bb55845d3e6005a01cbungeman@google.com}  // namespace http
3392e2f3f58b5b0599c776f20bb55845d3e6005a01cbungeman@google.com}  // namespace chromeos
3402e2f3f58b5b0599c776f20bb55845d3e6005a01cbungeman@google.com