Commit Graph

149 Commits

Author SHA1 Message Date
Emil Mikulic
1623dee16a Initial revision - this and the source are the only files in the 1.0
tarball.
2013-04-28 19:44:12 +10:00
Emil Mikulic
6ab21a586e . Don't expect user to define NDEBUG. 2013-04-28 19:44:12 +10:00
Emil Mikulic
761462e4e5 . __sun__ -> __sun since Sun's CC doesn't use the former. 2013-04-28 19:44:12 +10:00
Emil Mikulic
7df4b55839 . Fix chomp()'s checking of empty strings. 2013-04-28 19:44:12 +10:00
Emil Mikulic
c58880c10a . Added third BSD clause.
. Got rid of Solaris hint - it belongs in the README.
. Got rid of a tab.
2013-04-28 19:44:12 +10:00
Emil Mikulic
b175db347d . Added --accf instead of compile-time NO_ACCEPTFILTER.
. Fixed const issues in dlent_cmp().
. Fixed uninitialized from/to warning.
2013-04-28 19:44:12 +10:00
Emil Mikulic
36f027c8c8 Fix two memory leaks. 2013-04-28 19:44:12 +10:00
Emil Mikulic
a4be99dc3f . USE_ACCEPTFILTER -> NO_ACCEPTFILTER and document it. 2013-04-28 19:44:11 +10:00
Emil Mikulic
a0dddaf19a . Add USE_ACCEPTFILTER knob.
. debugf() sweep - turn non-verbose ones into printf()s
2013-04-28 19:44:11 +10:00
Emil Mikulic
3f6c57ca70 -DNDEBUG 2013-04-28 19:44:11 +10:00
Emil Mikulic
a4347fa196 . Added BSD license.
. Version is now 1.0.
. Display [!]NDEBUG in --version output.
2013-04-28 19:44:11 +10:00
Emil Mikulic
01f231eaea . -O won't hurt, and it catches uninitialized vars. 2013-04-28 19:44:11 +10:00
Emil Mikulic
3e378caaf0 . Implemented apbuf API.
. Reworked generate_dir_listing() to use apbuf - much nicer now.
2013-04-28 19:44:11 +10:00
Emil Mikulic
2776f8c35e . Cosmetics in mime_mapping_cmp().
. Added make_sorted_dirlist(), cleanup_sorted_dirlist().
. generate_dir_listing() works better and produces sorted output, but
  still looks awful.
2013-04-28 19:44:11 +10:00
Emil Mikulic
3dbf2f15b4 . Got rid of pretty top-of-file.
. Moved $Id$ into static rcsid[].
. Preened TODO list.
. Removed LIST_EMPTY() - it wasn't being used.
. Got rid of "mapping x -> y" debugf.
. Move exit() out of usage() and into caller to make program flow more
  obvious.
. Added --version handling that prints rcsid.
2013-04-28 19:44:11 +10:00
Emil Mikulic
fb2e40cae5 . Added file_exists().
. Added skeleton for generate_dir_listing().
. Tied it into process_get().
2013-04-28 19:44:11 +10:00
Emil Mikulic
917e7a2cc4 . De-constify offset for Linux. 2013-04-28 19:44:11 +10:00
Emil Mikulic
132757b8fe . Do a non-blocking open and only stat once. 2013-04-28 19:44:11 +10:00
Emil Mikulic
7abf59ea32 . Removed test_make_safe_uri(). 2013-04-28 19:44:11 +10:00
Emil Mikulic
19f70a46a9 . Added xclose().
. Changed reply_file from FILE to a file descriptor - using regular
  syscalls instead of stdio f* calls.
2013-04-28 19:44:11 +10:00
Emil Mikulic
6312e230fb . Implement chroot. 2013-04-28 19:44:11 +10:00
Emil Mikulic
45ac8883e0 . Correct order of checking name and id for --uid and --gid. 2013-04-28 19:44:11 +10:00
Emil Mikulic
7ef872fd6a Added handling of --uid. 2013-04-28 19:44:11 +10:00
Emil Mikulic
b5f0992e7e . Added str_to_num().
. Added handling of --uid.
2013-04-28 19:44:11 +10:00
Emil Mikulic
b2b6d75a05 . In NDEBUG, safefree() is just free().
. Originally there were three places where a pointer was NULL'd after
  being freed.  One of these is actually important, so annotate it.
2013-04-28 19:44:11 +10:00
Emil Mikulic
7014380256 Cosmetics. 2013-04-28 19:44:11 +10:00
Emil Mikulic
850543f7d6 . Patch up a leak by freeing target when needed. 2013-04-28 19:44:11 +10:00
Emil Mikulic
832851b83d . Add safefree(x) macro to set x to NULL after freeing. 2013-04-28 19:44:11 +10:00
Emil Mikulic
e74bb5a077 . Added redirect().
. Moved 404 reply up to stat() section.
. Redirect /dir to /dir/
. Separate permissions (403 Forbidden) from other fopen() failures
  (500 Internal Server Error)
2013-04-28 19:44:11 +10:00
Emil Mikulic
eee798c571 . stat() the file before opening it to avoid opening FIFOs, sockets, etc. 2013-04-28 19:44:11 +10:00
Emil Mikulic
db6517c62d . Use goto instead of code duplication. 2013-04-28 19:44:11 +10:00
Emil Mikulic
5563889b66 Make keep_alive() a macro instead of a tiny function. 2013-04-28 19:44:11 +10:00
Emil Mikulic
df4f6910de send_from_file(): Use sendfile() on Linux. 2013-04-28 19:44:11 +10:00
Emil Mikulic
8f4a5e6b60 . Split file sending into send_from_file().
. Optimize it with sendfile() on FreeBSD.
2013-04-28 19:44:11 +10:00
Emil Mikulic
e127c6acda make_safe_uri() improvements.
. Strip out debugging.
. Fix (elements == 0) returning an empty string.
2013-04-28 19:44:11 +10:00
Emil Mikulic
b082fa213f Faster, simpler, not yet completely correct reimplementation of
make_safe_uri().  It still has a lot of debugging cruft inside.
2013-04-28 19:44:11 +10:00
Emil Mikulic
b2f504f975 . Add consolidate_slashes().
. make_safe_uri() may modify the URI string given to it.
. SAFE() and UNSAFE() don't pass const strings to make_safe_uri().
2013-04-28 19:44:11 +10:00
Emil Mikulic
41d2f5867a Solaris compatibility fixes.
. INADDR_NONE is -1
. Change bindport to an unsigned short (ntohs implies short).
. Conditionally implement our own errx() and err().
. Conditionally use a custom vasprintf() that depends on vsnprintf().
2013-04-28 19:44:11 +10:00
Emil Mikulic
466de20e2e . Cosmetics. 2013-04-28 19:44:11 +10:00
Emil Mikulic
255a78d0c4 . strip_endslash() should not have been reallocating argv[1]
. Remove strip_endslash() by boiling it down to one line and putting
  that line where the function call used to be.
2013-04-28 19:44:11 +10:00
Emil Mikulic
f7c0995234 . Don't need to nonblock the listening socket.
. Use acceptfilter.
2013-04-28 19:44:11 +10:00
Emil Mikulic
f0766d80f3 . Don't kill the whole server if recv() error occurs.
. Set conn_close to 1 on error to ensure connection closure.
2013-04-28 19:44:11 +10:00
Emil Mikulic
376c8b29fb . Make parse_request return int so it can return failure on malformed
requests.
. Make it bomb out on malformed requests like "moo\r\n\r\n"
2013-04-28 19:44:10 +10:00
Emil Mikulic
00fea650ed . IDLETIME -> idletime
. Construct keep_alive_field from idletime.
. Send keep_alive_field when there's no `Connection: close'
2013-04-28 19:44:10 +10:00
Emil Mikulic
dd4a217817 Fix conn->close logic:
. HTTP/1.1 protocol enables keep-alive.
. `Connection: keep-alive' enables keep-alive, regardless of protocol.
. `Connection: close' disables keep-alive.
2013-04-28 19:44:10 +10:00
Emil Mikulic
3389cc39d4 . Keep-alive connections work now.
. free_connection() now calls log_connection() for us.
. keepalive_connection() -> recycle_connection().
. recycle_connection() calls free_connection() (results in logging).
. Don't reset conn->client in recycle.
. Before main select loop, recycle keep-alive DONE connections.
2013-04-28 19:44:10 +10:00
Emil Mikulic
a07492c1a8 . In poll_send_{header,reply}(), don't bother deallocating stuff that
free_connection will deallocate anyway.
2013-04-28 19:44:10 +10:00
Emil Mikulic
2080b05d4c Starting work on Keep-Alive:
. Added conn_close to struct connection.
  0 = Keep-Alive, 1 = Connection: close
. Added keepalive_connection() for recycling connection structs.
. Made "Connection: close\r\n" in reply headers optional.
. If protocol is HTTP/1.1, use Keep-Alive, unless Connection: close is
  given in the request.

Offtopic:
. Improved request parsing - allow extraneous spaces.
2013-04-28 19:44:10 +10:00
Emil Mikulic
1e3b874dca Import LIST_FOREACH_SAFE macro from FreeBSD. 2013-04-28 19:44:07 +10:00
Emil Mikulic
34db7c9e68 . Traditional C sucks. 2013-04-28 19:40:39 +10:00
Emil Mikulic
f246f24acb . Remove expand_tilde().
. Remove commented-out SIGINT/SIGQUIT handling.
2013-04-28 19:40:39 +10:00
Emil Mikulic
e70a830c2c . Add TODO reminders.
. Optimize string reassembly in make_safe_uri().
2013-04-28 19:40:39 +10:00
Emil Mikulic
8a05f349d8 . Fix assertions in split_string().
. Don't split_string() outside of the string in make_safe_uri()
. Added test_make_safe_uri(), called from main()
2013-04-28 19:40:39 +10:00
Emil Mikulic
f65f8520a0 . More assertions in split_string().
. Make some empty for() loops more obvious.
. Missed a 0 -> '\0' last time.
. err(EXIT_FAILURE, ...) -> err(1, ...) to retain existing style.
. Annotate default_extension_map[] - it must be NULL terminated.
. Don't expand_tilde() -- unsure about this.
2013-04-28 19:40:39 +10:00
Emil Mikulic
9988849ea7 Change 0 to '\0' in a character context. 2013-04-28 19:40:33 +10:00
Emil Mikulic
813d4463bc . Add read_line() and chomp().
. Greatly simplify parse_extension_map_file().
2013-04-28 19:40:21 +10:00
Emil Mikulic
a4740dfda2 . Uncast xmalloc() and xrealloc() returns.
. Changed `#if IDLETIME' to `if (IDLETIME)' - it will be
  optimized away by the compiler.
. Some casts and an int->size_t change to keep splint happy about
  integer types.
2013-04-28 19:40:02 +10:00
Emil Mikulic
b1b9432123 Changes to comments that have been waiting since Aug 4 07:54. 2013-04-28 19:30:35 +10:00
Emil Mikulic
6bb5b5af42 . Make mime_map a sorted array instead of a LIST_.
. Added add_mime_mapping() to add to mime_map in unsorted order.
. Added sort_mime_map() - uses qsort() and mime_mapping_cmp() to sort
  the mime_map.
. uri_content_type() uses bsearch() and mime_mapping_cmp_str() to search
  through the mime_map for an extension parsed out of a specified URI.
. Free mime_map in exit_quickly()
. Completely deallocate connlist in exit_quickly()
. In main(), parse_commandline() after parse_default_extension_map() so
  that a specified --mimetypes file will -override- the defaults.
2013-04-28 19:30:35 +10:00
Emil Mikulic
f56dcd2b76 Borged parts of sys/queue.h since non-BSDs don't have the header. 2013-04-28 19:30:35 +10:00
Emil Mikulic
9d6d7533fe . Linux needs _GNU_SOURCE defined.
. bindport is uint16_t like in Linux.
. Fix a bounds error in make_safe_uri().
. Remember to free temporaries in make_safe_uri().
. Free if_mod_since in process_get()
. Set reply_file to NULL after closing it in poll_send_reply() to avoid
  double fclose() in free_connection().
. Don't log connections with http_code == 0; these are connections that
  failed while receiving the request string.
. Initialise timeout more cleanly in httpd_poll().
. Made MAX_FD_SET use a { block } to keep gcc 3 happy.
. Don't free items in a LIST_FOREACH() block; use a temporary next
  pointer and LIST_NEXT().
. exit_quickly() closes logfile if it's open.
. exit_quickly() doesn't re-throw the signal that triggered it.
2013-04-28 19:30:35 +10:00
Emil Mikulic
d7bfc32d6d . Partial content is done, mark off TODO.
. Decrease send BUFSIZE to 40,000 (max I've seen is 33,000).
. Remove a debugf() from poll_send_reply().
. Add exit_quickly().
. SIGINT and SIGQUIT exit_quickly().
2013-04-28 19:30:35 +10:00
Emil Mikulic
67604878ec . Initialise range_* in struct connection.
. Added reply_start to struct connection.
. Added debugf() to free_connection().
. Construct HTTP 206 reply if Range specified.
. Take reply_start into consideration in poll_send_reply().
. Added fread() error handling - eof is non-fatal.
2013-04-28 19:30:35 +10:00
Emil Mikulic
295cd40bbb int type fixes to keep splint happy. 2013-04-28 19:30:35 +10:00
Emil Mikulic
7090baae35 . Added range fields to struct connection.
. Added sanity check in split_string(): left <= right
. Implemented parse_range_field()
2013-04-28 19:30:35 +10:00
Emil Mikulic
6ee7a85231 . Got rid of conn->lastmod field.
. rfc1123_date() takes a destination buffer instead of having the one,
  static, global buffer.
2013-04-28 19:30:35 +10:00
Emil Mikulic
6e0103cbc4 Fiddling with signed-ness and types to make splint happy. 2013-04-28 19:30:35 +10:00
Emil Mikulic
0c1ff8a258 Cleared up parse_field() synopsis. 2013-04-28 19:30:35 +10:00
Emil Mikulic
3dc4ce1216 . Made all sockets non-blocking
. Used simpler way of ignoring SIGPIPE
. Made sure closed sockets aren't written to
2013-04-28 19:30:35 +10:00
Emil Mikulic
70cbd12463 . Tested If-Modified-Since functionality
. Update last_active so connections don't time out
  (this also tested out the timeout functionality)
. Sprinkling of debugf()s
2013-04-28 19:30:35 +10:00
Emil Mikulic
ce7cfceabb Worked out warning flags from gcc manpage 2013-04-28 19:30:35 +10:00
Emil Mikulic
0d755c3618 . Added ogg mimetype
. Added xvasprintf()
. Added xasprintf()
. Some signed/unsigned clarifications
. Simplified asprintf() error handling using xasprintf()
. Check for failure of signal()
2013-04-28 19:30:35 +10:00
Emil Mikulic
5a6c7cf08e . Added lastmod (reply, not request) to struct connection
. Added xstrdup()
. Made expand_tilde use xstrdup() instead of strdup() (whoops)
. process_get() now handles "If-Modified-Since:"
. lastmod is generated before Date: so that only one asprintf() is
  needed to construct the header in process_get()
2013-04-28 19:30:35 +10:00
Emil Mikulic
72d0b5b301 . Use reasm instead of checking for a NULL reassembly element (safer) 2013-04-28 19:30:35 +10:00
Emil Mikulic
ce5eaa9f94 . Made split_string() return a string instead of taking char **dest
. Added make_safe_uri()
. Modified split_string() calls to match new prototype
. process_get() uses make_safe_uri() to prevent walking out of wwwroot
. free(target) AFTER we finish using it in process_get (whoops)
2013-04-28 19:30:35 +10:00
Emil Mikulic
5c0c18798c . Content-Type is now derived from mime_map
. Reordered default_extension_map[] for search speed
. Added uri_content_type()
. process_get() calls uri_content_type() when needed
. Removed a couple of debugf()s from process_request
2013-04-28 19:30:35 +10:00
Emil Mikulic
7a2daecf22 . Added debugf() to parse_mimetype_line()
. Added parse_extension_map_file()
. Added --mimetypes to usage() and parse_commandline()
2013-04-28 19:30:35 +10:00
Emil Mikulic
a0d608d1e3 . Added LIST mime_map
. Added struct mime_mapping
. Added default_extension_map[]
. Moved xmalloc() to top of file
. Added split_string()
. Added parse_mimetype_line()
. Added parse_default_extension_map()
. Made new_connection(), parse_request() use split_string()
. Comment in log_connection(): client -> client_ip
2013-04-28 19:30:35 +10:00
Emil Mikulic
d6b7871ade . TODO: dir entries -> dir listings
. TODO: minor cleanup
. --help as first parameter results in usage()
2013-04-28 19:30:35 +10:00
Emil Mikulic
7c29be2b7d . Added referer, user_agent to struct connection
. Moved xrealloc() to top of file
. Added parse_field()
. parse_request() calls parse_field() for referer, ua
. Logfile is opened in append mode, not write mode
. strip_endslash() calls xrealloc(), not realloc()
2013-04-28 19:30:35 +10:00
Emil Mikulic
aa2245e867 . Added expand_tilde()
. Added strip_endslash()
. wwwroot gets its tilde expanded and trailing slash clipped off
2013-04-28 19:30:35 +10:00
Emil Mikulic
f5703a9c82 . Added TODO entries
. Minor whitespace fixes
2013-04-28 19:30:35 +10:00
Emil Mikulic
09d69063bd . Ignoring SIGPIPE
. httpd_poll()'s select() will timeout after IDLETIME seconds if
  there are any connections currently in a send/recv state
2013-04-28 19:30:35 +10:00
Emil Mikulic
4456c044e5 . Implemented logging to file
. Moved parse_request's {method|url} to conn->{method|uri}
. Added http_code, total_sent to struct connection
. Added out-of-memory checks on a few asprintf()s
. Added assert()s where I tripped up before or could again
. Added log_connection()
. Open logfile from logfile_name in main()
2013-04-28 19:30:35 +10:00
Emil Mikulic
02964cc5a6 . TODO: Added If-Modified-Since
. TODO: Marked off Actually serve files
. Added min(a,b) macro
. Moved header_only from process_get() to struct connection
. MAX_REQUEST_LENGTH from 20000 to 4000
. xrealloc() to strlen+1 in urldecode()
. Made default_reply() take variable arguments like printf
. Mostly implemented process_get()
    . Handling of file-not-found
    . Handling of other fopen() errors
    . Header generation (except Content-Type)
. Made default_replies more specific
. poll_send_header() advances state to DONE if header_only
. Completed poll_send_reply() (implemented REPLY_FROMFILE)
2013-04-28 19:30:35 +10:00
Emil Mikulic
32b3855aeb . Added SIGPIPE ignoring to TODO
. Clear reply_sent and reply_length in new_connection()
  This was causing a bug that couldn't be seen on the first web request.
. Added urldecode()
. Started work on process_get()
2013-04-28 19:30:35 +10:00
Emil Mikulic
0615eb6a88 . Added to TODO list
. Default value for sockin is -1
. Added index_name default, parsing of --index, usage of --index
. Dereference char **method when passing to strntoupper()
2013-04-28 19:30:35 +10:00
Emil Mikulic
98c9fd318e . Added TODO list
. Changed a comment
2013-04-28 19:30:35 +10:00
Emil Mikulic
b959c6bc3a . Added strntoupper()
. rfc1123_date() now takes a time_t argument
. default_reply() now takes a `reason' string
. Skeleton process_get()
. Implemented process_request() completely (for now) (I hope)
. Changed oversized request error from 400 Bad Request
  to 413 Request Entity Too Large
2013-04-28 19:30:34 +10:00
Emil Mikulic
fd0a618d34 Initial implementation of parse_request() 2013-04-28 19:30:28 +10:00
Emil Mikulic
3759104f07 . Added rfc1123_date() and Date: header field to default_reply()
. Skeleton for parse_request()
2013-04-28 19:21:12 +10:00
Emil Mikulic
9074924be5 . Added MAX_REQUEST_LENGTH and a check for it in poll_recv_request()
. Fixed comment DEFAULT_PORT -> bindport
. "options:\n" -> "options:\n\n"
2013-04-28 19:21:12 +10:00
Emil Mikulic
cb3342472b . default_reply() ensures reply_type is REPLY_GENERATED
. Implemented poll_send_header()
. Partial implementation of poll_send_file() - can't send FROMFILE yet
2013-04-28 19:21:12 +10:00
Emil Mikulic
23b191239e . Added to struct connection:
o in_addr_t client
	o time last_active
	o {header,reply}_dont_free
. Added IDLETIME and poll_check_timeout()
. Added new_connection() and moved conn initialisation there
. Added default_reply()
. Skeleton for process_request()
. connnection.request is now null-terminated
. Removed debug code from poll_recv_request()
2013-04-28 19:21:12 +10:00
Emil Mikulic
ebe1e1bfa0 . Added LIST (sys/queue.h) of struct connection
. Added xmalloc()
. Filled out accept_connection()
. Added free_connection()
. Added xrealloc()
. Started poll_recv_request()
. Skeletons for poll_send_header(), poll_send_reply()
. Filled out httpd_poll()
2013-04-28 19:21:12 +10:00
Emil Mikulic
345c214212 . Added struct connection
. Skeleton accept_connection()
. Incomplete httpd_poll()
2013-04-28 19:21:12 +10:00
Emil Mikulic
7a8ff37bb3 . Changed argument --bind' -> --addr'
. Implemented arg parsing for port, addr, maxconn, log, chroot
. init_sockin() prints the addr:port that sockin is bound to
2013-04-28 19:21:12 +10:00
Emil Mikulic
79e52dfae2 . Moved pkgname, copyright to top of file to avoid having to duplicate
it in the comments.
. Got rid of DEFAULT_* defines in favour of initializers.
. Moved existing socket creation code to init_sockin().
. Added usage(). [needs work]
. Added parse_commandline() skeleton. [needs a lot of work]
2013-04-28 19:21:12 +10:00
Emil Mikulic
26aeb38a81 Initial revision - open and close a socket. 2013-04-28 19:21:00 +10:00