#ifndef _H_HTTP_PROTOCOL
#define _H_HTTP_PROTOCOL
#include "neterror.h"
#include "xfercore.h"
#include "protocol.h"
#include "transfer.h"
#include "netconnection.h"
#include <Security/ip++.h>
#include <Security/headermap.h>
#include <Security/inetreply.h>
namespace Security {
namespace Network {
class HTTPProtocol : public Protocol {
public:
class HTTPTransfer;
static const IPPort defaultHttpPort = 80;
HTTPProtocol(Manager &mgr, const char *scheme = "http");
public:
HTTPTransfer *makeTransfer(const Target &target, Operation operation);
private:
class HTTPHeaderMap : public HeaderMap {
public:
void merge(string key, string &old, string newValue);
};
protected:
class HTTPConnection : public TCPConnection {
static const int defaultSubVersion = 1; public:
HTTPConnection(Protocol &proto, const HostTarget &tgt);
enum State {
errorState, connecting, primaryResponse, readHeaders, readWholeBody,
idle, dead,
chunkHeader, chunkDownload, chunkGap, chunkTrailer,
START = primaryResponse
};
HTTPTransfer &transfer() { return transferAs<HTTPTransfer>(); }
HeaderMap &headers();
void request(const char *operation);
void abort();
protected:
void transit(Event event, char *input, size_t inputLength);
void transitError(const CssmCommonError &error);
void finish();
void fail(bool forceDrop = false); void fail(Transfer::ResultClass why, OSStatus how = Transfer::defaultOSStatusError)
{ transfer().fail(why, how); } bool validate();
void sendRequest();
void hostHeader();
void authorizationHeader(const char *headerName,
const HostTarget &host,
ParameterSource::Key userKey, ParameterSource::Key passKey);
void chooseRetain();
protected:
int subVersion; State state; bool deferSendRequest; string mOperation; unsigned int httpVersionMajor; unsigned int httpVersionMinor; };
public:
class HTTPTransfer : public Transfer {
public:
HTTPTransfer(Protocol &proto, const Target &tgt, Operation operation, IPPort defaultPort);
string &httpResponse() { return mPrimaryResponseString; }
unsigned int &httpResponseCode() { return mPrimaryResponseCode; }
unsigned int httpResponseCode() const { return mPrimaryResponseCode; }
HeaderMap &httpHeaders() { return mHeaders; }
void fail(ResultClass how, OSStatus err = defaultOSStatusError);
ResultClass resultClass() const;
void startRequest(); virtual bool useProxyHeaders() const;
protected:
void start(); void abort();
private:
string mPrimaryResponseString; unsigned int mPrimaryResponseCode; ResultClass mResultClass; HTTPHeaderMap mHeaders; };
};
inline HeaderMap &HTTPProtocol::HTTPConnection::headers()
{ return transfer().httpHeaders(); }
} }
#endif //_H_HTTP_PROTOCOL