drogon
C++14/17-based HTTP application framework
Loading...
Searching...
No Matches
HttpRequest.h
Go to the documentation of this file.
1
14
15#pragma once
16
17#include <drogon/exports.h>
19#include <drogon/DrClassMap.h>
20#include <drogon/HttpTypes.h>
21#include <drogon/Session.h>
22#include <drogon/Attribute.h>
23#include <drogon/UploadFile.h>
24#include <json/json.h>
25#include <trantor/net/InetAddress.h>
26#include <trantor/net/Certificate.h>
27#include <trantor/utils/Date.h>
28#include <memory>
29#include <string>
30#include <unordered_map>
31#include <optional>
32#include <string_view>
33#include <trantor/net/TcpConnection.h>
34
35namespace drogon
36{
37class HttpRequest;
38using HttpRequestPtr = std::shared_ptr<HttpRequest>;
39
44template <typename T>
46{
47 LOG_ERROR << "You must specialize the fromRequest template for the type of "
48 << DrClassMap::demangle(typeid(T).name());
49 exit(1);
50}
51
57template <typename T>
58HttpRequestPtr toRequest(T &&)
59{
60 LOG_ERROR << "You must specialize the toRequest template for the type of "
61 << DrClassMap::demangle(typeid(T).name());
62 exit(1);
63}
64
65template <>
66HttpRequestPtr toRequest<const Json::Value &>(const Json::Value &pJson);
67template <>
68HttpRequestPtr toRequest(Json::Value &&pJson);
69
70template <>
71inline HttpRequestPtr toRequest<Json::Value &>(Json::Value &pJson)
72{
73 return toRequest((const Json::Value &)pJson);
74}
75
76template <>
77std::shared_ptr<Json::Value> fromRequest(const HttpRequest &req);
78
80class DROGON_EXPORT HttpRequest
81{
82 public:
95 template <typename T>
96 operator T() const
97 {
98 return fromRequest<T>(*this);
99 }
100
105 template <typename T>
106 T as() const
107 {
108 return fromRequest<T>(*this);
109 }
110
112 virtual const char *methodString() const = 0;
113
114 const char *getMethodString() const
115 {
116 return methodString();
117 }
118
120 virtual HttpMethod method() const = 0;
121
122 HttpMethod getMethod() const
123 {
124 return method();
125 }
126
135 virtual bool isHead() const = 0;
136
138
143 virtual const std::string &getHeader(std::string key) const = 0;
144
152 virtual void addHeader(std::string field, const std::string &value) = 0;
153 virtual void addHeader(std::string field, std::string &&value) = 0;
154
160 virtual void removeHeader(std::string key) = 0;
161
162 // Clear all HTTP headers
163 virtual void clearHeaders() = 0;
164
166 virtual const std::string &getCookie(const std::string &field) const = 0;
167
169 virtual const SafeStringMap<std::string> &headers() const = 0;
170
172 const SafeStringMap<std::string> &getHeaders() const
173 {
174 return headers();
175 }
176
178 virtual const SafeStringMap<std::string> &cookies() const = 0;
179
181 const SafeStringMap<std::string> &getCookies() const
182 {
183 return cookies();
184 }
185
190 virtual size_t realContentLength() const = 0;
191
192 size_t getRealContentLength() const
193 {
194 return realContentLength();
195 }
196
198
201 virtual const std::string &query() const = 0;
202
204 const std::string &getQuery() const
205 {
206 return query();
207 }
208
211 std::string_view body() const
212 {
213 return std::string_view(bodyData(), bodyLength());
214 }
215
218 std::string_view getBody() const
219 {
220 return body();
221 }
222
223 virtual const char *bodyData() const = 0;
224 virtual size_t bodyLength() const = 0;
225
227 virtual void setBody(const std::string &body) = 0;
228
230 virtual void setBody(std::string &&body) = 0;
231
233 virtual const std::string &path() const = 0;
234
236 virtual const std::string &getOriginalPath() const = 0;
237
239 const std::string &getPath() const
240 {
241 return path();
242 }
243
245 std::string_view getMatchedPathPattern() const
246 {
247 return matchedPathPattern();
248 }
249
251 std::string_view matchedPathPattern() const
252 {
253 return std::string_view(matchedPathPatternData(),
254 matchedPathPatternLength());
255 }
256
259 virtual const std::vector<std::string> &getRoutingParameters() const = 0;
260
262 virtual void setRoutingParameters(std::vector<std::string> &&params) = 0;
263
264 virtual const char *matchedPathPatternData() const = 0;
265 virtual size_t matchedPathPatternLength() const = 0;
266
269 virtual const char *versionString() const = 0;
270
271 const char *getVersionString() const
272 {
273 return versionString();
274 }
275
277
281 virtual Version version() const = 0;
282
284 Version getVersion() const
285 {
286 return version();
287 }
288
290 virtual const SessionPtr &session() const = 0;
291
293 const SessionPtr &getSession() const
294 {
295 return session();
296 }
297
300 virtual const AttributesPtr &attributes() const = 0;
301
304 const AttributesPtr &getAttributes() const
305 {
306 return attributes();
307 }
308
310 virtual const SafeStringMap<std::string> &parameters() const = 0;
311
313 const SafeStringMap<std::string> &getParameters() const
314 {
315 return parameters();
316 }
317
319 virtual const std::string &getParameter(const std::string &key) const = 0;
320
330 template <typename T>
331 std::optional<T> getOptionalParameter(const std::string &key)
332 {
333 auto &params = getParameters();
334 auto it = params.find(key);
335 if (it != params.end())
336 {
337 try
338 {
339 return std::optional<T>(
340 drogon::utils::fromString<T>(it->second));
341 }
342 catch (const std::exception &e)
343 {
344 LOG_ERROR << e.what();
345 return std::optional<T>{};
346 }
347 }
348 else
349 {
350 return std::optional<T>{};
351 }
352 }
353
355 virtual const trantor::InetAddress &peerAddr() const = 0;
356
357 const trantor::InetAddress &getPeerAddr() const
358 {
359 return peerAddr();
360 }
361
363 virtual const trantor::InetAddress &localAddr() const = 0;
364
365 const trantor::InetAddress &getLocalAddr() const
366 {
367 return localAddr();
368 }
369
371 virtual const trantor::Date &creationDate() const = 0;
372
373 const trantor::Date &getCreationDate() const
374 {
375 return creationDate();
376 }
377
378 // Return the peer certificate (if any)
379 virtual const trantor::CertificatePtr &peerCertificate() const = 0;
380
381 const trantor::CertificatePtr &getPeerCertificate() const
382 {
383 return peerCertificate();
384 }
385
387
391 virtual const std::shared_ptr<Json::Value> &jsonObject() const = 0;
392
394 const std::shared_ptr<Json::Value> &getJsonObject() const
395 {
396 return jsonObject();
397 }
398
407 virtual const std::string &getJsonError() const = 0;
408
410 virtual ContentType contentType() const = 0;
411
412 ContentType getContentType() const
413 {
414 return contentType();
415 }
416
418 virtual void setMethod(const HttpMethod method) = 0;
419
423 virtual void setPath(const std::string &path) = 0;
424 virtual void setPath(std::string &&path) = 0;
425
434 virtual void setPathEncode(bool) = 0;
435
437 virtual void setParameter(const std::string &key,
438 const std::string &value) = 0;
439
444 virtual void setQueryParameter(const std::string &key,
445 const std::string &value) = 0;
451 virtual void setBodyParameter(const std::string &key,
452 const std::string &value) = 0;
453
455 virtual void setContentTypeCode(const ContentType type) = 0;
456
459 //
461 void setContentTypeString(const std::string_view &typeString)
462 {
463 setContentTypeString(typeString.data(), typeString.size());
464 }
465
469 virtual void setCustomContentTypeString(const std::string &type) = 0;
470
472 virtual void addCookie(std::string key, std::string value) = 0;
473
483 virtual void setPassThrough(bool flag) = 0;
484
487
489 static HttpRequestPtr newHttpRequest();
490
496 static HttpRequestPtr newHttpJsonRequest(const Json::Value &data);
497
502 static HttpRequestPtr newHttpFormPostRequest();
503
510 static HttpRequestPtr newFileUploadRequest(
511 const std::vector<UploadFile> &files);
512
517 template <typename T>
518 static HttpRequestPtr newCustomHttpRequest(T &&obj)
519 {
520 return toRequest(std::forward<T>(obj));
521 }
522
528 inline bool isCorsRequest() const
529 {
530 // Check presence of required headers
531 return headers().find("origin") != headers().end();
532 }
533
544 inline bool isCorsPreflightRequest() const
545 {
546 if (method() != HttpMethod::Options)
547 return false;
548 // Check presence of required headers
549 return isCorsRequest() &&
550 headers().find("access-control-request-method") !=
551 headers().end();
552 }
553
554 virtual bool isOnSecureConnection() const noexcept = 0;
555 virtual void setContentTypeString(const char *typeString,
556 size_t typeStringLength) = 0;
557
558 virtual bool connected() const noexcept = 0;
559
560 virtual const std::weak_ptr<trantor::TcpConnection> &getConnectionPtr()
561 const noexcept = 0;
562
563 virtual ~HttpRequest()
564 {
565 }
566};
567
568template <>
569inline HttpRequestPtr toRequest<const Json::Value &>(const Json::Value &pJson)
570{
572}
573
574template <>
575inline HttpRequestPtr toRequest(Json::Value &&pJson)
576{
577 return HttpRequest::newHttpJsonRequest(std::move(pJson));
578}
579
580template <>
581inline std::shared_ptr<Json::Value> fromRequest(const HttpRequest &req)
582{
583 return req.getJsonObject();
584}
585
586} // namespace drogon
static std::string demangle(const char *mangled_name)
demangle the type name which is returned by typeid(T).name().
Definition DrClassMap.h:116
Abstract class for webapp developer to get or set the Http request;.
Definition HttpRequest.h:81
static HttpRequestPtr newCustomHttpRequest(T &&obj)
Create a custom HTTP request object. For using this template, users must specialize the toRequest tem...
Definition HttpRequest.h:518
virtual const trantor::Date & creationDate() const =0
Return the creation timestamp set by the framework.
virtual HttpMethod method() const =0
Return the enum type method of the request.
virtual const std::vector< std::string > & getRoutingParameters() const =0
virtual const std::string & getHeader(std::string key) const =0
Get the header string identified by the key parameter.
virtual Version version() const =0
Return the enum type version of the request.
const SafeStringMap< std::string > & getCookies() const
Get all cookies of the request.
Definition HttpRequest.h:181
virtual const char * methodString() const =0
Return the method string of the request, such as GET, POST, etc.
virtual const std::string & getParameter(const std::string &key) const =0
Get a parameter identified by the.
const std::string & getPath() const
Get the path of the request.
Definition HttpRequest.h:239
virtual void addHeader(std::string field, const std::string &value)=0
Set the header string identified by the field parameter.
virtual void setQueryParameter(const std::string &key, const std::string &value)=0
void setContentTypeString(const std::string_view &typeString)
For example, "content-type: text/plain\r\n" or "text/plain".
Definition HttpRequest.h:461
virtual ContentType contentType() const =0
Get the content type.
virtual void setBodyParameter(const std::string &key, const std::string &value)=0
static HttpRequestPtr newHttpFormPostRequest()
std::string_view matchedPathPattern() const
Get the matched path pattern after routing.
Definition HttpRequest.h:251
virtual const SessionPtr & session() const =0
Get the session to which the request belongs.
static HttpRequestPtr newHttpRequest()
Create a normal request with http method Get and version Http1.1.
virtual void setPath(const std::string &path)=0
virtual const SafeStringMap< std::string > & parameters() const =0
Get parameters of the request.
virtual void setCustomContentTypeString(const std::string &type)=0
std::optional< T > getOptionalParameter(const std::string &key)
Get the optional parameter identified by the key. if the parameter doesn't exist, or the original par...
Definition HttpRequest.h:331
Version getVersion() const
Return the enum type version of the request.
Definition HttpRequest.h:284
const std::shared_ptr< Json::Value > & getJsonObject() const
Get the Json object of the request.
Definition HttpRequest.h:394
virtual void setParameter(const std::string &key, const std::string &value)=0
Set the parameter of the request.
const AttributesPtr & getAttributes() const
Definition HttpRequest.h:304
virtual const std::string & path() const =0
Get the path of the request.
virtual void setRoutingParameters(std::vector< std::string > &&params)=0
This method usually is called by the framework.
virtual const trantor::InetAddress & peerAddr() const =0
Return the remote IP address and port.
virtual void setPathEncode(bool)=0
The default behavior is to encode the value of setPath using urlEncode. Setting the path encode to fa...
virtual void setBody(std::string &&body)=0
Set the content string of the request.
virtual void setBody(const std::string &body)=0
Set the content string of the request.
virtual bool isHead() const =0
Check if the method is or was HttpMethod::Head.
virtual size_t realContentLength() const =0
Return content length parsed from the Content-Length header If no Content-Length header,...
virtual void removeHeader(std::string key)=0
Remove the header identified by the key parameter.
const SafeStringMap< std::string > & getParameters() const
Get parameters of the request.
Definition HttpRequest.h:313
virtual const std::string & query() const =0
Get the query string of the request.
virtual void addCookie(std::string key, std::string value)=0
Add a cookie.
virtual const std::string & getOriginalPath() const =0
Get the original path of the request.(before url-decoding).
virtual const trantor::InetAddress & localAddr() const =0
Return the local IP address and port.
virtual const SafeStringMap< std::string > & cookies() const =0
Get all cookies of the request.
virtual const std::string & getCookie(const std::string &field) const =0
Get the cookie string identified by the field parameter.
const SessionPtr & getSession() const
Get the session to which the request belongs.
Definition HttpRequest.h:293
std::string_view getMatchedPathPattern() const
Get the matched path pattern after routing.
Definition HttpRequest.h:245
std::string_view getBody() const
Definition HttpRequest.h:218
virtual void setContentTypeCode(const ContentType type)=0
Set or get the content type.
virtual const std::shared_ptr< Json::Value > & jsonObject() const =0
Get the Json object of the request.
std::string_view body() const
Definition HttpRequest.h:211
bool isCorsRequest() const
Check if the request is a CORS request.
Definition HttpRequest.h:528
virtual const SafeStringMap< std::string > & headers() const =0
Get all headers of the request.
bool isCorsPreflightRequest() const
Check if the request is a CORS pre-flight request.
Definition HttpRequest.h:544
static HttpRequestPtr newHttpJsonRequest(const Json::Value &data)
virtual void setPassThrough(bool flag)=0
Set the request object to the pass-through mode or not. It's not by default when a new request object...
virtual const std::string & getJsonError() const =0
Get the error message of parsing the JSON body received from peer. This method usually is called afte...
virtual const AttributesPtr & attributes() const =0
const std::string & getQuery() const
Get the query string of the request.
Definition HttpRequest.h:204
virtual void setMethod(const HttpMethod method)=0
Set the Http method.
T as() const
This template enables explicit type conversion, see the above template.
Definition HttpRequest.h:106
const SafeStringMap< std::string > & getHeaders() const
Get all headers of the request.
Definition HttpRequest.h:172
virtual const char * versionString() const =0
static HttpRequestPtr newFileUploadRequest(const std::vector< UploadFile > &files)
Drogon Test is a minimal effort test framework developed because the major C++ test frameworks doesn'...
Definition Attribute.h:23
T fromRequest(const HttpRequest &)
This template is used to convert a request object to a custom type object. Users must specialize the ...
Definition HttpRequest.h:45
HttpRequestPtr toRequest(T &&)
This template is used to create a request object from a custom type object by calling the newCustomHt...
Definition HttpRequest.h:58
STL namespace.