1 // distribution boxbackup-0.11_trunk_2979 (svn version: 2979) 2 // Box Backup, http://www.boxbackup.org/ 3 // 4 // Copyright (c) 2003-2010, Ben Summers and contributors. 5 // All rights reserved. 6 // 7 // Note that this project uses mixed licensing. Any file with this license 8 // attached, or where the code LICENSE-DUAL appears on the first line, falls 9 // under this license. See the file COPYING.txt for more information. 10 // 11 // This file is dual licensed. You may use and distribute it providing that you 12 // comply EITHER with the terms of the BSD license, OR the GPL license. It is 13 // not necessary to comply with both licenses, only one. 14 // 15 // The BSD license option follows: 16 // 17 // Redistribution and use in source and binary forms, with or without 18 // modification, are permitted provided that the following conditions are met: 19 // 20 // 1. Redistributions of source code must retain the above copyright 21 // notice, this list of conditions and the following disclaimer. 22 // 23 // 2. Redistributions in binary form must reproduce the above copyright 24 // notice, this list of conditions and the following disclaimer in the 25 // documentation and/or other materials provided with the distribution. 26 // 27 // 3. Neither the name of the Box Backup nor the names of its contributors may 28 // be used to endorse or promote products derived from this software without 29 // specific prior written permission. 30 // 31 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 32 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 33 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 34 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY 35 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 36 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 37 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 38 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 39 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 40 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 41 // 42 // [http://en.wikipedia.org/wiki/BSD_licenses#3-clause_license_.28.22New_BSD_License.22.29] 43 // 44 // The GPL license option follows: 45 // 46 // This program is free software; you can redistribute it and/or 47 // modify it under the terms of the GNU General Public License 48 // as published by the Free Software Foundation; either version 2 49 // of the License, or (at your option) any later version. 50 // 51 // This program is distributed in the hope that it will be useful, 52 // but WITHOUT ANY WARRANTY; without even the implied warranty of 53 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 54 // GNU General Public License for more details. 55 // 56 // You should have received a copy of the GNU General Public License 57 // along with this program; if not, write to the Free Software 58 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 59 // 60 // [http://www.gnu.org/licenses/old-licenses/gpl-2.0.html#SEC4] 61 // -------------------------------------------------------------------------- 62 // 63 // File 64 // Name: HTTPRequest.h 65 // Purpose: Request object for HTTP connections 66 // Created: 26/3/04 67 // 68 // -------------------------------------------------------------------------- 69 70 #ifndef HTTPREQUEST__H 71 #define HTTPREQUEST__H 72 73 #include <string> 74 #include <map> 75 76 #include "CollectInBufferStream.h" 77 78 class HTTPResponse; 79 class IOStream; 80 class IOStreamGetLine; 81 82 // -------------------------------------------------------------------------- 83 // 84 // Class 85 // Name: HTTPRequest 86 // Purpose: Request object for HTTP connections 87 // Created: 26/3/04 88 // 89 // -------------------------------------------------------------------------- 90 class HTTPRequest : public CollectInBufferStream 91 { 92 public: 93 enum Method 94 { 95 Method_UNINITIALISED = -1, 96 Method_UNKNOWN = 0, 97 Method_GET = 1, 98 Method_HEAD = 2, 99 Method_POST = 3, 100 Method_PUT = 4 101 }; 102 103 HTTPRequest(); 104 HTTPRequest(enum Method method, const std::string& rURI); 105 ~HTTPRequest(); 106 private: 107 // no copying 108 HTTPRequest(const HTTPRequest &); 109 HTTPRequest &operator=(const HTTPRequest &); 110 public: 111 typedef std::multimap<std::string, std::string> Query_t; 112 typedef Query_t::value_type QueryEn_t; 113 typedef std::pair<std::string, std::string> Header; 114 115 enum 116 { 117 HTTPVersion__MajorMultiplier = 1000, 118 HTTPVersion_0_9 = 9, 119 HTTPVersion_1_0 = 1000, 120 HTTPVersion_1_1 = 1001 121 }; 122 123 bool Receive(IOStreamGetLine &rGetLine, int Timeout); 124 bool Send(IOStream &rStream, int Timeout, bool ExpectContinue = false); 125 void SendWithStream(IOStream &rStreamToSendTo, int Timeout, 126 IOStream* pStreamToSend, HTTPResponse& rResponse); 127 void ReadContent(IOStream& rStreamToWriteTo); 128 129 typedef std::map<std::string, std::string> CookieJar_t; 130 131 // -------------------------------------------------------------------------- 132 // 133 // Function 134 // Name: HTTPResponse::Get*() 135 // Purpose: Various Get accessors 136 // Created: 26/3/04 137 // 138 // -------------------------------------------------------------------------- GetMethod()139 enum Method GetMethod() const {return mMethod;} GetRequestURI()140 const std::string &GetRequestURI() const {return mRequestURI;} 141 142 // Note: the HTTPRequest generates and parses the Host: header 143 // Do not attempt to set one yourself with AddHeader(). GetHostName()144 const std::string &GetHostName() const {return mHostName;} SetHostName(const std::string & rHostName)145 void SetHostName(const std::string& rHostName) 146 { 147 mHostName = rHostName; 148 } 149 GetHostPort()150 const int GetHostPort() const {return mHostPort;} GetQueryString()151 const std::string &GetQueryString() const {return mQueryString;} GetHTTPVersion()152 int GetHTTPVersion() const {return mHTTPVersion;} GetQuery()153 const Query_t &GetQuery() const {return mQuery;} GetContentLength()154 int GetContentLength() const {return mContentLength;} GetContentType()155 const std::string &GetContentType() const {return mContentType;} GetCookies()156 const CookieJar_t *GetCookies() const {return mpCookies;} // WARNING: May return NULL 157 bool GetCookie(const char *CookieName, std::string &rValueOut) const; 158 const std::string &GetCookie(const char *CookieName) const; GetHeader(const std::string & rName,std::string * pValueOut)159 bool GetHeader(const std::string& rName, std::string* pValueOut) const 160 { 161 std::string header = ToLowerCase(rName); 162 163 for (std::vector<Header>::const_iterator 164 i = mExtraHeaders.begin(); 165 i != mExtraHeaders.end(); i++) 166 { 167 if (i->first == header) 168 { 169 *pValueOut = i->second; 170 return true; 171 } 172 } 173 174 return false; 175 } GetHeaders()176 std::vector<Header> GetHeaders() { return mExtraHeaders; } 177 178 // -------------------------------------------------------------------------- 179 // 180 // Function 181 // Name: HTTPRequest::GetClientKeepAliveRequested() 182 // Purpose: Returns true if the client requested that the connection 183 // should be kept open for further requests. 184 // Created: 22/12/04 185 // 186 // -------------------------------------------------------------------------- GetClientKeepAliveRequested()187 bool GetClientKeepAliveRequested() const {return mClientKeepAliveRequested;} SetClientKeepAliveRequested(bool keepAlive)188 void SetClientKeepAliveRequested(bool keepAlive) 189 { 190 mClientKeepAliveRequested = keepAlive; 191 } 192 AddHeader(const std::string & rName,const std::string & rValue)193 void AddHeader(const std::string& rName, const std::string& rValue) 194 { 195 mExtraHeaders.push_back(Header(ToLowerCase(rName), rValue)); 196 } IsExpectingContinue()197 bool IsExpectingContinue() const { return mExpectContinue; } GetVerb()198 const char* GetVerb() const 199 { 200 if (!mHttpVerb.empty()) 201 { 202 return mHttpVerb.c_str(); 203 } 204 switch (mMethod) 205 { 206 case Method_UNINITIALISED: return "Uninitialized"; 207 case Method_UNKNOWN: return "Unknown"; 208 case Method_GET: return "GET"; 209 case Method_HEAD: return "HEAD"; 210 case Method_POST: return "POST"; 211 case Method_PUT: return "PUT"; 212 } 213 return "Bad"; 214 } 215 216 private: 217 void ParseHeaders(IOStreamGetLine &rGetLine, int Timeout); 218 void ParseCookies(const std::string &rHeader, int DataStarts); 219 220 enum Method mMethod; 221 std::string mRequestURI; 222 std::string mHostName; 223 int mHostPort; 224 std::string mQueryString; 225 int mHTTPVersion; 226 Query_t mQuery; 227 int mContentLength; 228 std::string mContentType; 229 CookieJar_t *mpCookies; 230 bool mClientKeepAliveRequested; 231 std::vector<Header> mExtraHeaders; 232 bool mExpectContinue; 233 IOStream* mpStreamToReadFrom; 234 std::string mHttpVerb; 235 ToLowerCase(const std::string & rInput)236 std::string ToLowerCase(const std::string& rInput) const 237 { 238 std::string output = rInput; 239 for (std::string::iterator c = output.begin(); 240 c != output.end(); c++) 241 { 242 *c = tolower(*c); 243 } 244 return output; 245 } 246 }; 247 248 #endif // HTTPREQUEST__H 249 250