291 lines
6.2 KiB
C
291 lines
6.2 KiB
C
|
/*
|
||
|
* This file is part of the UCB release of Plan 9. It is subject to the license
|
||
|
* terms in the LICENSE file found in the top-level directory of this
|
||
|
* distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
|
||
|
* part of the UCB release of Plan 9, including this file, may be copied,
|
||
|
* modified, propagated, or distributed except according to the terms contained
|
||
|
* in the LICENSE file.
|
||
|
*/
|
||
|
|
||
|
#pragma lib "libhttpd.a"
|
||
|
#pragma src "/sys/src/libhttpd"
|
||
|
|
||
|
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;
|
||
|
|
||
|
#pragma incomplete Bin
|
||
|
|
||
|
enum
|
||
|
{
|
||
|
HMaxWord = 32*1024,
|
||
|
HBufSize = 32*1024,
|
||
|
|
||
|
/*
|
||
|
* error messages
|
||
|
*/
|
||
|
HInternal = 0,
|
||
|
HTempFail,
|
||
|
HUnimp,
|
||
|
HBadReq,
|
||
|
HBadSearch,
|
||
|
HNotFound,
|
||
|
HUnauth,
|
||
|
HSyntax,
|
||
|
HNoSearch,
|
||
|
HNoData,
|
||
|
HExpectFail,
|
||
|
HUnkVers,
|
||
|
HBadCont,
|
||
|
HOK,
|
||
|
};
|
||
|
|
||
|
/*
|
||
|
* table of html character escape codes
|
||
|
*/
|
||
|
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.
|
||
|
*/
|
||
|
enum
|
||
|
{
|
||
|
Hnone,
|
||
|
Hread,
|
||
|
Hend,
|
||
|
Hwrite,
|
||
|
Herr,
|
||
|
|
||
|
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;
|
||
|
HSPairs *searchpairs;
|
||
|
};
|
||
|
|
||
|
/*
|
||
|
* 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;
|
||
|
HSPairs *cookie; /* if present, list of cookies */
|
||
|
HSPairs *authinfo; /* digest authorization */
|
||
|
|
||
|
/*
|
||
|
* 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 */
|
||
|
|
||
|
char *scheme; /* "http" vs. "https" */
|
||
|
char *port; /* may be arbitrary, i.e., neither 80 nor 443 */
|
||
|
|
||
|
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[];
|
||
|
|
||
|
/*
|
||
|
* .+2,/^$/ | sort -bd +1
|
||
|
*/
|
||
|
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 hlflush(Hio*);
|
||
|
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 hwrite(Hio*, void*, int);
|
||
|
int hxferenc(Hio*, int);
|
||
|
|
||
|
#pragma varargck argpos hprint 2
|
||
|
|
||
|
/*
|
||
|
* D is httpd format date conversion
|
||
|
* U is url escape convertsion
|
||
|
* H is html escape conversion
|
||
|
*/
|
||
|
#pragma varargck type "D" long
|
||
|
#pragma varargck type "D" ulong
|
||
|
#pragma varargck type "U" char*
|
||
|
#pragma varargck type "H" char*
|