HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
FS_WebAPI.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * COMMENTS:
7  *
8  * Sample usage:
9  * FS_WebAPIResponse response =
10  * FS_WebAPI("http://www.orbolt.com/api").call1(
11  * "is_asset_in_store", "SideFX::spaceship");
12  * response.myJSONResult.dump();
13  * std::cout << "\nerrors: " << response.myErrors.nonNullBuffer()
14  * << std::endl;
15  * Prints:
16  * true
17  * errors:
18  */
19 
20 #ifndef __FS_WebAPI_h__
21 #define __FS_WebAPI_h__
22 
23 #include "FS_API.h"
24 
25 #include <type_traits>
26 
27 #include <UT/UT_String.h>
28 #include <UT/UT_StringHolder.h>
29 #include <UT/UT_WorkBuffer.h>
30 
31 #include <UT/UT_ScopeExit.h>
32 #include <UT/UT_JSONValue.h>
33 #include <UT/UT_JSONWriter.h>
34 #include <UT/UT_UniquePtr.h>
35 #include <UT/UT_DeepString.h>
36 #include <UT/UT_Optional.h>
37 #include <UT/UT_Lock.h>
38 #include <UT/UT_StringArray.h>
39 #include <UT/UT_ArrayStringMap.h>
40 #include <UT/UT_Url.h>
41 
42 // Static check to see if the type is a string type. Note decay the type so that
43 // any provided type will be checked to see if its a string object
44 template <class T>
45 struct FS_IsString : std::integral_constant<bool,
46  std::is_same<UT_String, typename std::decay<T>::type>::value ||
47  std::is_same<UT_StringHolder, typename std::decay<T>::type>::value ||
48  std::is_same<UT_WorkBuffer, typename std::decay<T>::type>::value ||
49  std::is_same<std::string, typename std::decay<T>::type>::value>
50 {};
51 
52 // NOTE: Not a full list of http status codes
54 {
55  // Curl uses zero to indicate no status code received
57  // Info Codes
60  // Success Codes
61  FS_HTTPOk = 200,
68  // Redirect Codes
71  FS_HTTPFound = 302,
76  // Client Error Codes
87  FS_HTTPGone = 410,
102  // Server Error Codes
110 };
111 
112 // Response from client request
114 {
115 public:
117  FS_HTTPResponse();
118  explicit FS_HTTPResponse(FS_HTTPStatusCode code);
120  FS_HTTPResponse(FS_HTTPStatusCode code, const HeaderMap& headers,
121  const UT_StringHolder& data);
122  FS_HTTPResponse(FS_HTTPStatusCode code, const HeaderMap& headers);
123 
124  operator bool() const { return myStatus == FS_HTTPOk; }
125 
126  bool isRequestNotFound() const { return myStatus == FS_HTTPNotFound; }
127  bool hasTimedout() const { return myStatus == FS_HTTPRequestTimeout; }
128 
129  UT_StringHolder headersAsString() const;
130 
131  // Does this response object have a specific option specified.
132  bool hasHeader(const char* header_opt) const;
133 
134  bool errorReceivedNothing() const;
135 
136  const UT_StringHolder& data() const { return myData; }
137  const UT_StringHolder& errors() const
138  {
139  // If there are errors then return it
140  if (myErrors.length() > 0)
141  return myErrors;
142 
143  // If the request was not successful then return the bodies data
144  // instead as that will hold the error information for the request.
145  if (myStatus != FS_HTTPOk)
146  return myData;
147 
148  return myErrors;
149  }
150 
151  bool hasContentType(const UT_StringRef& mime) const;
152 
153  UT_Optional<const UT_StringHolder&> getHeaderContentType();
154  UT_Optional<exint> getHeaderContentLength();
155 
156  int modTime() const;
157 
158  bool hasJSONBody() const;
159  static bool isJSONBody(const HeaderMap &headers);
160 
161  // Get the stock message based on the status code
162  static void stockMsgFromCode(FS_HTTPStatusCode code, UT_WorkBuffer& msg);
163 
164  void clear();
165 
167  // The status of the response
169  // The headers of the response
172  // The body of the response
174  // Error that you might want hidden
176 };
177 
179 {
180 public:
183 };
184 
186 {
187 public:
189 
190  FS_WebAPI(const char *api_url);
191  explicit FS_WebAPI(const UT_Url &api_url);
192 
193  static UT_StringHolder decodeUri(const UT_StringView uri);
194  static UT_StringHolder encodeUri(const UT_StringView uri);
195 
196  void setProxy(const UT_StringHolder& proxy);
197  const UT_StringHolder& proxy() const { return myProxy; }
198 
199  void setTimeout(int timeout);
200  void followRedirects(bool follow);
201  bool shouldFollowRedirects() const { return myFollowRedirects; }
202 
203  // Send an HTTP post request
204  bool post(FS_HTTPResponse& resp, const WebMap& variables,
205  const UT_Optional<const WebMap&>& headers = UT_Optional<const WebMap&>()) const;
206  // Send an HTTP get request
207  bool get(FS_HTTPResponse &resp,
208  const UT_Optional<const WebMap &> &headers =
210  // The following method lets you make API calls to named functions in
211  // the Web API. Call the appropriate method for the given number of
212  // arguments.
213  template <typename... Args>
214  FS_WebAPIResponse call(const char* api_url, Args&&... args);
215 
216  bool hasValidProxy() const
217  {
218  return !myProxy.isEmpty();
219  }
220 
221  const UT_Url& getAPIUrl() const { return myAPIURL; }
222  UT_StringHolder getAPIUrlString() const { return myAPIURL.toString(); }
223  int getTimeout() const { return myTimeout; }
224  const UT_WorkBuffer& getCookies() const { return myCookies; }
225 
226  // Set the ssl certificate for ssl communication.
227  void sslCertificate(const UT_StringHolder& cert) { myCert = cert; }
228  const UT_StringHolder& getCertificate() const { return myCert; }
229 
230  // This is a really simple implementation. It doesn't check for duplicates
231  // or anything like that.
232  //
233  // USE AT YOUR OWN RISK
234  void addCookie(const char *name, const char *value);
235  void clearCookies();
236 
237  // Determines CURLOPT_CAPATH
238  static UT_StringHolder determineCAPath();
239  // Determines CURLOPT_CAINFO
240  static UT_StringHolder determineCAInfo();
241  UT_StringHolder connectionURL() const;
242 private:
243  // Send http request in our APIs format
244  FS_WebAPIResponse post(const WebMap &variables) const;
245 
246  static void webCall(UT_JSONWriter& writer);
247  template <typename T>
248  static void webCall(UT_JSONWriter& writer, T&& arg);
249  template <typename T, typename... REST>
250  static void webCall(UT_JSONWriter& writer, T&& args, REST&&... rest);
251 
252  FS_WebAPIResponse callFunctionWithJSONArgs(
253  const UT_WorkBuffer &json_data) const;
254 
255  FS_WebAPIResponse postAndGetJSONResponse(
256  void *curl, const char *post_data) const;
257 
258  void writeAPICallPrefixToJSON(
259  UT_JSONWriter &writer, const char *api_function) const;
260  void writeAPICallSuffixToJSON(UT_JSONWriter &writer) const;
261 
262  UT_Url myAPIURL;
263  UT_StringHolder myProxy;
264  UT_WorkBuffer myCookies;
265  int myTimeout;
266  bool myFollowRedirects;
267  UT_StringHolder myCert;
268 };
269 
270 //---------------------------------------------------------------------------
271 
272 // Needed until we switch to c++17 (needs constexpr if)
273 inline
274 void
275 FS_WebAPI::webCall(UT_JSONWriter& writer)
276 {}
277 
278 template <typename T>
279 inline
280 void
281 FS_WebAPI::webCall(UT_JSONWriter& writer, T&& arg)
282 {
283  writer.jsonValue(arg);
284 }
285 
286 template <typename T, typename ...REST>
287 void
288 FS_WebAPI::webCall(UT_JSONWriter& writer, T&& arg, REST&&... rest)
289 {
290  writer.jsonValue(arg);
291  webCall(writer, std::forward<REST>(rest)...);
292 }
293 
294 template <typename ...Args>
295 inline
297 FS_WebAPI::call(const char* api_function, Args&&... args)
298 {
299  UT_WorkBuffer json_data;
300  UT_UniquePtr<UT_JSONWriter> json_writer(
301  UT_JSONWriter::allocWriter(json_data));
302 
303  writeAPICallPrefixToJSON(*json_writer, api_function);
304  // When we switch to c++17 switch this to check if the number of elements is
305  // > 0 so we don't need the no-op function (needs constexpr if)
306  webCall(*json_writer, std::forward<Args>(args)...);
307  writeAPICallSuffixToJSON(*json_writer);
308  return callFunctionWithJSONArgs(json_data);
309 }
310 
311 #endif
FS_WebAPIResponse call(const char *api_url, Args &&...args)
Definition: FS_WebAPI.h:297
int getTimeout() const
Definition: FS_WebAPI.h:223
bool jsonValue(bool value)
const UT_StringHolder & getCertificate() const
Definition: FS_WebAPI.h:228
GLuint const GLchar * name
Definition: glew.h:1814
UT_StringHolder myErrors
Definition: FS_WebAPI.h:175
const Args & args
Definition: printf.h:628
internal::named_arg< T, char > arg(string_view name, const T &arg)
Definition: core.h:1393
static UT_JSONWriter * allocWriter(UT_WorkBuffer &buffer)
Class which writes ASCII or binary JSON streams.
Definition: UT_JSONWriter.h:32
UT_JSONValue myJSONResult
Definition: FS_WebAPI.h:181
UT_StringArray myCookies
Definition: FS_WebAPI.h:171
A utility class to do read-only operations on a subset of an existing string.
Definition: UT_StringView.h:32
hboost::optional< T > UT_Optional
Definition: UT_Optional.h:16
const UT_StringHolder & proxy() const
Definition: FS_WebAPI.h:197
GLint GLenum GLsizei GLint GLsizei const void * data
Definition: glew.h:1379
UT_StringHolder myData
Definition: FS_WebAPI.h:173
bool hasValidProxy() const
Definition: FS_WebAPI.h:216
void sslCertificate(const UT_StringHolder &cert)
Definition: FS_WebAPI.h:227
FS_HTTPStatusCode myStatus
Definition: FS_WebAPI.h:168
Definition: UT_Url.h:22
UT_DeepString myErrors
Definition: FS_WebAPI.h:182
const UT_StringHolder & data() const
Definition: FS_WebAPI.h:136
const UT_WorkBuffer & getCookies() const
Definition: FS_WebAPI.h:224
bool shouldFollowRedirects() const
Definition: FS_WebAPI.h:201
const UT_StringHolder & errors() const
Definition: FS_WebAPI.h:137
Class to store JSON objects as C++ objects.
Definition: UT_JSONValue.h:76
HeaderMap myHeaders
Definition: FS_WebAPI.h:170
bool isRequestNotFound() const
Definition: FS_WebAPI.h:126
FS_HTTPStatusCode
Definition: FS_WebAPI.h:53
GLbitfield GLuint64 timeout
Definition: glew.h:6605
bool hasTimedout() const
Definition: FS_WebAPI.h:127
UT_StringHolder getAPIUrlString() const
Definition: FS_WebAPI.h:222
GridType::Ptr curl(const GridType &grid, bool threaded, InterruptT *interrupt)
Compute the curl of the given vector-valued grid.
GA_API const UT_StringHolder rest
GLsizei const GLfloat * value
Definition: glew.h:1849
const UT_Url & getAPIUrl() const
Definition: FS_WebAPI.h:221
#define FS_API
Definition: FS_API.h:10