term% ls -F
term% cat index.txt
HTTPD(2)                      System Calls Manual                     HTTPD(2)

       HConnect,  HContent, HContents, HETag, HFields, Hio, Htmlesc, HttpHead,
       HttpReq, HRange, HSPairs, hmydomain, hversion, htmlesc, halloc,  hbody‐
       push,  hbuflen,  hcheckcontent,  hclose,  hdate2sec,  hdatefmt,  hfail,
       hflush, hgetc, hgethead, hinit, hiserror,  hload,  hlower,  hmkcontent,
       hmkhfields, hmkmimeboundary, hmkspairs, hmoved, hokheaders, hparsehead‐
       ers, hparsequery, hparsereq, hprint, hputc, hreadbuf, hredirected, hre‐
       qcleanup, hrevhfields, hrevspairs, hstrdup, http11, httpfmt, httpunesc,
       hunallowed, hungetc,  hunload,  hurlfmt,  hurlunesc,  hvprint,  hwrite,
        - routines for creating an http server

       #include <u.h>
       #include <libc.h>
       #include <httpd.h>

       typedef struct HConnect HConnect;
       typedef struct HContent HContent;
       typedef struct HContents HContents;
       typedef struct HETag HETag;
       typedef struct HFields HFields;
       typedef struct Hio Hio;
       typedef struct Htmlesc Htmlesc;
       typedef struct HttpHead HttpHead;
       typedef struct HttpReq HttpReq;
       typedef struct HRange HRange;
       typedef struct HSPairs HSPairs;

       typedef struct Bin Bin;

       struct Htmlesc
                 char        *name;
                 Rune        value;

       struct HContent
                 HContent    *next;
                 char        *generic;
                 char        *specific;
                 float       q;                     /* desirability of this kind of file */
                 int         mxb;                   /* max uchars until worthless */

       struct HContents
                 HContent    *type;
                 HContent     *encoding;

        * generic http header with a list of tokens,
        * each with an optional list of parameters
       struct HFields
                 char        *s;
                 HSPairs     *params;
                 HFields     *next;

        * list of pairs a strings
        * used for tag=val pairs for a search or form submission,
        * and attribute=value pairs in headers.
       struct HSPairs
                 char        *s;
                 char        *t;
                 HSPairs     *next;

        * byte ranges within a file
       struct HRange
                 int         suffix;                /* is this a suffix request? */
                 ulong       start;
                 ulong       stop;                  /* ~0UL -> not given */
                 HRange      *next;

        * list of http/1.1 entity tags
       struct HETag
                 char        *etag;
                 int         weak;
                 HETag       *next;

        * HTTP custom IO
        * supports chunked transfer encoding
        * and initialization of the input buffer from a string.

                 Hsize = HBufSize

       struct Hio {
                 Hio         *hh;                   /* next lower layer Hio, or nil if reads from fd */
                 int         fd;                    /* associated file descriptor */
                 ulong       seek;                  /* of start */
                 uchar       state;                 /* state of the file */
                 uchar       xferenc;               /* chunked transfer encoding state */
                 uchar       *pos;                  /* current position in the buffer */
                 uchar       *stop;                 /* last character active in the buffer */
                 uchar       *start;                /* start of data buffer */
                 ulong       bodylen;               /* remaining length of message body */
                 uchar       buf[Hsize+32];

        * request line
       struct HttpReq
                 char        *meth;
                 char        *uri;
                 char        *urihost;
                 char        *search;
                 int         vermaj;
                 int         vermin;

        * header lines
       struct HttpHead
                 int         closeit;               /* http1.1 close connection after this request? */
                 uchar       persist;               /* http/1.1 requests a persistent connection */

                 uchar       expectcont;            /* expect a 100-continue */
                 uchar       expectother;           /* expect anything else; should reject with ExpectFail */
                 ulong       contlen;               /* if != ~0UL, length of included message body */
                 HFields     *transenc;             /* if present, encoding of included message body */
                 char        *client;
                 char        *host;
                 HContent    *okencode;
                 HContent    *oklang;
                 HContent    *oktype;
                 HContent    *okchar;
                 ulong       ifmodsince;
                 ulong       ifunmodsince;
                 ulong       ifrangedate;
                 HETag       *ifmatch;
                 HETag       *ifnomatch;
                 HETag       *ifrangeetag;
                 HRange      *range;
                 char        *authuser;             /* authorization info */
                 char        *authpass;

                  * experimental headers
                 int         fresh_thresh;
                 int         fresh_have;

        * all of the state for a particular connection
       struct HConnect
                 void        *private;              /* for the library clients */
                 void        (*replog)(HConnect*, char*, ...);/* called when reply sent */

                 HttpReq     req;
                 HttpHead    head;

                 Bin         *bin;

                 ulong       reqtime;               /* time at start of request */
                 char        xferbuf[HBufSize];     /* buffer for making up or transferring data */
                 uchar       header[HBufSize + 2];  /* room for \n\0 */
                 uchar       *hpos;
                 uchar       *hstop;
                 Hio         hin;
                 Hio         hout;

        * configuration for all connections within the server
       extern    char        *hmydomain;
       extern    char        *hversion;
       extern    Htmlesc     htmlesc[];

       void      *halloc(HConnect *c, ulong size);
       Hio       *hbodypush(Hio *hh, ulong len, HFields *te);
       int       hbuflen(Hio *h, void *p);
       int       hcheckcontent(HContent*, HContent*, char*, int);
       void      hclose(Hio*);
       ulong     hdate2sec(char*);
       int       hdatefmt(Fmt*);
       int       hfail(HConnect*, int, ...);
       int       hflush(Hio*);
       int       hgetc(Hio*);
       int       hgethead(HConnect *c, int many);
       int       hinit(Hio*, int, int);
       int       hiserror(Hio *h);
       int       hload(Hio*, char*);
       char      *hlower(char*);
       HContent  *hmkcontent(HConnect *c, char *generic, char *specific, HContent *next);
       HFields   *hmkhfields(HConnect *c, char *s, HSPairs *p, HFields *next);
       char      *hmkmimeboundary(HConnect *c);
       HSPairs   *hmkspairs(HConnect *c, char *s, char *t, HSPairs *next);
       int       hmoved(HConnect *c, char *uri);
       void      hokheaders(HConnect *c);
       int       hparseheaders(HConnect*, int timeout);
       HSPairs   *hparsequery(HConnect *c, char *search);
       int       hparsereq(HConnect *c, int timeout);
       int       hprint(Hio*, char*, ...);
       int       hputc(Hio*, int);
       void      *hreadbuf(Hio *h, void *vsave);
       int       hredirected(HConnect *c, char *how, char *uri);
       void      hreqcleanup(HConnect *c);
       HFields   *hrevhfields(HFields *hf);
       HSPairs   *hrevspairs(HSPairs *sp);
       char      *hstrdup(HConnect *c, char *s);
       int       http11(HConnect*);
       int       httpfmt(Fmt*);
       char      *httpunesc(HConnect *c, char *s);
       int       hunallowed(HConnect *, char *allowed);
       int       hungetc(Hio *h);
       char      *hunload(Hio*);
       int       hurlfmt(Fmt*);
       char      *hurlunesc(HConnect *c, char *s);
       int       hvprint(Hio*, char*, va_list);
       int       hwrite(Hio*, void*, int);
       int       hxferenc(Hio*, int);

       For now, look at the source, or httpd(8).



       This is a rough implementation and many details are going to change.