1 /* -*-mode:c++; c-file-style: "gnu";-*- */ 2 /* 3 * $Id: CgiEnvironment.h,v 1.21 2014/04/23 20:55:03 sebdiaz Exp $ 4 * 5 * Copyright (C) 1996 - 2004 Stephen F. Booth <sbooth@gnu.org> 6 * 2007 Sebastien DIAZ <sebastien.diaz@gmail.com> 7 * Part of the GNU cgicc library, http://www.gnu.org/software/cgicc 8 * 9 * This library is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU Lesser General Public 11 * License as published by the Free Software Foundation; either 12 * version 3 of the License, or (at your option) any later version. 13 * 14 * This library is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * Lesser General Public License for more details. 18 * 19 * You should have received a copy of the GNU Lesser General Public 20 * License along with this library; if not, write to the Free Software 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA 22 */ 23 24 #ifndef _CGIENVIRONMENT_H_ 25 #define _CGIENVIRONMENT_H_ 1 26 27 #ifdef __GNUG__ 28 # pragma interface 29 #endif 30 31 /*! \file CgiEnvironment.h 32 * \brief Class encapsulating the CGI runtime environment 33 * 34 * The \c CgiEnvironment class encapsulates the environment of 35 * the CGI application as described by the HTTP server. \c CgiEnvironment 36 * contains the \c GET or \c POST data along with all environment variables 37 * set by the HTTP server specified in the CGI specification. 38 */ 39 40 #include <string> 41 #include <vector> 42 #include <cstdlib> 43 44 #include "CgiDefs.h" 45 #include "CgiUtils.h" 46 #include "CgiInput.h" 47 #include "HTTPCookie.h" 48 49 namespace cgicc { 50 51 #ifdef WIN32 52 template class CGICC_API std::vector<HTTPCookie>; 53 #endif 54 55 // ============================================================ 56 // Iterator typedefs 57 // ============================================================ 58 59 //! A vector of HTTPCookie objects 60 typedef std::vector<HTTPCookie>::iterator cookie_iterator; 61 //! A vector of \c const HTTPCookie objects 62 typedef std::vector<HTTPCookie>::const_iterator const_cookie_iterator; 63 64 // ============================================================ 65 // Class CgiEnvironment 66 // ============================================================ 67 68 /*! \class CgiEnvironment CgiEnvironment.h cgicc/CgiEnvironment.h 69 * \brief Class encapsulating the CGI runtime environment 70 * 71 * The \c CgiEnvironment class encapsulates the environment of 72 * the CGI application as described by the HTTP server. \c CgiEnvironment 73 * contains the \c GET or \c POST data along with all environment variables 74 * set by the HTTP server specified in the CGI specification. 75 */ 76 class CGICC_API CgiEnvironment 77 { 78 public: 79 80 friend class Cgicc; 81 82 // ============================================================ 83 84 /*! \name Constructors and Destructor */ 85 //@{ 86 87 /*! 88 * \brief Read in the CGI environment passed to the CGI application 89 * by the server 90 * 91 * This function is not usually called directly; instead, an object of type 92 * CgiEnvironment is retrieved by calling the \c getEnvironment() method 93 * on Cgicc. 94 * If you are using %cgicc with FastCGI, you will need to pass 95 * a \c CgiInput subclass that %cgicc will use to read input. If 96 * \c input is omitted, standard input and environment 97 * variables will be used. 98 * \param input A CgiInput object to use for reading input 99 * \see Cgicc::getEnvironment 100 */ 101 CgiEnvironment(CgiInput *input); 102 103 /*! 104 * \brief Copy constructor. 105 * 106 * Sets the values of this CgiEnvironment to those of \c env. 107 * \param env The CgiEnvironment to copy. 108 */ 109 inline CgiEnvironment(const CgiEnvironment & env)110 CgiEnvironment(const CgiEnvironment& env) 111 { operator=(env); } 112 113 /*! 114 * \brief Destructor 115 * 116 * Delete this CgiEnvironment object 117 */ 118 ~CgiEnvironment(); 119 //@} 120 121 // ============================================================ 122 123 /*! \name Overloaded Operators */ 124 //@{ 125 126 /*! 127 * \brief Compare two CgiEnvironments for equality. 128 * 129 * CgiEnvironments are equal if they have the same environment variables. 130 * \param env The CgiEnvironment to compare to this one. 131 * \return \c true if the two CgiEnvironments are equal, \c false otherwise. 132 */ 133 bool 134 operator== (const CgiEnvironment& env) const; 135 136 /*! 137 * \brief Compare two CgiEnvironments for inequality. 138 * 139 * CgiEnvironments are equal if they have the same environment variables. 140 * \param env The CgiEnvironment to compare to this one. 141 * \return \c false if the two CgiEnvironments are equal, \c true otherwise. 142 */ 143 inline bool 144 operator!= (const CgiEnvironment& env) const 145 { return ! operator==(env); } 146 147 #ifdef WIN32 148 /* Dummy operator for MSVC++ */ 149 inline bool 150 operator< (const CgiEnvironment& env) const 151 { return false; } 152 #endif 153 154 /*! 155 * \brief Assign one CgiEnvironment to another. 156 * 157 * Sets the environment variables in this CgiEnvironment to those of \c env. 158 * \param env The CgiEnvironment to copy. 159 * \return A reference to this. 160 */ 161 CgiEnvironment& 162 operator= (const CgiEnvironment& env); 163 //@} 164 165 // ============================================================ 166 167 /*! \name Server Information 168 * Information on the server handling the HTTP/CGI request 169 */ 170 //@{ 171 172 /*! 173 * \brief Get the name and version of the HTTP server software 174 * 175 * For example, \c Apache/1.3.4 176 * \return The name of the server software 177 */ 178 inline std::string getServerSoftware()179 getServerSoftware() const 180 { return fServerSoftware; } 181 182 /*! 183 * \brief Get the hostname, DNS name or IP address of the HTTP server 184 * 185 * This is \e not a URL, for example \c www.gnu.org (no leading http://) 186 * \return The name of the server 187 */ 188 inline std::string getServerName()189 getServerName() const 190 { return fServerName; } 191 192 /*! 193 * \brief Get the name and version of the gateway interface. 194 * 195 * This is usually \c CGI/1.1 196 * \return The name and version of the gateway interface 197 */ 198 inline std::string getGatewayInterface()199 getGatewayInterface() const 200 { return fGatewayInterface;} 201 202 /*! 203 * \brief Get the name and revision of the protocol used for this request. 204 * 205 * This is usually \c HTTP/1.0 or \c HTTP/1.1 206 * \return The protocol in use 207 */ 208 inline std::string getServerProtocol()209 getServerProtocol() const 210 { return fServerProtocol; } 211 212 /*! 213 * \brief Get the port number on the server to which this request was sent. 214 * 215 * This will usually be 80. 216 * \return The port number 217 */ 218 inline unsigned long getServerPort()219 getServerPort() const 220 { return fServerPort; } 221 222 /*! 223 * \brief Determine if this is a secure request 224 * 225 * A secure request is usually made using SSL via HTTPS 226 * \return \c true if this connection is via https, \c false otherwise 227 */ 228 inline bool usingHTTPS()229 usingHTTPS() const 230 { return fUsingHTTPS; } 231 //@} 232 233 // ============================================================ 234 235 /*! \name CGI Query Information 236 * Information specific to this CGI query 237 */ 238 //@{ 239 240 /*! 241 * \brief Get the HTTP cookies associated with this query, if any. 242 * 243 * The string returned by this method may contain multiple cookies; it is 244 * recommended to use the method getCookieList() instead, which returns 245 * a \c vector<HTTPCookie>. 246 * \return The HTTP cookies 247 * \see getCookieList 248 */ 249 inline std::string getCookies()250 getCookies() const 251 { return fCookie; } 252 253 /*! 254 * \brief Get a \c vector containing the HTTP cookies 255 * associated with this query 256 * 257 * This vector may be empty 258 * \return A \c vector containing the HTTP cookies associated with this 259 * query 260 * \see HTTPCookie 261 */ 262 inline const std::vector<HTTPCookie>& getCookieList()263 getCookieList() const 264 { return fCookies; } 265 266 /*! 267 * \brief Get the request method used for this query. 268 * 269 * This is usually one of \c GET or \c POST 270 * \return The request method 271 */ 272 inline std::string getRequestMethod()273 getRequestMethod() const 274 { return fRequestMethod; } 275 276 /*! 277 * \brief Get the extra path information for this request, given by the 278 * client. 279 * 280 * For example, in the string \c foo.cgi/cgicc the path information is 281 * \c cgicc. 282 * \return The absolute path info 283 */ 284 inline std::string getPathInfo()285 getPathInfo() const 286 { return fPathInfo; } 287 288 /*! 289 * \brief Get the translated path information (virtual to physical mapping). 290 * 291 * For example, \c www.gnu.org may be translated to \c /htdocs/index.html 292 * \return The translated path info 293 */ 294 inline std::string getPathTranslated()295 getPathTranslated() const 296 { return fPathTranslated; } 297 298 /*! 299 * \brief Get the full path to this CGI application 300 * 301 * This is useful for self-referencing URIs 302 * \return The full path of this application 303 */ 304 inline std::string getScriptName()305 getScriptName() const 306 { return fScriptName; } 307 308 /*! 309 * \brief Get the query string for this request. 310 * 311 * The query string follows the <tt>?</tt> in the URI which called this 312 * application. This is usually only valid for scripts called with 313 * the \c GET method. For example, in the string \c foo.cgi?cgicc=yes 314 * the query string is \c cgicc=yes. 315 * @return The query string 316 */ 317 inline std::string getQueryString()318 getQueryString() const 319 { return fQueryString; } 320 321 /*! 322 * \brief Get the length of the data read from standard input, in chars. 323 * 324 * This is usually only valid for scripts called with the POST method. 325 * \return The data length 326 */ 327 inline unsigned long getContentLength()328 getContentLength() const 329 { return fContentLength; } 330 331 /*! 332 * \brief Get the content type of the submitted information. 333 * 334 * For applications called via the GET method, this information is 335 * irrelevant. For applications called with the POST method, this is 336 * specifies the MIME type of the information, 337 * usually \c application/x-www-form-urlencoded or as specified by 338 * getContentType(). 339 * \return The content type 340 * \see getContentType 341 */ 342 inline std::string getContentType()343 getContentType() const 344 { return fContentType; } 345 346 /*! 347 * \brief Get the data passed to the CGI application via standard input. 348 * 349 * This data is of MIME type \c getContentType(). 350 * \return The post data. 351 */ 352 inline std::string getPostData()353 getPostData() const 354 { return fPostData; } 355 //@} 356 357 // ============================================================ 358 359 /*! \name Server Specific Information 360 * Information dependent on the type of HTTP server in use 361 */ 362 //@{ 363 364 /*! 365 * \brief Get the URL of the page which called this CGI application. 366 * 367 * Depending on the HTTP server software, this value may not be set. 368 * \return The URI which called this application. 369 */ 370 inline std::string getReferrer()371 getReferrer() const 372 { return fReferrer; } 373 //@} 374 375 // ============================================================ 376 377 /*! \name Remote User Information 378 * Information about the user making the CGI request 379 */ 380 //@{ 381 382 /*! 383 * \brief Get the hostname of the remote machine making this request 384 * 385 * This may be either an IP address or a hostname 386 * \return The remote host 387 */ 388 inline std::string getRemoteHost()389 getRemoteHost() const 390 { return fRemoteHost; } 391 392 /*! 393 * \brief Get the IP address of the remote machine making this request 394 * 395 * This is a standard IP address of the form \c 123.123.123.123 396 * \return The remote IP address 397 */ 398 inline std::string getRemoteAddr()399 getRemoteAddr() const 400 { return fRemoteAddr; } 401 402 /*! 403 * \brief Get the protocol-specific user authentication method used. 404 * 405 * This is only applicable if the server supports user authentication, 406 * and the user has authenticated. 407 * \return The authorization type 408 */ 409 inline std::string getAuthType()410 getAuthType() const 411 { return fAuthType; } 412 413 /*! 414 * \brief Get the authenticated remote user name. 415 * 416 * This is only applicable if the server supports user authentication, 417 * and the user has authenticated. 418 * \return The remote username 419 */ 420 inline std::string getRemoteUser()421 getRemoteUser() const 422 { return fRemoteUser; } 423 424 /*! 425 * \brief Get the remote user name retrieved from the server. 426 * 427 * This is only applicable if the server supports RFC 931 428 * identification. This variable should \e only be used 429 * for logging purposes. 430 * \return The remote identification 431 * \see RFC 1431 at 432 * http://info.internet.isi.edu:80/in-notes/rfc/files/rfc1413.txt 433 */ 434 inline std::string getRemoteIdent()435 getRemoteIdent() const 436 { return fRemoteIdent; } 437 438 /*! 439 * \brief Get the MIME data types accepted by the client's browser. 440 * 441 * For example <TT>image/gif, image/x-xbitmap, image/jpeg, image/pjpeg</TT> 442 * \return The accepted data types 443 */ 444 inline std::string getAccept()445 getAccept() const 446 { return fAccept; } 447 448 /*! 449 * \brief Get the name of the browser used for this CGI request. 450 * 451 * For example <TT>Mozilla/5.0 (X11; U; Linux 2.4.0 i686; en-US; 0.8.1) 452 * Gecko/20010421</TT> 453 * \return The browser name 454 */ 455 inline std::string getUserAgent()456 getUserAgent() const 457 { return fUserAgent; } 458 //@} 459 460 // ============================================================ 461 462 /*! \name ErrorDocument Handling 463 * For a tutorial on ErrorDocument handling, see 464 * http://hoohoo.ncsa.uiuc.edu/cgi/ErrorCGI.html 465 */ 466 //@{ 467 468 /*! 469 * \brief Get the redirect request. 470 * 471 * This will only be valid if you are using this script as a script 472 * to use in place of the default server messages. 473 * @return The redirect request. 474 */ 475 inline std::string getRedirectRequest()476 getRedirectRequest() const 477 { return fRedirectRequest; } 478 479 /*! 480 * \brief Get the redirect URL. 481 * 482 * This will only be valid if you are using this script as a script 483 * to use in place of the default server messages. 484 * \return The redirect URL. 485 * \see http://hoohoo.ncsa.uiuc.edu/docs/setup/srm/ErrorDocument.html 486 */ 487 inline std::string getRedirectURL()488 getRedirectURL() const 489 { return fRedirectURL; } 490 491 /*! 492 * \brief Get the redirect status. 493 * 494 * This will only be valid if you are using this script as a script 495 * to use in place of the default server messages. 496 * \return The redirect status. 497 */ 498 inline std::string getRedirectStatus()499 getRedirectStatus() const 500 { return fRedirectStatus; } 501 //@} 502 503 protected: 504 505 // ============================================================ 506 507 /*! \name Saving and Restoring 508 * These are implementation methods only 509 */ 510 //@{ 511 512 /*! 513 * \brief Implementation of save, for saving CGI environments 514 * 515 * This is called internally by Cgicc 516 * \param filename The name of the file to which to save 517 */ 518 void 519 save(const std::string& filename) const; 520 521 /*! 522 * \brief Implementation of restore, for restoring CGI environments 523 * 524 * This is called internally by Cgicc 525 * \param filename The name of the file from which to restore 526 */ 527 // Implementation of restore 528 void 529 restore(const std::string& filename); 530 //@} 531 532 // ============================================================ 533 534 private: 535 536 // Parse the list of cookies from a string to a vector 537 void 538 parseCookies(); 539 540 // Parse a single cookie string (name=value) pair 541 void 542 parseCookie(const std::string& data); 543 544 // Read in all the environment variables 545 void 546 readEnvironmentVariables(CgiInput *input); 547 548 unsigned long fServerPort; 549 unsigned long fContentLength; 550 bool fUsingHTTPS; 551 std::string fServerSoftware; 552 std::string fServerName; 553 std::string fGatewayInterface; 554 std::string fServerProtocol; 555 std::string fRequestMethod; 556 std::string fPathInfo; 557 std::string fPathTranslated; 558 std::string fScriptName; 559 std::string fQueryString; 560 std::string fRemoteHost; 561 std::string fRemoteAddr; 562 std::string fAuthType; 563 std::string fRemoteUser; 564 std::string fRemoteIdent; 565 std::string fContentType; 566 std::string fAccept; 567 std::string fUserAgent; 568 std::string fPostData; 569 std::string fRedirectRequest; 570 std::string fRedirectURL; 571 std::string fRedirectStatus; 572 std::string fReferrer; 573 std::string fCookie; 574 std::vector<HTTPCookie> fCookies; 575 std::string fAcceptLanguageString; 576 }; 577 578 } // namespace cgicc 579 580 #endif /* ! _CGIENVIRONMENT_H_ */ 581