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