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
336
337
338
339
|
/****************************************************************************
* netutils/thttpd/libhttpd.h
* HTTP Protocol Library Definitions
*
* Copyright (C) 2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
*
* Derived from the file of the same name in the original THTTPD package:
*
* Copyright � 1995,1998,1999,2000,2001 by Jef Poskanzer <jef@mail.acme.com>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
****************************************************************************/
#ifndef __NETUTILS_THTTPD_LIBHTTPD_H
#define __NETUTILS_THTTPD_LIBHTTPD_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#ifndef CONFIG_THTTPD_PORT
# define CONFIG_THTTPD_PORT 80
#endif
#ifndef CONFIG_THTTPD_CHARSET
# define CONFIG_THTTPD_CHARSET "iso-8859-1"
#endif
#ifndef CONFIG_THTTPD_IOBUFFERSIZE
# define CONFIG_THTTPD_IOBUFFERSIZE 256
#endif
#if CONFIG_THTTPD_IOBUFFERSIZE > 65535
# error "Can't use uint16 for buffer"
#endif
/* A few convenient defines. */
#ifndef MAX
# define MAX(a,b) ((a) > (b) ? (a) : (b))
#endif
#ifndef MIN
# define MIN(a,b) ((a) < (b) ? (a) : (b))
#endif
#define NEW(t,n) ((t*) malloc( sizeof(t) * (n) ))
#define RENEW(o,t,n) ((t*) realloc( (void*) o, sizeof(t) * (n) ))
/* Methods. */
#define METHOD_UNKNOWN 0
#define METHOD_GET 1
#define METHOD_HEAD 2
#define METHOD_POST 3
/* States for checked_state. */
#define CHST_FIRSTWORD 0
#define CHST_FIRSTWS 1
#define CHST_SECONDWORD 2
#define CHST_SECONDWS 3
#define CHST_THIRDWORD 4
#define CHST_THIRDWS 5
#define CHST_LINE 6
#define CHST_LF 7
#define CHST_CR 8
#define CHST_CRLF 9
#define CHST_CRLFCR 10
#define CHST_BOGUS 11
#define GC_FAIL 0
#define GC_OK 1
#define GC_NO_MORE 2
#define GR_NO_REQUEST 0
#define GR_GOT_REQUEST 1
#define GR_BAD_REQUEST 2
/****************************************************************************
* Public Type Definitions
****************************************************************************/
/* A multi-family sockaddr. */
typedef union
{
struct sockaddr sa;
#ifdef CONFIG_NET_IPv6
struct sockaddr_in6 sa_in6;
#else
struct sockaddr_in sa_in;
#endif /* CONFIG_NET_IPv6 */
} httpd_sockaddr;
/* A server. */
typedef struct
{
char *binding_hostname;
char *server_hostname;
int cgi_count;
char *cwd;
int listen_fd;
} httpd_server;
/* A connection. */
typedef struct
{
int initialized;
httpd_server *hs;
httpd_sockaddr client_addr;
char *read_buf;
size_t read_size, read_idx, checked_idx;
int checked_state;
int method;
int status;
off_t bytes_to_send;
off_t bytes_sent;
char *encodedurl;
char *decodedurl;
char *protocol;
char *origfilename;
char *expnfilename;
char *encodings;
char *pathinfo;
char *query;
char *referer;
char *useragent;
char *accept;
char *accepte;
char *acceptl;
char *cookie;
char *contenttype;
char *reqhost;
char *hdrhost;
char *hostdir;
char *authorization;
char *remoteuser;
size_t maxdecodedurl, maxorigfilename, maxexpnfilename, maxencodings,
maxpathinfo, maxquery, maxaccept, maxaccepte, maxreqhost, maxhostdir,
maxremoteuser, maxresponse;
#ifdef TILDE_MAP_2
char *altdir;
size_t maxaltdir;
#endif /* TILDE_MAP_2 */
time_t if_modified_since, range_if;
size_t contentlength;
char *type; /* not malloc()ed */
#ifdef CONFIG_THTTPD_VHOST
char *vhostname; /* not malloc()ed */
#endif
boolean mime_flag;
boolean one_one; /* HTTP/1.1 or better */
boolean got_range;
boolean tildemapped; /* this connection got tilde-mapped */
boolean keep_alive;
boolean should_linger;
int conn_fd; /* Connection to the client */
int file_fd; /* Descriptor for open, outgoing file */
off_t range_start; /* File range start from Range= */
off_t range_end; /* File range end from Range= */
struct stat sb;
/* This is the I/O buffer that is used to buffer portions of outgoing files */
uint16 buflen; /* Index to first valid data in buffer */
ubyte buffer[CONFIG_THTTPD_IOBUFFERSIZE];
} httpd_conn;
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/* Initializes. Does the socket(), bind(), and listen(). Returns an
* httpd_server* which includes a socket fd that you can select() on.
* Return (httpd_server*) 0 on error.
*/
#ifdef CONFIG_NET_IPv6
extern httpd_server *httpd_initialize(struct sockaddr_in6 *sa, char *cwd);
#else
extern httpd_server *httpd_initialize(struct sockaddr_in *sa, char *cwd);
#endif
/* Call to unlisten/close socket(s) listening for new connections. */
extern void httpd_unlisten(httpd_server * hs);
/* Call to shut down. */
extern void httpd_terminate(httpd_server * hs);
/* When a listen fd is ready to read, call this. It does the accept() and
* returns an httpd_conn* which includes the fd to read the request from and
* write the response to. Returns an indication of whether the accept()
* failed, succeeded, or if there were no more connections to accept.
*
* In order to minimize malloc()s, the caller passes in the httpd_conn.
* The caller is also responsible for setting initialized to zero before the
* first call using each different httpd_conn.
*/
extern int httpd_get_conn(httpd_server * hs, int listen_fd, httpd_conn * hc);
/* Checks whether the data in hc->read_buf constitutes a complete request
* yet. The caller reads data into hc->read_buf[hc->read_idx] and advances
* hc->read_idx. This routine checks what has been read so far, using
* hc->checked_idx and hc->checked_state to keep track, and returns an
* indication of whether there is no complete request yet, there is a
* complete request, or there won't be a valid request due to a syntax error.
*/
extern int httpd_got_request(httpd_conn * hc);
/* Parses the request in hc->read_buf. Fills in lots of fields in hc,
* like the URL and the various headers.
*
* Returns -1 on error.
*/
extern int httpd_parse_request(httpd_conn * hc);
/* Starts sending data back to the client. In some cases (directories,
* CGI programs), finishes sending by itself - in those cases, hc->file_fd
* is negative. If there is more data to be sent, then hc->file_fd is a file
* stream for the file to send. If you don't have a current timeval
* handy just pass in 0.
*
* Returns -1 on error.
*/
extern int httpd_start_request(httpd_conn * hc, struct timeval *nowP);
/* Actually sends any buffered response text. */
extern void httpd_write_response(httpd_conn * hc);
/* Call this to close down a connection and free the data. A fine point,
* if you fork() with a connection open you should still call this in the
* parent process - the connection will stay open in the child.
* If you don't have a current timeval handy just pass in 0.
*/
extern void httpd_close_conn(httpd_conn * hc, struct timeval *nowP);
/* Call this to de-initialize a connection struct and *really* free the
* mallocced strings.
*/
extern void httpd_destroy_conn(httpd_conn * hc);
/* Send an error message back to the client. */
extern void httpd_send_err(httpd_conn * hc, int status, char *title,
char *extraheads, char *form, char *arg);
/* Some error messages. */
extern char *httpd_err400title;
extern char *httpd_err400form;
extern char *httpd_err408title;
extern char *httpd_err408form;
extern char *httpd_err503title;
extern char *httpd_err503form;
/* Generate a string representation of a method number. */
extern char *httpd_method_str(int method);
/* Reallocate a string. */
extern void httpd_realloc_str(char **strP, size_t * maxsizeP, size_t size);
/* Format a network socket to a string representation. */
extern char *httpd_ntoa(httpd_sockaddr * saP);
/* Set NDELAY mode on a socket. */
extern void httpd_set_ndelay(int fd);
/* Clear NDELAY mode on a socket. */
extern void httpd_clear_ndelay(int fd);
/* Generate debugging statistics syslog message. */
#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_NET)
extern void httpd_logstats(long secs);
#else
# define httpd_logstats(secs)
#endif
/* Read to requested buffer, accounting for interruptions and EOF */
extern int httpd_read(int fd, const void *buf, size_t nbytes);
/* Write the buffer completely, accounting for interruptions */
extern int httpd_write(int fd, const void *buf, size_t nbytes);
#endif /* __NETUTILS_THTTPD_LIBHTTPD_H */
|