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
5fed60b0c640828b320f56293c8bebc43fd2b1da8Alex Vakulenko#ifndef LIBBRILLO_BRILLO_HTTP_HTTP_REQUEST_H_
6fed60b0c640828b320f56293c8bebc43fd2b1da8Alex Vakulenko#define LIBBRILLO_BRILLO_HTTP_HTTP_REQUEST_H_
7f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
8f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko#include <limits>
9f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko#include <map>
10f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko#include <memory>
11f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko#include <string>
12f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko#include <utility>
13f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko#include <vector>
14f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
15f2418e562d358917b02b53290d5f4b3690d6f5d3Alex Vakulenko#include <base/macros.h>
169ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko#include <brillo/brillo_export.h>
179ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko#include <brillo/errors/error.h>
189ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko#include <brillo/http/http_connection.h>
199ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko#include <brillo/http/http_transport.h>
20f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
219ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenkonamespace brillo {
22f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkonamespace http {
23f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
24f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// HTTP request verbs
25f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkonamespace request_type {
269ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kOptions[];
279ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kGet[];
289ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kHead[];
299ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kPost[];
309ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kPut[];
319ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kPatch[];  // Non-standard HTTP/1.1 verb
329ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kDelete[];
339ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kTrace[];
349ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kConnect[];
359ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kCopy[];   // Non-standard HTTP/1.1 verb
369ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kMove[];   // Non-standard HTTP/1.1 verb
37f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko}  // namespace request_type
38f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
39f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// HTTP request header names
40f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkonamespace request_header {
419ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kAccept[];
429ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kAcceptCharset[];
439ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kAcceptEncoding[];
449ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kAcceptLanguage[];
459ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kAllow[];
469ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kAuthorization[];
479ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kCacheControl[];
489ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kConnection[];
499ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kContentEncoding[];
509ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kContentLanguage[];
519ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kContentLength[];
529ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kContentLocation[];
539ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kContentMd5[];
549ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kContentRange[];
559ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kContentType[];
569ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kCookie[];
579ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kDate[];
589ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kExpect[];
599ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kExpires[];
609ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kFrom[];
619ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kHost[];
629ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kIfMatch[];
639ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kIfModifiedSince[];
649ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kIfNoneMatch[];
659ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kIfRange[];
669ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kIfUnmodifiedSince[];
679ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kLastModified[];
689ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kMaxForwards[];
699ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kPragma[];
709ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kProxyAuthorization[];
719ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kRange[];
729ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kReferer[];
739ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kTE[];
749ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kTrailer[];
759ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kTransferEncoding[];
769ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kUpgrade[];
779ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kUserAgent[];
789ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kVia[];
799ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kWarning[];
80f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko}  // namespace request_header
81f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
82f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// HTTP response header names
83f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkonamespace response_header {
849ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kAcceptRanges[];
859ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kAge[];
869ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kAllow[];
879ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kCacheControl[];
889ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kConnection[];
899ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kContentEncoding[];
909ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kContentLanguage[];
919ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kContentLength[];
929ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kContentLocation[];
939ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kContentMd5[];
949ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kContentRange[];
959ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kContentType[];
969ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kDate[];
979ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kETag[];
989ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kExpires[];
999ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kLastModified[];
1009ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kLocation[];
1019ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kPragma[];
1029ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kProxyAuthenticate[];
1039ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kRetryAfter[];
1049ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kServer[];
1059ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kSetCookie[];
1069ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kTrailer[];
1079ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kTransferEncoding[];
1089ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kUpgrade[];
1099ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kVary[];
1109ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kVia[];
1119ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kWarning[];
1129ed0cab99f18acb3570a35e9408f24355f6b8324Alex VakulenkoBRILLO_EXPORT extern const char kWwwAuthenticate[];
113f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko}  // namespace response_header
114f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
115f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// HTTP request status (error) codes
116f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkonamespace status_code {
117f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// OK to continue with request
118f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkostatic const int Continue = 100;
119f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// Server has switched protocols in upgrade header
120f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkostatic const int SwitchProtocols = 101;
121f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
122f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// Request completed
123f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkostatic const int Ok = 200;
124f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// Object created, reason = new URI
125f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkostatic const int Created = 201;
126f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// Async completion (TBS)
127f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkostatic const int Accepted = 202;
128f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// Partial completion
129f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkostatic const int Partial = 203;
130f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// No info to return
131f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkostatic const int NoContent = 204;
132f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// Request completed, but clear form
133f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkostatic const int ResetContent = 205;
134f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// Partial GET fulfilled
135f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkostatic const int PartialContent = 206;
136f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
137f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// Server couldn't decide what to return
138f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkostatic const int Ambiguous = 300;
139f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// Object permanently moved
140f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkostatic const int Moved = 301;
141f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// Object temporarily moved
142f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkostatic const int Redirect = 302;
143f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// Redirection w/ new access method
144f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkostatic const int RedirectMethod = 303;
145f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// If-Modified-Since was not modified
146f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkostatic const int NotModified = 304;
147f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// Redirection to proxy, location header specifies proxy to use
148f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkostatic const int UseProxy = 305;
149f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// HTTP/1.1: keep same verb
150f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkostatic const int RedirectKeepVerb = 307;
151f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
152f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// Invalid syntax
153f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkostatic const int BadRequest = 400;
154f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// Access denied
155f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkostatic const int Denied = 401;
156f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// Payment required
157f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkostatic const int PaymentRequired = 402;
158f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// Request forbidden
159f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkostatic const int Forbidden = 403;
160f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// Object not found
161f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkostatic const int NotFound = 404;
162f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// Method is not allowed
163f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkostatic const int BadMethod = 405;
164f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// No response acceptable to client found
165f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkostatic const int NoneAcceptable = 406;
166f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// Proxy authentication required
167f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkostatic const int ProxyAuthRequired = 407;
168f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// Server timed out waiting for request
169f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkostatic const int RequestTimeout = 408;
170f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// User should resubmit with more info
171f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkostatic const int Conflict = 409;
172f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// The resource is no longer available
173f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkostatic const int Gone = 410;
174f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// The server refused to accept request w/o a length
175f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkostatic const int LengthRequired = 411;
176f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// Precondition given in request failed
177f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkostatic const int PrecondionFailed = 412;
178f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// Request entity was too large
179f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkostatic const int RequestTooLarge = 413;
180f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// Request URI too long
181f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkostatic const int UriTooLong = 414;
182f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// Unsupported media type
183f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkostatic const int UnsupportedMedia = 415;
184f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// Retry after doing the appropriate action.
185f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkostatic const int RetryWith = 449;
186f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
187f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// Internal server error
188f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkostatic const int InternalServerError = 500;
189f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// Request not supported
190f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkostatic const int NotSupported = 501;
191f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// Error response received from gateway
192f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkostatic const int BadGateway = 502;
193f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// Temporarily overloaded
194f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkostatic const int ServiceUnavailable = 503;
195f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// Timed out waiting for gateway
196f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkostatic const int GatewayTimeout = 504;
197f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// HTTP version not supported
198f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkostatic const int VersionNotSupported = 505;
199f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko}  // namespace status_code
200f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
201f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenkoclass Response;  // Just a forward declaration.
20247e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenkoclass FormData;
203f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
204f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko///////////////////////////////////////////////////////////////////////////////
205f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// Request class is the main object used to set up and initiate an HTTP
206f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// communication session. It is used to specify the HTTP request method,
207f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// request URL and many optional parameters (such as HTTP headers, user agent,
208f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// referer URL and so on.
209f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko//
210f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// Once everything is setup, GetResponse() method is used to send the request
211f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// and obtain the server response. The returned Response object can be
212f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// used to inspect the response code, HTTP headers and/or response body.
213f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko///////////////////////////////////////////////////////////////////////////////
2149ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenkoclass BRILLO_EXPORT Request final {
215f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko public:
216f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // The main constructor. |url| specifies the remote host address/path
217f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // to send the request to. |method| is the HTTP request verb and
218f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // |transport| is the HTTP transport implementation for server communications.
2192e1579107504b584d59e4ab036544369321f2a58Alex Vakulenko  Request(const std::string& url,
2202e1579107504b584d59e4ab036544369321f2a58Alex Vakulenko          const std::string& method,
221f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko          std::shared_ptr<Transport> transport);
222f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  ~Request();
223f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
224f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // Gets/Sets "Accept:" header value. The default value is "*/*" if not set.
2252e1579107504b584d59e4ab036544369321f2a58Alex Vakulenko  void SetAccept(const std::string& accept_mime_types);
226f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko  const std::string& GetAccept() const;
227f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
228f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // Gets/Sets "Content-Type:" header value
2292e1579107504b584d59e4ab036544369321f2a58Alex Vakulenko  void SetContentType(const std::string& content_type);
230f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko  const std::string& GetContentType() const;
231f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
232f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // Adds additional HTTP request header
2332e1579107504b584d59e4ab036544369321f2a58Alex Vakulenko  void AddHeader(const std::string& header, const std::string& value);
234f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  void AddHeaders(const HeaderList& headers);
235f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
236f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // Removes HTTP request header
2372e1579107504b584d59e4ab036544369321f2a58Alex Vakulenko  void RemoveHeader(const std::string& header);
238f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
239f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // Adds a request body. This is not to be used with GET method
2409ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko  bool AddRequestBody(const void* data, size_t size, brillo::ErrorPtr* error);
2419ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko  bool AddRequestBody(StreamPtr stream, brillo::ErrorPtr* error);
24247e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko
24347e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  // Adds a request body. This is not to be used with GET method.
24447e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  // This method also sets the correct content-type of the request, including
24547e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  // the multipart data boundary.
24647e9a9dd3dce9d197820ee4241135e6859f95360Alex Vakulenko  bool AddRequestBodyAsFormData(std::unique_ptr<FormData> form_data,
2479ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko                                brillo::ErrorPtr* error);
248f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
2492eed2f9a423b8e776b4d54530c567736c371ba48Nathan Bullock  // Adds a stream for the response. Otherwise a MemoryStream will be used.
2509ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko  bool AddResponseStream(StreamPtr stream, brillo::ErrorPtr* error);
2512eed2f9a423b8e776b4d54530c567736c371ba48Nathan Bullock
252f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // Makes a request for a subrange of data. Specifies a partial range with
253f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // either from beginning of the data to the specified offset (if |bytes| is
254f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // negative) or from the specified offset to the end of data (if |bytes| is
255f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // positive).
256f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // All individual ranges will be sent as part of "Range:" HTTP request header.
257f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  void AddRange(int64_t bytes);
258f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
259f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // Makes a request for a subrange of data. Specifies a full range with
260f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // start and end bytes from the beginning of the requested data.
261f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // All individual ranges will be sent as part of "Range:" HTTP request header.
262f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  void AddRange(uint64_t from_byte, uint64_t to_byte);
263f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
264f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // Returns the request URL
265f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko  const std::string& GetRequestURL() const;
266f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko
267f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko  // Returns the request verb.
268f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko  const std::string& GetRequestMethod() const;
269f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
270f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // Gets/Sets a request referer URL (sent as "Referer:" request header).
2712e1579107504b584d59e4ab036544369321f2a58Alex Vakulenko  void SetReferer(const std::string& referer);
272f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko  const std::string& GetReferer() const;
273f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
274f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // Gets/Sets a user agent string (sent as "User-Agent:" request header).
2752e1579107504b584d59e4ab036544369321f2a58Alex Vakulenko  void SetUserAgent(const std::string& user_agent);
276f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko  const std::string& GetUserAgent() const;
277f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
278f95a2b9e277726d8793a5849ec6e81c038c22be3Alex Vakulenko  // Sends the request to the server and blocks until the response is received,
279f95a2b9e277726d8793a5849ec6e81c038c22be3Alex Vakulenko  // which is returned as the response object.
280f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // In case the server couldn't be reached for whatever reason, returns
281f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // empty unique_ptr (null). In such a case, the additional error information
282f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // can be returned through the optional supplied |error| parameter.
2839ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko  std::unique_ptr<Response> GetResponseAndBlock(brillo::ErrorPtr* error);
284f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
285f95a2b9e277726d8793a5849ec6e81c038c22be3Alex Vakulenko  // Sends out the request and invokes the |success_callback| when the response
286f95a2b9e277726d8793a5849ec6e81c038c22be3Alex Vakulenko  // is received. In case of an error, the |error_callback| is invoked.
287ac3059d5edad2af5a75184d1e31133e712c91f60Alex Vakulenko  // Returns the ID of the asynchronous request created.
2888757d061cd87578b5b158e8efcc8a6cf4715c7a1Alex Vakulenko  RequestID GetResponse(const SuccessCallback& success_callback,
2898757d061cd87578b5b158e8efcc8a6cf4715c7a1Alex Vakulenko                        const ErrorCallback& error_callback);
290f95a2b9e277726d8793a5849ec6e81c038c22be3Alex Vakulenko
291f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko private:
292f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko  friend class HttpRequestTest;
293f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko
294f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // Helper function to create an http::Connection and send off request headers.
2959ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko  BRILLO_PRIVATE bool SendRequestIfNeeded(brillo::ErrorPtr* error);
296f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
297f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // Implementation that provides particular HTTP transport.
298f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  std::shared_ptr<Transport> transport_;
299f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
300f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // An established connection for adding request body. This connection
301f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // is maintained by the request object after the headers have been
302f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // sent and before the response is requested.
303f95a2b9e277726d8793a5849ec6e81c038c22be3Alex Vakulenko  std::shared_ptr<Connection> connection_;
304f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
305f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // Full request URL, such as "http://www.host.com/path/to/object"
3068757d061cd87578b5b158e8efcc8a6cf4715c7a1Alex Vakulenko  const std::string request_url_;
307f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // HTTP request verb, such as "GET", "POST", "PUT", ...
3088757d061cd87578b5b158e8efcc8a6cf4715c7a1Alex Vakulenko  const std::string method_;
309f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
310f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // Referrer URL, if any. Sent to the server via "Referer: " header.
311f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  std::string referer_;
312f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // User agent string, if any. Sent to the server via "User-Agent: " header.
313f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  std::string user_agent_;
314f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // Content type of the request body data.
315f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // Sent to the server via "Content-Type: " header.
316f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  std::string content_type_;
317f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // List of acceptable response data types.
318f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // Sent to the server via "Accept: " header.
319f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  std::string accept_ = "*/*";
320f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
321f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // List of optional request headers provided by the caller.
322f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko  std::multimap<std::string, std::string> headers_;
323f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // List of optional data ranges to request partial content from the server.
324f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // Sent to the server as "Range: " header.
325f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  std::vector<std::pair<uint64_t, uint64_t>> ranges_;
326f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
327f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // range_value_omitted is used in |ranges_| list to indicate omitted value.
328f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // E.g. range (10,range_value_omitted) represents bytes from 10 to the end
329f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // of the data stream.
330f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  const uint64_t range_value_omitted = std::numeric_limits<uint64_t>::max();
331f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
332f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  DISALLOW_COPY_AND_ASSIGN(Request);
333f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko};
334f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
335f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko///////////////////////////////////////////////////////////////////////////////
336f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// Response class is returned from Request::GetResponse() and is a way
337f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// to get to response status, error codes, response HTTP headers and response
338f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko// data (body) if available.
339f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko///////////////////////////////////////////////////////////////////////////////
3409ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenkoclass BRILLO_EXPORT Response final {
341f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko public:
342f95a2b9e277726d8793a5849ec6e81c038c22be3Alex Vakulenko  explicit Response(const std::shared_ptr<Connection>& connection);
343f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  ~Response();
344f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
345f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // Returns true if server returned a success code (status code below 400).
346f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  bool IsSuccessful() const;
347f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
348f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // Returns the HTTP status code (e.g. 200 for success)
349f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  int GetStatusCode() const;
350f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
351f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // Returns the status text (e.g. for error 403 it could be "NOT AUTHORIZED").
352f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  std::string GetStatusText() const;
353f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
354f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // Returns the content type of the response data.
355f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  std::string GetContentType() const;
356f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
35720d497f58d7abdec1e011cb1efadb45e53e5af0bAlex Vakulenko  // Returns response data stream by transferring ownership of the data stream
35820d497f58d7abdec1e011cb1efadb45e53e5af0bAlex Vakulenko  // from Response class to the caller.
35920d497f58d7abdec1e011cb1efadb45e53e5af0bAlex Vakulenko  StreamPtr ExtractDataStream(ErrorPtr* error);
360f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
36120d497f58d7abdec1e011cb1efadb45e53e5af0bAlex Vakulenko  // Extracts the data from the underlying response data stream as a byte array.
36220d497f58d7abdec1e011cb1efadb45e53e5af0bAlex Vakulenko  std::vector<uint8_t> ExtractData();
36320d497f58d7abdec1e011cb1efadb45e53e5af0bAlex Vakulenko
36420d497f58d7abdec1e011cb1efadb45e53e5af0bAlex Vakulenko  // Extracts the data from the underlying response data stream as a string.
36520d497f58d7abdec1e011cb1efadb45e53e5af0bAlex Vakulenko  std::string ExtractDataAsString();
366f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
367f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  // Returns a value of a given response HTTP header.
3682e1579107504b584d59e4ab036544369321f2a58Alex Vakulenko  std::string GetHeader(const std::string& header_name) const;
369f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
370f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko private:
371f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko  friend class HttpRequestTest;
372f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko
373f95a2b9e277726d8793a5849ec6e81c038c22be3Alex Vakulenko  std::shared_ptr<Connection> connection_;
3742e1579107504b584d59e4ab036544369321f2a58Alex Vakulenko
375f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko  DISALLOW_COPY_AND_ASSIGN(Response);
376f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko};
377f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
378f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko}  // namespace http
3799ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko}  // namespace brillo
380f788c95c111d0dccff735b8e02939e4e95ee2f5dAlex Vakulenko
381fed60b0c640828b320f56293c8bebc43fd2b1da8Alex Vakulenko#endif  // LIBBRILLO_BRILLO_HTTP_HTTP_REQUEST_H_
382