mod_opendap.cc

Go to the documentation of this file.
00001 // mod_opendap.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 <unistd.h>
00034 #include <iostream>
00035 
00036 using std::cerr ;
00037 using std::endl ;
00038 
00039 #include "httpd.h"
00040 #include "http_config.h"
00041 #include "http_core.h"
00042 #include "http_log.h"
00043 #include "http_protocol.h"
00044 #include "http_request.h"
00045 #include "http_main.h"
00046 #include "util_script.h"
00047 #include "util_md5.h"
00048 
00049 #include "BESDataRequestInterface.h"
00050 #include "BESApacheWrapper.h"
00051 
00052 char * ltoa(long val, char *buf,int base)                         
00053 {
00054   ldiv_t r;                                 /* result of val / base  */
00055   if (base > 36 || base < 2)          /* no conversion if wrong base */
00056     {
00057       *buf = '\0';
00058       return buf;
00059     }
00060   if (val < 0)
00061     *buf++ = '-';
00062   r = ldiv (labs(val), base);
00063   /* output digits of val/base first */
00064   if (r.quot > 0)
00065     buf = ltoa ( r.quot, buf, base);
00066   
00067   /* output last digit */
00068   
00069   *buf++ = "0123456789abcdefghijklmnopqrstuvwxyz"[(int)r.rem];
00070   *buf   = '\0';
00071   return buf;
00072 }
00073 
00074 
00075 static int util_read(request_rec *r, const char **rbuf)
00076 {
00077     int rc = OK;
00078 
00079     if ((rc = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR)))
00080     {
00081         return rc;
00082     }
00083 
00084     if (ap_should_client_block(r))
00085     {
00086         char argsbuffer[HUGE_STRING_LEN];
00087         int rsize, len_read, rpos=0;
00088         long length = r->remaining;
00089         //*rbuf = (char*) ap_pcalloc(r->pool, length + 1); 
00090         *rbuf = (char*) apr_pcalloc(r->pool, length + 1); 
00091 
00092         ap_hard_timeout("util_read", r);
00093 
00094         while((len_read = ap_get_client_block(r, argsbuffer, sizeof(argsbuffer))) > 0)
00095         {
00096             ap_reset_timeout(r);
00097             if ((rpos + len_read) > length)
00098             {
00099                 rsize = length - rpos;
00100             }
00101             else
00102             {
00103                 rsize = len_read;
00104             }
00105             memcpy((char*)*rbuf + rpos, argsbuffer, rsize);
00106             rpos += rsize;
00107         }
00108 
00109         ap_kill_timeout(r);
00110     }
00111     return rc;
00112 }
00113 
00114 static int
00115 header_trace( void *data, const char *key, const char *val )
00116 {
00117     request_rec *r = (request_rec *)data ;
00118     cerr << "Header Field '" << key << "' = '" << val << "'" << endl ;
00119     return TRUE ;
00120 }
00121 
00122 static void
00123 list_headers( request_rec *r )
00124 {
00125     //ap_table_do( header_trace, r, r->headers_in, NULL ) ;
00126     apr_table_do( header_trace, r, r->headers_in, NULL ) ;
00127 }
00128 
00129 static int opendap_handler(request_rec *r)
00130 { 
00131     char port_number_buffer[80];
00132     dup2(r->connection->client->fd,STDOUT_FILENO);
00133     BESDataRequestInterface rq;
00134 
00135     // BEGIN Initialize all data request elements correctly to a null pointer 
00136     rq.server_name=0;
00137     rq.server_address=0;
00138     rq.server_protocol=0;
00139     rq.server_port=0;
00140     rq.script_name=0;
00141     rq.user_address=0;
00142     rq.user_agent=0;
00143     rq.request=0;
00144     // END Initialize all the data request elements correctly to a null pointer
00145 
00146     rq.server_name=ap_get_server_name(r);
00147     rq.server_address="jose";
00148     rq.server_protocol=r->protocol;
00149     ltoa(ap_get_server_port(r), port_number_buffer, 10);
00150     rq.server_port=port_number_buffer;
00151     rq.script_name=r->uri;
00152     rq.user_address=r->connection->remote_ip;
00153     //rq.user_agent = ap_table_get(r->headers_in, "User-Agent");
00154     rq.user_agent = apr_table_get(r->headers_in, "User-Agent");
00155 
00156     const char* m_method = r->method;
00157     if (!m_method) 
00158     {
00159         cerr << "mod_opendap: Fatal, Can not load request method" << endl;
00160         //return SERVER_ERROR;
00161         return HTTP_INTERNAL_SERVER_ERROR;
00162     }
00163 
00164     BESApacheWrapper wrapper;
00165     if ( strcmp(m_method, "GET") == 0 ) 
00166     {
00167         if(r->parsed_uri.query)
00168         {
00169             wrapper.process_request(r->parsed_uri.query);
00170             rq.cookie=wrapper.process_user(r->parsed_uri.query);
00171             rq.token=wrapper.process_token(r->parsed_uri.query);
00172         }
00173         else
00174         {
00175             rq.request=0;
00176             rq.cookie=0;
00177             rq.token=0;
00178         }
00179     }
00180     else if (strcmp(m_method, "POST") == 0 ) 
00181     {
00182         const char *post_data=0;
00183         util_read(r, &post_data);
00184         wrapper.process_request(post_data);
00185         rq.cookie=wrapper.process_user(post_data);
00186         rq.token=wrapper.process_token(r->parsed_uri.query);
00187     }
00188     else
00189     {
00190         rq.request=0;
00191         rq.cookie=0;
00192         rq.token=0;
00193     }
00194 
00195     // These two lines will print out the header information to the error
00196     // log
00197     // list_headers( r ) ;
00198     // exit( 0 ) ;
00199 
00200     if( !rq.cookie || !strcmp(rq.cookie,"") )
00201     {
00202         //rq.cookie = ap_table_get( r->headers_in, "Cookie" ) ;
00203         rq.cookie = apr_table_get( r->headers_in, "Cookie" ) ;
00204     }
00205 
00206     int status = 0 ;
00207     rq.request = wrapper.get_first_request() ;
00208     while( rq.request && status == 0 )
00209     {
00210         status = wrapper.call_BES(rq);
00211         rq.request = wrapper.get_next_request() ;
00212     }
00213 
00214     // always flush the socket at the end...
00215     // and since stdout is now the tcp/ip socket for this connection
00216     cout << flush ;
00217 
00218     // exit instead of returning
00219     exit( 0 ) ;
00220 
00221     return OK;
00222 }
00223 
00224 /* Make the name of the content handler known to Apache */
00225 static handler_rec opendap_handlers[] =
00226 {
00227     {"opendap-handler", opendap_handler},
00228     {NULL}
00229 };
00230 
00231 /* Tell Apache what phases of the transaction we handle */
00232 module MODULE_VAR_EXPORT opendap_module =
00233 {
00234     STANDARD_MODULE_STUFF,
00235     NULL,               /* module initializer                 */
00236     NULL,               /* per-directory config creator       */
00237     NULL,               /* dir config merger                  */
00238     NULL,               /* server config creator              */
00239     NULL,               /* server config merger               */
00240     NULL,               /* command table                      */
00241     opendap_handlers,      /* [7]  content handlers              */
00242     NULL,               /* [2]  URI-to-filename translation   */
00243     NULL,               /* [5]  check/validate user_id        */
00244     NULL,               /* [6]  check user_id is valid *here* */
00245     NULL,               /* [4]  check access by host address  */
00246     NULL,               /* [7]  MIME type checker/setter      */
00247     NULL,               /* [8]  fixups                        */
00248     NULL,               /* [9]  logger                        */
00249     NULL,               /* [3]  header parser                 */
00250     NULL,               /* process initialization             */
00251     NULL,               /* process exit/cleanup               */
00252     NULL                /* [1]  post read_request handling    */
00253 };
00254 

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