Chris Sosa | 45d9f10 | 2014-03-24 11:18:54 -0700 | [diff] [blame] | 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 "buffet/http_request.h" |
| 6 | |
| 7 | #include "buffet/http_transport_curl.h" |
| 8 | #include "buffet/mime_utils.h" |
| 9 | |
| 10 | using namespace chromeos; |
| 11 | using namespace chromeos::http; |
| 12 | |
| 13 | // request_type |
| 14 | const char request_type::kOptions[] = "OPTIONS"; |
| 15 | const char request_type::kGet[] = "GET"; |
| 16 | const char request_type::kHead[] = "HEAD"; |
| 17 | const char request_type::kPost[] = "POST"; |
| 18 | const char request_type::kPut[] = "PUT"; |
| 19 | const char request_type::kPatch[] = "PATCH"; |
| 20 | const char request_type::kDelete[] = "DELETE"; |
| 21 | const char request_type::kTrace[] = "TRACE"; |
| 22 | const char request_type::kConnect[] = "CONNECT"; |
| 23 | const char request_type::kCopy[] = "COPY"; |
| 24 | const char request_type::kMove[] = "MOVE"; |
| 25 | |
| 26 | // request_header |
| 27 | const char request_header::kAccept[] = "Accept"; |
| 28 | const char request_header::kAcceptCharset[] = "Accept-Charset"; |
| 29 | const char request_header::kAcceptEncoding[] = "Accept-Encoding"; |
| 30 | const char request_header::kAcceptLanguage[] = "Accept-Language"; |
| 31 | const char request_header::kAllow[] = "Allow"; |
| 32 | const char request_header::kAuthorization[] = "Authorization"; |
| 33 | const char request_header::kCacheControl[] = "Cache-Control"; |
| 34 | const char request_header::kConnection[] = "Connection"; |
| 35 | const char request_header::kContentEncoding[] = "Content-Encoding"; |
| 36 | const char request_header::kContentLanguage[] = "Content-Language"; |
| 37 | const char request_header::kContentLength[] = "Content-Length"; |
| 38 | const char request_header::kContentLocation[] = "Content-Location"; |
| 39 | const char request_header::kContentMd5[] = "Content-MD5"; |
| 40 | const char request_header::kContentRange[] = "Content-Range"; |
| 41 | const char request_header::kContentType[] = "Content-Type"; |
| 42 | const char request_header::kCookie[] = "Cookie"; |
| 43 | const char request_header::kDate[] = "Date"; |
| 44 | const char request_header::kExpect[] = "Expect"; |
| 45 | const char request_header::kExpires[] = "Expires"; |
| 46 | const char request_header::kFrom[] = "From"; |
| 47 | const char request_header::kHost[] = "Host"; |
| 48 | const char request_header::kIfMatch[] = "If-Match"; |
| 49 | const char request_header::kIfModifiedSince[] = "If-Modified-Since"; |
| 50 | const char request_header::kIfNoneMatch[] = "If-None-Match"; |
| 51 | const char request_header::kIfRange[] = "If-Range"; |
| 52 | const char request_header::kIfUnmodifiedSince[] = "If-Unmodified-Since"; |
| 53 | const char request_header::kLastModified[] = "Last-Modified"; |
| 54 | const char request_header::kMaxForwards[] = "Max-Forwards"; |
| 55 | const char request_header::kPragma[] = "Pragma"; |
| 56 | const char request_header::kProxyAuthorization[] = "Proxy-Authorization"; |
| 57 | const char request_header::kRange[] = "Range"; |
| 58 | const char request_header::kReferer[] = "Referer"; |
| 59 | const char request_header::kTE[] = "TE"; |
| 60 | const char request_header::kTrailer[] = "Trailer"; |
| 61 | const char request_header::kTransferEncoding[] = "Transfer-Encoding"; |
| 62 | const char request_header::kUpgrade[] = "Upgrade"; |
| 63 | const char request_header::kUserAgent[] = "User-Agent"; |
| 64 | const char request_header::kVia[] = "Via"; |
| 65 | const char request_header::kWarning[] = "Warning"; |
| 66 | |
| 67 | // response_header |
| 68 | const char response_header::kAcceptRanges[] = "Accept-Ranges"; |
| 69 | const char response_header::kAge[] = "Age"; |
| 70 | const char response_header::kAllow[] = "Allow"; |
| 71 | const char response_header::kCacheControl[] = "Cache-Control"; |
| 72 | const char response_header::kConnection[] = "Connection"; |
| 73 | const char response_header::kContentEncoding[] = "Content-Encoding"; |
| 74 | const char response_header::kContentLanguage[] = "Content-Language"; |
| 75 | const char response_header::kContentLength[] = "Content-Length"; |
| 76 | const char response_header::kContentLocation[] = "Content-Location"; |
| 77 | const char response_header::kContentMd5[] = "Content-MD5"; |
| 78 | const char response_header::kContentRange[] = "Content-Range"; |
| 79 | const char response_header::kContentType[] = "Content-Type"; |
| 80 | const char response_header::kDate[] = "Date"; |
| 81 | const char response_header::kETag[] = "ETag"; |
| 82 | const char response_header::kExpires[] = "Expires"; |
| 83 | const char response_header::kLastModified[] = "Last-Modified"; |
| 84 | const char response_header::kLocation[] = "Location"; |
| 85 | const char response_header::kPragma[] = "Pragma"; |
| 86 | const char response_header::kProxyAuthenticate[] = "Proxy-Authenticate"; |
| 87 | const char response_header::kRetryAfter[] = "Retry-After"; |
| 88 | const char response_header::kServer[] = "Server"; |
| 89 | const char response_header::kSetCookie[] = "Set-Cookie"; |
| 90 | const char response_header::kTrailer[] = "Trailer"; |
| 91 | const char response_header::kTransferEncoding[] = "Transfer-Encoding"; |
| 92 | const char response_header::kUpgrade[] = "Upgrade"; |
| 93 | const char response_header::kVary[] = "Vary"; |
| 94 | const char response_header::kVia[] = "Via"; |
| 95 | const char response_header::kWarning[] = "Warning"; |
| 96 | const char response_header::kWwwAuthenticate[] = "WWW-Authenticate"; |
| 97 | |
| 98 | //************************************************************************** |
| 99 | //********************** Request Class ********************** |
| 100 | //************************************************************************** |
| 101 | Request::Request(std::string const& url, char const* method) : |
| 102 | transport_(new curl::Transport(url, method)) { |
| 103 | } |
| 104 | |
| 105 | Request::Request(std::string const& url) : |
| 106 | transport_(new curl::Transport(url, nullptr)) { |
| 107 | } |
| 108 | |
| 109 | Request::Request(std::shared_ptr<TransportInterface> transport) : |
| 110 | transport_(transport) { |
| 111 | } |
| 112 | |
| 113 | void Request::AddRange(int64_t bytes) { |
| 114 | if (transport_) |
| 115 | transport_->AddRange(bytes); |
| 116 | } |
| 117 | |
| 118 | void Request::AddRange(uint64_t from_byte, uint64_t to_byte) { |
| 119 | if (transport_) |
| 120 | transport_->AddRange(from_byte, to_byte); |
| 121 | } |
| 122 | |
| 123 | std::unique_ptr<Response> Request::GetResponse() { |
| 124 | if (transport_) { |
| 125 | if (transport_->GetStage() == TransportInterface::Stage::initialized) { |
| 126 | if(transport_->Perform()) |
| 127 | return std::unique_ptr<Response>(new Response(transport_)); |
| 128 | } else if (transport_->GetStage() == |
| 129 | TransportInterface::Stage::response_received) { |
| 130 | return std::unique_ptr<Response>(new Response(transport_)); |
| 131 | } |
| 132 | } |
| 133 | return std::unique_ptr<Response>(); |
| 134 | } |
| 135 | |
| 136 | void Request::SetAccept(char const* accept_mime_types) { |
| 137 | if (transport_) |
| 138 | transport_->SetAccept(accept_mime_types); |
| 139 | } |
| 140 | |
| 141 | std::string Request::GetAccept() const { |
| 142 | return transport_ ? transport_->GetAccept() : std::string(); |
| 143 | } |
| 144 | |
| 145 | std::string Request::GetRequestURL() const { |
| 146 | return transport_ ? transport_->GetRequestURL() : std::string(); |
| 147 | } |
| 148 | |
| 149 | void Request::SetContentType(char const* contentType) { |
| 150 | if (transport_) |
| 151 | transport_->SetContentType(contentType); |
| 152 | } |
| 153 | |
| 154 | std::string Request::GetContentType() const { |
| 155 | return transport_ ? transport_->GetContentType() : std::string(); |
| 156 | } |
| 157 | |
| 158 | void Request::AddHeader(char const* header, char const* value) { |
| 159 | if (transport_) |
| 160 | transport_->AddHeader(header, value); |
| 161 | } |
| 162 | |
| 163 | bool Request::AddRequestBody(void const* data, size_t size) { |
| 164 | return transport_ && transport_->AddRequestBody(data, size); |
| 165 | } |
| 166 | |
| 167 | void Request::SetMethod(char const* method) { |
| 168 | if (transport_) |
| 169 | transport_->SetMethod(method); |
| 170 | } |
| 171 | |
| 172 | std::string Request::GetMethod() const { |
| 173 | return transport_ ? transport_->GetMethod() : std::string(); |
| 174 | } |
| 175 | |
| 176 | void Request::SetReferer(char const* referer) { |
| 177 | if (transport_) |
| 178 | transport_->SetReferer(referer); |
| 179 | } |
| 180 | |
| 181 | std::string Request::GetReferer() const { |
| 182 | return transport_ ? transport_->GetReferer() : std::string(); |
| 183 | } |
| 184 | |
| 185 | void Request::SetUserAgent(char const* user_agent) { |
| 186 | if (transport_) |
| 187 | transport_->SetUserAgent(user_agent); |
| 188 | } |
| 189 | |
| 190 | std::string Request::GetUserAgent() const { |
| 191 | return transport_ ? transport_->GetUserAgent() : std::string(); |
| 192 | } |
| 193 | |
| 194 | std::string Request::GetErrorMessage() const { |
| 195 | if (transport_ && |
| 196 | transport_->GetStage() == TransportInterface::Stage::failed) { |
| 197 | return transport_->GetErrorMessage(); |
| 198 | } |
| 199 | |
| 200 | return std::string(); |
| 201 | } |
| 202 | |
| 203 | //************************************************************************** |
| 204 | //********************** Response Class ********************** |
| 205 | //************************************************************************** |
| 206 | Response::Response(std::shared_ptr<TransportInterface> transport) : |
| 207 | transport_(transport) { |
| 208 | } |
| 209 | |
| 210 | bool Response::IsSuccessful() const { |
| 211 | if (transport_ && |
| 212 | transport_->GetStage() == TransportInterface::Stage::response_received) { |
| 213 | int code = GetStatusCode(); |
| 214 | return code >= status_code::Continue && code < status_code::BadRequest; |
| 215 | } |
| 216 | return false; |
| 217 | } |
| 218 | |
| 219 | int Response::GetStatusCode() const { |
| 220 | if (!transport_) |
| 221 | return -1; |
| 222 | |
| 223 | return transport_->GetResponseStatusCode(); |
| 224 | } |
| 225 | |
| 226 | std::string Response::GetStatusText() const { |
| 227 | if (!transport_) |
| 228 | return std::string(); |
| 229 | |
| 230 | return transport_->GetResponseStatusText(); |
| 231 | } |
| 232 | |
| 233 | std::string Response::GetContentType() const { |
| 234 | return GetHeader(response_header::kContentType); |
| 235 | } |
| 236 | |
| 237 | std::vector<unsigned char> Response::GetData() const { |
| 238 | if (transport_) |
| 239 | return transport_->GetResponseData(); |
| 240 | |
| 241 | return std::vector<unsigned char>(); |
| 242 | } |
| 243 | |
| 244 | std::string Response::GetDataAsString() const { |
| 245 | if (transport_) { |
| 246 | auto data = transport_->GetResponseData(); |
| 247 | char const* data_buf = reinterpret_cast<char const*>(data.data()); |
| 248 | return std::string(data_buf, data_buf + data.size()); |
| 249 | } |
| 250 | |
| 251 | return std::string(); |
| 252 | } |
| 253 | |
| 254 | std::string Response::GetHeader(char const* header_name) const { |
| 255 | if (transport_) |
| 256 | return transport_->GetResponseHeader(header_name); |
| 257 | |
| 258 | return std::string(); |
| 259 | } |
| 260 | |