shithub: tcp80

ref: f423629013854dfd09b37ce2f1c7ba637df8a541
dir: /README.html/

View raw version
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>tcp80 README</title>
</head>
<body>
<style type="text/css">body{width: 50rem; max-width: 96%; margin: 0 auto;}pre{border: 1px solid;}</style>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="margin-top: 0; margin-bottom: 0.50in"></p>
<p style="line-height: 1.2em; text-indent: 0.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<header><h1><span style="font-size: 12pt"><b>tcp80 README
</b></span></h1><span style="font-size: 12pt"><b></b></span><span style="font-size: 10pt"><b></b></span><span style="font-size: 10pt"></span></header></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="line-height: 1.2em; text-indent: 0.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<header><span style="font-size: 10pt"><b>What is tcp80?
</b></span></header></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>

<p style="line-height: 1.2em; text-indent: 0.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">tcp80 is an HTTP daemon originally written by cinap_lenrek, and then forked
by several people, to include kvik, phil9, and myself. This fork is a
combination of kvik and phil9&rsquo;s ports, which includes phil9&rsquo;s integration of
execfs, and a functional MIME type system to send the correct Content-Type
headers that modern browsers insist upon.
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>

<p style="line-height: 1.2em; text-indent: 0.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">Other features in this fork include the ability to redirect error pages so
can use your own, usually generated dynamically using the built-in execfs,
and the ability to serve different content based on the Host header sent by
the client.
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>

<p style="line-height: 1.2em; text-indent: 0.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">This server is also entirely capable of running
<a href="https://shithub.us/garden/shithub/HEAD/info.html">shithub</a> using the built-in execfs.
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>

<p style="line-height: 1.2em; text-indent: 0.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">Running a basic tcp80 setup is very simple, and requires only one file, and
one directory.
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>

<p style="line-height: 1.2em; text-indent: 0.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">First, you must ensure
</span><span style="font-size: 10pt"><tt>/usr/web</tt></span><span style="font-size: 10pt">
exists, and world readable/executable. Once this requirement is met, you need
only create the world readable/executable file
</span><span style="font-size: 10pt"><tt>/rc/bin/service/tcp80</tt></span><span style="font-size: 10pt">
with contents:
<pre><code>#!/bin/rc
exec /bin/tcp80
</code></pre></span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>

<p style="line-height: 1.2em; text-indent: 0.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">This is sufficient for serving static files, and uses none of the advanced
features available.
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>

<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="line-height: 1.2em; text-indent: 0.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<h2><span style="font-size: 10pt"><b>Advanced Features
</b></span><span style="font-size: 10pt"></span></h2><span style="font-size: 10pt"></span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>

<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="line-height: 1.2em; text-indent: 0.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<h3><span style="font-size: 10pt"><b>Serving different static content based on request hostname
</b></span><span style="font-size: 10pt"></span></h3><span style="font-size: 10pt"></span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>

<p style="line-height: 1.2em; text-indent: 0.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">This feature requires a configuration file containing mappings, the format of
which is quite simple.
Each line contains a regex to match the hostname against, followed by at least
one tab, and a path from which to serve files, as in the following example:
<pre>server1.domain.org          /usr/webroot/server1
aardvark.different.org      /usr/webroot/aardvark
</pre></span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>

<p style="line-height: 1.2em; text-indent: 0.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">Once you have your configuration stored, you must change your
</span><span style="font-size: 10pt"><tt>/rc/bin/service/tcp80</tt></span><span style="font-size: 10pt">
script. If you use captures in the regular expression, they can be used in the
pathname section.
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>

<p style="line-height: 1.2em; text-indent: 0.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt"><pre><code>#!/bin/rc
exec /bin/tcp80 -h /sys/lib/hostrules
</code></pre></span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>

<p style="line-height: 1.2em; text-indent: 0.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">This currently does not affect the execution of execfs rules, which exist in a
single "namespace", however the configuration will likely be expanded to support
the use of different execfs rules for each hostname.
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>

<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="line-height: 1.2em; text-indent: 0.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<h3><span style="font-size: 10pt"><b>Error Page Redirection
</b></span><span style="font-size: 10pt"></span></h3><span style="font-size: 10pt"></span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>

<p style="line-height: 1.2em; text-indent: 0.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">It is possible to produce custom error pages. The normal action when tcp80
encounters a situation requiring an error response, such as a 404 Not Found,
it produces a very simple HTML snippet. This feature allows you to replace this
functionality, however, it does so in a non-standard way.
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>

<p style="line-height: 1.2em; text-indent: 0.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">Instead of allowing for the direct replacement of this snippet, it issues a
</span><span style="font-size: 10pt"><tt>303 See Other</tt></span><span style="font-size: 10pt">
response. This redirects the browser to a URL containing the error code and the
location that generated it. For example, if you were to access
</span><span style="font-size: 10pt"><tt>http://server.domain.com/nonexistent.html</tt></span><span style="font-size: 10pt">
tcp80 would redirect the client to
</span><span style="font-size: 10pt"><tt>http://server.domain.com/404/nonexistent.html</tt></span><span style="font-size: 10pt">
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>

<p style="line-height: 1.2em; text-indent: 0.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">To use this feature, you pass multiple
</span><span style="font-size: 10pt"><tt>-e</tt></span><span style="font-size: 10pt">
options to tcp80 in your
</span><span style="font-size: 10pt"><tt>/rc/bin/service/tcp80</tt></span><span style="font-size: 10pt">
script.
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>

<p style="line-height: 1.2em; text-indent: 0.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt"><pre><code>#!/bin/rc
exec /bin/tcp80 -e 404 -e 403
</code></pre></span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>

<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="line-height: 1.2em; text-indent: 0.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<h3><span style="font-size: 10pt"><b>Integrated execfs
</b></span><span style="font-size: 10pt"></span></h3><span style="font-size: 10pt"></span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>

<p style="line-height: 1.2em; text-indent: 0.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">The integrated execfs functionality is the most advanced and powerful feature
available in tcp80. Used correctly, it can provide a powerful tool for dynamic
websites. Used incorrectly, it can destroy your server, open security holes,
and probably set your house on fire while you&rsquo;re trying to fix the security.
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>

<p style="line-height: 1.2em; text-indent: 0.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">execfs uses the same configuration format as documented above, consisting of a
regex to match the pathname (instead of hostname) against, at least one tab,
and a script to run. If the regular expression contains captures, they can be
used in the script section as arguments. See the shithub
<a href="https://shithub.us/garden/shithub/HEAD/gitrules/f.html">gitrules</a> file for an example.
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>

<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="line-height: 1.2em; text-indent: 0.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<h3><span style="font-size: 10pt"><b>Common Gateway Interface
</b></span><span style="font-size: 10pt"></span></h3><span style="font-size: 10pt"></span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>

<p style="line-height: 1.2em; text-indent: 0.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">The integrated execfs functionality now also supports running applications that
rely upon the Common Gateway Interface, CGI/1.1 (RFC 3875).
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>

<p style="line-height: 1.2em; text-indent: 0.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">To use this, you need some bindings, and a rule (or rules) like the following:
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>

<p style="line-height: 1.2em; text-indent: 0.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt"><pre><code>/sys/lib/tcp80:
/cgi-bin/.*\.cgi            cgi
</code></pre></span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>

<p style="line-height: 1.2em; text-indent: 0.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt"><pre><code>/rc/bin/service/tcp80:
#!/bin/rc
aux/stub -d /cgi-bin
bind /usr/web/cgi-bin /cgi-bin
exec /bin/tcp80 -r /sys/lib/tcp80 $3 &gt;&gt;[2]/sys/log/httpd/log
</code></pre></span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>

<p style="line-height: 1.2em; text-indent: 0.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">Please note the addition of
</span><span style="font-size: 10pt"><tt>$3</tt></span><span style="font-size: 10pt">
in the
</span><span style="font-size: 10pt"><tt>exec</tt></span><span style="font-size: 10pt">
line. This lets tcp80 find the IP address of the client, which the CGI/1.1
specification requires.
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>

<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="line-height: 1.2em; text-indent: 0.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<h2><span style="font-size: 10pt"><b>An Example Configuration (for shithub)
</b></span><span style="font-size: 10pt"></span></h2><span style="font-size: 10pt"></span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>

<p style="line-height: 1.2em; text-indent: 0.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt"><pre><code>/rc/bin/service/tcp80:
#!/bin/auth/box -r/mnt -r/usr/git -r/sys/lib/ -r/usr/web -r/sys/lib/shithub -r/n -r/dev -eMa -s
&lt;[3]/srv/clone{
    d=&lsquo;{&lt;[0=3]read}
    bind /srv/$d /srv
    &lt;[3=0]{
        bind /usr/web /mnt/static
        exec /bin/tcp80 -r /sys/lib/tcp80 &gt;&gt;[2]/sys/log/httpd/log
    }
}
</code></pre></span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>

<p style="line-height: 1.2em; text-indent: 0.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt"><pre><code>/rc/bin/service/tcp443:
#!/bin/auth/box -r/mnt -r/usr/git -r/sys/lib -r/usr/web -r/sys/lib/shithub -r/n -r/dev -eMa -s
&lt;[3]/srv/clone{
    d=&lsquo;{&lt;[0=3]read}
    bind /srv/$d /srv
    &lt;[3=0]{
        bind /usr/web /mnt/static
        exec /bin/tlssrv -c/sys/lib/tls/cert.pem -lhttpd -r&lsquo;{cat $3/remote} /bin/tcp80 \
                -r /sys/lib/tcp80 &gt;&gt;[2]/sys/log/httpd/log
    }
}
</code></pre></span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>

<p style="line-height: 1.2em; text-indent: 0.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt"><pre><code>/lib/namespace.httpd:
bind /mnt/static /usr/web/static
</code></pre></span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>

<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="line-height: 1.2em; text-indent: 0.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<h2><span style="font-size: 10pt"><b>Oddities in the Documentation and Implementation
</b></span><span style="font-size: 10pt"></span></h2><span style="font-size: 10pt"></span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>

<p style="line-height: 1.2em; text-indent: 0.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">The astute among you may have noticed that we have
</span><span style="font-size: 10pt"><tt>/lib/namespace.httpd</tt></span><span style="font-size: 10pt">
but also seem to ignore it in multiple places in the documentation. This can be found in the
examples revolving around
</span><span style="font-size: 10pt"><tt>/rc/bin/service/tcp80</tt></span><span style="font-size: 10pt">.
The reason for this is quite simple;
</span><span style="font-size: 10pt"><tt>/lib/namespace.httpd</tt></span><span style="font-size: 10pt">
is used only in untrusted mode, and only for static files. Anything involving execfs or CGI
is expected to handle setting up the namespace for itself. This allows scripts full run of the
system, so their first step should always be to isolate themselves as much as possible.
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>

<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="line-height: 1.2em; text-indent: 0.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<h2><span style="font-size: 10pt"><b>Contact Information
</b></span><span style="font-size: 10pt"></span></h2><span style="font-size: 10pt"></span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>

<p style="line-height: 1.2em; text-indent: 0.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">If you find a bug, or have a patch, please feel free to send email to the tcp80
mailing list at
<a href="mailto:[email protected]">[email protected]</a> </span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>

<p style="line-height: 1.2em; text-indent: 0.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">To subscribe to the list, send an e-mail to
<a href="mailto:[email protected]">[email protected]</a> </span></p><p style="margin-top: 0; margin-bottom: 0.50in"></p>
</body>
</html>