• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright 2016 The TensorFlow Authors. All Rights Reserved.
2 
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6 
7     http://www.apache.org/licenses/LICENSE-2.0
8 
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 ==============================================================================*/
15 
16 #ifndef TENSORFLOW_CORE_PLATFORM_CLOUD_HTTP_REQUEST_H_
17 #define TENSORFLOW_CORE_PLATFORM_CLOUD_HTTP_REQUEST_H_
18 
19 #include <string>
20 #include <unordered_map>
21 #include <vector>
22 #include "tensorflow/core/lib/core/errors.h"
23 #include "tensorflow/core/lib/core/status.h"
24 #include "tensorflow/core/lib/core/stringpiece.h"
25 #include "tensorflow/core/platform/env.h"
26 #include "tensorflow/core/platform/macros.h"
27 #include "tensorflow/core/platform/protobuf.h"
28 #include "tensorflow/core/platform/types.h"
29 
30 namespace tensorflow {
31 
32 /// \brief An abstract basic HTTP client.
33 ///
34 /// The usage pattern for the class is based on the libcurl library:
35 /// create a request object, set request parameters and call Send().
36 ///
37 /// For example:
38 ///   HttpRequest request;
39 ///   request.SetUri("http://www.google.com");
40 ///   request.SetResultsBuffer(out_buffer);
41 ///   request.Send();
42 class HttpRequest {
43  public:
44   class Factory {
45    public:
~Factory()46     virtual ~Factory() {}
47     virtual HttpRequest* Create() = 0;
48   };
49 
50   /// RequestMethod is used to capture what type of HTTP request is made and
51   /// is used in conjunction with RequestStats for instrumentation and
52   /// monitoring of HTTP requests and their responses.
53   enum class RequestMethod : char {
54     kGet,
55     kPost,
56     kPut,
57     kDelete,
58   };
59 
60   /// RequestMethodName converts a RequestMethod to the canonical method string.
RequestMethodName(RequestMethod m)61   inline static const char* RequestMethodName(RequestMethod m) {
62     switch (m) {
63       case RequestMethod::kGet:
64         return "GET";
65       case RequestMethod::kPost:
66         return "POST";
67       case RequestMethod::kPut:
68         return "PUT";
69       case RequestMethod::kDelete:
70         return "DELETE";
71       default:
72         return "???";
73     }
74   }
75 
76   /// RequestStats is a class that can be used to instrument an Http Request.
77   class RequestStats {
78    public:
79     virtual ~RequestStats() = default;
80 
81     /// RecordRequest is called right before a request is sent on the wire.
82     virtual void RecordRequest(const HttpRequest* request, const string& uri,
83                                RequestMethod method) = 0;
84 
85     /// RecordResponse is called after the response has been received.
86     virtual void RecordResponse(const HttpRequest* request, const string& uri,
87                                 RequestMethod method, const Status& result) = 0;
88   };
89 
HttpRequest()90   HttpRequest() {}
~HttpRequest()91   virtual ~HttpRequest() {}
92 
93   /// Sets the request URI.
94   virtual void SetUri(const string& uri) = 0;
95 
96   /// \brief Sets the Range header.
97   ///
98   /// Used for random seeks, for example "0-999" returns the first 1000 bytes
99   /// (note that the right border is included).
100   virtual void SetRange(uint64 start, uint64 end) = 0;
101 
102   /// Sets a request header.
103   virtual void AddHeader(const string& name, const string& value) = 0;
104 
105   /// Sets a DNS resolve mapping (to skip DNS resolution).
106   ///
107   /// Note: because GCS is available over HTTPS, we cannot replace the hostname
108   /// in the URI with an IP address, as that will cause the certificate check
109   /// to fail.
110   virtual void AddResolveOverride(const string& hostname, int64 port,
111                                   const string& ip_addr) = 0;
112 
113   /// Sets the 'Authorization' header to the value of 'Bearer ' + auth_token.
114   virtual void AddAuthBearerHeader(const string& auth_token) = 0;
115 
116   /// Sets the RequestStats object to use to record the request and response.
117   virtual void SetRequestStats(RequestStats* stats) = 0;
118 
119   /// Makes the request a DELETE request.
120   virtual void SetDeleteRequest() = 0;
121 
122   /// \brief Makes the request a PUT request.
123   ///
124   /// The request body will be taken from the specified file starting from
125   /// the given offset.
126   virtual Status SetPutFromFile(const string& body_filepath, size_t offset) = 0;
127 
128   /// Makes the request a PUT request with an empty body.
129   virtual void SetPutEmptyBody() = 0;
130 
131   /// \brief Makes the request a POST request.
132   ///
133   /// The request body will be taken from the specified buffer.
134   virtual void SetPostFromBuffer(const char* buffer, size_t size) = 0;
135 
136   /// Makes the request a POST request with an empty body.
137   virtual void SetPostEmptyBody() = 0;
138 
139   /// \brief Specifies the buffer for receiving the response body.
140   ///
141   /// Size of out_buffer after an access will be exactly the number of bytes
142   /// read. Existing content of the vector will be cleared.
143   virtual void SetResultBuffer(std::vector<char>* out_buffer) = 0;
144 
145   /// \brief Specifies the buffer for receiving the response body.
146   ///
147   /// This method should be used when a caller knows the upper bound of the
148   /// size of the response data.  The caller provides a pre-allocated buffer
149   /// and its size. After the Send() method is called, the
150   /// GetResultBufferDirectBytesTransferred() method may be used to learn to the
151   /// number of bytes that were transferred using this method.
152   virtual void SetResultBufferDirect(char* buffer, size_t size) = 0;
153 
154   /// \brief Returns the number of bytes transferred, when using
155   /// SetResultBufferDirect(). This method may only be used when using
156   /// SetResultBufferDirect().
157   virtual size_t GetResultBufferDirectBytesTransferred() = 0;
158 
159   /// \brief Returns the response headers of a completed request.
160   ///
161   /// If the header is not found, returns an empty string.
162   virtual string GetResponseHeader(const string& name) const = 0;
163 
164   /// Returns the response code of a completed request.
165   virtual uint64 GetResponseCode() const = 0;
166 
167   /// \brief Sends the formed request.
168   ///
169   /// If the result buffer was defined, the response will be written there.
170   /// The object is not designed to be re-used after Send() is executed.
171   virtual Status Send() = 0;
172 
173   // Url encodes str and returns a new string.
174   virtual string EscapeString(const string& str) = 0;
175 
176   /// \brief Set timeouts for this request.
177   ///
178   /// The connection parameter controls how long we should wait for the
179   /// connection to be established. The inactivity parameter controls how long
180   /// we should wait between additional responses from the server. Finally the
181   /// total parameter controls the maximum total connection time to prevent
182   /// hanging indefinitely.
183   virtual void SetTimeouts(uint32 connection, uint32 inactivity,
184                            uint32 total) = 0;
185 
186   TF_DISALLOW_COPY_AND_ASSIGN(HttpRequest);
187 };
188 
189 }  // namespace tensorflow
190 
191 #endif  // TENSORFLOW_CORE_PLATFORM_CLOUD_HTTP_REQUEST_H_
192