1 /***********************************************************************************************************************************
2 HTTP Request
3
4 Send a request to an HTTP server and get a response. The interface is natively asynchronous, i.e. httpRequestNew() sends a request
5 and httpRequestResponse() waits for a response. These can be called together for synchronous behavior or separately for asynchronous
6 behavior.
7 ***********************************************************************************************************************************/
8 #ifndef COMMON_IO_HTTP_REQUEST_H
9 #define COMMON_IO_HTTP_REQUEST_H
10
11 /***********************************************************************************************************************************
12 Object type
13 ***********************************************************************************************************************************/
14 typedef struct HttpRequest HttpRequest;
15
16 #include "common/io/http/header.h"
17 #include "common/io/http/query.h"
18 #include "common/io/http/response.h"
19 #include "common/type/object.h"
20
21 /***********************************************************************************************************************************
22 HTTP Constants
23 ***********************************************************************************************************************************/
24 #define HTTP_VERSION "HTTP/1.1"
25 STRING_DECLARE(HTTP_VERSION_STR);
26 #define HTTP_VERSION_10 "HTTP/1.0"
27 STRING_DECLARE(HTTP_VERSION_10_STR);
28
29 #define HTTP_VERB_DELETE "DELETE"
30 STRING_DECLARE(HTTP_VERB_DELETE_STR);
31 #define HTTP_VERB_GET "GET"
32 STRING_DECLARE(HTTP_VERB_GET_STR);
33 #define HTTP_VERB_HEAD "HEAD"
34 STRING_DECLARE(HTTP_VERB_HEAD_STR);
35 #define HTTP_VERB_POST "POST"
36 STRING_DECLARE(HTTP_VERB_POST_STR);
37 #define HTTP_VERB_PUT "PUT"
38 STRING_DECLARE(HTTP_VERB_PUT_STR);
39
40 #define HTTP_HEADER_AUTHORIZATION "authorization"
41 STRING_DECLARE(HTTP_HEADER_AUTHORIZATION_STR);
42 #define HTTP_HEADER_CONTENT_LENGTH "content-length"
43 STRING_DECLARE(HTTP_HEADER_CONTENT_LENGTH_STR);
44 #define HTTP_HEADER_CONTENT_MD5 "content-md5"
45 STRING_DECLARE(HTTP_HEADER_CONTENT_MD5_STR);
46 #define HTTP_HEADER_CONTENT_RANGE "content-range"
47 STRING_DECLARE(HTTP_HEADER_CONTENT_RANGE_STR);
48 #define HTTP_HEADER_CONTENT_TYPE "content-type"
49 STRING_DECLARE(HTTP_HEADER_CONTENT_TYPE_STR);
50 #define HTTP_HEADER_CONTENT_TYPE_APP_FORM_URL "application/x-www-form-urlencoded"
51 STRING_DECLARE(HTTP_HEADER_CONTENT_TYPE_APP_FORM_URL_STR);
52 #define HTTP_HEADER_CONTENT_RANGE_BYTES "bytes"
53 #define HTTP_HEADER_DATE "date"
54 STRING_DECLARE(HTTP_HEADER_DATE_STR);
55 #define HTTP_HEADER_ETAG "etag"
56 STRING_DECLARE(HTTP_HEADER_ETAG_STR);
57 #define HTTP_HEADER_HOST "host"
58 STRING_DECLARE(HTTP_HEADER_HOST_STR);
59 #define HTTP_HEADER_LAST_MODIFIED "last-modified"
60 STRING_DECLARE(HTTP_HEADER_LAST_MODIFIED_STR);
61
62 /***********************************************************************************************************************************
63 Constructors
64 ***********************************************************************************************************************************/
65 typedef struct HttpRequestNewParam
66 {
67 VAR_PARAM_HEADER;
68 const HttpQuery *query;
69 const HttpHeader *header;
70 const Buffer *content;
71 } HttpRequestNewParam;
72
73 #define httpRequestNewP(client, verb, path, ...) \
74 httpRequestNew(client, verb, path, (HttpRequestNewParam){VAR_PARAM_INIT, __VA_ARGS__})
75
76 HttpRequest *httpRequestNew(HttpClient *client, const String *verb, const String *path, HttpRequestNewParam param);
77
78 /***********************************************************************************************************************************
79 Getters/Setters
80 ***********************************************************************************************************************************/
81 typedef struct HttpRequestPub
82 {
83 MemContext *memContext; // Mem context
84 const String *verb; // HTTP verb (GET, POST, etc.)
85 const String *path; // HTTP path
86 const HttpQuery *query; // HTTP query
87 const HttpHeader *header; // HTTP headers
88 } HttpRequestPub;
89
90 // Request path
91 __attribute__((always_inline)) static inline const String *
httpRequestPath(const HttpRequest * const this)92 httpRequestPath(const HttpRequest *const this)
93 {
94 return THIS_PUB(HttpRequest)->path;
95 }
96
97 // Request query
98 __attribute__((always_inline)) static inline const HttpQuery *
httpRequestQuery(const HttpRequest * const this)99 httpRequestQuery(const HttpRequest *const this)
100 {
101 return THIS_PUB(HttpRequest)->query;
102 }
103
104 // Request headers
105 __attribute__((always_inline)) static inline const HttpHeader *
httpRequestHeader(const HttpRequest * const this)106 httpRequestHeader(const HttpRequest *const this)
107 {
108 return THIS_PUB(HttpRequest)->header;
109 }
110
111 // Request verb
112 __attribute__((always_inline)) static inline const String *
httpRequestVerb(const HttpRequest * const this)113 httpRequestVerb(const HttpRequest *const this)
114 {
115 return THIS_PUB(HttpRequest)->verb;
116 }
117
118 /***********************************************************************************************************************************
119 Functions
120 ***********************************************************************************************************************************/
121 // Wait for a response from the request
122 HttpResponse *httpRequestResponse(HttpRequest *this, bool contentCache);
123
124 // Throw an error if the request failed
125 void httpRequestError(const HttpRequest *this, HttpResponse *response) __attribute__((__noreturn__));
126
127 // Move to a new parent mem context
128 __attribute__((always_inline)) static inline HttpRequest *
httpRequestMove(HttpRequest * const this,MemContext * const parentNew)129 httpRequestMove(HttpRequest *const this, MemContext *const parentNew)
130 {
131 return objMove(this, parentNew);
132 }
133
134 /***********************************************************************************************************************************
135 Destructor
136 ***********************************************************************************************************************************/
137 __attribute__((always_inline)) static inline void
httpRequestFree(HttpRequest * const this)138 httpRequestFree(HttpRequest *const this)
139 {
140 objFree(this);
141 }
142
143 /***********************************************************************************************************************************
144 Macros for function logging
145 ***********************************************************************************************************************************/
146 String *httpRequestToLog(const HttpRequest *this);
147
148 #define FUNCTION_LOG_HTTP_REQUEST_TYPE \
149 HttpRequest *
150 #define FUNCTION_LOG_HTTP_REQUEST_FORMAT(value, buffer, bufferSize) \
151 FUNCTION_LOG_STRING_OBJECT_FORMAT(value, httpRequestToLog, buffer, bufferSize)
152
153 #endif
154