barrier/lib/http/CHTTPProtocol.h

201 lines
5.1 KiB
C++

/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2002 Chris Schoeneman
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file COPYING that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef CHTTPPROTOCOL_H
#define CHTTPPROTOCOL_H
#include "CString.h"
#include "BasicTypes.h"
#include "stdlist.h"
#include "stdmap.h"
#include "stdvector.h"
class IInputStream;
class IOutputStream;
//! HTTP request type
/*!
This class encapsulates an HTTP request.
*/
class CHTTPRequest {
private:
typedef std::list<std::pair<CString, CString> > CHeaderList;
public:
//! Iterator on headers
/*!
An iterator on the headers. Each element is a std::pair; first is
the header name as a CString, second is the header value as a CString.
*/
typedef CHeaderList::const_iterator const_iterator;
CHTTPRequest();
~CHTTPRequest();
//! @name manipulators
//@{
//! Insert header
/*!
Add a header by name replacing the existing header, if any.
Headers are sent in the order they're inserted. Replacing
a header does not change its original position in the order.
*/
void insertHeader(const CString& name, const CString& value);
//! Append header
/*!
Append a header. Equivalent to insertHeader() if the header
doesn't exist, otherwise it appends a comma and the value to
the existing header.
*/
void appendHeader(const CString& name, const CString& value);
//! Remove header
/*!
Remove a header by name. Does nothing if the header doesn't exist.
*/
void eraseHeader(const CString& name);
//@}
//! @name accessors
//@{
//! Check header existence
/*!
Returns true iff the header exists.
*/
bool isHeader(const CString& name) const;
//! Get header
/*!
Get a header by name. Returns the empty string if the header
doesn't exist.
*/
CString getHeader(const CString& name) const;
// headers are iterated in the order they were added.
//! Get beginning header iterator
const_iterator begin() const { return m_headers.begin(); }
//! Get ending header iterator
const_iterator end() const { return m_headers.end(); }
//@}
public:
// note -- these members are public for convenience
//! The HTTP method
CString m_method;
//! The HTTP URI
CString m_uri;
//! The HTTP major version number
SInt32 m_majorVersion;
//! The HTTP minor version number
SInt32 m_minorVersion;
//! The HTTP body, after transfer decoding
CString m_body;
private:
typedef std::map<CString, CHeaderList::iterator,
CStringUtil::CaselessCmp> CHeaderMap;
CHeaderList m_headers;
CHeaderMap m_headerByName;
};
//! HTTP reply type
/*!
This class encapsulates an HTTP reply.
*/
class CHTTPReply {
public:
//! Header list
/*!
The type of the reply header list. Each pair is the header name
and value, respectively for first and second.
*/
typedef std::vector<std::pair<CString, CString> > CHeaderList;
// note -- these members are public for convenience
//! The HTTP major version number
SInt32 m_majorVersion;
//! The HTTP minor version number
SInt32 m_minorVersion;
//! The HTTP status code
SInt32 m_status;
//! The HTTP reason phrase
CString m_reason;
//! The HTTP method
CString m_method;
//! The HTTP headers
CHeaderList m_headers;
//! The HTTP body
CString m_body;
};
//! HTTP protocol utilities
/*!
This class provides utility functions for HTTP.
*/
class CHTTPProtocol {
public:
//! Multipart form parts
/*!
Each element is the contents of a multipart form part indexed by
it's name.
*/
typedef std::map<CString, CString> CFormParts;
//! Read HTTP request
/*!
Read and parse an HTTP request. The result is returned in a
CHTTPRequest which the client must delete. Throws an
XHTTP if there was a parse error. Throws an XIO exception
if there was a read error. If \c maxSize is greater than
zero and the request is larger than \c maxSize bytes then
throws XHTTP(413) (request entity too large).
*/
static CHTTPRequest* readRequest(IInputStream*, UInt32 maxSize = 0);
//! Send HTTP response
/*!
Send an HTTP reply. The Content-Length and Date headers are set
automatically.
*/
static void reply(IOutputStream*, CHTTPReply&);
//! Parse multipart form data
/*!
Parse a multipart/form-data body into its parts. Returns true
iff the entire body was correctly parsed.
*/
// FIXME -- name/value pairs insufficient to save part headers
static bool parseFormData(const CHTTPRequest&,
CFormParts& parts);
private:
static CString readLine(IInputStream*, CString& tmpBuffer);
static CString readBlock(IInputStream*,
UInt32 numBytes, CString& tmpBuffer);
static CString readChunk(IInputStream*, CString& tmpBuffer,
UInt32* maxSize);
static void readHeaders(IInputStream*,
CHTTPRequest*, bool isFooter,
CString& tmpBuffer,
UInt32* maxSize);
static bool isValidToken(const CString&);
};
#endif