httpd.h
9.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
/******************************************************************************
* MiniWeb - a mini and high efficiency HTTP server implementation
* Distributed under BSD license
******************************************************************************/
#ifndef _HTTPAPI_H_
#define _HTTPAPI_H_
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include "httppil.h"
#define FD_ISSET_BOOL(n, p) ((FD_ISSET(n,p)) >> ((n) % NFDBITS))
#ifndef min
#define min(x,y) (x>y?y:x)
#endif
#ifdef HTTP_DEBUG
#define DBG printf
#else
#define DBG
#endif
#define LOG_ERR 1
#define ASSERT
#define GETDWORD(ptrData) (*(DWORD*)(ptrData))
#define SETDWORD(ptrData,data) (*(DWORD*)(ptrData)=data)
#define GETWORD(ptrData) (*(WORD*)(ptrData))
#define SETWORD(ptrData,data) (*(WORD*)(ptrData)=data)
#ifndef BIG_ENDINE
#define DEFDWORD(char1,char2,char3,char4) ((char1)+((char2)<<8)+((char3)<<16)+((char4)<<24))
#define DEFWORD(char1,char2) (char1+(char2<<8))
#else
#define DEFDWORD(char1,char2,char3,char4) ((char4)+((char3)<<8)+((char2)<<16)+((char1)<<24))
#define DEFWORD(char1,char2) (char2+(char1<<8))
#endif
///////////////////////////////////////////////////////////////////////
// Public definitions
///////////////////////////////////////////////////////////////////////
#ifdef __cplusplus
extern "C" {
#endif
// file types
typedef enum {
HTTPFILETYPE_UNKNOWN = 0,
HTTPFILETYPE_HTML,
HTTPFILETYPE_XML,
HTTPFILETYPE_TEXT,
HTTPFILETYPE_XUL,
HTTPFILETYPE_CSS,
HTTPFILETYPE_JS,
HTTPFILETYPE_PNG,
HTTPFILETYPE_JPEG,
HTTPFILETYPE_GIF,
HTTPFILETYPE_SWF,
HTTPFILETYPE_MPA,
HTTPFILETYPE_MPEG,
HTTPFILETYPE_AVI,
HTTPFILETYPE_MP4,
HTTPFILETYPE_MOV,
HTTPFILETYPE_264,
HTTPFILETYPE_FLV,
HTTPFILETYPE_TS,
HTTPFILETYPE_3GP,
HTTPFILETYPE_ASF,
HTTPFILETYPE_OCTET,
HTTPFILETYPE_STREAM,
HTTPFILETYPE_M3U8,
HTTPFILETYPE_SDP,
HTTPFILETYPE_HEX,
HTTPFILETYPE_JSON,
} HttpFileType;
/////////////////////////////////////////////////////////////////////////////
// typedefs
/////////////////////////////////////////////////////////////////////////////
#define FLAG_REQUEST_GET 0x1
#define FLAG_REQUEST_POST 0x2
#define FLAG_HEADER_SENT 0x80
#define FLAG_CONN_CLOSE 0x100
#define FLAG_ABSOLUTE_PATH 0x200
#define FLAG_AUTHENTICATION 0x400
#define FLAG_MORE_CONTENT 0x800
#define FLAG_TO_FREE 0x1000
#define FLAG_CHUNK 0x2000
#define FLAG_CLOSE_CALLBACK 0x4000
#define FLAG_DATA_FILE 0x10000
#define FLAG_DATA_RAW 0x20000
#define FLAG_DATA_REDIRECT 0x80000
#define FLAG_DATA_STREAM 0x100000
#define FLAG_CUSTOM_HEADER 0x200000
#define FLAG_MULTIPART 0x400000
#define FLAG_RECEIVING 0x40000000
#define FLAG_SENDING 0x80000000
#define SETFLAG(hs,bit) (hs->flags|=(bit));
#define CLRFLAG(hs,bit) (hs->flags&=~(bit));
#define ISFLAGSET(hs,bit) (hs->flags&(bit))
typedef union {
unsigned long laddr;
unsigned short saddr[2];
unsigned char caddr[4];
} IPADDR;
typedef struct {
int iHttpVer;
unsigned int startByte;
char *pucPath;
const char *pucReferer;
char* pucHost;
int headerSize;
char* pucPayload;
unsigned int payloadSize;
int iCSeq;
const char* pucTransport;
const char* pucAuthInfo;
} HttpRequest;
typedef struct {
int statusCode;
int headerBytes;
int sentBytes;
unsigned int contentLength;
HttpFileType fileType;
} HttpResponse;
typedef struct {
char *name;
char *value;
} HttpVariables;
typedef struct {
uint32_t reqCount;
size_t totalSentBytes;
uint32_t authFailCount;
uint16_t clientCount;
uint16_t clientCountMax;
uint16_t openedFileCount;
} HttpStats;
#ifndef ARDUINO
#define HTTP_BUFFER_SIZE (1024*1024 /*bytes*/)
#define MAX_POST_PAYLOAD_SIZE (1024*1024 /*bytes*/)
#define HTTP_MAX_CLIENTS_DEFAULT 128
#else
#define HTTP_BUFFER_SIZE (16*1024 /*bytes*/)
#define MAX_POST_PAYLOAD_SIZE (16*1024 /*bytes*/)
#define HTTP_MAX_CLIENTS_DEFAULT 16
#endif
// per connection/socket structure
typedef struct _HttpSocket{
SOCKET socket;
IPADDR ipAddr;
HttpRequest request;
HttpResponse response;
char *pucData;
uint32_t bufferSize; // the size of buffer pucData pointing to
uint32_t contentLength;
FILE* fp;
uint32_t flags;
void* handler; // http handler function address
void* ptr;
time_t tmExpirationTime;
char* mimeType;
char* buffer;
uint16_t reqCount;
} HttpSocket;
typedef struct {
void* hp;
HttpSocket* hs;
const char *pucRequest;
HttpVariables* pxVars;
int iVarCount;
char *pucHeader;
char *pucBuffer;
unsigned int bufSize;
char *pucPayload;
unsigned int payloadSize;
unsigned int contentLength;
HttpFileType contentType;
} UrlHandlerParam;
// Callback function protos
typedef int (*PFNURLCALLBACK)(UrlHandlerParam*);
typedef int (*PFN_UDP_CALLBACK)(void* hp);
typedef int (*PFN_PROXY_CALLBACK)(void* hp, int op, char* buf, int len);
typedef struct {
const char* pchUrlPrefix;
PFNURLCALLBACK pfnUrlHandler;
} UrlHandler;
#define AUTH_NO_NEED (0)
#define AUTH_SUCCESSED (1)
#define AUTH_REQUIRED (2)
#define AUTH_FAILED (-1)
#define MAX_AUTH_INFO_LEN 64
typedef struct {
const char* pchUrlPrefix;
const char* pchUsername;
const char* pchPassword;
const char* pchOtherInfo;
char pchAuthString[MAX_AUTH_INFO_LEN];
} AuthHandler;
#define FLAG_DIR_LISTING 1
#define FLAG_DISABLE_RANGE 2
#define FLAG_ENABLE_PROXY 4
#define FLAG_PROXY_CONNECTED 8
#define PROXY_DATA_REQUESTED 0
#define PROXY_DATA_RECEIVED 1
#define PROXY_RX_BUF_SIZE 1024
#define PROXY_TX_BUF_SIZE 1024
typedef struct _httpParam {
HttpSocket* hsSocketQueue; /* socket queue*/
uint16_t maxClients;
uint16_t maxClientsPerIP;
unsigned int flags;
SOCKET listenSocket;
SOCKET udpSocket;
uint16_t httpPort;
uint16_t udpPort;
char* pchWebPath;
UrlHandler *pxUrlHandler; /* pointer to URL handler array */
AuthHandler *pxAuthHandler; /* pointer to authorization handler array */
// incoming udp callback
PFN_UDP_CALLBACK pfnIncomingUDP;
// proxy
struct sockaddr_in proxy_addr;
SOCKET proxySocket;
const char* pchProxyUrl;
PFN_PROXY_CALLBACK pfnProxyData;
char* proxyBuffer;
int proxyBufferBytes;
// misc
uint32_t dwAuthenticatedNode;
time_t tmAuthExpireTime;
HttpStats stats;
DWORD hlBindIP;
BOOL bKillWebserver;
BOOL bWebserverRunning;
} HttpParam;
typedef struct {
const char* pchRootPath;
const char* pchHttpPath;
char cFilePath[MAX_PATH];
char* pchExt;
int fTailSlash;
} HttpFilePath;
///////////////////////////////////////////////////////////////////////
// Return codes
///////////////////////////////////////////////////////////////////////
// for post callback
#define WEBPOST_OK (0)
#define WEBPOST_AUTHENTICATED (1)
#define WEBPOST_NOTAUTHENTICATED (2)
#define WEBPOST_AUTHENTICATIONON (3)
#define WEBPOST_AUTHENTICATIONOFF (4)
// for multipart file uploads
#define HTTPUPLOAD_MORECHUNKS (0)
#define HTTPUPLOAD_FIRSTCHUNK (1)
#define HTTPUPLOAD_LASTCHUNK (2)
///////////////////////////////////////////////////////////////////////
// Public functions
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
// mwInitParam. Init the context structure with default values
///////////////////////////////////////////////////////////////////////
void mwInitParam(HttpParam* hp, int port, const char* webPath, unsigned int flags, const char* proxyHost, int proxyPort);
///////////////////////////////////////////////////////////////////////
// mwServerStart. Startup the webserver
///////////////////////////////////////////////////////////////////////
int mwServerStart(HttpParam* hp);
void mwServerExit(HttpParam* hp);
///////////////////////////////////////////////////////////////////////
// mwHttpLoop. Enter webserver loop
///////////////////////////////////////////////////////////////////////
void mwHttpLoop(HttpParam *hp, uint32_t timeout);
///////////////////////////////////////////////////////////////////////
// mwServerShutdown. Shutdown the webserver (closes connections and
// releases resources)
///////////////////////////////////////////////////////////////////////
int mwServerShutdown(HttpParam* hp);
///////////////////////////////////////////////////////////////////////
// mwSetRcvBufSize. Change the TCP windows size of acceped sockets
///////////////////////////////////////////////////////////////////////
int mwSetRcvBufSize(WORD wSize);
///////////////////////////////////////////////////////////////////////
// Default subst, post and file-upload callback processing
///////////////////////////////////////////////////////////////////////
int mwGetHttpDateTime(time_t tm, char *buf, int bufsize);
int mwGetLocalFileName(HttpFilePath* hfp);
char* mwGetVarValue(HttpVariables* vars, const char *varname, const char *defval);
int mwGetVarValueInt(HttpVariables* vars, const char *varname, int defval);
unsigned int mwGetVarValueHex(HttpVariables* vars, const char *varname, unsigned int defval);
int64_t mwGetVarValueInt64(HttpVariables* vars, const char *varname);
float mwGetVarValueFloat(HttpVariables* vars, const char *varname);
int mwParseQueryString(UrlHandlerParam* up);
int mwGetContentType(const char *pchExtname);
void mwDecodeString(char* s);
#ifdef __cplusplus
}
#endif
#endif // _HTTPAPI_H
////////////////////////// END OF FILE ////////////////////////////////