CGI.cc

00001 /*
00002  * $Id: CGI.cc,v 1.38 2006/04/03 15:11:18 brook Exp $
00003  */
00004 
00005 /*
00006  * ClearSilver++ Software License.
00007  *
00008  * Copyright (c) 2005,2006 Brook Milligan <brook@nmsu.edu>
00009  * All rights reserved.
00010  * 
00011  * Redistribution and use in source and binary forms, with or without
00012  * modification, are permitted provided that the following conditions
00013  * are met:
00014  * 
00015  * 1. Redistributions of source code must retain the above copyright
00016  *    notice, this list of conditions and the following disclaimer.
00017  * 2. Redistributions in binary form must reproduce the above
00018  *    copyright notice, this list of conditions and the following
00019  *    disclaimer in the documentation and/or other materials provided
00020  *    with the distribution.
00021  * 3. The name of the author may not be used to endorse or promote
00022  *    products derived from this software without specific prior
00023  *    written permission.
00024  * 
00025  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
00026  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00027  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00028  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
00029  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00030  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
00031  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00032  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
00033  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036  */
00037 
00038 #include "CGI.h"
00039 
00040 #include <stdexcept>
00041 #if __GNUC__ >= 3
00042 #include <ext/stdio_filebuf.h>
00043 #else
00044 #include <stdiostream.h>
00045 #endif
00046 #include <syslog.h>
00047 
00048 #include "ClearSilverError.h"
00049 #include "ClearSilverException.h"
00050 #include "URL.h"
00051 
00052 #define CGI ClearSilverCGI
00053 #define HDF ClearSilverHDF
00054 #include <ClearSilver.h>
00055 #undef CGI
00056 #undef HDF
00057 
00058 using namespace std;
00059 
00060 namespace ClearSilver
00061 {
00062 
00063   static void cgi_free (ClearSilverCGI*);
00064 
00065                                 // constructors
00066   CGI::CGI ()
00067     : TraceObject(debug(), "CGI"), cgi_(), hdf_()
00068   {
00069     ClearSilverCGI* cgi;
00070     ClearSilverError error (cgi_init (&cgi, 0));
00071     if (error)
00072       {
00073         string message;
00074         message += "ClearSilver::Nodes::CGI::CGI (const HDF&): ";
00075         ClearSilverException e (message);
00076         e += error;
00077         throw e;
00078       }
00079     error = ClearSilverError (cgi_parse (cgi));
00080     if (error)
00081       {
00082         string message;
00083         message += "ClearSilver::Nodes::CGI::CGI (const HDF&): ";
00084         ClearSilverException e (message);
00085         e += error;
00086         throw e;
00087       }
00088     cgi_ = Ptr(cgi, cgi_free);
00089     hdf_ = HDF(RootNode(cgi_->hdf, true));
00090   }
00091 
00092   CGI::CGI (const HDF& hdf)
00093     : TraceObject(debug(), "CGI", "const HDF&"), cgi_(), hdf_(hdf)
00094   {
00095     ClearSilverCGI* cgi;
00096     ClearSilverError error (cgi_init (&cgi, hdf.root().get()));
00097     if (error)
00098       {
00099         string message;
00100         message += "ClearSilver::Nodes::CGI::CGI (const HDF&): ";
00101         ClearSilverException e (message);
00102         e += error;
00103         throw e;
00104       }
00105     error = ClearSilverError (cgi_parse (cgi));
00106     if (error)
00107       {
00108         string message;
00109         message += "ClearSilver::Nodes::CGI::CGI (const HDF&): ";
00110         ClearSilverException e (message);
00111         e += error;
00112         throw e;
00113       }
00114     cgi_ = Ptr(cgi, cgi_free);
00115   }
00116 
00117   CGI::CGI (const CGI& cgi)
00118     : TraceObject(cgi), cgi_(cgi.cgi_), hdf_(cgi.hdf_) {}
00119 
00120   CGI::~CGI () throw() {}
00121 
00122                                 // assignment
00123   CGI&
00124   CGI::operator = (const CGI& cgi)
00125   {
00126     TraceObject::operator = (cgi);
00127     CGI cgi_(cgi);
00128     swap(cgi_);
00129     return *this;
00130   }
00131 
00132                                 // swap contents
00133   void
00134   CGI::swap (CGI& cgi) throw()
00135   {
00136     TraceObject::swap (cgi);
00137     cgi_.swap(cgi.cgi_);
00138     hdf_.swap(cgi.hdf_);
00139   }
00140 
00141                                 // conversions
00142                                 // XXX - assume knowledge of data structure
00143   CGI::operator bool () const
00144   {
00145     return cgi_->hdf && hdf().find("CGI") != hdf().end();
00146   }
00147 
00148                                 // data access
00149   ConstHDF
00150   CGI::hdf () const
00151   {
00152     return ConstHDF (hdf_);
00153   }
00154 
00155   HDF
00156   CGI::hdf ()
00157   {
00158     return hdf_;
00159   }
00160 
00161   string
00162   CGI::DocumentRoot () const
00163   {
00164     return string(hdf()["CGI.DocumentRoot"]);
00165   }
00166 
00167   string
00168   CGI::ScriptFilename () const
00169   {
00170     return string(hdf()["CGI.ScriptFilename"]);
00171   }
00172 
00173   string
00174   CGI::ScriptDirectory () const
00175   {
00176     string script_file = hdf().get_value ("CGI.ScriptFilename");
00177     string::size_type n = script_file.rfind ('/');
00178     string cgi_directory (script_file, 0, n);
00179     return cgi_directory;
00180   }
00181 
00182   string
00183   CGI::ScriptBasename () const
00184   {
00185     string script_file = hdf().get_value ("CGI.ScriptFilename");
00186     string::size_type n = script_file.rfind ('/');
00187     string cgi_basename (script_file, n+1);
00188     return cgi_basename;
00189   }
00190 
00191   string
00192   CGI::ScriptBasename (const char * suffix) const
00193   {
00194     string s (suffix);
00195     return ScriptBasename (s);
00196   }
00197 
00198   string
00199   CGI::ScriptBasename (const string& suffix) const
00200   {
00201     string cgi_basename = ScriptBasename();
00202     string::size_type n = cgi_basename.rfind (suffix);
00203     if (n != string::npos)
00204       cgi_basename.erase (n);
00205     return cgi_basename;
00206   }
00207 
00208                                 // display
00209   void
00210   CGI::display (const char* cs_filename) const
00211   {
00212     display (string(cs_filename));
00213   }
00214 
00215   void
00216   CGI::display (const string& cs_filename) const
00217   {
00218     ClearSilverError error (cgi_display (cgi_.get(), cs_filename.c_str()));
00219     if (error)
00220       {
00221         string message;
00222         message += "ClearSilver::CGI::display (const string& filename): ";
00223         message += "filename=" + cs_filename + ": ";
00224         ClearSilverException e (message);
00225         e += error;
00226         throw e;
00227       }
00228   }
00229 
00230                                 // URI redirection
00231                                 // redirect to a full URI.
00232   void
00233   CGI::redirect (const URL& url)
00234   {
00235     cgi_redirect_uri (cgi_.get(), "%s", url().c_str());
00236   }
00237 
00238                                 // redirect to a new path
00239                                 // within the same protocol/host/port.
00240   void
00241   CGI::redirect_path (const URL& path)
00242   {
00243     cgi_redirect (cgi_.get(), "%s", path().c_str());
00244   }
00245 
00246                                 // cookie management
00247   void
00248   CGI::set (const Cookie& c)
00249   {
00250     ClearSilverError error
00251       (cgi_cookie_set
00252        (cgi_.get(),
00253         c.name().c_str(),
00254         c.value().c_str(),
00255         c.credentials().path().empty()?
00256         static_cast<const char*>(0) : c.credentials().path()().c_str(),
00257         c.credentials().authority().empty()?
00258         static_cast<const char*>(0) : c.credentials().authority()().c_str(),
00259         c.credentials().persist() && !c.credentials().expires().empty()?
00260         c.credentials().expires()().c_str() : static_cast<const char*>(0),
00261         c.credentials().persist()? 1 : 0,
00262         c.credentials().secure()? 1 : 0));
00263     if (error)
00264       {
00265         string message;
00266         message += "ClearSilver::CGI::set (const Cookie&): ";
00267         ClearSilverException e (message);
00268         e += error;
00269         throw e;
00270       }
00271   }
00272 
00273   void
00274   CGI::clear (const Cookie& c)
00275   {
00276     ClearSilverError error
00277       (cgi_cookie_clear
00278        (cgi_.get(),
00279         c.name().c_str(),
00280         c.credentials().authority().empty()?
00281         static_cast<const char*>(0) : c.credentials().authority()().c_str(),
00282         c.credentials().path().empty()?
00283         static_cast<const char*>(0) : c.credentials().path()().c_str()));
00284     if (error)
00285       {
00286         string message;
00287         message += "ClearSilver::CGI::clear (const Cookie&): ";
00288         ClearSilverException e (message);
00289         e += error;
00290         throw e;
00291       }
00292   }
00293 
00294                                 // debug flag.
00295   bool&
00296   CGI::debug ()
00297   {
00298     static bool debug_ = false;
00299     return debug_;
00300   }
00301 
00302 
00303   Cookie::Authority
00304   CGI::cookie_authority (const char * host) const
00305   {
00306     return cookie_authority (string (host));
00307   }
00308 
00309   Cookie::Authority
00310   CGI::cookie_authority (const string& host) const
00311   {
00312     return Cookie::Authority (cgi_cookie_authority (cgi_.get(), host.c_str()));
00313   }
00314 
00315                                 // file upload handling
00316   FILE*
00317   CGI::upload () const
00318   {
00319     return upload (0);
00320   }
00321 
00322   FILE*
00323   CGI::upload (const char * form) const
00324   {
00325     return upload (form? string(form) : string());
00326   }
00327 
00328   FILE*
00329   CGI::upload (const string& form) const
00330   {
00331     FILE* f = cgi_filehandle
00332       (cgi_.get(), form.empty()? static_cast<char*>(0) : form.c_str());
00333     return f;
00334   }
00335 
00336   /*
00337    * This function should only be called when the boost::shared_ptr
00338    * destroys the ClearSilver C API CGI structure.  However, the HDF
00339    * object associated with the corresponding CGI object owns the HDF
00340    * dataset memory pointed to by the CGI structure.  Consequently, the
00341    * pointer within the CGI structure must be disassociated from the HDF
00342    * dataset prior to destroying the CGI structure.
00343    */
00344 
00345   void
00346   cgi_free (ClearSilverCGI* cgi)
00347   {
00348     syslog (LOG_DEBUG, "%s", "ClearSilver::cgi_free(ClearSilverCGI*)"); // XXX
00349     cgi->hdf = 0;               // XXX - see above.
00350     cgi_destroy (&cgi);
00351   }
00352 };                              // namespace ClearSilver

Generated on Tue May 16 14:50:52 2006 for ClearSilver C++ Library by  doxygen 1.4.5