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 Atmostpheric 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 "cgi_util.h"
00046 #include "BESBasicHttpTransmitter.h"
00047 #include "BESTransmitException.h"
00048 #include "BESAggregationServer.h"
00049 #include "BESDataNames.h"
00050 
00051 #define DEFAULT_ADMINISTRATOR "support@unidata.ucar.edu"
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() ;
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         set_mime_text( stdout, unknown_type ) ;
00273         bool found = false ;
00274         string administrator =
00275             TheBESKeys::TheKeys()->get_key( "BES.ServerAdministrator", found ) ;
00276         if(administrator=="")
00277             fprintf( stdout, "%s %s %s\n",
00278                              "BES: internal server error please contact",
00279                              DEFAULT_ADMINISTRATOR,
00280                              "with the following message:" ) ;
00281         else
00282             fprintf( stdout, "%s %s %s\n",
00283                              "BES: internal server error please contact",
00284                              administrator.c_str(),
00285                              "with the following message:" ) ;
00286         fprintf( stdout, "%s %s\n",
00287                          "BES: can not interact with browser", agent.c_str() ) ;
00288     }
00289     else // Yes, _agent contains the signature of a browser               
00290     {
00291         bool found = false ;
00292         string method =
00293             TheBESKeys::TheKeys()->get_key( "BES.DefaultResponseMethod", found ) ;
00294         if( (method!="GET") && (method!="POST") )
00295         {
00296             set_mime_text( stdout, dods_error ) ;
00297             found = false ;
00298             string administrator =
00299                 TheBESKeys::TheKeys()->get_key( "BES.ServerAdministrator", found ) ;
00300             if(administrator=="")
00301                 fprintf( stdout, "%s %s %s\n",
00302                                  "BES: internal server error please contact",
00303                                  DEFAULT_ADMINISTRATOR,
00304                                  "with the following message:" ) ;
00305             else
00306                 fprintf( stdout, "%s %s %s\n",
00307                                  "BES: internal server error please contact",
00308                                  administrator.c_str(),
00309                                  "with the following message:" ) ;
00310             fprintf( stdout, "%s %s\n",
00311                              "BES: fatal, can not get/understand the key",
00312                              "BES.DefaultResponseMethod" ) ;
00313         }
00314         else
00315         {
00316             //set_mime_text( stdout, unknown_type ) ;
00317             fprintf( stdout, "HTTP/1.0 200 OK\n" ) ;
00318             fprintf( stdout, "Content-type: text/html\n\n" ) ;
00319             fflush( stdout ) ;
00320 
00321             fprintf( stdout, "<HTML>\n" ) ;
00322             fprintf( stdout, "<HEAD>\n" ) ;
00323             fprintf( stdout, "<TITLE> Request to the BES server</TITLE>\n" ) ;
00324             fprintf( stdout, "<BODY>\n" ) ;
00325             if (method=="GET")
00326                 fprintf(stdout,"<form action=\"http://%s:%s%s\" method=get>\n",
00327                                _dri->server_name,
00328                                _dri->server_port,
00329                                _dri->script_name ) ;
00330             else if (method=="POST")
00331                 fprintf(stdout,"<form action=\"http://%s:%s%s\" method=post>\n",
00332                                _dri->server_name,
00333                                _dri->server_port,
00334                                _dri->script_name ) ;
00335 
00336             fprintf( stdout, "<p>Request: <br><textarea name=\"request\" cols=85 rows=11 size=40,4 wrap=\"virtual\" ></textarea></p>\n" ) ;
00337             fprintf( stdout, "<input type=\"submit\" value=\"Submit to BES\">\n" ) ;
00338             fprintf( stdout, "<input type=\"reset\" value=\"Clean Text Field\">\n" ) ;
00339             fprintf( stdout, "</form>\n" ) ;
00340             fprintf( stdout, "</body>\n" ) ;
00341             fprintf( stdout, "</html>\n" ) ;
00342         }
00343     }
00344 }
00345 

Generated on Wed Aug 29 03:20:58 2007 for OPeNDAP Back End Server (BES) by  doxygen 1.5.2