BESApacheInterface.cc

Go to the documentation of this file.
00001 // BESApacheInterface.cc
00002 
00003 // This file is part of bes, A C++ back-end server implementation framework
00004 // for the OPeNDAP Data Access Protocol.
00005 
00006 // Copyright (c) 2004,2005 University Corporation for Atmospheric Research
00007 // Author: Patrick West <pwest@ucar.edu> and Jose Garcia <jgarcia@ucar.edu>
00008 //
00009 // This library is free software; you can redistribute it and/or
00010 // modify it under the terms of the GNU Lesser General Public
00011 // License as published by the Free Software Foundation; either
00012 // version 2.1 of the License, or (at your option) any later version.
00013 // 
00014 // This library is distributed in the hope that it will be useful,
00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017 // Lesser General Public License for more details.
00018 // 
00019 // You should have received a copy of the GNU Lesser General Public
00020 // License along with this library; if not, write to the Free Software
00021 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022 //
00023 // You can contact University Corporation for Atmospheric Research at
00024 // 3080 Center Green Drive, Boulder, CO 80301
00025  
00026 // (c) COPYRIGHT University Corporation for Atmospheric Research 2004-2005
00027 // Please read the full copyright statement in the file COPYRIGHT_UCAR.
00028 //
00029 // Authors:
00030 //      pwest       Patrick West <pwest@ucar.edu>
00031 //      jgarcia     Jose Garcia <jgarcia@ucar.edu>
00032 
00033 #include <iostream>
00034 
00035 using std::endl ;
00036 
00037 #include "BESApacheInterface.h"
00038 #include "BESMemoryManager.h"
00039 
00040 #include "BESLog.h"
00041 #include "TheBESKeys.h"
00042 #include "BESMemoryGlobalArea.h"
00043 #include "BESStatusReturn.h"
00044 #include "BESIncorrectRequestException.h"
00045 #include "BESUtil.h"
00046 #include "BESBasicHttpTransmitter.h"
00047 #include "BESTransmitException.h"
00048 #include "BESAggregationServer.h"
00049 #include "BESDataNames.h"
00050 
00051 #define DEFAULT_ADMINISTRATOR "support@opendap.org"
00052 
00060 BESApacheInterface::BESApacheInterface( const BESDataRequestInterface &dri )
00061     : BESCmdInterface()
00062 {
00063     _dri = &dri ;
00064 }
00065 
00066 BESApacheInterface::~BESApacheInterface()
00067 {
00068     clean() ;
00069 }
00070 
00081 int
00082 BESApacheInterface::execute_request()
00083 {
00084     BESMemoryManager::register_global_pool() ; 
00085 
00086     int status = BESCmdInterface::execute_request( "cedar" ) ;
00087 
00088     if( !BESMemoryManager::unregister_global_pool() )
00089         return BES_TERMINATE_IMMEDIATE ;
00090 
00091     return status;
00092 }
00093 
00101 void
00102 find_user_from_cookie( const char *cookie, string &user )
00103 {
00104     if( cookie )
00105     {
00106         string s_cookie = cookie ;
00107         string var = "OpenDAP.remoteuser=" ;
00108         int user_var = s_cookie.find( var ) ;
00109         if( user_var >= 0 )
00110         {
00111             string s_user_var = s_cookie.substr( user_var + var.length(),
00112                                                  s_cookie.length() ) ;
00113             int semi = s_user_var.find( ";" ) ;
00114             if( semi < 0 )
00115             {
00116                 user = s_user_var ;
00117             }
00118             else
00119             {
00120                 user = s_user_var.substr( 0, semi ) ;
00121             }
00122         }
00123     }
00124 }
00125 
00144 void
00145 BESApacheInterface::initialize()
00146 {
00147     BESMemoryManager::initialize_memory_pool() ;
00148 
00149     string https = _dri->server_protocol ;
00150     std::string::size_type http = https.find("HTTP");
00151     if( http == string::npos )
00152     {
00153         _dhi.transmit_protocol = _dri->server_protocol ;
00154     }
00155     else
00156     {
00157         _dhi.transmit_protocol = "HTTP" ;
00158     }
00159 
00160     _dhi.data[USER_ADDRESS] = _dri->user_address ;
00161     _dhi.data[DATA_REQUEST] = _dri->request ;
00162 
00163     string user = "undef" ;
00164     if( _dri->cookie )
00165     {
00166         find_user_from_cookie( _dri->cookie, user ) ;
00167     }
00168 
00169     _dhi.data[USER_NAME] = user ;
00170     _dhi.data[USER_TOKEN] = _dri->token ;
00171 
00172     if( BESLog::TheLog() && BESLog::TheLog()->is_verbose() )
00173     {
00174         *(BESLog::TheLog()) << "Data Request Interface:" << endl ;
00175         *(BESLog::TheLog()) << "    server_name = " << _dri->server_name << endl ;
00176         *(BESLog::TheLog()) << "    server_address = " << _dri->server_address << endl ;
00177         *(BESLog::TheLog()) << "    server_protocol = " << _dri->server_protocol << endl ;
00178         *(BESLog::TheLog()) << "    server_port = " << _dri->server_port << endl ;
00179         *(BESLog::TheLog()) << "    script_name = " << _dri->script_name << endl ;
00180         *(BESLog::TheLog()) << "    user_address = " << _dri->user_address << endl ;
00181         *(BESLog::TheLog()) << "    user_agent = " << _dri->user_agent << endl ;
00182         *(BESLog::TheLog()) << "    request = " << _dri->request << endl ;
00183         if( _dri->cookie )
00184             *(BESLog::TheLog()) << "    cookie = " << _dri->cookie << endl ;
00185         else
00186             *(BESLog::TheLog()) << "    cookie = no cookie set" << endl ;
00187     }
00188 
00189     BESCmdInterface::initialize() ;
00190 }
00191 
00194 void
00195 BESApacheInterface::validate_data_request()
00196 {
00197     if (!_dri->server_name)
00198         throw BESIncorrectRequestException("undefined server name", __FILE__, __LINE__ );
00199     if(!_dri->server_address)
00200         throw BESIncorrectRequestException("undefined server address", __FILE__, __LINE__ );
00201     if(!_dri->server_protocol)
00202         throw BESIncorrectRequestException("undefined server protocol", __FILE__, __LINE__ );
00203     if(!_dri->server_port)
00204         throw BESIncorrectRequestException("undefined server port", __FILE__, __LINE__ );
00205     if(!_dri->script_name)
00206         throw BESIncorrectRequestException("undefined script name", __FILE__, __LINE__ );
00207     if(!_dri->user_address)
00208         throw BESIncorrectRequestException("undefined user address", __FILE__, __LINE__ );
00209     if(!_dri->user_agent)
00210         throw BESIncorrectRequestException("undefined user agent", __FILE__, __LINE__ );
00211     if(!_dri->request)
00212         throw BESIncorrectRequestException("undefined request", __FILE__, __LINE__ );
00213 }
00214 
00232 int
00233 BESApacheInterface::exception_manager( BESException &e )
00234 {
00235     bool ishttp = false ;
00236     if( _dhi.transmit_protocol == "HTTP" )
00237         ishttp = true ;
00238 
00239     BESIncorrectRequestException *ireqx=dynamic_cast<BESIncorrectRequestException*>(&e);
00240     if (ireqx)
00241     {
00242         if (e.get_message()=="undefined request")
00243         {
00244             // Everything is OK but  BESDataRequestInterface::request is null.
00245             if( ishttp )
00246             {
00247                 welcome_browser();
00248             }
00249         }
00250         else
00251         {
00252             return BESCmdInterface::exception_manager( e ) ;
00253         }
00254         return BES_REQUEST_INCORRECT;
00255     }
00256     return BESCmdInterface::exception_manager( e ) ;
00257 }
00258 
00259 void
00260 BESApacheInterface::welcome_browser()
00261 {
00262     string who = _dri->user_address ;
00263     string agent = _dri->user_agent ;
00264     if( BESLog::TheLog() )
00265         (*BESLog::TheLog()) << "Incoming request from " << who.c_str() << " using " << agent.c_str() << endl;
00266 
00267     // see if request comes from the Netscape or the HotJava...
00268     int mo=agent.find("Mozilla");
00269     int ho=agent.find("HotJava");
00270     if ((mo<0)&&(ho<0)) // No, sorry. For you just a message and good bye :-(
00271     {
00272         BESUtil::set_mime_text( stdout ) ;
00273         bool found = false ;
00274         string administrator =
00275             TheBESKeys::TheKeys()->get_key( "BES.ServerAdministrator", found ) ;
00276         if(administrator=="")
00277             cout << "BES: internal server error please contact"
00278                  << DEFAULT_ADMINISTRATOR
00279                  << "with the following message:\n" ;
00280         else
00281             cout << "BES: internal server error please contact"
00282                  << administrator.c_str()
00283                  << "with the following message:\n" ;
00284         cout << "BES: can not interact with browser" << agent.c_str() << endl ;
00285     }
00286     else // Yes, _agent contains the signature of a browser               
00287     {
00288         bool found = false ;
00289         string method =
00290             TheBESKeys::TheKeys()->get_key( "BES.DefaultResponseMethod", found ) ;
00291         if( (method!="GET") && (method!="POST") )
00292         {
00293             BESUtil::set_mime_text( stdout ) ;
00294             found = false ;
00295             string administrator =
00296                 TheBESKeys::TheKeys()->get_key( "BES.ServerAdministrator", found ) ;
00297             if(administrator=="")
00298                 cout << "BES: internal server error please contact"
00299                      << DEFAULT_ADMINISTRATOR
00300                      << "with the following message:\n" ;
00301             else
00302                 cout << "BES: internal server error please contact"
00303                      << administrator.c_str()
00304                      << "with the following message:\n" ;
00305             cout << "BES: fatal, can not get/understand the key BES.DefaultResponseMethod"
00306                  << endl ;
00307         }
00308         else
00309         {
00310             cout << "HTTP/1.0 200 OK\n" ;
00311             cout << "Content-type: text/html\n\n" ;
00312             cout << flush ;
00313 
00314             cout << "<HTML>\n" ;
00315             cout << "<HEAD>\n" ;
00316             cout << "<TITLE> Request to the BES server</TITLE>\n" ;
00317             cout << "<BODY>\n" ;
00318             if (method=="GET")
00319                 cout << "<form action=\"http://" << _dri->server_name
00320                      << ":" << _dri->server_port << _dri->script_name
00321                      << "\" method=get>\n" ;
00322             else if (method=="POST")
00323                 cout << "<form action=\"http://" << _dri->server_name
00324                      << ":" << _dri->server_port << _dri->script_name
00325                      << "\" method=post>\n" ;
00326 
00327             cout << "<p>Request: <br><textarea name=\"request\" cols=85 rows=11 size=40,4 wrap=\"virtual\" ></textarea></p>\n" ;
00328             cout << "<input type=\"submit\" value=\"Submit to BES\">\n" ;
00329             cout << "<input type=\"reset\" value=\"Clean Text Field\">\n" ;
00330             cout << "</form>\n" ;
00331             cout << "</body>\n" ;
00332             cout << "</html>\n" ;
00333         }
00334     }
00335 }
00336 

Generated on Wed Jan 2 06:00:39 2008 for OPeNDAP Back End Server (BES) by  doxygen 1.5.4