From 95f5a1c2dff53b88c274e358bd0cd07758819a12 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 4 Jan 2009 13:56:55 +0000 Subject: Allow adding headers to an HTTPRequest. Allow getting response headers out of HTTPResponse. Rename HTTPRequest Read and Write methods to Send and Receive, to avoid confusion with IOStream. --- lib/httpserver/HTTPRequest.cpp | 14 ++++++++++---- lib/httpserver/HTTPRequest.h | 23 ++++++++++++++++++----- lib/httpserver/HTTPResponse.h | 29 +++++++++++++++++++++++++++-- lib/httpserver/HTTPServer.cpp | 4 ++-- 4 files changed, 57 insertions(+), 13 deletions(-) diff --git a/lib/httpserver/HTTPRequest.cpp b/lib/httpserver/HTTPRequest.cpp index a14f1eb3..8ba44903 100644 --- a/lib/httpserver/HTTPRequest.cpp +++ b/lib/httpserver/HTTPRequest.cpp @@ -93,7 +93,7 @@ HTTPRequest::~HTTPRequest() // -------------------------------------------------------------------------- // // Function -// Name: HTTPRequest::Read(IOStreamGetLine &, int) +// Name: HTTPRequest::Receive(IOStreamGetLine &, int) // Purpose: Read the request from an IOStreamGetLine (and // attached stream). // Returns false if there was no valid request, @@ -101,7 +101,7 @@ HTTPRequest::~HTTPRequest() // Created: 26/3/04 // // -------------------------------------------------------------------------- -bool HTTPRequest::Read(IOStreamGetLine &rGetLine, int Timeout) +bool HTTPRequest::Receive(IOStreamGetLine &rGetLine, int Timeout) { // Check caller's logic if(mMethod != Method_UNINITIALISED) @@ -312,12 +312,12 @@ bool HTTPRequest::Read(IOStreamGetLine &rGetLine, int Timeout) // -------------------------------------------------------------------------- // // Function -// Name: HTTPRequest::Write(IOStream &, int) +// Name: HTTPRequest::Send(IOStream &, int) // Purpose: Write the request to an IOStream using HTTP. // Created: 03/01/09 // // -------------------------------------------------------------------------- -bool HTTPRequest::Write(IOStream &rStream, int Timeout) +bool HTTPRequest::Send(IOStream &rStream, int Timeout) { switch (mMethod) { @@ -386,6 +386,12 @@ bool HTTPRequest::Write(IOStream &rStream, int Timeout) oss << "Connection: close\n"; } + for (std::vector
::iterator i = mExtraHeaders.begin(); + i != mExtraHeaders.end(); i++) + { + oss << i->first << ": " << i->second << "\n"; + } + rStream.Write(oss.str().c_str()); rStream.Write("\n"); diff --git a/lib/httpserver/HTTPRequest.h b/lib/httpserver/HTTPRequest.h index 501bce53..dc81d593 100644 --- a/lib/httpserver/HTTPRequest.h +++ b/lib/httpserver/HTTPRequest.h @@ -44,9 +44,8 @@ private: HTTPRequest(const HTTPRequest &); HTTPRequest &operator=(const HTTPRequest &); public: - typedef std::multimap Query_t; - typedef std::pair QueryEn_t; + typedef std::pair QueryEn_t, Header; enum { @@ -56,8 +55,8 @@ public: HTTPVersion_1_1 = 1001 }; - bool Read(IOStreamGetLine &rGetLine, int Timeout); - bool Write(IOStream &rStream, int Timeout); + bool Receive(IOStreamGetLine &rGetLine, int Timeout); + bool Send(IOStream &rStream, int Timeout); typedef std::map CookieJar_t; @@ -71,7 +70,15 @@ public: // -------------------------------------------------------------------------- enum Method GetMethod() const {return mMethod;} const std::string &GetRequestURI() const {return mRequestURI;} - const std::string &GetHostName() const {return mHostName;} // note: request does splitting of Host: header + + // Note: the HTTPRequest generates and parses the Host: header + // Do not attempt to set one yourself with AddHeader(). + const std::string &GetHostName() const {return mHostName;} + void SetHostName(const std::string& rHostName) + { + mHostName = rHostName; + } + const int GetHostPort() const {return mHostPort;} // into host name and port number const std::string &GetQueryString() const {return mQueryString;} int GetHTTPVersion() const {return mHTTPVersion;} @@ -98,6 +105,11 @@ public: mClientKeepAliveRequested = keepAlive; } + void AddHeader(const std::string& rName, const std::string& rValue) + { + mExtraHeaders.push_back(Header(rName, rValue)); + } + private: void ParseHeaders(IOStreamGetLine &rGetLine, int Timeout); void ParseCookies(const std::string &rHeader, int DataStarts); @@ -114,6 +126,7 @@ private: std::string mContentType; CookieJar_t *mpCookies; bool mClientKeepAliveRequested; + std::vector
mExtraHeaders; }; #endif // HTTPREQUEST__H diff --git a/lib/httpserver/HTTPResponse.h b/lib/httpserver/HTTPResponse.h index 58cc3baa..e4d4fd91 100644 --- a/lib/httpserver/HTTPResponse.h +++ b/lib/httpserver/HTTPResponse.h @@ -30,12 +30,14 @@ class HTTPResponse : public CollectInBufferStream public: HTTPResponse(); ~HTTPResponse(); + private: // no copying HTTPResponse(const HTTPResponse &); HTTPResponse &operator=(const HTTPResponse &); -public: + typedef std::pair Header; +public: void SetResponseCode(int Code); int GetResponseCode() { return mResponseCode; } void SetContentType(const char *ContentType); @@ -52,6 +54,29 @@ public: void AddHeader(const char *Header, const char *Value); void AddHeader(const char *Header, const std::string &rValue); void AddHeader(const std::string &rHeader, const std::string &rValue); + bool GetHeader(const std::string& rName, std::string* pValueOut) const + { + for (std::vector
::const_iterator + i = mExtraHeaders.begin(); + i != mExtraHeaders.end(); i++) + { + if (i->first == rName) + { + *pValueOut = i->second; + return true; + } + } + return false; + } + std::string GetHeaderValue(const std::string& rName) + { + std::string value; + if (!GetHeader(rName, &value)) + { + THROW_EXCEPTION(CommonException, ConfigNoKey); + } + return value; + } // Set dynamic content flag, default is content is dynamic void SetResponseIsDynamicContent(bool IsDynamic) {mResponseIsDynamicContent = IsDynamic;} @@ -68,6 +93,7 @@ public: Code_Found = 302, // redirection Code_NotModified = 304, Code_TemporaryRedirect = 307, + Code_MethodNotAllowed = 400, Code_Unauthorized = 401, Code_Forbidden = 403, Code_NotFound = 404, @@ -111,7 +137,6 @@ private: bool mResponseIsDynamicContent; bool mKeepAlive; std::string mContentType; - typedef std::pair Header; std::vector
mExtraHeaders; int mContentLength; // only used when reading response from stream diff --git a/lib/httpserver/HTTPServer.cpp b/lib/httpserver/HTTPServer.cpp index 742b392f..fbdadfa7 100644 --- a/lib/httpserver/HTTPServer.cpp +++ b/lib/httpserver/HTTPServer.cpp @@ -145,7 +145,7 @@ void HTTPServer::Connection(SocketStream &rStream) { // Parse the request HTTPRequest request; - if(!request.Read(getLine, mTimeout)) + if(!request.Receive(getLine, mTimeout)) { // Didn't get request, connection probably closed. break; @@ -186,7 +186,7 @@ void HTTPServer::Connection(SocketStream &rStream) response.Send(rStream, request.GetMethod() == HTTPRequest::Method_HEAD); } - // Notify dervived claases + // Notify derived claases HTTPConnectionClosing(); } -- cgit v1.2.3