9c606f49f74e3f8312f47ca37711fbccf44e6761
[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
20 #define VERSION         "1.38"          /* Version                      */
21
22 #ifndef CONFIG
23 #define CONFIG          "shttpd.conf"   /* Configuration file           */
24 #endif /* CONFIG */
25
26 #define HTPASSWD        ".htpasswd"     /* Passwords file name          */
27 #define DFLT_IO_SIZ     "16384"         /* Default max request size     */
28 #define LISTENING_PORTS "80"            /* Default listening ports      */
29 #define INDEX_FILES     "index.html index.htm index.php index.cgi"
30 #define CGI_EXT         ".cgi .pl .php" /* Default CGI extensions       */
31 #define SSI_EXT         ".shtml .shtm"  /* Default SSI extensions       */
32 #define REALM           "mydomain.com"  /* Default authentication realm */
33 #define DELIM_CHARS     " ,"            /* Separators for lists         */
34
35 #define EXPIRE_TIME     3600            /* Expiration time, seconds     */
36 #define ENV_MAX         4096            /* Size of environment block    */
37 #define CGI_ENV_VARS    64              /* Maximum vars passed to CGI   */
38 #define URI_MAX         32768           /* Maximum URI size             */
39 #define MIN_REQ_LEN     16              /* "GET / HTTP/1.1\n\n"         */
40
41 #define NELEMS(ar)      (sizeof(ar) / sizeof(ar[0]))
42
43 #ifdef _DEBUG
44 #define DBG(x)  do { printf x ; putchar('\n'); fflush(stdout); } while (0)
45 #else
46 #define DBG(x)
47 #endif /* DEBUG */
48
49 #ifdef EMBEDDED
50 #include "shttpd.h"
51 #endif /* EMBEDDED */
52
53 /*
54  * Darwin prior to 7.0 and Win32 do not have socklen_t
55  */
56 #ifdef NO_SOCKLEN_T
57 typedef int socklen_t;
58 #endif /* NO_SOCKLEN_T */
59
60 /*
61  * For parsing. This guy represents a substring.
62  */
63 struct vec {
64         const char      *ptr;
65         int             len;
66 };
67
68 enum {METHOD_GET, METHOD_POST, METHOD_PUT, METHOD_DELETE, METHOD_HEAD};
69 enum {HDR_DATE, HDR_INT, HDR_STRING};   /* HTTP header types            */
70 enum {E_FATAL = 1, E_LOG = 2};          /* Flags for elog() function    */
71 typedef unsigned long big_int_t;        /* Type for Content-Length      */
72         
73 /*
74  * Unified socket address
75  */
76 struct usa {
77         socklen_t len;
78         union {
79                 struct sockaddr sa;
80                 struct sockaddr_in sin;
81         } u;
82 };
83
84 /*
85  * This thing is aimed to hold values of any type.
86  * Used to store parsed headers' values.
87  */
88 union variant {
89         char            *v_str;
90         int             v_int;
91         big_int_t       v_big_int;
92         time_t          v_time;
93         void            (*v_func)(void);
94         void            *v_void;
95         struct vec      v_vec;
96 };
97
98 /*
99  * This structure is used to hold mime types and associated file extensions.
100  */
101 struct mime_type {
102         const char      *ext;
103         int             ext_len;
104         const char      *mime;
105 };
106
107 struct mime_type_link {
108         struct llhead   link;
109         char            *ext;
110         int             ext_len;
111         char            *mime;
112 };
113
114 /*
115  * This is used only in embedded configuration. This structure holds a
116  * registered URI, associated callback function with callback data.
117  * For non-embedded compilation shttpd_callback_t is not defined, so
118  * we use union variant to keep the compiler silent.
119  */
120 struct registered_uri {
121         struct llhead   link;
122         const char      *uri;
123         union variant   callback;
124         void            *callback_data;
125 };
126
127 /*
128  * User may bind a passwords file to any URI. This makes that URI password
129  * protected: anybody who accesses that URI will be asked to authorize.
130  */
131 struct uri_auth {
132         struct llhead   link;
133         const char      *uri;
134         const char      *file_name;
135         size_t          uri_len;
136 };
137
138 /*
139  * User may want to handle certain errors. This structure holds the
140  * handlers for corresponding error codes.
141  */
142 struct error_handler {
143         struct llhead   link;
144         int             code;
145         union variant   callback;
146         void            *callback_data;
147 };
148
149 struct http_header {
150         int             len;            /* Header name length           */
151         int             type;           /* Header type                  */
152         size_t          offset;         /* Value placeholder            */
153         const char      *name;          /* Header name                  */
154 };
155
156 /*
157  * This guy holds parsed HTTP headers
158  */
159 struct headers {
160         union variant   cl;             /* Content-Length:              */
161         union variant   ct;             /* Content-Type:                */
162         union variant   connection;     /* Connection:                  */
163         union variant   ims;            /* If-Modified-Since:           */
164         union variant   user;           /* Remote user name             */
165         union variant   auth;           /* Authorization                */
166         union variant   useragent;      /* User-Agent:                  */
167         union variant   referer;        /* Referer:                     */
168         union variant   cookie;         /* Cookie:                      */
169         union variant   location;       /* Location:                    */
170         union variant   range;          /* Range:                       */
171         union variant   status;         /* Status:                      */
172         union variant   transenc;       /* Transfer-Encoding:           */
173 };
174
175 /* Must go after union variant definition */
176 #include "ssl.h"
177
178 /*
179  * The communication channel
180  */
181 union channel {
182         int             fd;             /* Regular static file          */
183         int             sock;           /* Connected socket             */
184         struct {
185                 int             sock;   /* XXX important. must be first */
186                 SSL             *ssl;   /* shttpd_poll() assumes that   */
187         } ssl;                          /* SSL-ed socket                */
188         struct {
189                 DIR     *dirp;
190                 char    *path;
191         } dir;                          /* Opened directory             */
192         struct {
193                 void            *state; /* For keeping state            */
194                 union variant   func;   /* User callback function       */
195                 void            *data;  /* User defined parameters      */
196         } emb;                          /* Embedded, user callback      */
197 };
198
199 struct stream;
200
201 /*
202  * IO class descriptor (file, directory, socket, SSL, CGI, etc)
203  * These classes are defined in io_*.c files.
204  */
205 struct io_class {
206         const char *name;
207         int (*read)(struct stream *, void *buf, size_t len);
208         int (*write)(struct stream *, const void *buf, size_t len);
209         void (*close)(struct stream *);
210 };
211
212 /*
213  * Data exchange stream. It is backed by some communication channel:
214  * opened file, socket, etc. The 'read' and 'write' methods are
215  * determined by a communication channel.
216  */
217 struct stream {
218         struct conn             *conn;
219         union channel           chan;           /* Descriptor           */
220         struct io               io;             /* IO buffer            */
221         const struct io_class   *io_class;      /* IO class             */
222         int                     nread_last;     /* Bytes last read      */
223         int                     headers_len;
224         big_int_t               content_len;
225         unsigned int            flags;
226 #define FLAG_HEADERS_PARSED     1
227 #define FLAG_SSL_ACCEPTED       2
228 #define FLAG_R                  4               /* Can read in general  */
229 #define FLAG_W                  8               /* Can write in general */
230 #define FLAG_CLOSED             16
231 #define FLAG_DONT_CLOSE         32
232 #define FLAG_ALWAYS_READY       64              /* File, dir, user_func */
233 };
234
235 struct conn {
236         struct llhead   link;           /* Connections chain            */
237         struct shttpd_ctx *ctx;         /* Context this conn belongs to */
238         struct usa      sa;             /* Remote socket address        */
239         time_t          birth_time;     /* Creation time                */
240         time_t          expire_time;    /* Expiration time              */
241
242         int             loc_port;       /* Local port                   */
243         int             status;         /* Reply status code            */
244         int             method;         /* Request method               */
245         char            *uri;           /* Decoded URI                  */
246         unsigned long   major_version;  /* Major HTTP version number    */
247         unsigned long   minor_version;  /* Minor HTTP version number    */
248         char            *request;       /* Request line                 */
249         char            *headers;       /* Request headers              */
250         char            *query;         /* QUERY_STRING part of the URI */
251         char            *path_info;     /* PATH_INFO thing              */
252         const char      *mime_type;     /* Mime type                    */
253
254         struct headers  ch;             /* Parsed client headers        */
255
256         struct stream   loc;            /* Local stream                 */
257         struct stream   rem;            /* Remote stream                */
258
259 #if !defined(NO_SSI)
260         void                    *ssi;   /* SSI descriptor               */
261 #endif /* NO_SSI */
262 };
263
264
265 /*
266  * SHTTPD context
267  */
268 struct shttpd_ctx {
269         time_t          start_time;     /* Start time                   */
270         int             nactive;        /* # of connections now         */
271         unsigned long   nrequests;      /* Requests made                */
272         uint64_t        in, out;        /* IN/OUT traffic counters      */
273         SSL_CTX         *ssl_ctx;       /* SSL context                  */
274         struct llhead   connections;    /* List of connections          */
275
276         struct llhead   mime_types;     /* Known mime types             */
277         struct llhead   registered_uris;/* User urls                    */
278         struct llhead   uri_auths;      /* User auth files              */
279         struct llhead   error_handlers; /* Embedded error handlers      */
280
281         FILE    *access_log;            /* Access log stream            */
282         FILE    *error_log;             /* Error log stream             */
283         char    *put_auth_file;         /* PUT auth file                */
284         char    *document_root;         /* Document root                */
285         char    *index_files;           /* Index files                  */
286         char    *aliases;               /* Aliases                      */
287         char    *mime_file;             /* Mime types file              */
288 #if !defined(NO_CGI)
289         char    *cgi_vars;              /* CGI environment variables    */
290         char    *cgi_extensions;        /* CGI extensions               */
291         char    *cgi_interpreter;       /* CGI script interpreter       */
292 #endif /* NO_CGI */
293 #if !defined(NO_SSI)
294         char    *ssi_extensions;        /* SSI file extensions          */
295         struct llhead   ssi_funcs;      /* SSI callback functions       */
296 #endif /* NO_SSI */
297         char    *auth_realm;            /* Auth realm                   */
298         char    *global_passwd_file;    /* Global passwords file        */
299         char    *uid;                   /* Run as user                  */
300         char    *ports;                 /* Listening ports              */
301         int     dirlist;                /* Directory listing            */
302         int     gui;                    /* Show GUI flag                */
303         int     auto_start;             /* Start on OS boot             */
304         int     io_buf_size;            /* IO buffer size               */
305         int     inetd_mode;             /* Inetd flag                   */
306 #if defined(_WIN32)
307         CRITICAL_SECTION mutex;         /* For MT case                  */
308         HANDLE          ev[2];          /* For thread synchronization */
309 #elif defined(__rtems__)
310         rtems_id         mutex;
311 #endif /* _WIN32 */
312 };
313
314 /* Option setter function */
315 typedef void (*optset_t)(struct shttpd_ctx *, void *ptr, const char *string);
316 struct opt {
317         int             sw;             /* Command line switch          */
318         const char      *name;          /* Option name in config file   */
319         const char      *desc;          /* Description                  */
320         optset_t        setter;         /* Option setter function       */
321         size_t          ofs;            /* Value offset in context      */
322         const char      *arg;           /* Argument format              */
323         const char      *def;           /* Default option value         */
324         unsigned int    flags;          /* Flags                        */
325 #define OPT_BOOL        1
326 #define OPT_INT         2
327 #define OPT_FILE        4
328 #define OPT_DIR         8
329 #define OPT_ADVANCED    16
330 };
331
332 extern const struct opt options[];
333
334 /*
335  * In SHTTPD, list of values are represented as comma or space separated
336  * string. For example, list of CGI extensions can be represented as
337  * ".cgi,.php,.pl", or ".cgi .php .pl". The macro that follows allows to
338  * loop through the individual values in that list.
339  * A "const char *" pointer and size_t variable must be passed to the macro.
340  * Spaces or commas can be used as delimiters (macro DELIM_CHARS)
341  */
342 #define FOR_EACH_WORD_IN_LIST(s,len)    \
343         for (; s != NULL && (len = strcspn(s, DELIM_CHARS)) != 0; s += len + 1)
344
345 /*
346  * shttpd.c
347  */
348 extern time_t           current_time;   /* Current UTC time             */
349 extern int              tz_offset;      /* Offset from GMT time zone    */
350 extern const struct vec known_http_methods[];
351
352 extern void     stop_stream(struct stream *stream);
353 extern int      url_decode(const char *, int, char *dst, int);
354 extern void     send_server_error(struct conn *, int code, const char *reason);
355 extern int      get_headers_len(const char *buf, size_t buflen);
356 extern void     parse_headers(const char *s, int len, struct headers *parsed);
357 extern void     open_listening_ports(struct shttpd_ctx *ctx);
358
359 /*
360  * mime_type.c
361  */
362 extern const char *get_mime_type(struct shttpd_ctx *, const char *uri, int len);
363 extern void     set_mime_types(struct shttpd_ctx *ctx, const char *path);
364
365 /*
366  * config.c
367  */
368 extern void     usage(const char *prog);
369 extern struct shttpd_ctx *init_from_argc_argv(const char *, int, char *[]);
370
371 /*
372  * log.c
373  */
374 extern void     elog(int flags, struct conn *c, const char *fmt, ...);
375 extern void     log_access(FILE *fp, const struct conn *c);
376
377 /*
378  * string.c
379  */
380 extern void     my_strlcpy(register char *, register const char *, size_t);
381 extern int      my_strncasecmp(register const char *,
382                 register const char *, size_t);
383 extern char     *my_strndup(const char *ptr, size_t len);
384 extern char     *my_strdup(const char *str);
385 extern int      my_snprintf(char *buf, size_t buflen, const char *fmt, ...);
386 extern int      match_extension(const char *path, const char *ext_list);
387
388 /*
389  * compat_*.c
390  */
391 extern void     set_close_on_exec(int fd);
392 extern int      set_non_blocking_mode(int fd);
393 extern int      my_stat(const char *, struct stat *stp);
394 extern int      my_open(const char *, int flags, int mode);
395 extern int      my_remove(const char *);
396 extern int      my_rename(const char *, const char *);
397 extern int      my_mkdir(const char *, int);
398 extern char *   my_getcwd(char *, int);
399 extern int      spawn_process(struct conn *c, const char *prog,
400                 char *envblk, char *envp[], int sock, const char *dir);
401
402 /*
403  * io_*.c
404  */
405 extern const struct io_class    io_file;
406 extern const struct io_class    io_socket;
407 extern const struct io_class    io_ssl;
408 extern const struct io_class    io_cgi;
409 extern const struct io_class    io_dir;
410 extern const struct io_class    io_embedded;
411 extern const struct io_class    io_ssi;
412
413 extern int      put_dir(const char *path);
414 extern void     get_dir(struct conn *c);
415 extern void     get_file(struct conn *c, struct stat *stp);
416 extern void     ssl_handshake(struct stream *stream);
417 extern void     setup_embedded_stream(struct conn *, union variant, void *);
418 extern struct registered_uri *is_registered_uri(struct shttpd_ctx *,
419                 const char *uri);
420 extern void     do_ssi(struct conn *);
421 extern void     free_ssi_funcs(struct shttpd_ctx *ctx);
422
423 /*
424  * auth.c
425  */
426 extern int      check_authorization(struct conn *c, const char *path);
427 extern int      is_authorized_for_put(struct conn *c);
428 extern void     send_authorization_request(struct conn *c);
429 extern int      edit_passwords(const char *fname, const char *domain,
430                 const char *user, const char *pass);
431
432 /*
433  * cgi.c
434  */
435 extern int      run_cgi(struct conn *c, const char *prog);
436 extern void     do_cgi(struct conn *c);
437
438 #define CGI_REPLY       "HTTP/1.1     OK\r\n"
439 #define CGI_REPLY_LEN   (sizeof(CGI_REPLY) - 1)
440
441 #endif /* DEFS_HEADER_DEFINED */