/* Web Polygraph http://www.web-polygraph.org/
* (C) 2003-2006 The Measurement Factory
* Licensed under the Apache License, Version 2.0 */
#ifndef POLYGRAPH__RUNTIME_HTTPHDRS_H
#define POLYGRAPH__RUNTIME_HTTPHDRS_H
#include "xstd/h/iostream.h"
#include "xstd/Array.h"
#include "xstd/NetAddr.h"
#include "xstd/Checksum.h"
#include "base/ObjId.h"
#include "runtime/ObjWorld.h"
#include "runtime/XactAbortCoord.h"
#include "runtime/HttpVersion.h"
class MsgHdrParsTab;
class HttpCookies;
class HttpUri {
public:
HttpUri(): pathBuf(0), pathLen(-1) {}
public:
ObjId oid;
NetAddr host;
const char *pathBuf;
int pathLen;
};
// common interface for parsing HTTP requests and responses
class MsgHdr {
public:
typedef bool (MsgHdr::*Parser)(const char *buf, const char *eoh);
protected:
static bool ParseHostInUri(const char *&start, const char *eorl, NetAddr &host);
public:
MsgHdr(const MsgHdrParsTab &aTab);
virtual ~MsgHdr() {}
virtual void reset();
bool persistentConnection() const;
bool knownContentType() const;
bool markupContent() const;
bool chunkedEncoding() const;
bool parse(const char *buf, Size sz);
bool parseUri(const char *&buf, const char *eoh, HttpUri &uri);
virtual void store(OLog &log) const;
protected:
static void Configure(MsgHdrParsTab &tab);
static int AddParser(const String &field, Parser parser, MsgHdrParsTab &tab);
protected:
void parseFields();
bool parseUniqId(const char *&buf, const char *eoh, UniqId &id);
bool parseWorld(const char *buf, const char *eoh, ObjWorld &world);
virtual bool parseRLine(const char *buf, const char *eol) = 0;
public:
// can be used by both requests and replies
bool parseHttpVersion(const char *&beg, const char *end, HttpVersion &v);
bool parseDate(const char *buf, const char *eoh);
bool parseContLen(const char *buf, const char *eoh);
bool parseContMd5(const char *buf, const char *eoh);
bool parseContType(const char *buf, const char *eoh);
bool parsePragma(const char *buf, const char *eoh);
bool parseCControl(const char *buf, const char *eoh);
bool parseXXact(const char *buf, const char *eoh);
bool parseXTarget(const char *buf, const char *eoh);
bool parseXRemWorld(const char *buf, const char *eoh);
bool parseXAbort(const char *buf, const char *eoh);
bool parseXPhaseSyncPos(const char *buf, const char *eoh);
bool parseConnection(const char *buf, const char *eoh);
bool parseTransferEncoding(const char *buf, const char *eoh);
// these have to be here so we can register them in req
virtual bool parseGetReqLine(const char *buf, const char *eorl);
virtual bool parseHeadReqLine(const char *buf, const char *eorl);
virtual bool parsePostReqLine(const char *buf, const char *eorl);
virtual bool parsePutReqLine(const char *buf, const char *eorl);
virtual bool parseHost(const char *buf, const char *eoh);
virtual bool parseIms(const char *buf, const char *eoh);
virtual bool parseXLocWorld(const char *buf, const char *eoh);
virtual bool parseAcceptEncoding(const char *buf, const char *eoh);
// these have to be here so we can register them in rep
virtual bool parseServer(const char *buf, const char *eoh);
virtual bool parseLocation(const char *buf, const char *eoh);
virtual bool parseLMT(const char *buf, const char *eoh);
virtual bool parseExpires(const char *buf, const char *eoh);
virtual bool parseCookie(const char *buf, const char *eoh);
public:
const MsgHdrParsTab &theParsTab;
Size theHdrSize;
HttpVersion theHttpVersion;
Time theDate; // Date: header field
Size theContSize;
Checksum theChecksum; // Content-MD5
UniqId theGroupId;
UniqId theXactId;
NetAddr theTarget;
ObjWorld theRemWorld; // remote object world specs
XactAbortCoord theAbortCoord; // abort coordinates
int thePhaseSyncPos; // index of a ready-to-stop phase
enum { kaNo, kaDefault, kaYes } theConnectionKeepAlive;
enum { ctUnknown, ctMarkup, ctOther } theContType; // content type
enum { tcNone, tcChunked, tcIdentity, tcOther } theTransferEncoding;
bool isCachable;
protected:
Array<const char *> theFields; // positions of header fields
const char *theBufBeg, *theBufEnd;
const char *theSrchPtr; // parse buffer iterator
enum { ssFirst, ssSkip, ssFound } theSrchState;
};
class ReqHdr: public MsgHdr {
public:
static void Configure();
static void Clean();
public:
ReqHdr();
virtual void reset();
virtual void store(OLog &log) const;
bool expectBody() const;
bool acceptedEncoding(int coding) const;
protected:
virtual bool parseRLine(const char *buf, const char *eol);
bool parseAnyReqLine(const char *buf, const char *eorl);
virtual bool parseAcceptEncoding(const char *buf, const char *eoh);
virtual bool parseGetReqLine(const char *buf, const char *eorl);
virtual bool parseHeadReqLine(const char *buf, const char *eorl);
virtual bool parsePostReqLine(const char *buf, const char *eorl);
virtual bool parsePutReqLine(const char *buf, const char *eorl);
virtual bool parseHost(const char *buf, const char *eoh);
virtual bool parseIms(const char *buf, const char *eoh);
virtual bool parseXLocWorld(const char *buf, const char *eoh);
protected:
static MsgHdrParsTab *TheParsTab;
public:
HttpUri theUri;
Time theIms; // If-Modified-Since timestamp
ObjWorld theLocWorld; // local world info
bool isHealthCheck;
bool isAcceptingGzip;
};
class RepHdr: public MsgHdr {
public:
enum StatusCode { scUnknown = -1, sc200_OK = 200,
sc204_NoContent = 204,
sc300_Choices = 300, sc302_Found = 302, sc303_Other = 303,
sc304_NotModified = 304, sc307_TmpRedir = 307,
sc403_Forbidden = 403,
sc406_NotAcceptable = 406,
sc407_ProxyAuthRequired = 407 };
static bool PositiveStatusCode(int code);
public:
static void Configure();
static void Clean();
public:
RepHdr();
virtual void reset();
bool polyHeaders() const { return theXactId || theTarget; }
bool expectPolyHeaders() const;
bool expectBody() const;
bool redirect() const;
Time calcLmt() const;
virtual void store(OLog &log) const;
void collectCookies(HttpCookies *cookies);
bool acceptedEncoding(int coding) const;
protected:
virtual bool parseRLine(const char *buf, const char *eol);
virtual bool parseServer(const char *buf, const char *eoh);
virtual bool parseLocation(const char *buf, const char *eoh);
virtual bool parseLMT(const char *buf, const char *eoh);
virtual bool parseExpires(const char *buf, const char *eoh);
virtual bool parseCookie(const char *buf, const char *eoh);
protected:
static MsgHdrParsTab *TheParsTab;
public:
HttpUri theLocn; // Location: in 3xx responses
Time theLMT; // Last-Modified-Time header field
Time theExpires; // Expires HTTP header field
int theStatus; // HTTP status code
String theServer; // server agent string
HttpCookies *theCookies; // a place to collect cookies, if needed
};
inline ostream &crlf(ostream &os) { return os.write("\r\n", 2); }
#endif
syntax highlighted by Code2HTML, v. 0.9.1