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-2009 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::cout ;
00036 using std::endl ;
00037 using std::flush ;
00038 
00039 #include "BESApacheInterface.h"
00040 #include "BESMemoryManager.h"
00041 
00042 #include "BESLog.h"
00043 #include "TheBESKeys.h"
00044 #include "BESMemoryGlobalArea.h"
00045 #include "BESInternalError.h"
00046 #include "BESUtil.h"
00047 #include "BESBasicHttpTransmitter.h"
00048 #include "BESAggregationServer.h"
00049 #include "BESDataNames.h"
00050 #include "BESDebug.h"
00051 
00052 #define DEFAULT_ADMINISTRATOR "cedar_db@hao.ucar.edu"
00053 #define INCORRECT_REQUEST (BES_NOT_FOUND_ERROR + 1)
00054 #define INCORRECT_REQUEST_MSG "undefined request"
00055 
00063 BESApacheInterface::BESApacheInterface( const BESDataRequestInterface &dri )
00064     : BESCmdInterface( "", &cout )
00065 {
00066     _dri = &dri ;
00067 }
00068 
00069 BESApacheInterface::~BESApacheInterface()
00070 {
00071     clean() ;
00072 }
00073 
00084 int
00085 BESApacheInterface::execute_request()
00086 {
00087     BESMemoryManager::register_global_pool() ; 
00088 
00089     int status = BESCmdInterface::execute_request( "cedar" ) ;
00090 
00091     if( !BESMemoryManager::unregister_global_pool() )
00092         return BES_INTERNAL_FATAL_ERROR ;
00093 
00094     return status;
00095 }
00096 
00104 void
00105 find_user_from_cookie( const char *cookie, string &user )
00106 {
00107     if( cookie )
00108     {
00109         string s_cookie = cookie ;
00110         string var = "OpenDAP.remoteuser=" ;
00111         int user_var = s_cookie.find( var ) ;
00112         if( user_var >= 0 )
00113         {
00114             string s_user_var = s_cookie.substr( user_var + var.length(),
00115                                                  s_cookie.length() ) ;
00116             int semi = s_user_var.find( ";" ) ;
00117             if( semi < 0 )
00118             {
00119                 user = s_user_var ;
00120             }
00121             else
00122             {
00123                 user = s_user_var.substr( 0, semi ) ;
00124             }
00125         }
00126     }
00127 }
00128 
00147 void
00148 BESApacheInterface::initialize()
00149 {
00150     BESMemoryManager::initialize_memory_pool() ;
00151 
00152     string https = _dri->server_protocol ;
00153     std::string::size_type http = https.find("HTTP");
00154     if( http == string::npos )
00155     {
00156         _dhi.transmit_protocol = _dri->server_protocol ;
00157     }
00158     else
00159     {
00160         _dhi.transmit_protocol = "HTTP" ;
00161     }
00162 
00163     _dhi.data[USER_ADDRESS] = _dri->user_address ;
00164     _dhi.data[DATA_REQUEST] = _dri->request ;
00165 
00166     string user = "undef" ;
00167     if( _dri->cookie )
00168     {
00169         find_user_from_cookie( _dri->cookie, user ) ;
00170     }
00171 
00172     _dhi.data[USER_NAME] = user ;
00173     _dhi.data[USER_TOKEN] = _dri->token ;
00174 
00175     if( BESLog::TheLog() && BESLog::TheLog()->is_verbose() )
00176     {
00177         *(BESLog::TheLog()) << "Data Request Interface:" << endl ;
00178         *(BESLog::TheLog()) << "    server_name = " << _dri->server_name << endl ;
00179         *(BESLog::TheLog()) << "    server_address = " << _dri->server_address << endl ;
00180         *(BESLog::TheLog()) << "    server_protocol = " << _dri->server_protocol << endl ;
00181         *(BESLog::TheLog()) << "    server_port = " << _dri->server_port << endl ;
00182         *(BESLog::TheLog()) << "    script_name = " << _dri->script_name << endl ;
00183         *(BESLog::TheLog()) << "    user_address = " << _dri->user_address << endl ;
00184         *(BESLog::TheLog()) << "    user_agent = " << _dri->user_agent << endl ;
00185         *(BESLog::TheLog()) << "    request = " << _dri->request << endl ;
00186         if( _dri->cookie )
00187             *(BESLog::TheLog()) << "    cookie = " << _dri->cookie << endl ;
00188         else
00189             *(BESLog::TheLog()) << "    cookie = no cookie set" << endl ;
00190     }
00191 
00192     BESDEBUG( "apache", "BESApacheInterface dhi = " << _dhi << endl )
00193 
00194     BESCmdInterface::initialize() ;
00195 }
00196 
00199 void
00200 BESApacheInterface::validate_data_request()
00201 {
00202     if (!_dri->server_name)
00203     {
00204         BESInternalError e("undefined server name", __FILE__, __LINE__ );
00205         e.set_error_type( INCORRECT_REQUEST ) ;
00206         throw e ;
00207     }
00208     if(!_dri->server_address)
00209     {
00210         BESInternalError e("undefined server address", __FILE__, __LINE__ );
00211         e.set_error_type( INCORRECT_REQUEST ) ;
00212         throw e ;
00213     }
00214     if(!_dri->server_protocol)
00215     {
00216         BESInternalError e("undefined server protocol", __FILE__, __LINE__ );
00217         e.set_error_type( INCORRECT_REQUEST ) ;
00218         throw e ;
00219     }
00220     if(!_dri->server_port)
00221     {
00222         BESInternalError e("undefined server port", __FILE__, __LINE__ );
00223         e.set_error_type( INCORRECT_REQUEST ) ;
00224         throw e ;
00225     }
00226     if(!_dri->script_name)
00227     {
00228         BESInternalError e("undefined script name", __FILE__, __LINE__ );
00229         e.set_error_type( INCORRECT_REQUEST ) ;
00230         throw e ;
00231     }
00232     if(!_dri->user_address)
00233     {
00234         BESInternalError e("undefined user address", __FILE__, __LINE__ );
00235         e.set_error_type( INCORRECT_REQUEST ) ;
00236         throw e ;
00237     }
00238     if(!_dri->user_agent)
00239     {
00240         BESInternalError e("undefined user agent", __FILE__, __LINE__ );
00241         e.set_error_type( INCORRECT_REQUEST ) ;
00242         throw e ;
00243     }
00244     if(!_dri->request)
00245     {
00246         BESInternalError e(INCORRECT_REQUEST_MSG, __FILE__, __LINE__ );
00247         e.set_error_type( INCORRECT_REQUEST ) ;
00248         throw e ;
00249     }
00250 }
00251 
00269 int
00270 BESApacheInterface::exception_manager( BESError &e )
00271 {
00272     bool ishttp = false ;
00273     if( _dhi.transmit_protocol == "HTTP" )
00274         ishttp = true ;
00275 
00276     if( e.get_error_type() == INCORRECT_REQUEST )
00277     {
00278         if( e.get_message() == INCORRECT_REQUEST_MSG )
00279         {
00280             // Everything is OK but  BESDataRequestInterface::request is null.
00281             if( ishttp )
00282             {
00283                 welcome_browser();
00284             }
00285         }
00286         else
00287         {
00288             return BESCmdInterface::exception_manager( e ) ;
00289         }
00290         return BES_INTERNAL_ERROR ;
00291     }
00292     return BESCmdInterface::exception_manager( e ) ;
00293 }
00294 
00295 void
00296 BESApacheInterface::welcome_browser()
00297 {
00298     string who = _dri->user_address ;
00299     string agent = _dri->user_agent ;
00300     if( BESLog::TheLog() )
00301         (*BESLog::TheLog()) << "Incoming request from " << who.c_str() << " using " << agent.c_str() << endl;
00302 
00303     // see if request comes from the Netscape or the HotJava...
00304     int mo=agent.find("Mozilla");
00305     int ho=agent.find("HotJava");
00306     if ((mo<0)&&(ho<0)) // No, sorry. For you just a message and good bye :-(
00307     {
00308         BESUtil::set_mime_text( cout ) ;
00309         bool found = false ;
00310         string administrator =
00311             TheBESKeys::TheKeys()->get_key( "BES.ServerAdministrator", found ) ;
00312         if(administrator=="")
00313             cout << "BES: internal server error please contact"
00314                  << DEFAULT_ADMINISTRATOR
00315                  << "with the following message:\n" ;
00316         else
00317             cout << "BES: internal server error please contact"
00318                  << administrator.c_str()
00319                  << "with the following message:\n" ;
00320         cout << "BES: cannot interact with browser" << agent.c_str() << endl ;
00321     }
00322     else // Yes, _agent contains the signature of a browser               
00323     {
00324         bool found = false ;
00325         string method =
00326             TheBESKeys::TheKeys()->get_key( "BES.DefaultResponseMethod", found ) ;
00327         if( (method!="GET") && (method!="POST") )
00328         {
00329             BESUtil::set_mime_text( cout ) ;
00330             found = false ;
00331             string administrator =
00332                 TheBESKeys::TheKeys()->get_key( "BES.ServerAdministrator", found ) ;
00333             if(administrator=="")
00334                 cout << "BES: internal server error please contact"
00335                      << DEFAULT_ADMINISTRATOR
00336                      << "with the following message:\n" ;
00337             else
00338                 cout << "BES: internal server error please contact"
00339                      << administrator.c_str()
00340                      << "with the following message:\n" ;
00341             cout << "BES: fatal, cannot get/understand the key BES.DefaultResponseMethod"
00342                  << endl ;
00343         }
00344         else
00345         {
00346             cout << "HTTP/1.0 200 OK\n" ;
00347             cout << "Content-type: text/html\n\n" ;
00348             cout << flush ;
00349 
00350             cout << "<HTML>\n" ;
00351             cout << "<HEAD>\n" ;
00352             cout << "<TITLE> Request to the BES server</TITLE>\n" ;
00353             cout << "<BODY>\n" ;
00354             if (method=="GET")
00355                 cout << "<form action=\"http://" << _dri->server_name
00356                      << ":" << _dri->server_port << _dri->script_name
00357                      << "\" method=get>\n" ;
00358             else if (method=="POST")
00359                 cout << "<form action=\"http://" << _dri->server_name
00360                      << ":" << _dri->server_port << _dri->script_name
00361                      << "\" method=post>\n" ;
00362 
00363             cout << "<p>Request: <br><textarea name=\"request\" cols=85 rows=11 size=40,4 wrap=\"virtual\" ></textarea></p>\n" ;
00364             cout << "<input type=\"submit\" value=\"Submit to BES\">\n" ;
00365             cout << "<input type=\"reset\" value=\"Clean Text Field\">\n" ;
00366             cout << "</form>\n" ;
00367             cout << "</body>\n" ;
00368             cout << "</html>\n" ;
00369         }
00370     }
00371 }
00372 

Generated on 18 Feb 2010 for OPeNDAP Hyrax Back End Server (BES) by  doxygen 1.6.1