HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
NET_HTTPRequest.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  * NAME: NET_HTTPRequest.h (LM Library, C++)
7  *
8  * COMMENTS: HTTP Request object
9  */
10 
11 #ifndef __NET_HTTPRequest_H__
12 #define __NET_HTTPRequest_H__
13 
14 #include "NET_API.h"
15 
16 #include "NET_HTTPUploadedFile.h"
17 #include "NET_WebAPI.h"
18 #include "NET_WebTypes.h"
19 #include "NET_Time.h"
20 #include "NET_WebStream.h"
21 
22 #include <UT/UT_Array.h>
23 #include <UT/UT_ArrayStringMap.h>
24 #include <UT/UT_Optional.h>
25 #include <UT/UT_SharedPtr.h>
26 #include <UT/UT_StringHolder.h>
27 #include <UT/UT_StringView.h>
28 #include <UT/UT_WorkBuffer.h>
29 
30 #include <SYS/SYS_Inline.h>
31 
32 #include <utility>
33 
34 
35 // Object that parses an http(s) request from any NET_Stream source and
36 // writes to any NET_Stream.
37 class NET_API NET_HTTPRequest
38 {
39 public:
43 
44  // Callback to check if a function is considered to be a valid one
45  // by the caller.
46  using PathChecker =
47  std::function<NET_HTTPStatusCode(const UT_String &, const UT_String &)>;
48 
50  {
52  kHTTPS
53  };
54 
56  virtual ~NET_HTTPRequest() = default;
57 
58  explicit operator bool() const { return isValid(); }
59 
60  // This is a line that holds useful information that could be piped to
61  // the command line or a file for debugging.
62  UT_StringHolder debugLine() const;
63 
65  {
66  UT_StringHolder str;
67  str.format("HTTP/{}.{}", myVersionMaj, myVersionMin);
68  return str;
69  }
71  {
72  UT_StringHolder str;
73  auto header = getHeaderOpt("Content-Length");
74  if (header)
75  str = header.get();
76  return str;
77  }
79  {
80  UT_StringHolder str;
81  auto header = getHeaderOpt("Content-Type");
82  if (header)
83  str = header.get();
84  return str;
85  }
87  {
88  UT_StringHolder str;
89  auto header = getHeaderOpt("Host");
90  if (header)
91  {
92  const UT_StringHolder& host = header.get();
93  exint idx = UT_StringView(host.begin(), host.end()).findFirstOf(':');
94  if (idx < 0)
95  idx = host.length();
96  return UT_StringHolder(host.buffer(), idx);
97  }
98  return str;
99  }
100  // get the version of this request
101  unsigned versionMaj() const { return myVersionMaj; }
102  unsigned versionMin() const { return myVersionMin; }
103  // Get the request method (i.e. GET, POST, etc..)
104  const UT_StringHolder &method() const { return myMethod; }
105  // Get this objects request path without the file at the end
106  const UT_StringHolder &path() const { return myPath; }
107  const UT_StringHolder &queryString() const { return myQueryString; }
108 
109  UT_Optional<NET_HTTPUploadedFile &> getFile(const char *name);
110  // Get the optionally found header option
111  UT_Optional<const UT_StringHolder &> getHeaderOpt(const char *name) const;
113  {
114  return myHeaders.contains(name);
115  }
116  // Get the optionally found body variable
117  UT_Optional<const UT_StringHolder &> getVariable(const char *name) const;
119  {
120  return myPost.contains(name);
121  }
122  // Get the optionally found uri variable
123  UT_Optional<const UT_StringHolder &> getUriVariable(const char *name) const;
124  // Get the optionally found cookie
125  UT_Optional<const UT_StringHolder &> getCookie(const char *name) const;
126  // Grab the entire body if one was provided.
127  const UT_StringHolder& body() const
128  {
129  return myBody;
130  }
131 
132  bool isValid() const { return myStatus == NET_HTTPOk; }
133 
134  void setClientIp(unsigned short ip[4])
135  {
136  myClientIp[0] = ip[0];
137  myClientIp[1] = ip[1];
138  myClientIp[2] = ip[2];
139  myClientIp[3] = ip[3];
140  }
141  void getClientIp(unsigned short ip[4]) const
142  {
143  ip[0] = myClientIp[0];
144  ip[1] = myClientIp[1];
145  ip[2] = myClientIp[2];
146  ip[3] = myClientIp[3];
147  }
149  {
150  UT_StringHolder str;
151  str.format("{}.{}.{}.{}", myClientIp[0], myClientIp[1], myClientIp[2],
152  myClientIp[3]);
153  return str;
154  }
155 
156  // Is this request a websocket upgrade request.
157  bool isWebSocketUpgrade() const;
158 
159  const NET_Time &timestamp() const { return myTimestamp; }
160  void setTimestamp(const NET_Time &t) { myTimestamp = t; }
161 
162  const NET_WebMap &headers() const { return myHeaders; }
163  const ReqMap &variables() const { return myPost; }
164  const ReqMap &uriVariables() const { return myGet; }
165  const ReqMap &cookieJar() const { return myCookieJar; }
166 
167  // This holds the last error that occurred while performing some action.
168  // (i.e. reading the request)
169  NET_HTTPStatusCode requestStatus() const { return myStatus; }
170  void clearStatus() { myStatus = NET_HTTPOk; }
171 
172  static bool matchesAcceptHeader(const UT_StringRef &header,
173  const UT_StringRef &ct);
174  bool canUseContentTypeInResponse(const UT_StringRef &ct);
175 
177  {
178  return myReqType == RequestType::kHTTPS;
179  }
180 
181  // Generate a web socket upgrade response
182  bool generateWebSocketUpgradeResponse(NET_WebResponse &resp);
183 
185  {
186  return myFiles;
187  }
189 
190  static UT_StringHolder sanitizePath(const UT_StringHolder &path);
191  /// Parse out all ranges found in the header value
192  static void parseRanges(const UT_StringHolder &header, Ranges &ranges);
193 
194  /// Helper to check if the request was a local request.
195  bool isLocalRequest() const;
196 public:
197  // This is a sort of scratch pad for extra information that youd like to
198  // attach to a request but isnt necessarly apart of a standard http request
200  // This is the port the request came from. The server backend will update
201  // this as needed.
202  int myPort;
204 
205 protected:
206  // reset the http request back to a clean state for reading
207  void resetForRead();
208 
209 private:
210  // The HttpIO class reads/writes based off this class so it needs full
211  // access
212  friend class NET_HttpIO;
213 
214  unsigned myVersionMaj;
215  unsigned myVersionMin;
216  UT_StringHolder myMethod;
217  UT_StringHolder myPath;
218  UT_StringHolder myQueryString;
219  NET_WebMap myHeaders;
220  ReqMap myPost;
221  ReqMap myGet;
222  ReqMap myCookieJar;
223  UT_StringHolder myBody;
224 
226 
227  NET_HTTPStatusCode myStatus;
228 
229  NET_Time myTimestamp;
230 
231  unsigned short myClientIp[4];
232 
233  RequestType myReqType;
234 };
235 
236 #endif // __NET_HTTPRequest_H__
SYS_FORCE_INLINE const_iterator begin() const
Response object used for responding to request in the server.
GLuint const GLchar * name
Definition: glew.h:1814
bool isValid() const
NET_WebStream * myStream
int64 exint
Definition: SYS_Types.h:125
NET_HTTPStatusCode requestStatus() const
std::function< NET_HTTPStatusCode(const UT_String &, const UT_String &)> PathChecker
SYS_FORCE_INLINE bool hasHeader(const UT_StringRef &name) const
UT_StringHolder host() const
UT_StringHolder contentLength() const
NET_HTTPStatusCode
void setTimestamp(const NET_Time &t)
void setClientIp(unsigned short ip[4])
SYS_FORCE_INLINE const_iterator end() const
UT_StringHolder contentType() const
A utility class to do read-only operations on a subset of an existing string.
Definition: UT_StringView.h:40
const UT_StringHolder & path() const
UT_ArrayStringMap< NET_HTTPUploadedFile > & files()
hboost::optional< T > UT_Optional
Definition: UT_Optional.h:16
exint length() const
SYS_FORCE_INLINE const char * buffer() const
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
void getClientIp(unsigned short ip[4]) const
const UT_ArrayStringMap< NET_HTTPUploadedFile > & files() const
NET_WebMap myMetaData
size_t format(const char *fmt, const Args &...args)
Format a string using the same formatting codes as UTformat.
const UT_StringHolder & queryString() const
UT_StringHolder clientIpStr() const
const ReqMap & variables() const
const UT_StringHolder & method() const
GLsizei const GLchar *const * path
Definition: glew.h:6461
unsigned versionMaj() const
SYS_FORCE_INLINE bool hasVariable(const UT_StringRef &name) const
UT_StringHolder protocol() const
const NET_Time & timestamp() const
const ReqMap & cookieJar() const
SYS_FORCE_INLINE bool isSecure() const
unsigned versionMin() const
const UT_StringHolder & body() const
const NET_WebMap & headers() const
GLdouble GLdouble t
Definition: glew.h:1398
const ReqMap & uriVariables() const