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