HTTPD(2)                                                 HTTPD(2)

          HConnect, HContent, HContents, HETag, HFields, Hio, Htmlesc,
          HttpHead, HttpReq, HRange, HSPairs, hmydomain, hversion,
          htmlesc, halloc, hbodypush, hbuflen, hcheckcontent, hclose,
          hdate2sec, hdatefmt, hfail, hflush, hgetc, hgethead, hinit,
          hiserror, hload, hlower, hmkcontent, hmkhfields,
          hmkmimeboundary, hmkspairs, hmoved, hokheaders,
          hparseheaders, hparsequery, hparsereq, hprint, hputc,
          hreadbuf, hredirected, hreqcleanup, hrevhfields, hrevspairs,
          hstrdup, http11, httpfmt, httpunesc, hunallowed, hungetc,
          hunload, hurlfmt, hurlunesc, hvprint, hwrite, hxferenc,
           - 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;

     Page 1                       Plan 9             (printed 4/18/24)

     HTTPD(2)                                                 HTTPD(2)

                    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.

     Page 2                       Plan 9             (printed 4/18/24)

     HTTPD(2)                                                 HTTPD(2)


                    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;

     Page 3                       Plan 9             (printed 4/18/24)

     HTTPD(2)                                                 HTTPD(2)

                    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);

     Page 4                       Plan 9             (printed 4/18/24)

     HTTPD(2)                                                 HTTPD(2)

          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

     Page 5                       Plan 9             (printed 4/18/24)

     HTTPD(2)                                                 HTTPD(2)


     Page 6                       Plan 9             (printed 4/18/24)