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 "md5.h" 18 #include "config.h" 19 #include "shttpd.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 /* 30 * Darwin prior to 7.0 and Win32 do not have socklen_t 31 */ 32 #ifdef NO_SOCKLEN_T 33 typedef int socklen_t; 34 #endif /* NO_SOCKLEN_T */ 35 36 /* 37 * For parsing. This guy represents a substring. 38 */ 39 struct vec { 40 const char *ptr; 41 int len; 42 }; 43 44 #if !defined(FALSE) 45 enum {FALSE, TRUE}; 46 #endif /* !FALSE */ 47 48 enum {METHOD_GET, METHOD_POST, METHOD_PUT, METHOD_DELETE, METHOD_HEAD}; 49 enum {HDR_DATE, HDR_INT, HDR_STRING}; /* HTTP header types */ 50 enum {E_FATAL = 1, E_LOG = 2}; /* Flags for elog() function */ 51 typedef unsigned long big_int_t; /* Type for Content-Length */ 52 53 /* 54 * Unified socket address 55 */ 56 struct usa { 57 socklen_t len; 58 union { 59 struct sockaddr sa; 60 struct sockaddr_in sin; 61 } u; 62 }; 63 64 /* 65 * This thing is aimed to hold values of any type. 66 * Used to store parsed headers' values. 67 */ 68 union variant { 69 char *v_str; 70 int v_int; 71 big_int_t v_big_int; 72 time_t v_time; 73 void (*v_func)(void); 74 void *v_void; 75 struct vec v_vec; 76 }; 77 78 /* 79 * This is used only in embedded configuration. This structure holds a 80 * registered URI, associated callback function with callback data. 81 * For non-embedded compilation shttpd_callback_t is not defined, so 82 * we use union variant to keep the compiler silent. 83 */ 84 struct registered_uri { 85 struct llhead link; 86 const char *uri; 87 union variant callback; 88 void *callback_data; 89 }; 90 91 /* 92 * User may want to handle certain errors. This structure holds the 93 * handlers for corresponding error codes. 94 */ 95 struct error_handler { 96 struct llhead link; 97 int code; 98 union variant callback; 99 void *callback_data; 100 }; 101 102 struct http_header { 103 int len; /* Header name length */ 104 int type; /* Header type */ 105 size_t offset; /* Value placeholder */ 106 const char *name; /* Header name */ 107 }; 108 109 /* 110 * This guy holds parsed HTTP headers 111 */ 112 struct headers { 113 union variant cl; /* Content-Length: */ 114 union variant ct; /* Content-Type: */ 115 union variant connection; /* Connection: */ 116 union variant ims; /* If-Modified-Since: */ 117 union variant user; /* Remote user name */ 118 union variant auth; /* Authorization */ 119 union variant useragent; /* User-Agent: */ 120 union variant referer; /* Referer: */ 121 union variant cookie; /* Cookie: */ 122 union variant location; /* Location: */ 123 union variant range; /* Range: */ 124 union variant status; /* Status: */ 125 union variant transenc; /* Transfer-Encoding: */ 126 }; 127 128 /* Must go after union variant definition */ 129 #include "ssl.h" 130 131 /* 132 * The communication channel 133 */ 134 union channel { 135 int fd; /* Regular static file */ 136 int sock; /* Connected socket */ 137 struct { 138 int sock; /* XXX important. must be first */ 139 SSL *ssl; /* shttpd_poll() assumes that */ 140 } ssl; /* SSL-ed socket */ 141 struct { 142 DIR *dirp; 143 char *path; 144 } dir; /* Opened directory */ 145 struct { 146 void *state; /* For keeping state */ 147 union variant func; /* User callback function */ 148 void *data; /* User defined parameters */ 149 } emb; /* Embedded, user callback */ 150 }; 151 152 struct stream; 153 154 /* 155 * IO class descriptor (file, directory, socket, SSL, CGI, etc) 156 * These classes are defined in io_*.c files. 157 */ 158 struct io_class { 159 const char *name; 160 int (*read)(struct stream *, void *buf, size_t len); 161 int (*write)(struct stream *, const void *buf, size_t len); 162 void (*close)(struct stream *); 163 }; 164 165 /* 166 * Data exchange stream. It is backed by some communication channel: 167 * opened file, socket, etc. The 'read' and 'write' methods are 168 * determined by a communication channel. 169 */ 170 struct stream { 171 struct conn *conn; 172 union channel chan; /* Descriptor */ 173 struct io io; /* IO buffer */ 174 const struct io_class *io_class; /* IO class */ 175 int headers_len; 176 big_int_t content_len; 177 unsigned int flags; 178 #define FLAG_HEADERS_PARSED 1 179 #define FLAG_SSL_ACCEPTED 2 180 #define FLAG_R 4 /* Can read in general */ 181 #define FLAG_W 8 /* Can write in general */ 182 #define FLAG_CLOSED 16 183 #define FLAG_DONT_CLOSE 32 184 #define FLAG_ALWAYS_READY 64 /* File, dir, user_func */ 185 #define FLAG_SUSPEND 128 186 }; 187 188 struct worker { 189 struct llhead link; 190 int num_conns; /* Num of active connections */ 191 int exit_flag; /* Ditto - exit flag */ 192 int ctl[2]; /* Control socket pair */ 193 struct shttpd_ctx *ctx; /* Context reference */ 194 struct llhead connections; /* List of connections */ 195 }; 196 197 struct conn { 198 struct llhead link; /* Connections chain */ 199 struct worker *worker; /* Worker this conn belongs to */ 200 struct shttpd_ctx *ctx; /* Context this conn belongs to */ 201 struct usa sa; /* Remote socket address */ 202 time_t birth_time; /* Creation time */ 203 time_t expire_time; /* Expiration time */ 204 205 int loc_port; /* Local port */ 206 int status; /* Reply status code */ 207 int method; /* Request method */ 208 char *uri; /* Decoded URI */ 209 unsigned long major_version; /* Major HTTP version number */ 210 unsigned long minor_version; /* Minor HTTP version number */ 211 char *request; /* Request line */ 212 char *headers; /* Request headers */ 213 char *query; /* QUERY_STRING part of the URI */ 214 char *path_info; /* PATH_INFO thing */ 215 struct vec mime_type; /* Mime type */ 216 217 struct headers ch; /* Parsed client headers */ 218 219 struct stream loc; /* Local stream */ 220 struct stream rem; /* Remote stream */ 221 222 #if !defined(NO_SSI) 223 void *ssi; /* SSI descriptor */ 224 #endif /* NO_SSI */ 225 }; 226 227 enum { 228 OPT_ROOT, OPT_INDEX_FILES, OPT_PORTS, OPT_DIR_LIST, 229 OPT_CGI_EXTENSIONS, OPT_CGI_INTERPRETER, OPT_CGI_ENVIRONMENT, 230 OPT_SSI_EXTENSIONS, OPT_AUTH_REALM, OPT_AUTH_GPASSWD, 231 OPT_AUTH_PUT, OPT_ACCESS_LOG, OPT_ERROR_LOG, OPT_MIME_TYPES, 232 OPT_SSL_CERTIFICATE, OPT_ALIASES, OPT_ACL, OPT_INETD, OPT_UID, 233 OPT_CFG_URI, OPT_PROTECT, OPT_SERVICE, OPT_HIDE, OPT_THREADS, 234 NUM_OPTIONS 235 }; 236 237 /* 238 * SHTTPD context 239 */ 240 struct shttpd_ctx { 241 SSL_CTX *ssl_ctx; /* SSL context */ 242 243 struct llhead registered_uris;/* User urls */ 244 struct llhead error_handlers; /* Embedded error handlers */ 245 struct llhead acl; /* Access control list */ 246 struct llhead ssi_funcs; /* SSI callback functions */ 247 struct llhead listeners; /* Listening sockets */ 248 struct llhead workers; /* Worker workers */ 249 250 FILE *access_log; /* Access log stream */ 251 FILE *error_log; /* Error log stream */ 252 253 char *options[NUM_OPTIONS]; /* Configurable options */ 254 #if defined(__rtems__) 255 rtems_id mutex; 256 #endif /* _WIN32 */ 257 }; 258 259 struct listener { 260 struct llhead link; 261 struct shttpd_ctx *ctx; /* Context that socket belongs */ 262 int sock; /* Listening socket */ 263 int is_ssl; /* Should be SSL-ed */ 264 }; 265 266 /* Types of messages that could be sent over the control socket */ 267 enum {CTL_PASS_SOCKET, CTL_WAKEUP}; 268 269 /* 270 * In SHTTPD, list of values are represented as comma or space separated 271 * string. For example, list of CGI extensions can be represented as 272 * ".cgi,.php,.pl", or ".cgi .php .pl". The macro that follows allows to 273 * loop through the individual values in that list. 274 * 275 * A "const char *" pointer and size_t variable must be passed to the macro. 276 * Spaces or commas can be used as delimiters (macro DELIM_CHARS). 277 * 278 * In every iteration of the loop, "s" points to the current value, and 279 * "len" specifies its length. The code inside loop must not change 280 * "s" and "len" parameters. 281 */ 282 #define FOR_EACH_WORD_IN_LIST(s,len) \ 283 for (; s != NULL && (len = strcspn(s, DELIM_CHARS)) != 0; \ 284 s += len, s+= strspn(s, DELIM_CHARS)) 285 286 /* 287 * IPv4 ACL entry. Specifies subnet with deny/allow flag 288 */ 289 struct acl { 290 struct llhead link; 291 uint32_t ip; /* IP, in network byte order */ 292 uint32_t mask; /* Also in network byte order */ 293 int flag; /* Either '+' or '-' */ 294 }; 295 296 /* 297 * shttpd.c 298 */ 299 extern time_t _shttpd_current_time; /* Current UTC time */ 300 extern int _shttpd_tz_offset; /* Offset from GMT time zone */ 301 extern const struct vec _shttpd_known_http_methods[]; 302 303 extern void _shttpd_stop_stream(struct stream *stream); 304 extern int _shttpd_url_decode(const char *, int, char *dst, int); 305 extern void _shttpd_send_server_error(struct conn *, int, const char *); 306 extern int _shttpd_get_headers_len(const char *buf, size_t buflen); 307 extern void _shttpd_parse_headers(const char *s, int, struct headers *); 308 extern int _shttpd_is_true(const char *str); 309 extern int _shttpd_socketpair(int pair[2]); 310 extern void _shttpd_get_mime_type(struct shttpd_ctx *, 311 const char *, int, struct vec *); 312 313 #define IS_TRUE(ctx, opt) _shttpd_is_true((ctx)->options[opt]) 314 315 /* 316 * config.c 317 */ 318 extern void _shttpd_usage(const char *prog); 319 320 /* 321 * log.c 322 */ 323 extern void _shttpd_elog(int flags, struct conn *c, const char *fmt, ...); 324 extern void _shttpd_log_access(FILE *fp, const struct conn *c); 325 326 /* 327 * string.c 328 */ 329 extern void _shttpd_strlcpy(register char *, register const char *, size_t); 330 extern int _shttpd_strncasecmp(register const char *, 331 register const char *, size_t); 332 extern char *_shttpd_strndup(const char *ptr, size_t len); 333 extern char *_shttpd_strdup(const char *str); 334 extern int _shttpd_snprintf(char *buf, size_t len, const char *fmt, ...); 335 extern int _shttpd_match_extension(const char *path, const char *ext_list); 336 337 /* 338 * compat_*.c 339 */ 340 extern void _shttpd_set_close_on_exec(int fd); 341 extern int _shttpd_set_non_blocking_mode(int fd); 342 extern int _shttpd_stat(const char *, struct stat *stp); 343 extern int _shttpd_open(const char *, int flags, int mode); 344 extern int _shttpd_remove(const char *); 345 extern int _shttpd_rename(const char *, const char *); 346 extern int _shttpd_mkdir(const char *, int); 347 extern char * _shttpd_getcwd(char *, int); 348 extern int _shttpd_spawn_process(struct conn *c, const char *prog, 349 char *envblk, char *envp[], int sock, const char *dir); 350 351 extern int _shttpd_set_nt_service(struct shttpd_ctx *, const char *); 352 extern int _shttpd_set_systray(struct shttpd_ctx *, const char *); 353 extern void _shttpd_try_to_run_as_nt_service(void); 354 355 /* 356 * io_*.c 357 */ 358 extern const struct io_class _shttpd_io_file; 359 extern const struct io_class _shttpd_io_socket; 360 extern const struct io_class _shttpd_io_ssl; 361 extern const struct io_class _shttpd_io_cgi; 362 extern const struct io_class _shttpd_io_dir; 363 extern const struct io_class _shttpd_io_embedded; 364 extern const struct io_class _shttpd_io_ssi; 365 366 extern int _shttpd_put_dir(const char *path); 367 extern void _shttpd_get_dir(struct conn *c); 368 extern void _shttpd_get_file(struct conn *c, struct stat *stp); 369 extern void _shttpd_ssl_handshake(struct stream *stream); 370 extern void _shttpd_setup_embedded_stream(struct conn *, 371 union variant, void *); 372 extern struct registered_uri *_shttpd_is_registered_uri(struct shttpd_ctx *, 373 const char *uri); 374 extern void _shttpd_do_ssi(struct conn *); 375 extern void _shttpd_ssi_func_destructor(struct llhead *lp); 376 377 /* 378 * auth.c 379 */ 380 extern int _shttpd_check_authorization(struct conn *c, const char *path); 381 extern int _shttpd_is_authorized_for_put(struct conn *c); 382 extern void _shttpd_send_authorization_request(struct conn *c); 383 extern int _shttpd_edit_passwords(const char *fname, const char *domain, 384 const char *user, const char *pass); 385 386 /* 387 * cgi.c 388 */ 389 extern int _shttpd_run_cgi(struct conn *c, const char *prog); 390 extern void _shttpd_do_cgi(struct conn *c); 391 392 #define CGI_REPLY "HTTP/1.1 OK\r\n" 393 #define CGI_REPLY_LEN (sizeof(CGI_REPLY) - 1) 394 395 #endif /* DEFS_HEADER_DEFINED */ 396