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

Generated on Wed May 12 09:53:08 2010 for OPeNDAP Hyrax Back End Server (BES) by  doxygen 1.4.7