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 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 <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 
00091         ap_hard_timeout("util_read", r);
00092 
00093         while((len_read = ap_get_client_block(r, argsbuffer, sizeof(argsbuffer))) > 0)
00094         {
00095             ap_reset_timeout(r);
00096             if ((rpos + len_read) > length)
00097             {
00098                 rsize = length - rpos;
00099             }
00100             else
00101             {
00102                 rsize = len_read;
00103             }
00104             memcpy((char*)*rbuf + rpos, argsbuffer, rsize);
00105             rpos += rsize;
00106         }
00107 
00108         ap_kill_timeout(r);
00109     }
00110     return rc;
00111 }
00112 
00113 static int
00114 header_trace( void *data, const char *key, const char *val )
00115 {
00116     request_rec *r = (request_rec *)data ;
00117     cerr << "Header Field '" << key << "' = '" << val << "'" << endl ;
00118     return TRUE ;
00119 }
00120 
00121 static void
00122 list_headers( request_rec *r )
00123 {
00124     ap_table_do( header_trace, r, r->headers_in, NULL ) ;
00125 }
00126 
00127 static int opendap_handler(request_rec *r)
00128 { 
00129     char port_number_buffer[80];
00130     dup2(r->connection->client->fd,STDOUT_FILENO);
00131     BESDataRequestInterface rq;
00132 
00133     // BEGIN Initialize all data request elements correctly to a null pointer 
00134     rq.server_name=0;
00135     rq.server_address=0;
00136     rq.server_protocol=0;
00137     rq.server_port=0;
00138     rq.script_name=0;
00139     rq.user_address=0;
00140     rq.user_agent=0;
00141     rq.request=0;
00142     // END Initialize all the data request elements correctly to a null pointer
00143 
00144     rq.server_name=ap_get_server_name(r);
00145     rq.server_address="jose";
00146     rq.server_protocol=r->protocol;
00147     ltoa(ap_get_server_port(r), port_number_buffer, 10);
00148     rq.server_port=port_number_buffer;
00149     rq.script_name=r->uri;
00150     rq.user_address=r->connection->remote_ip;
00151     rq.user_agent = ap_table_get(r->headers_in, "User-Agent");
00152 
00153     const char* m_method = r->method;
00154     if (!m_method) 
00155     {
00156         cerr << "mod_opendap: Fatal, Can not load request method" << endl;
00157         return SERVER_ERROR;
00158     }
00159 
00160     BESApacheWrapper wrapper;
00161     if ( strcmp(m_method, "GET") == 0 ) 
00162     {
00163         if(r->parsed_uri.query)
00164         {
00165             wrapper.process_request(r->parsed_uri.query);
00166             rq.cookie=wrapper.process_user(r->parsed_uri.query);
00167             rq.token=wrapper.process_token(r->parsed_uri.query);
00168         }
00169         else
00170         {
00171             rq.request=0;
00172             rq.cookie=0;
00173             rq.token=0;
00174         }
00175     }
00176     else if (strcmp(m_method, "POST") == 0 ) 
00177     {
00178         const char *post_data=0;
00179         util_read(r, &post_data);
00180         wrapper.process_request(post_data);
00181         rq.cookie=wrapper.process_user(post_data);
00182         rq.token=wrapper.process_token(r->parsed_uri.query);
00183     }
00184     else
00185     {
00186         rq.request=0;
00187         rq.cookie=0;
00188         rq.token=0;
00189     }
00190 
00191     // These two lines will print out the header information to the error
00192     // log
00193     // list_headers( r ) ;
00194     // exit( 0 ) ;
00195 
00196     if( !rq.cookie || !strcmp(rq.cookie,"") )
00197     {
00198         rq.cookie = ap_table_get( r->headers_in, "Cookie" ) ;
00199     }
00200 
00201     int status = 0 ;
00202     rq.request = wrapper.get_first_request() ;
00203     while( rq.request && status == 0 )
00204     {
00205         status = wrapper.call_BES(rq);
00206         rq.request = wrapper.get_next_request() ;
00207     }
00208 
00209     // always flush the socket at the end...
00210     // and since stdout is now the tcp/ip socket for this connection
00211     fflush(stdout);
00212 
00213     // exit instead of returning
00214     exit( 0 ) ;
00215 
00216     return OK;
00217 }
00218 
00219 /* Make the name of the content handler known to Apache */
00220 static handler_rec opendap_handlers[] =
00221 {
00222     {"opendap-handler", opendap_handler},
00223     {NULL}
00224 };
00225 
00226 /* Tell Apache what phases of the transaction we handle */
00227 module MODULE_VAR_EXPORT opendap_module =
00228 {
00229     STANDARD_MODULE_STUFF,
00230     NULL,               /* module initializer                 */
00231     NULL,               /* per-directory config creator       */
00232     NULL,               /* dir config merger                  */
00233     NULL,               /* server config creator              */
00234     NULL,               /* server config merger               */
00235     NULL,               /* command table                      */
00236     opendap_handlers,      /* [7]  content handlers              */
00237     NULL,               /* [2]  URI-to-filename translation   */
00238     NULL,               /* [5]  check/validate user_id        */
00239     NULL,               /* [6]  check user_id is valid *here* */
00240     NULL,               /* [4]  check access by host address  */
00241     NULL,               /* [7]  MIME type checker/setter      */
00242     NULL,               /* [8]  fixups                        */
00243     NULL,               /* [9]  logger                        */
00244     NULL,               /* [3]  header parser                 */
00245     NULL,               /* process initialization             */
00246     NULL,               /* process exit/cleanup               */
00247     NULL                /* [1]  post read_request handling    */
00248 };
00249 

Generated on Wed Aug 29 02:59:01 2007 for OPeNDAP Back End Server (BES) by  doxygen 1.5.2