1/* libhttpd.h - defines for libhttpd
2**
3** Copyright �� 1995,1998,1999,2000,2001 by Jef Poskanzer <jef@mail.acme.com>.
4** All rights reserved.
5**
6** Redistribution and use in source and binary forms, with or without
7** modification, are permitted provided that the following conditions
8** are met:
9** 1. Redistributions of source code must retain the above copyright
10**    notice, this list of conditions and the following disclaimer.
11** 2. Redistributions in binary form must reproduce the above copyright
12**    notice, this list of conditions and the following disclaimer in the
13**    documentation and/or other materials provided with the distribution.
14**
15** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18** ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25** SUCH DAMAGE.
26*/
27
28#ifndef _LIBHTTPD_H_
29#define _LIBHTTPD_H_
30
31#include <sys/types.h>
32#include <sys/time.h>
33#include <sys/param.h>
34#include <sys/socket.h>
35#include <sys/stat.h>
36#include <netinet/in.h>
37#include <arpa/inet.h>
38#include <netdb.h>
39#include <stdio.h>
40
41#if defined(AF_INET6) && defined(IN6_IS_ADDR_V4MAPPED)
42#define USE_IPV6
43#endif
44
45
46/* A few convenient defines. */
47
48#ifndef MAX
49#define MAX(a,b) ((a) > (b) ? (a) : (b))
50#endif
51#ifndef MIN
52#define MIN(a,b) ((a) < (b) ? (a) : (b))
53#endif
54#define NEW(t,n) ((t*) malloc( sizeof(t) * (n) ))
55#define RENEW(o,t,n) ((t*) realloc( (void*) o, sizeof(t) * (n) ))
56
57/* Do overlapping strcpy safely, by using memmove. */
58#define ol_strcpy(dst,src) memmove(dst,src,strlen(src)+1)
59
60
61/* The httpd structs. */
62
63/* A multi-family sockaddr. */
64typedef union {
65    struct sockaddr sa;
66    struct sockaddr_in sa_in;
67#ifdef USE_IPV6
68    struct sockaddr_in6 sa_in6;
69    struct sockaddr_storage sa_stor;
70#endif /* USE_IPV6 */
71    } httpd_sockaddr;
72
73/* A server. */
74typedef struct {
75    char* binding_hostname;
76    char* server_hostname;
77    unsigned short port;
78    char* cgi_pattern;
79    int cgi_limit, cgi_count;
80    char* charset;
81    char* p3p;
82    int max_age;
83    char* cwd;
84    int listen4_fd, listen6_fd;
85    int no_log;
86    FILE* logfp;
87    int no_symlink_check;
88    int vhost;
89    int global_passwd;
90    char* url_pattern;
91    char* local_pattern;
92    int no_empty_referrers;
93    //added for poorman
94    int do_list_dir;
95    char* index_name;
96    } httpd_server;
97
98/* A connection. */
99typedef struct {
100    int initialized;
101    httpd_server* hs;
102    httpd_sockaddr client_addr;
103    char* read_buf;
104    size_t read_size, read_idx, checked_idx;
105    int checked_state;
106    int method;
107    int status;
108    off_t bytes_to_send;
109    off_t bytes_sent;
110    char* encodedurl;
111    char* decodedurl;
112    char* protocol;
113    char* origfilename;
114    char* expnfilename;
115    char* encodings;
116    char* pathinfo;
117    char* query;
118    char* referrer;
119    char* useragent;
120    char* accept;
121    char* accepte;
122    char* acceptl;
123    char* cookie;
124    char* contenttype;
125    char* reqhost;
126    char* hdrhost;
127    char* hostdir;
128    char* authorization;
129    char* remoteuser;
130    char* response;
131    size_t maxdecodedurl, maxorigfilename, maxexpnfilename, maxencodings,
132	maxpathinfo, maxquery, maxaccept, maxaccepte, maxreqhost, maxhostdir,
133	maxremoteuser, maxresponse;
134#ifdef TILDE_MAP_2
135    char* altdir;
136    size_t maxaltdir;
137#endif /* TILDE_MAP_2 */
138    size_t responselen;
139    time_t if_modified_since, range_if;
140    size_t contentlength;
141    char* type;		/* not malloc()ed */
142    char* hostname;	/* not malloc()ed */
143    int mime_flag;
144    int one_one;	/* HTTP/1.1 or better */
145    int got_range;
146    int tildemapped;	/* this connection got tilde-mapped */
147    off_t first_byte_index, last_byte_index;
148    int keep_alive;
149    int should_linger;
150    struct stat sb;
151    int conn_fd;
152	int processed_directory_index;
153    char* file_address;
154    } httpd_conn;
155
156/* Methods. */
157#define METHOD_UNKNOWN 0
158#define METHOD_GET 1
159#define METHOD_HEAD 2
160#define METHOD_POST 3
161#define METHOD_PUT 4
162#define METHOD_DELETE 5
163#define METHOD_TRACE 6
164
165/* States for checked_state. */
166#define CHST_FIRSTWORD 0
167#define CHST_FIRSTWS 1
168#define CHST_SECONDWORD 2
169#define CHST_SECONDWS 3
170#define CHST_THIRDWORD 4
171#define CHST_THIRDWS 5
172#define CHST_LINE 6
173#define CHST_LF 7
174#define CHST_CR 8
175#define CHST_CRLF 9
176#define CHST_CRLFCR 10
177#define CHST_BOGUS 11
178
179#ifdef __cplusplus
180extern "C" {
181#endif
182
183/* Initializes.  Does the socket(), bind(), and listen().   Returns an
184** httpd_server* which includes a socket fd that you can select() on.
185** Return (httpd_server*) 0 on error.
186*/
187extern httpd_server* httpd_initialize(
188    char* hostname, httpd_sockaddr* sa4P, httpd_sockaddr* sa6P,
189    unsigned short port, char* cgi_pattern, int cgi_limit, char* charset,
190    char* p3p, int max_age, char* cwd, int no_log, FILE* logfp,
191    int no_symlink_check, int vhost, int global_passwd, char* url_pattern,
192    char* local_pattern, int no_empty_referrers );
193
194/* PoorMan: Initialize_listen_socket() is changed from static to extern.
195** httpd_unlisten() needs an opposite operation that can be accessed from
196** outside libhttpd. So this is it.
197*/
198extern int httpd_initialize_listen_socket( httpd_sockaddr* saP );
199
200/* Change the log file. */
201extern void httpd_set_logfp( httpd_server* hs, FILE* logfp );
202
203/* Call to unlisten/close socket(s) listening for new connections. */
204extern void httpd_unlisten( httpd_server* hs );
205
206/* Call to shut down. */
207extern void httpd_terminate( httpd_server* hs );
208
209
210/* When a listen fd is ready to read, call this.  It does the accept() and
211** returns an httpd_conn* which includes the fd to read the request from and
212** write the response to.  Returns an indication of whether the accept()
213** failed, succeeded, or if there were no more connections to accept.
214**
215** In order to minimize malloc()s, the caller passes in the httpd_conn.
216** The caller is also responsible for setting initialized to zero before the
217** first call using each different httpd_conn.
218*/
219extern int httpd_get_conn( httpd_server* hs, int listen_fd, httpd_conn* hc );
220#define GC_FAIL 0
221#define GC_OK 1
222#define GC_NO_MORE 2
223
224/* Checks whether the data in hc->read_buf constitutes a complete request
225** yet.  The caller reads data into hc->read_buf[hc->read_idx] and advances
226** hc->read_idx.  This routine checks what has been read so far, using
227** hc->checked_idx and hc->checked_state to keep track, and returns an
228** indication of whether there is no complete request yet, there is a
229** complete request, or there won't be a valid request due to a syntax error.
230*/
231extern int httpd_got_request( httpd_conn* hc );
232#define GR_NO_REQUEST 0
233#define GR_GOT_REQUEST 1
234#define GR_BAD_REQUEST 2
235
236/* Parses the request in hc->read_buf.  Fills in lots of fields in hc,
237** like the URL and the various headers.
238**
239** Returns -1 on error.
240*/
241extern int httpd_parse_request( httpd_conn* hc );
242
243/* Starts sending data back to the client.  In some cases (directories,
244** CGI programs), finishes sending by itself - in those cases, hc->file_fd
245** is <0.  If there is more data to be sent, then hc->file_fd is a file
246** descriptor for the file to send.  If you don't have a current timeval
247** handy just pass in 0.
248**
249** Returns -1 on error.
250*/
251extern int httpd_start_request( httpd_conn* hc, struct timeval* nowP );
252
253/* Actually sends any buffered response text. */
254extern void httpd_write_response( httpd_conn* hc );
255
256/* Call this to close down a connection and free the data.  A fine point,
257** if you fork() with a connection open you should still call this in the
258** parent process - the connection will stay open in the child.
259** If you don't have a current timeval handy just pass in 0.
260*/
261extern void httpd_close_conn( httpd_conn* hc, struct timeval* nowP );
262
263/* Call this to de-initialize a connection struct and *really* free the
264** mallocced strings.
265*/
266extern void httpd_destroy_conn( httpd_conn* hc );
267
268
269/* Send an error message back to the client. */
270extern void httpd_send_err(
271    httpd_conn* hc, int status, char* title, char* extraheads, char* form,
272    char* arg );
273
274/* Some error messages. */
275extern char* httpd_err400title;
276extern char* httpd_err400form;
277extern char* httpd_err408title;
278extern char* httpd_err408form;
279extern char* httpd_err503title;
280extern char* httpd_err503form;
281
282/* Generate a string representation of a method number. */
283extern char* httpd_method_str( int method );
284
285/* Reallocate a string. */
286extern void httpd_realloc_str( char** strP, size_t* maxsizeP, size_t size );
287
288/* Format a network socket to a string representation. */
289extern char* httpd_ntoa( httpd_sockaddr* saP );
290
291/* Set NDELAY mode on a socket. */
292extern void httpd_set_ndelay( int fd );
293
294/* Clear NDELAY mode on a socket. */
295extern void httpd_clear_ndelay( int fd );
296
297/* Read the requested buffer completely, accounting for interruptions. */
298extern int httpd_read_fully( int fd, void* buf, size_t nbytes );
299
300/* Write the requested buffer completely, accounting for interruptions. */
301extern int httpd_write_fully( int fd, const char* buf, size_t nbytes );
302
303/* Generate debugging statistics syslog message. */
304extern void httpd_logstats( long secs );
305
306#ifdef __cplusplus
307}
308#endif
309
310#endif /* _LIBHTTPD_H_ */
311