diff options
Diffstat (limited to 'src/http.h')
-rw-r--r-- | src/http.h | 271 |
1 files changed, 271 insertions, 0 deletions
diff --git a/src/http.h b/src/http.h new file mode 100644 index 0000000..4ee4470 --- /dev/null +++ b/src/http.h | |||
@@ -0,0 +1,271 @@ | |||
1 | /**\file http.h | ||
2 | * Describe a Hyper Text Transfer Protocol processor. This class will allow | ||
3 | * any program to act as either an HTTP server, client, or both. It contains | ||
4 | * a number of additional helpers and subclasses. | ||
5 | *@author Mike Buland | ||
6 | */ | ||
7 | |||
8 | #ifndef HTTP_H | ||
9 | #define HTTP_H | ||
10 | |||
11 | #include <iostream> | ||
12 | #include "connection.h" | ||
13 | #include "linkedlist.h" | ||
14 | #include "hashtable.h" | ||
15 | |||
16 | #define CR '\r' /**< The ASCII value of a Carrage Return */ | ||
17 | #define LF '\n' /**< The ASCII value of a Line Feed */ | ||
18 | #define CRLF CR LF /**< Combo of CR+LF for use in http */ | ||
19 | |||
20 | /** | ||
21 | * Macro to create combined http version codes. This just makes processing a | ||
22 | * little bit faster for the most part. | ||
23 | *@param maj Major version number, between 0 and 15 | ||
24 | *@param min Minor version number, between 0 and 15 | ||
25 | *@returns A one byte combined version number suitable for use in switches. | ||
26 | */ | ||
27 | #define HTTPVER( maj, min ) ((maj<<4)|(min)) | ||
28 | |||
29 | #define HTTP10 HTTPVER( 1, 0 ) /**< Combined version code for http 1.0 */ | ||
30 | #define HTTP11 HTTPVER( 1, 1 ) /**< Combined version code for http 1.1 */ | ||
31 | |||
32 | /** | ||
33 | * This is the master HTTP processing class. One instance handles one | ||
34 | * transaction, in the future a different mechanism may be thought up, but for | ||
35 | * now this means that you must create multiple objects to handle a single | ||
36 | * connection that contains multiple requests. | ||
37 | * In the constructor the Http class is given a connection object. This object | ||
38 | * should already be initialized and connected to whatever socket it wants to | ||
39 | * be sending and receiving data to and from. Once that's done you can call | ||
40 | * parseRequest if you're acting as a server, or a variety of buildRequest | ||
41 | * functions to create and send a request if you're a client. | ||
42 | * Please note that this class does not provide any HTTP or extended format | ||
43 | * processing systems, but will allow for mime types tables to be registered. | ||
44 | *@author Mike Buland | ||
45 | */ | ||
46 | class Http | ||
47 | { | ||
48 | public: | ||
49 | /** | ||
50 | * Create an Http object tied to an existing connection object. | ||
51 | *@param pConnection The live connection object to deal with. | ||
52 | */ | ||
53 | Http( Connection *pConnection ); | ||
54 | |||
55 | /** | ||
56 | * Standard Deconstructor. | ||
57 | */ | ||
58 | ~Http(); | ||
59 | |||
60 | /** | ||
61 | * Perform all parsing needed to figure out what an HTTP client wants from | ||
62 | * us. This will setup a number of properties in the Http object itself | ||
63 | * and has the possibility of setting one or more response states initially. | ||
64 | * These states should be checked for immediately after parsing to see if | ||
65 | * an appropriate error message should be generated. These errors can | ||
66 | * include issues with protocol, data formats, or unknown versions of the | ||
67 | * protocol. | ||
68 | *@returns True means that all processing is finished, false means that | ||
69 | * the parseRequest function should be called again when more data is | ||
70 | * ready. A return value of true does not indicate success, only that | ||
71 | * processing is finished, the getResponseStatus function should be called | ||
72 | * to see what status was set in the parse routine. A 200 indicates that | ||
73 | * as far as the parser is concerned, everything when smoothly. Otherwise | ||
74 | * it's your responsibility to build the appropriate error response body | ||
75 | * (like an html file) and send it as the response. | ||
76 | */ | ||
77 | bool parseRequest(); | ||
78 | |||
79 | /** | ||
80 | * Get a request type's internal Http object id based on the string | ||
81 | * representation. These can be any HTTP/1.1 standard request type. | ||
82 | *@param sType The string that should be checked for type. This is in all | ||
83 | * caps, just like if it came from the HTTP client, which is most often | ||
84 | * the case. | ||
85 | *@returns The numerical ID of the given request type. Please note that | ||
86 | * HTTP/1.1 standard specifies that any string is valid here as long as | ||
87 | * the non-basic string is a request type understood by the serving | ||
88 | * software. This means that anything that is non-standard will return | ||
89 | * a type reqExtension and not an error. This is not a mistake. | ||
90 | */ | ||
91 | short getRequestType( const char *sType ); | ||
92 | |||
93 | /** | ||
94 | * Get the string representation of an Http object request type integer ID. | ||
95 | * This is used mainly for debugging to be sure the system has what we | ||
96 | * think it has. | ||
97 | *@param nType The integer ID of the request type to process. | ||
98 | *@returns The HTTP/1.1 string representation of that Http object ID code. | ||
99 | */ | ||
100 | const char *getRequestType( short nType ); | ||
101 | |||
102 | /** | ||
103 | * Returns the Http object request type ID code that is stored in the | ||
104 | * object by either the parseRequest function or use of the buildRequest | ||
105 | * functions. | ||
106 | *@returns The ID of the request type stored in the object. | ||
107 | */ | ||
108 | short getRequestType(); | ||
109 | |||
110 | /** | ||
111 | * Same as getRequestType, only returns the string representation. | ||
112 | *@returns The string representation of the request type ID stored in the | ||
113 | * object. | ||
114 | */ | ||
115 | const char *getRequestTypeStr(); | ||
116 | |||
117 | /** | ||
118 | * Sets the version of the request used by the system. This will be used | ||
119 | * by parse request, but is also part of the buildRequest tool functions. | ||
120 | *@param nMajor The major version number. | ||
121 | *@param nMinor The minor version number. | ||
122 | */ | ||
123 | void setRequestVersion( unsigned char nMajor, unsigned char nMinor ); | ||
124 | |||
125 | /** | ||
126 | * Gets the major version number of the protocol used/to be used in this | ||
127 | * request. | ||
128 | *@returns The major version number of the request protocol. | ||
129 | */ | ||
130 | unsigned char getRequestMinorVer(); | ||
131 | |||
132 | /** | ||
133 | * Gets the minor version number of the protocol used/to be used in this | ||
134 | * request. | ||
135 | *@returns The minor version number of the request protocol. | ||
136 | */ | ||
137 | unsigned char getRequestMajorVer(); | ||
138 | |||
139 | /** | ||
140 | * Checks the stored request version against an internal table of supported | ||
141 | * protocol versions. | ||
142 | *@returns True if the protocol version is supported, false otherwise. | ||
143 | */ | ||
144 | bool checkRequestVer(); | ||
145 | |||
146 | /** | ||
147 | * Converts an arbitrary string to a new string object with space saving | ||
148 | * operations performed ala the HTTP/1.1 specs. All leading and trailing | ||
149 | * whitespace is stripped, and all whitespace within the string is reduced | ||
150 | * to a single space char. | ||
151 | *@param sStr A pointer to the string data to process. | ||
152 | *@param nLen The length of the string to process. Since this function is | ||
153 | * often called on stream data, there is no null terminator where we need | ||
154 | * one. This is here for convinience so the data doesn't need to be hacked | ||
155 | * up or moved to an intermediate buffer. | ||
156 | *@returns A new string that may well be shorter than the original but that | ||
157 | * will have the same value as far as the HTTP/1.1 specs are concerned. | ||
158 | */ | ||
159 | std::string *convSpaceString( const char *sStr, int nLen ); | ||
160 | |||
161 | /** | ||
162 | * Gets a string pointer to the URI that was/is being requested. This can | ||
163 | * be any RFC standard URI, with or without protocol and domain. | ||
164 | *@returns A pointer to the URI that was/is being requested. | ||
165 | */ | ||
166 | const char *getRequestURI(); | ||
167 | |||
168 | /** | ||
169 | * Set a new response status. This status can be anything that the HTTP | ||
170 | * specs allow. Other values are allowed as well, but beware, not all | ||
171 | * servers/clients will accept values that are not in the tables in this | ||
172 | * class. | ||
173 | *@param nStatus The status to set. | ||
174 | */ | ||
175 | void setResponseStatus( short nStatus ); | ||
176 | |||
177 | bool buildResponse( short nResponseCode=-1, const char *sResponse=NULL ); | ||
178 | void setResponseContent( const char *sMime, const char *sContent, int nLen ); | ||
179 | void setResponsePersistant( bool bPersistant ); | ||
180 | bool sendResponse(); | ||
181 | |||
182 | enum | ||
183 | { | ||
184 | reqOptions, | ||
185 | reqGet, | ||
186 | reqHead, | ||
187 | reqPost, | ||
188 | reqPut, | ||
189 | reqDelete, | ||
190 | reqTrace, | ||
191 | reqConnect, | ||
192 | reqExtension | ||
193 | }; | ||
194 | |||
195 | enum | ||
196 | { | ||
197 | statusContinue = 100, | ||
198 | statusSwitchProto = 101, | ||
199 | |||
200 | statusOK = 200, | ||
201 | statusCreated = 201, | ||
202 | statusAccepted = 202, | ||
203 | statusNonAuthInfo = 203, | ||
204 | statusNoContent = 204, | ||
205 | statusResetContent = 205, | ||
206 | statusPartialContent = 206, | ||
207 | |||
208 | statusMultiChoices = 300, | ||
209 | statusMovedPermanently = 301, | ||
210 | statusFound = 302, | ||
211 | statusSeeOther = 303, | ||
212 | statusNotModified = 304, | ||
213 | statusUseProxy = 305, | ||
214 | statusUnused = 306, | ||
215 | statusTempRedirect = 307, | ||
216 | |||
217 | statusBadRequest = 400, | ||
218 | statusUnauthorized = 401, | ||
219 | statusPaymentRequired = 402, | ||
220 | statusForbidden = 403, | ||
221 | statusNotFound = 404, | ||
222 | statusMethodNotAllowed = 405, | ||
223 | statusNotAcceptable = 406, | ||
224 | statusProxyAuthRequired = 407, | ||
225 | statusRequestTimeout = 408, | ||
226 | statusConflict = 409, | ||
227 | statusGone = 410, | ||
228 | statusLengthRequired = 411, | ||
229 | statusPreconditionFailed = 412, | ||
230 | statusRequestEntityTooLarge = 413, | ||
231 | statusRequestURITooLong = 414, | ||
232 | statusUnsupportedMediaType = 415, | ||
233 | statusRequestedRangeNotSatisfiable = 416, | ||
234 | statusExpectationFailed = 417, | ||
235 | |||
236 | statusInternalServerError = 500, | ||
237 | statusNotImplemented = 501, | ||
238 | statusBadGateway = 502, | ||
239 | statusServiceUnavailable = 503, | ||
240 | statusGatewayTimeout = 504, | ||
241 | statusHTTPVersionNotSupported = 505 | ||
242 | }; | ||
243 | |||
244 | private: | ||
245 | Connection *pCon; | ||
246 | unsigned char nParseState; | ||
247 | |||
248 | short nReqType; | ||
249 | std::string *pReqStr; | ||
250 | std::string sReqURI; | ||
251 | unsigned char cReqVersion; | ||
252 | HashTable hReqHeader; | ||
253 | LinkedList lStrings; | ||
254 | |||
255 | std::string sServerStr; | ||
256 | std::string sResMime; | ||
257 | std::string sResContent; | ||
258 | std::string sResStatusStr; | ||
259 | bool bResPersistant; | ||
260 | struct tm tResTime; | ||
261 | short nResStatus; | ||
262 | |||
263 | enum | ||
264 | { | ||
265 | parseInit, | ||
266 | parseHeader, | ||
267 | parseFinished | ||
268 | }; | ||
269 | }; | ||
270 | |||
271 | #endif | ||