version 0.2.1
[fms.git] / libs / shttpd / defs.h
1 /*
2  * Copyright (c) 2004-2005 Sergey Lyubka <valenok@gmail.com>
3  * All rights reserved
4  *
5  * "THE BEER-WARE LICENSE" (Revision 42):
6  * Sergey Lyubka wrote this file.  As long as you retain this notice you
7  * can do whatever you want with this stuff. If we meet some day, and you think
8  * this stuff is worth it, you can buy me a beer in return.
9  */
10
11 #ifndef DEFS_HEADER_DEFINED
12 #define DEFS_HEADER_DEFINED
13
14 #include "std_includes.h"
15 #include "llist.h"
16 #include "io.h"
17 #include "shttpd.h"
18 #include "md5.h"
19 #include "config.h"
20
21 #define NELEMS(ar)      (sizeof(ar) / sizeof(ar[0]))
22
23 #ifdef _DEBUG
24 #define DBG(x)  do { printf x ; putchar('\n'); fflush(stdout); } while (0)
25 #else
26 #define DBG(x)
27 #endif /* DEBUG */
28
29 #ifdef EMBEDDED
30 #include "shttpd.h"
31 #endif /* EMBEDDED */
32
33 /*
34  * Darwin prior to 7.0 and Win32 do not have socklen_t
35  */
36 #ifdef NO_SOCKLEN_T
37 typedef int socklen_t;
38 #endif /* NO_SOCKLEN_T */
39
40 /*
41  * For parsing. This guy represents a substring.
42  */
43 struct vec {
44         const char      *ptr;
45         int             len;
46 };
47
48 #if !defined(_WIN32)
49 enum {FALSE, TRUE};
50 #endif /* _WIN32 */
51 enum {METHOD_GET, METHOD_POST, METHOD_PUT, METHOD_DELETE, METHOD_HEAD};
52 enum {HDR_DATE, HDR_INT, HDR_STRING};   /* HTTP header types            */
53 enum {E_FATAL = 1, E_LOG = 2};          /* Flags for elog() function    */
54 typedef unsigned long big_int_t;        /* Type for Content-Length      */
55         
56 /*
57  * Unified socket address
58  */
59 struct usa {
60         socklen_t len;
61         union {
62                 struct sockaddr sa;
63                 struct sockaddr_in sin;
64         } u;
65 };
66
67 /*
68  * This thing is aimed to hold values of any type.
69  * Used to store parsed headers' values.
70  */
71 union variant {
72         char            *v_str;
73         int             v_int;
74         big_int_t       v_big_int;
75         time_t          v_time;
76         void            (*v_func)(void);
77         void            *v_void;
78         struct vec      v_vec;
79 };
80
81 /*
82  * This is used only in embedded configuration. This structure holds a
83  * registered URI, associated callback function with callback data.
84  * For non-embedded compilation shttpd_callback_t is not defined, so
85  * we use union variant to keep the compiler silent.
86  */
87 struct registered_uri {
88         struct llhead   link;
89         const char      *uri;
90         union variant   callback;
91         void            *callback_data;
92 };
93
94 /*
95  * User may want to handle certain errors. This structure holds the
96  * handlers for corresponding error codes.
97  */
98 struct error_handler {
99         struct llhead   link;
100         int             code;
101         union variant   callback;
102         void            *callback_data;
103 };
104
105 struct http_header {
106         int             len;            /* Header name length           */
107         int             type;           /* Header type                  */
108         size_t          offset;         /* Value placeholder            */
109         const char      *name;          /* Header name                  */
110 };
111
112 /*
113  * This guy holds parsed HTTP headers
114  */
115 struct headers {
116         union variant   cl;             /* Content-Length:              */
117         union variant   ct;             /* Content-Type:                */
118         union variant   connection;     /* Connection:                  */
119         union variant   ims;            /* If-Modified-Since:           */
120         union variant   user;           /* Remote user name             */
121         union variant   auth;           /* Authorization                */
122         union variant   useragent;      /* User-Agent:                  */
123         union variant   referer;        /* Referer:                     */
124         union variant   cookie;         /* Cookie:                      */
125         union variant   location;       /* Location:                    */
126         union variant   range;          /* Range:                       */
127         union variant   status;         /* Status:                      */
128         union variant   transenc;       /* Transfer-Encoding:           */
129 };
130
131 /* Must go after union variant definition */
132 #include "ssl.h"
133
134 /*
135  * The communication channel
136  */
137 union channel {
138         int             fd;             /* Regular static file          */
139         int             sock;           /* Connected socket             */
140         struct {
141                 int             sock;   /* XXX important. must be first */
142                 SSL             *ssl;   /* shttpd_poll() assumes that   */
143         } ssl;                          /* SSL-ed socket                */
144         struct {
145                 DIR     *dirp;
146                 char    *path;
147         } dir;                          /* Opened directory             */
148         struct {
149                 void            *state; /* For keeping state            */
150                 union variant   func;   /* User callback function       */
151                 void            *data;  /* User defined parameters      */
152         } emb;                          /* Embedded, user callback      */
153 };
154
155 struct stream;
156
157 /*
158  * IO class descriptor (file, directory, socket, SSL, CGI, etc)
159  * These classes are defined in io_*.c files.
160  */
161 struct io_class {
162         const char *name;
163         int (*read)(struct stream *, void *buf, size_t len);
164         int (*write)(struct stream *, const void *buf, size_t len);
165         void (*close)(struct stream *);
166 };
167
168 /*
169  * Data exchange stream. It is backed by some communication channel:
170  * opened file, socket, etc. The 'read' and 'write' methods are
171  * determined by a communication channel.
172  */
173 struct stream {
174         struct conn             *conn;
175         union channel           chan;           /* Descriptor           */
176         struct io               io;             /* IO buffer            */
177         const struct io_class   *io_class;      /* IO class             */
178         int                     nread_last;     /* Bytes last read      */
179         int                     headers_len;
180         big_int_t               content_len;
181         unsigned int            flags;
182 #define FLAG_HEADERS_PARSED     1
183 #define FLAG_SSL_ACCEPTED       2
184 #define FLAG_R                  4               /* Can read in general  */
185 #define FLAG_W                  8               /* Can write in general */
186 #define FLAG_CLOSED             16
187 #define FLAG_DONT_CLOSE         32
188 #define FLAG_ALWAYS_READY       64              /* File, dir, user_func */
189 };
190
191 struct conn {
192         struct llhead   link;           /* Connections chain            */
193         struct shttpd_ctx *ctx;         /* Context this conn belongs to */
194         struct usa      sa;             /* Remote socket address        */
195         time_t          birth_time;     /* Creation time                */
196         time_t          expire_time;    /* Expiration time              */
197
198         int             loc_port;       /* Local port                   */
199         int             status;         /* Reply status code            */
200         int             method;         /* Request method               */
201         char            *uri;           /* Decoded URI                  */
202         unsigned long   major_version;  /* Major HTTP version number    */
203         unsigned long   minor_version;  /* Minor HTTP version number    */
204         char            *request;       /* Request line                 */
205         char            *headers;       /* Request headers              */
206         char            *query;         /* QUERY_STRING part of the URI */
207         char            *path_info;     /* PATH_INFO thing              */
208         struct vec      mime_type;      /* Mime type                    */
209
210         struct headers  ch;             /* Parsed client headers        */
211
212         struct stream   loc;            /* Local stream                 */
213         struct stream   rem;            /* Remote stream                */
214
215 #if !defined(NO_SSI)
216         void                    *ssi;   /* SSI descriptor               */
217 #endif /* NO_SSI */
218 };
219
220 enum {
221         OPT_ROOT, OPT_INDEX_FILES, OPT_PORTS, OPT_DIR_LIST,
222         OPT_CGI_EXTENSIONS, OPT_CGI_INTERPRETER, OPT_CGI_ENVIRONMENT,
223         OPT_SSI_EXTENSIONS, OPT_AUTH_REALM, OPT_AUTH_GPASSWD,
224         OPT_AUTH_PUT, OPT_ACCESS_LOG, OPT_ERROR_LOG, OPT_MIME_TYPES,
225         OPT_SSL_CERTIFICATE, OPT_ALIASES, OPT_ACL, OPT_INETD, OPT_UID,
226         OPT_CFG_URI, OPT_PROTECT,
227         NUM_OPTIONS
228 };
229
230 /*
231  * SHTTPD context
232  */
233 struct shttpd_ctx {
234         time_t          start_time;     /* Start time                   */
235         int             nactive;        /* # of connections now         */
236         unsigned long   nrequests;      /* Requests made                */
237         uint64_t        in, out;        /* IN/OUT traffic counters      */
238         SSL_CTX         *ssl_ctx;       /* SSL context                  */
239         struct llhead   connections;    /* List of connections          */
240
241         struct llhead   registered_uris;/* User urls                    */
242         struct llhead   error_handlers; /* Embedded error handlers      */
243         struct llhead   acl;            /* Access control list          */
244         struct llhead   ssi_funcs;      /* SSI callback functions       */
245         struct llhead   listeners;      /* Listening sockets            */
246
247         FILE    *access_log;            /* Access log stream            */
248         FILE    *error_log;             /* Error log stream             */
249
250         char    *options[NUM_OPTIONS];  /* Configurable options         */
251
252 #if defined(_WIN32)
253         CRITICAL_SECTION mutex;         /* For MT case                  */
254         HANDLE          ev[2];          /* For thread synchronization */
255 #elif defined(__rtems__)
256         rtems_id         mutex;
257 #endif /* _WIN32 */
258 };
259
260 #define IS_TRUE(ctx, opt) ((ctx)->options[opt] && (ctx)->options[opt][0] =='1')
261
262 /*
263  * In SHTTPD, list of values are represented as comma or space separated
264  * string. For example, list of CGI extensions can be represented as
265  * ".cgi,.php,.pl", or ".cgi .php .pl". The macro that follows allows to
266  * loop through the individual values in that list.
267  *
268  * A "const char *" pointer and size_t variable must be passed to the macro.
269  * Spaces or commas can be used as delimiters (macro DELIM_CHARS).
270  *
271  * In every iteration of the loop, "s" points to the current value, and
272  * "len" specifies its length. The code inside loop must not change
273  * "s" and "len" parameters.
274  */
275 #define FOR_EACH_WORD_IN_LIST(s,len)                                    \
276         for (; s != NULL && (len = strcspn(s, DELIM_CHARS)) != 0;       \
277                         s += len, s+= strspn(s, DELIM_CHARS))
278
279 /*
280  * IPv4 ACL entry. Specifies subnet with deny/allow flag
281  */
282 struct acl {
283         struct llhead   link;
284         uint32_t        ip;             /* IP, in network byte order    */
285         uint32_t        mask;           /* Also in network byte order   */
286         int             flag;           /* Either '+' or '-'            */
287 };
288
289 /*
290  * shttpd.c
291  */
292 extern time_t           current_time;   /* Current UTC time             */
293 extern int              tz_offset;      /* Offset from GMT time zone    */
294 extern const struct vec known_http_methods[];
295
296 extern void     stop_stream(struct stream *stream);
297 extern int      url_decode(const char *, int, char *dst, int);
298 extern void     send_server_error(struct conn *, int code, const char *reason);
299 extern int      get_headers_len(const char *buf, size_t buflen);
300 extern void     parse_headers(const char *s, int len, struct headers *parsed);
301 extern void     open_listening_ports(struct shttpd_ctx *ctx);
302 extern void get_mime_type(struct shttpd_ctx *, const char *, int, struct vec *);
303 extern void     free_list(struct llhead *head, void (*)(struct llhead *));
304 extern void     registered_uri_destructor(struct llhead *);
305 extern void     listener_destructor(struct llhead *);
306
307 /*
308  * config.c
309  */
310 extern void     usage(const char *prog);
311
312 /*
313  * log.c
314  */
315 extern void     elog(int flags, struct conn *c, const char *fmt, ...);
316 extern void     log_access(FILE *fp, const struct conn *c);
317
318 /*
319  * string.c
320  */
321 extern void     my_strlcpy(register char *, register const char *, size_t);
322 extern int      my_strncasecmp(register const char *,
323                 register const char *, size_t);
324 extern char     *my_strndup(const char *ptr, size_t len);
325 extern char     *my_strdup(const char *str);
326 extern int      my_snprintf(char *buf, size_t buflen, const char *fmt, ...);
327 extern int      match_extension(const char *path, const char *ext_list);
328
329 /*
330  * compat_*.c
331  */
332 extern void     set_close_on_exec(int fd);
333 extern int      set_non_blocking_mode(int fd);
334 extern int      my_stat(const char *, struct stat *stp);
335 extern int      my_open(const char *, int flags, int mode);
336 extern int      my_remove(const char *);
337 extern int      my_rename(const char *, const char *);
338 extern int      my_mkdir(const char *, int);
339 extern char *   my_getcwd(char *, int);
340 extern int      spawn_process(struct conn *c, const char *prog,
341                 char *envblk, char *envp[], int sock, const char *dir);
342
343 /*
344  * io_*.c
345  */
346 extern const struct io_class    io_file;
347 extern const struct io_class    io_socket;
348 extern const struct io_class    io_ssl;
349 extern const struct io_class    io_cgi;
350 extern const struct io_class    io_dir;
351 extern const struct io_class    io_embedded;
352 extern const struct io_class    io_ssi;
353
354 extern int      put_dir(const char *path);
355 extern void     get_dir(struct conn *c);
356 extern void     get_file(struct conn *c, struct stat *stp);
357 extern void     ssl_handshake(struct stream *stream);
358 extern void     setup_embedded_stream(struct conn *, union variant, void *);
359 extern struct registered_uri *is_registered_uri(struct shttpd_ctx *,
360                 const char *uri);
361 extern void     do_ssi(struct conn *);
362 extern void     ssi_func_destructor(struct llhead *lp);
363
364 /*
365  * auth.c
366  */
367 extern int      check_authorization(struct conn *c, const char *path);
368 extern int      is_authorized_for_put(struct conn *c);
369 extern void     send_authorization_request(struct conn *c);
370 extern int      edit_passwords(const char *fname, const char *domain,
371                 const char *user, const char *pass);
372
373 /*
374  * cgi.c
375  */
376 extern int      run_cgi(struct conn *c, const char *prog);
377 extern void     do_cgi(struct conn *c);
378
379 #define CGI_REPLY       "HTTP/1.1     OK\r\n"
380 #define CGI_REPLY_LEN   (sizeof(CGI_REPLY) - 1)
381
382 #endif /* DEFS_HEADER_DEFINED */