code: plan9front

ref: cb5b36f7c62545b92bbe577175de82c6c6cc9be9
dir: /sys/man/2/httpd/

View raw version
.TH HTTPD 2
.SH NAME
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
.SH SYNOPSIS
.nf
.B #include <u.h>
.B #include <libc.h>
.B #include <httpd.h>
.PP
.ft L
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;
.ta \w'\fLHContents 'u +\w'\fLHContentsxx 'u +\w'\fLheader[HBufSize + 2];  'u

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

/*
 * 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);
.ft R
.SH DESCRIPTION
For now, look at the source, or
.IR httpd (8).
.SH SOURCE
.B /sys/src/libhttpd
.SH SEE ALSO
.IR bin (2)
.SH BUGS
This is a rough implementation and many details are going to change.