202 lines
5.1 KiB
C++
202 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 "CStringUtil.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
|