Subversion Repositories planix.SVN

Rev

Blame | Last modification | View Log | RSS feed

#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*