defs.h 12 KB

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