diff options
-rw-r--r-- | doc/quickstart.html | 37 | ||||
-rw-r--r-- | doc/tipidee.conf.html | 42 | ||||
-rw-r--r-- | src/config/defaults.c | 2 | ||||
-rw-r--r-- | src/config/lexparse.c | 81 | ||||
-rw-r--r-- | src/tipideed/tipideed.c | 2 |
5 files changed, 104 insertions, 60 deletions
diff --git a/doc/quickstart.html b/doc/quickstart.html index f9627f5..312b87f 100644 --- a/doc/quickstart.html +++ b/doc/quickstart.html @@ -103,6 +103,43 @@ your service manager scripts. </li> containing service files to run tipidee under various service managers. </p> +<div id="caveats"> +<h2> Caveats </h2> +</div> + +<h3> <tt>Host</tt> support in HTTP/1.0 </h3> + +<p> + A strict reading of the +<a href="https://datatracker.ietf.org/doc/html/rfc1945">HTTP/1.0 specification</a> +says that the Request-Line is the only piece of client-provided data that can +be used to identify a resource, and that extension headers can modify the +interpretation and processing of that resource but not <em>change</em> what +resource is served. +</p> + +<p> + This goes directly against the use of the <tt>Host</tt> header to identify +the host of a resource and that is used in HTTP/1.1. +</p> + +<p> + A lot of HTTP servers out there don't really care about that, and have +historically used <tt>Host</tt> to perform virtual hosting even in HTTP/1.0, +even though it goes against the specification. Consequently, clients have +adapted, and +<a href="https://github.com/curl/curl/issues/5976">even the popular +<tt>curl</tt> client</a> sends a <tt>Host</tt> header in HTTP/1.0. +</p> + +<p> + Since the point of the Web is interoperability, tipidee aligns with +the common practice, and will read a client-provided <tt>Host</tt> header, +if any, to determine what domain the request is directed to, even in +HTTP/1.0 though it is contrary to the specification. I refer to this +practice as "HTTP/1.05". +</p> + <div id="faq"> <h2> Frequently asked questions </h2> </div> diff --git a/doc/tipidee.conf.html b/doc/tipidee.conf.html index 10de524..7ead60f 100644 --- a/doc/tipidee.conf.html +++ b/doc/tipidee.conf.html @@ -139,14 +139,20 @@ directive! </li> </ul> <div id="global"> -<h3> Global directives </h3> +<h3> Simple global settings </h3> </div> <p> Global directives control global aspects of <a href="tipideed.html">tipideed</a> — values that apply to the server itself, no matter what domain it is -serving. The directive name is <tt>global</tt>, and it takes two arguments: the -name and the value of a setting. +serving. + +<p> + Some global directives are introduced by their own keywords, see below. +Others are simple configuration values that would clutter up the +directive namespace, so we put them together under a unique umbrella, +the <tt>global</tt> directive. +<tt>global</tt> takes two arguments: the name of a setting and its value. </p> <div id="read_timeout"> @@ -270,20 +276,25 @@ output data. And this is "private dirty" memory, i.e. memory that that setting — and with the CGI scripts you choose to run. </li> </ul> -<div id="index_file"> -<h4> <tt>index_file</tt> </h4> +<div id="index-file"> +<h3> The <tt>index-file</tt> directive </h3> </div> <p> - <code> global index_file <em>file1</em> <em>file2</em> ... </code> + <code> index-file <em>file1</em> <em>file2</em> ... </code> +</p> + +<p> + <tt>index-file</tt> is a global directive, the first one in this +list that is introduced by its own keyword and does not use <tt>global</tt>. </p> <ul> - <li> The <tt>global index_file</tt> directive has a variable number of + <li> The <tt>index-file</tt> directive has a variable number of arguments. <em>file1</em>, <em>file2</em>, and so on are the names of the files that should be used to try and complete the URI when a client request resolves to a directory. </li> - <li> For instance: <tt>global index_file index.cgi index.html index.htm</tt> + <li> For instance: <tt>index-file index.cgi index.html index.htm</tt> means that when <a href="tipideed.html">tipideed</a> is asked to serve <tt>http://example.com</tt>, it will first try to serve as if the request had been <tt>http://example.com/index.cgi</tt>, then @@ -295,7 +306,7 @@ resources exist, <a href="tipideed.html">tipideed</a> responds 404 (Not Found). <tt>http://example.com/foo/index.cgi</tt>, then (if not found) <tt>http://example.com/foo/index.html</tt>, then (if not found) <tt>http://example.com/foo/index.htm</tt>. </li> - <li> The default is <tt>global index_file index.html</tt>, meaning that + <li> The default is <tt>index-file index.html</tt>, meaning that only the <tt>index.html</tt> file will be looked up when a resource resolves to a directory. </li> </ul> @@ -305,9 +316,8 @@ to a directory. </li> </div> <p> - <tt>log</tt> is also a global directive, but is introduced by the -keyword <tt>log</tt>, without prepending <tt>global</tt>. It allows -the user to control what will appear in + <tt>log</tt> is a global directive, introduced by the +keyword <tt>log</tt>. It allows the user to control what will appear in <a href="tipideed.html">tipideed</a>'s log output. </p> @@ -409,8 +419,8 @@ This keyword has no effect when given without the <tt>answer</tt> keyword. </dd> </div> <p> - <tt>content-type</tt> is also a global directive, but is introduced by the -keyword <tt>content-type</tt>, without prepending <tt>global</tt>. It allows + <tt>content-type</tt> is a global directive, introduced by the +keyword <tt>content-type</tt>. It allows the user to define mappings from a document's extension to a standard Content-Type. </p> @@ -435,8 +445,8 @@ serving files with uncommon extensions or have specific needs. </li> </div> <p> - <tt>custom-header</tt> is also a global directive, but is introduced by the -keyword <tt>custom-header</tt>, without prepending <tt>global</tt>. It allows + <tt>custom-header</tt> is global directive, introduced by the +keyword <tt>custom-header</tt>. It allows the user to define custom headers that are to be added to every response. </p> diff --git a/src/config/defaults.c b/src/config/defaults.c index 3db2ad2..dfc13f2 100644 --- a/src/config/defaults.c +++ b/src/config/defaults.c @@ -23,7 +23,7 @@ static struct defaults_s const defaults[] = RECU32("G:cgi_timeout", 0), RECU32("G:max_request_body_length", 8192), RECU32("G:max_cgi_body_length", 4194304), - RECS("G:index_file", "index.html"), + RECS("G:index-file", "index.html"), RECU32("G:logv", TIPIDEE_LOG_DEFAULT), RECS("T:html", "text/html"), diff --git a/src/config/lexparse.c b/src/config/lexparse.c index 783e39f..650e8a1 100644 --- a/src/config/lexparse.c +++ b/src/config/lexparse.c @@ -2,6 +2,7 @@ #include <stdint.h> #include <string.h> +#include <stdlib.h> #include <errno.h> #include <skalibs/uint32.h> @@ -26,13 +27,6 @@ struct mdt_s } ; #define MDT_ZERO { .filepos = 0, .line = 0, .linefmt = "0" } -struct globalkey_s -{ - char const *name ; - char const *key ; - uint32_t type ; -} ; - struct logkey_s { char const *name ; @@ -43,6 +37,7 @@ enum token_e { T_BANG, T_GLOBAL, + T_INDEXFILE, T_LOG, T_CONTENTTYPE, T_CUSTOMHEADER, @@ -98,47 +93,45 @@ static void add_unique (char const *key, char const *value, size_t valuelen, mdt static inline void parse_global (char const *s, size_t const *word, size_t n, mdt const *md) { - static struct globalkey_s const globalkeys[] = + static char const *const globalkeys[] = { - { .name = "cgi_timeout", .key = "G:cgi_timeout", .type = 0 }, - { .name = "index_file", .key = "G:index_file", .type = 1 }, - { .name = "max_cgi_body_length", .key = "G:max_cgi_body_length", .type = 0 }, - { .name = "max_request_body_length", .key = "G:max_request_body_length", .type = 0 }, - { .name = "read_timeout", .key = "G:read_timeout", .type = 0 }, - { .name = "write_timeout", .key = "G:write_timeout", .type = 0 } + "cgi_timeout", + "max_cgi_body_length", + "max_request_body_length", + "read_timeout", + "write_timeout" } ; - struct globalkey_s const *gl ; - if (n < 2) - strerr_dief8x(1, "too ", "few", " arguments to directive ", "global", " in file ", g.storage.s + md->filepos, " line ", md->linefmt) ; - gl = BSEARCH(struct globalkey_s, s + word[0], globalkeys) ; - if (!gl) strerr_dief6x(1, "unrecognized global setting ", s + word[0], " in file ", g.storage.s + md->filepos, " line ", md->linefmt) ; - switch (gl->type) + char const *const *x ; + uint32_t u ; + char pack[4] ; + if (n != 2) + strerr_dief8x(1, "too ", n < 2 ? "few" : "many", " arguments to directive ", "global", " in file ", g.storage.s + md->filepos, " line ", md->linefmt) ; + x = BSEARCH(char const *, s + word[0], globalkeys) ; + if (!x) strerr_dief6x(1, "unrecognized global setting ", s + word[0], " in file ", g.storage.s + md->filepos, " line ", md->linefmt) ; + if (!uint320_scan(s + word[1], &u)) + strerr_dief6x(1, "invalid (non-numeric) value for global setting ", s + word[0], " in file ", g.storage.s + md->filepos, " line ", md->linefmt) ; + uint32_pack_big(pack, u) ; { - case 0 : /* 4 bytes */ - { - char pack[4] ; - uint32_t u ; - if (n > 2) - strerr_dief8x(1, "too ", "many", " arguments to global setting ", s + word[0], " in file ", g.storage.s + md->filepos, " line ", md->linefmt) ; - if (!uint320_scan(s + word[1], &u)) - strerr_dief6x(1, "invalid (non-numeric) value for global setting ", s + word[0], " in file ", g.storage.s + md->filepos, " line ", md->linefmt) ; - uint32_pack_big(pack, u) ; - add_unique(gl->key, pack, 4, md) ; - break ; - } - case 1 : /* argv */ - { - node node ; - conftree_checkunique(gl->key, md) ; - confnode_start(&node, gl->key, md->filepos, md->line) ; - for (size_t i = 1 ; i < n ; i++) - confnode_add(&node, s + word[i], strlen(s + word[i]) + 1) ; - conftree_add(&node) ; - break ; - } + size_t len = strlen(*x) ; + char key[len + 3] ; + memcpy(key, "G:", 2) ; + memcpy(key + 2, *x, len + 1) ; + add_unique(key, pack, 4, md) ; } } +static inline void parse_indexfile (char const *s, size_t const *word, size_t n, mdt const *md) +{ + node node ; + if (!n) + strerr_dief8x(1, "too ", "few", " arguments to directive ", "index_file", " in file ", g.storage.s + md->filepos, " line ", md->linefmt) ; + conftree_checkunique("G:index-file", md) ; + confnode_start(&node, "G:index-file", md->filepos, md->line) ; + for (size_t i = 0 ; i < n ; i++) + confnode_add(&node, s + word[i], strlen(s + word[i]) + 1) ; + conftree_add(&node) ; +} + static inline void parse_log (char const *s, size_t const *word, size_t n, mdt const *md) { static struct logkey_s const logkeys[] = @@ -387,6 +380,7 @@ static inline void process_line (char const *s, size_t const *word, size_t n, st { .s = "domain", .token = T_DOMAIN }, { .s = "file-type", .token = T_FILETYPE }, { .s = "global", .token = T_GLOBAL }, + { .s = "index-file", .token = T_INDEXFILE }, { .s = "log", .token = T_LOG }, { .s = "no-auth", .token = T_NOAUTH }, { .s = "noncgi", .token = T_NONCGI }, @@ -421,6 +415,9 @@ static inline void process_line (char const *s, size_t const *word, size_t n, st case T_GLOBAL : parse_global(s, word, n, md) ; break ; + case T_INDEXFILE : + parse_indexfile(s, word, n, md) ; + break ; case T_LOG : parse_log(s, word, n, md) ; break ; diff --git a/src/tipideed/tipideed.c b/src/tipideed/tipideed.c index aef608b..da4724b 100644 --- a/src/tipideed/tipideed.c +++ b/src/tipideed/tipideed.c @@ -393,7 +393,7 @@ int main (int argc, char const *const *argv, char const *const *envp) g.maxrqbody = get_uint32("G:max_request_body_length") ; g.maxcgibody = get_uint32("G:max_cgi_body_length") ; g.logv = get_uint32("G:logv") ; - n = tipidee_conf_get_argv(&g.conf, "G:index_file", g.indexnames, 16, &g.indexlen) ; + n = tipidee_conf_get_argv(&g.conf, "G:index-file", g.indexnames, 16, &g.indexlen) ; if (!n) strerr_dief3x(102, "bad", " config value for ", "G:index_file") ; g.indexn = n-1 ; |