summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2023-10-24 14:12:19 +0000
committerLaurent Bercot <ska@appnovation.com>2023-10-24 14:12:19 +0000
commit713994fd2c7a6da9e69222695e7d7a1e963312f8 (patch)
tree296d3df0b1b3c403df7377a3c7ca795bc8fa7648
parent4bd3cae342a3c29adef0c46a205d7e3b9bca7214 (diff)
downloadtipidee-713994fd2c7a6da9e69222695e7d7a1e963312f8.tar.xz
Deglobal index-file
Signed-off-by: Laurent Bercot <ska@appnovation.com>
-rw-r--r--doc/quickstart.html37
-rw-r--r--doc/tipidee.conf.html42
-rw-r--r--src/config/defaults.c2
-rw-r--r--src/config/lexparse.c81
-rw-r--r--src/tipideed/tipideed.c2
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>
&mdash; 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 &mdash; 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 ;