180ee5cbfSDavid du Colombier #pragma lib "libhttpd.a" 280ee5cbfSDavid du Colombier #pragma src "/sys/src/libhttpd" 380ee5cbfSDavid du Colombier 480ee5cbfSDavid du Colombier typedef struct HConnect HConnect; 580ee5cbfSDavid du Colombier typedef struct HContent HContent; 680ee5cbfSDavid du Colombier typedef struct HContents HContents; 780ee5cbfSDavid du Colombier typedef struct HETag HETag; 880ee5cbfSDavid du Colombier typedef struct HFields HFields; 980ee5cbfSDavid du Colombier typedef struct Hio Hio; 1080ee5cbfSDavid du Colombier typedef struct Htmlesc Htmlesc; 1180ee5cbfSDavid du Colombier typedef struct HttpHead HttpHead; 1280ee5cbfSDavid du Colombier typedef struct HttpReq HttpReq; 1380ee5cbfSDavid du Colombier typedef struct HRange HRange; 1480ee5cbfSDavid du Colombier typedef struct HSPairs HSPairs; 1580ee5cbfSDavid du Colombier 1680ee5cbfSDavid du Colombier typedef struct Bin Bin; 1780ee5cbfSDavid du Colombier 1812fd1c83SDavid du Colombier #pragma incomplete Bin 1912fd1c83SDavid du Colombier 2080ee5cbfSDavid du Colombier enum 2180ee5cbfSDavid du Colombier { 2280ee5cbfSDavid du Colombier HMaxWord = 32*1024, 2380ee5cbfSDavid du Colombier HBufSize = 32*1024, 2480ee5cbfSDavid du Colombier 2580ee5cbfSDavid du Colombier /* 2680ee5cbfSDavid du Colombier * error messages 2780ee5cbfSDavid du Colombier */ 2880ee5cbfSDavid du Colombier HInternal = 0, 2980ee5cbfSDavid du Colombier HTempFail, 3080ee5cbfSDavid du Colombier HUnimp, 3180ee5cbfSDavid du Colombier HBadReq, 3280ee5cbfSDavid du Colombier HBadSearch, 3380ee5cbfSDavid du Colombier HNotFound, 3480ee5cbfSDavid du Colombier HUnauth, 3580ee5cbfSDavid du Colombier HSyntax, 3680ee5cbfSDavid du Colombier HNoSearch, 3780ee5cbfSDavid du Colombier HNoData, 3880ee5cbfSDavid du Colombier HExpectFail, 3980ee5cbfSDavid du Colombier HUnkVers, 4080ee5cbfSDavid du Colombier HBadCont, 4180ee5cbfSDavid du Colombier HOK, 4280ee5cbfSDavid du Colombier }; 4380ee5cbfSDavid du Colombier 4480ee5cbfSDavid du Colombier /* 4580ee5cbfSDavid du Colombier * table of html character escape codes 4680ee5cbfSDavid du Colombier */ 4780ee5cbfSDavid du Colombier struct Htmlesc 4880ee5cbfSDavid du Colombier { 4980ee5cbfSDavid du Colombier char *name; 5080ee5cbfSDavid du Colombier Rune value; 5180ee5cbfSDavid du Colombier }; 5280ee5cbfSDavid du Colombier 5380ee5cbfSDavid du Colombier struct HContent 5480ee5cbfSDavid du Colombier { 5580ee5cbfSDavid du Colombier HContent *next; 5680ee5cbfSDavid du Colombier char *generic; 5780ee5cbfSDavid du Colombier char *specific; 5880ee5cbfSDavid du Colombier float q; /* desirability of this kind of file */ 5980ee5cbfSDavid du Colombier int mxb; /* max uchars until worthless */ 6080ee5cbfSDavid du Colombier }; 6180ee5cbfSDavid du Colombier 6280ee5cbfSDavid du Colombier struct HContents 6380ee5cbfSDavid du Colombier { 6480ee5cbfSDavid du Colombier HContent *type; 6580ee5cbfSDavid du Colombier HContent *encoding; 6680ee5cbfSDavid du Colombier }; 6780ee5cbfSDavid du Colombier 6880ee5cbfSDavid du Colombier /* 6980ee5cbfSDavid du Colombier * generic http header with a list of tokens, 7080ee5cbfSDavid du Colombier * each with an optional list of parameters 7180ee5cbfSDavid du Colombier */ 7280ee5cbfSDavid du Colombier struct HFields 7380ee5cbfSDavid du Colombier { 7480ee5cbfSDavid du Colombier char *s; 7580ee5cbfSDavid du Colombier HSPairs *params; 7680ee5cbfSDavid du Colombier HFields *next; 7780ee5cbfSDavid du Colombier }; 7880ee5cbfSDavid du Colombier 7980ee5cbfSDavid du Colombier /* 8080ee5cbfSDavid du Colombier * list of pairs a strings 8180ee5cbfSDavid du Colombier * used for tag=val pairs for a search or form submission, 8280ee5cbfSDavid du Colombier * and attribute=value pairs in headers. 8380ee5cbfSDavid du Colombier */ 8480ee5cbfSDavid du Colombier struct HSPairs 8580ee5cbfSDavid du Colombier { 8680ee5cbfSDavid du Colombier char *s; 8780ee5cbfSDavid du Colombier char *t; 8880ee5cbfSDavid du Colombier HSPairs *next; 8980ee5cbfSDavid du Colombier }; 9080ee5cbfSDavid du Colombier 9180ee5cbfSDavid du Colombier /* 929a747e4fSDavid du Colombier * byte ranges within a file 9380ee5cbfSDavid du Colombier */ 9480ee5cbfSDavid du Colombier struct HRange 9580ee5cbfSDavid du Colombier { 9680ee5cbfSDavid du Colombier int suffix; /* is this a suffix request? */ 9780ee5cbfSDavid du Colombier ulong start; 9880ee5cbfSDavid du Colombier ulong stop; /* ~0UL -> not given */ 9980ee5cbfSDavid du Colombier HRange *next; 10080ee5cbfSDavid du Colombier }; 10180ee5cbfSDavid du Colombier 10280ee5cbfSDavid du Colombier /* 10380ee5cbfSDavid du Colombier * list of http/1.1 entity tags 10480ee5cbfSDavid du Colombier */ 10580ee5cbfSDavid du Colombier struct HETag 10680ee5cbfSDavid du Colombier { 10780ee5cbfSDavid du Colombier char *etag; 10880ee5cbfSDavid du Colombier int weak; 10980ee5cbfSDavid du Colombier HETag *next; 11080ee5cbfSDavid du Colombier }; 11180ee5cbfSDavid du Colombier 11280ee5cbfSDavid du Colombier /* 11380ee5cbfSDavid du Colombier * HTTP custom IO 11480ee5cbfSDavid du Colombier * supports chunked transfer encoding 11580ee5cbfSDavid du Colombier * and initialization of the input buffer from a string. 11680ee5cbfSDavid du Colombier */ 11780ee5cbfSDavid du Colombier enum 11880ee5cbfSDavid du Colombier { 11980ee5cbfSDavid du Colombier Hnone, 12080ee5cbfSDavid du Colombier Hread, 12180ee5cbfSDavid du Colombier Hend, 12280ee5cbfSDavid du Colombier Hwrite, 12380ee5cbfSDavid du Colombier Herr, 12480ee5cbfSDavid du Colombier 12580ee5cbfSDavid du Colombier Hsize = HBufSize 12680ee5cbfSDavid du Colombier }; 12780ee5cbfSDavid du Colombier 12880ee5cbfSDavid du Colombier struct Hio { 12980ee5cbfSDavid du Colombier Hio *hh; /* next lower layer Hio, or nil if reads from fd */ 13080ee5cbfSDavid du Colombier int fd; /* associated file descriptor */ 13180ee5cbfSDavid du Colombier ulong seek; /* of start */ 13280ee5cbfSDavid du Colombier uchar state; /* state of the file */ 13380ee5cbfSDavid du Colombier uchar xferenc; /* chunked transfer encoding state */ 13480ee5cbfSDavid du Colombier uchar *pos; /* current position in the buffer */ 13580ee5cbfSDavid du Colombier uchar *stop; /* last character active in the buffer */ 13680ee5cbfSDavid du Colombier uchar *start; /* start of data buffer */ 13780ee5cbfSDavid du Colombier ulong bodylen; /* remaining length of message body */ 13880ee5cbfSDavid du Colombier uchar buf[Hsize+32]; 13980ee5cbfSDavid du Colombier }; 14080ee5cbfSDavid du Colombier 14180ee5cbfSDavid du Colombier /* 14280ee5cbfSDavid du Colombier * request line 14380ee5cbfSDavid du Colombier */ 14480ee5cbfSDavid du Colombier struct HttpReq 14580ee5cbfSDavid du Colombier { 14680ee5cbfSDavid du Colombier char *meth; 14780ee5cbfSDavid du Colombier char *uri; 14880ee5cbfSDavid du Colombier char *urihost; 14980ee5cbfSDavid du Colombier char *search; 15080ee5cbfSDavid du Colombier int vermaj; 15180ee5cbfSDavid du Colombier int vermin; 1527ef45392SDavid du Colombier HSPairs *searchpairs; 15380ee5cbfSDavid du Colombier }; 15480ee5cbfSDavid du Colombier 15580ee5cbfSDavid du Colombier /* 15680ee5cbfSDavid du Colombier * header lines 15780ee5cbfSDavid du Colombier */ 15880ee5cbfSDavid du Colombier struct HttpHead 15980ee5cbfSDavid du Colombier { 16080ee5cbfSDavid du Colombier int closeit; /* http1.1 close connection after this request? */ 1619a747e4fSDavid du Colombier uchar persist; /* http/1.1 requests a persistent connection */ 16280ee5cbfSDavid du Colombier 16380ee5cbfSDavid du Colombier uchar expectcont; /* expect a 100-continue */ 16480ee5cbfSDavid du Colombier uchar expectother; /* expect anything else; should reject with ExpectFail */ 16580ee5cbfSDavid du Colombier ulong contlen; /* if != ~0UL, length of included message body */ 16680ee5cbfSDavid du Colombier HFields *transenc; /* if present, encoding of included message body */ 16780ee5cbfSDavid du Colombier char *client; 16880ee5cbfSDavid du Colombier char *host; 16980ee5cbfSDavid du Colombier HContent *okencode; 17080ee5cbfSDavid du Colombier HContent *oklang; 17180ee5cbfSDavid du Colombier HContent *oktype; 17280ee5cbfSDavid du Colombier HContent *okchar; 17380ee5cbfSDavid du Colombier ulong ifmodsince; 17480ee5cbfSDavid du Colombier ulong ifunmodsince; 17580ee5cbfSDavid du Colombier ulong ifrangedate; 17680ee5cbfSDavid du Colombier HETag *ifmatch; 17780ee5cbfSDavid du Colombier HETag *ifnomatch; 17880ee5cbfSDavid du Colombier HETag *ifrangeetag; 17980ee5cbfSDavid du Colombier HRange *range; 18080ee5cbfSDavid du Colombier char *authuser; /* authorization info */ 18180ee5cbfSDavid du Colombier char *authpass; 1822bef681aSDavid du Colombier HSPairs *cookie; /* if present, list of cookies */ 183*b39189fdSDavid du Colombier HSPairs *authinfo; /* digest authorization */ 18480ee5cbfSDavid du Colombier 18580ee5cbfSDavid du Colombier /* 18680ee5cbfSDavid du Colombier * experimental headers 18780ee5cbfSDavid du Colombier */ 18880ee5cbfSDavid du Colombier int fresh_thresh; 18980ee5cbfSDavid du Colombier int fresh_have; 19080ee5cbfSDavid du Colombier }; 19180ee5cbfSDavid du Colombier 19280ee5cbfSDavid du Colombier /* 19380ee5cbfSDavid du Colombier * all of the state for a particular connection 19480ee5cbfSDavid du Colombier */ 19580ee5cbfSDavid du Colombier struct HConnect 19680ee5cbfSDavid du Colombier { 19780ee5cbfSDavid du Colombier void *private; /* for the library clients */ 19880ee5cbfSDavid du Colombier void (*replog)(HConnect*, char*, ...); /* called when reply sent */ 19980ee5cbfSDavid du Colombier 200*b39189fdSDavid du Colombier char *scheme; /* "http" vs. "https" */ 201*b39189fdSDavid du Colombier char *port; /* may be arbitrary, i.e., neither 80 nor 443 */ 202*b39189fdSDavid du Colombier 20380ee5cbfSDavid du Colombier HttpReq req; 20480ee5cbfSDavid du Colombier HttpHead head; 20580ee5cbfSDavid du Colombier 20680ee5cbfSDavid du Colombier Bin *bin; 20780ee5cbfSDavid du Colombier 20880ee5cbfSDavid du Colombier ulong reqtime; /* time at start of request */ 20980ee5cbfSDavid du Colombier char xferbuf[HBufSize]; /* buffer for making up or transferring data */ 21080ee5cbfSDavid du Colombier uchar header[HBufSize + 2]; /* room for \n\0 */ 21180ee5cbfSDavid du Colombier uchar *hpos; 21280ee5cbfSDavid du Colombier uchar *hstop; 21380ee5cbfSDavid du Colombier Hio hin; 21480ee5cbfSDavid du Colombier Hio hout; 21580ee5cbfSDavid du Colombier }; 21680ee5cbfSDavid du Colombier 21780ee5cbfSDavid du Colombier /* 21880ee5cbfSDavid du Colombier * configuration for all connections within the server 21980ee5cbfSDavid du Colombier */ 22080ee5cbfSDavid du Colombier extern char* hmydomain; 22180ee5cbfSDavid du Colombier extern char* hversion; 22280ee5cbfSDavid du Colombier extern Htmlesc htmlesc[]; 22380ee5cbfSDavid du Colombier 2249a747e4fSDavid du Colombier /* 2259a747e4fSDavid du Colombier * .+2,/^$/ | sort -bd +1 2269a747e4fSDavid du Colombier */ 22780ee5cbfSDavid du Colombier void *halloc(HConnect *c, ulong size); 22880ee5cbfSDavid du Colombier Hio *hbodypush(Hio *hh, ulong len, HFields *te); 2299a747e4fSDavid du Colombier int hbuflen(Hio *h, void *p); 23080ee5cbfSDavid du Colombier int hcheckcontent(HContent*, HContent*, char*, int); 2319a747e4fSDavid du Colombier void hclose(Hio*); 23280ee5cbfSDavid du Colombier ulong hdate2sec(char*); 2339a747e4fSDavid du Colombier int hdatefmt(Fmt*); 23480ee5cbfSDavid du Colombier int hfail(HConnect*, int, ...); 2359a747e4fSDavid du Colombier int hflush(Hio*); 2369a747e4fSDavid du Colombier int hgetc(Hio*); 23780ee5cbfSDavid du Colombier int hgethead(HConnect *c, int many); 2389a747e4fSDavid du Colombier int hinit(Hio*, int, int); 2399a747e4fSDavid du Colombier int hiserror(Hio *h); 240b7327ca2SDavid du Colombier int hlflush(Hio*); 2419a747e4fSDavid du Colombier int hload(Hio*, char*); 24280ee5cbfSDavid du Colombier char *hlower(char*); 24380ee5cbfSDavid du Colombier HContent *hmkcontent(HConnect *c, char *generic, char *specific, HContent *next); 24480ee5cbfSDavid du Colombier HFields *hmkhfields(HConnect *c, char *s, HSPairs *p, HFields *next); 2459a747e4fSDavid du Colombier char *hmkmimeboundary(HConnect *c); 24680ee5cbfSDavid du Colombier HSPairs *hmkspairs(HConnect *c, char *s, char *t, HSPairs *next); 24780ee5cbfSDavid du Colombier int hmoved(HConnect *c, char *uri); 24880ee5cbfSDavid du Colombier void hokheaders(HConnect *c); 24980ee5cbfSDavid du Colombier int hparseheaders(HConnect*, int timeout); 25080ee5cbfSDavid du Colombier HSPairs *hparsequery(HConnect *c, char *search); 2519a747e4fSDavid du Colombier int hparsereq(HConnect *c, int timeout); 2529a747e4fSDavid du Colombier int hprint(Hio*, char*, ...); 2539a747e4fSDavid du Colombier int hputc(Hio*, int); 2549a747e4fSDavid du Colombier void *hreadbuf(Hio *h, void *vsave); 25580ee5cbfSDavid du Colombier int hredirected(HConnect *c, char *how, char *uri); 25680ee5cbfSDavid du Colombier void hreqcleanup(HConnect *c); 25780ee5cbfSDavid du Colombier HFields *hrevhfields(HFields *hf); 25880ee5cbfSDavid du Colombier HSPairs *hrevspairs(HSPairs *sp); 2599a747e4fSDavid du Colombier char *hstrdup(HConnect *c, char *s); 2609a747e4fSDavid du Colombier int http11(HConnect*); 2619a747e4fSDavid du Colombier int httpfmt(Fmt*); 2629a747e4fSDavid du Colombier char *httpunesc(HConnect *c, char *s); 26380ee5cbfSDavid du Colombier int hunallowed(HConnect *, char *allowed); 2649a747e4fSDavid du Colombier int hungetc(Hio *h); 2659a747e4fSDavid du Colombier char *hunload(Hio*); 2669a747e4fSDavid du Colombier int hurlfmt(Fmt*); 26780ee5cbfSDavid du Colombier char *hurlunesc(HConnect *c, char *s); 2689a747e4fSDavid du Colombier int hwrite(Hio*, void*, int); 2699a747e4fSDavid du Colombier int hxferenc(Hio*, int); 2709a747e4fSDavid du Colombier 2719a747e4fSDavid du Colombier #pragma varargck argpos hprint 2 27280ee5cbfSDavid du Colombier 27380ee5cbfSDavid du Colombier /* 27480ee5cbfSDavid du Colombier * D is httpd format date conversion 27580ee5cbfSDavid du Colombier * U is url escape convertsion 27680ee5cbfSDavid du Colombier * H is html escape conversion 27780ee5cbfSDavid du Colombier */ 27880ee5cbfSDavid du Colombier #pragma varargck type "D" long 27980ee5cbfSDavid du Colombier #pragma varargck type "D" ulong 28080ee5cbfSDavid du Colombier #pragma varargck type "U" char* 28180ee5cbfSDavid du Colombier #pragma varargck type "H" char* 282