apache_application.h

00001 /*
00002  * apache_application.h
00003  * This file is part of dbPager Classes Library (DCL)
00004  *
00005  * Copyright (c) 2008 Dennis Prochko <wolfsoft@mail.ru>
00006  *
00007  * DCL is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation version 3.
00010  *
00011  * DCL is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with DCL; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor,
00019  * Boston, MA  02110-1301  USA
00020  */
00021 
00022 #ifndef _APACHE_APPLICATION_H_
00023 #define _APACHE_APPLICATION_H_
00024 
00025 #include <string>
00026 
00027 #include <httpd.h>
00028 #include <http_config.h>
00029 #include <http_core.h>
00030 #include <http_protocol.h>
00031 
00032 #include "dcl/delegate.h"
00033 #include "dcl/http_header.h"
00034 #include "dcl/web_application.h"
00035 
00036 namespace dbp {
00037 
00038 namespace local {
00039 
00040 // Apache helper class interface
00041 class apache_helper {
00042 public:
00043         virtual const char* get_server_banner() = 0;
00044         virtual void set_content_type(const char*, request_rec*) = 0;
00045         virtual void input(size_t*, char**, request_rec*) = 0;
00046         virtual void output(int, const char*, request_rec*) = 0;
00047 };
00048 
00049 #ifndef _LIBRARY_
00050 // Apache helper class implementation
00051 class apache_helper_impl: public apache_helper {
00052 public:
00053         virtual const char* get_server_banner() {
00054                 return ap_get_server_banner();
00055         };
00056         virtual void set_content_type(const char *type, request_rec *r) {
00057                 ap_set_content_type(r, type);
00058         };
00059         virtual void input(size_t *len, char **str, request_rec *r) {
00060                 *len = 0;
00061                 apr_bucket_brigade *bb_in = apr_brigade_create(r->pool,
00062                   r->connection->bucket_alloc);
00063                 if (!bb_in) return;
00064                 bool seen_eos = false;
00065                 do {
00066                         apr_status_t rc = ap_get_brigade(r->input_filters, bb_in,
00067                           AP_MODE_READBYTES, APR_BLOCK_READ, HUGE_STRING_LEN);
00068                         if (rc != APR_SUCCESS) {
00069                                 return;
00070                         }
00071                         for (apr_bucket *bucket = APR_BRIGADE_FIRST(bb_in);
00072                           bucket != APR_BRIGADE_SENTINEL(bb_in);
00073                           bucket = APR_BUCKET_NEXT(bucket)) {
00074                                 const char *buf;
00075                                 apr_size_t buflen;
00076                                 rc = apr_bucket_read(bucket, &buf, &buflen, APR_BLOCK_READ);
00077                                 if (rc != APR_SUCCESS) {
00078                         return;
00079                                 }
00080                                 if (APR_BUCKET_IS_EOS(bucket))
00081                                         seen_eos = true;
00082                                 *len += buflen;
00083                                 *str = (char*)realloc(*str, *len);
00084                                 memcpy(*str + *len - buflen, buf, buflen);
00085                         }
00086                         apr_brigade_cleanup(bb_in);
00087                 } while (!seen_eos);
00088         };
00089         virtual void output(int len, const char *str, request_rec *r) {
00090                 ap_rwrite(str, len, r);
00091         };
00092 };
00093 #endif
00094 
00095 } // namespace local
00096 
00098 
00109 class apache_application: public web_application_int {
00110 public:
00112         apache_application(): apache(NULL), apache_req(NULL) { };
00113         virtual void on_handle_request(on_request_handler handler) {
00114                 request_handler = handler;
00115         };
00116         virtual void on_exception(on_exception_handler handler) {
00117                 exception_handler = handler;
00118         };
00119         static void apache_register_hooks(apr_pool_t*);
00120 protected:
00121         virtual http_request get_request();
00122         virtual void send_response(const http_response &response);
00123 private:
00124         local::apache_helper *apache;
00125         request_rec *apache_req;
00126         on_request_handler request_handler;
00127         on_exception_handler exception_handler;
00128         static int apache_handler(request_rec *r);
00129         int handle_request();
00130 };
00131 
00132 } //namespace
00133 
00134 #undef IMPLEMENT_APP
00135 
00136 #define IMPLEMENT_APP(module_name, app_class)                                                           \
00137                                                                                                                                                         \
00138 int dbp::apache_application::apache_handler(request_rec *r) {                           \
00139         if (strcmp(r->handler, #module_name) != 0) return DECLINED;                             \
00140         dbp::local::apache_helper_impl apache;                                                                  \
00141         app_class app;                                                                                                                  \
00142         dbp::apache_application &_app = app.application_impl();                                 \
00143         _app.apache = &apache;                                                                                                  \
00144         _app.apache_req = r;                                                                                                    \
00145         return _app.handle_request();                                                                                   \
00146 }                                                                                                                                                       \
00147                                                                                                                                                         \
00148 void dbp::apache_application::apache_register_hooks(apr_pool_t*) {                      \
00149         ap_hook_handler(dbp::apache_application::apache_handler, NULL, NULL,    \
00150           APR_HOOK_LAST);                                                                                                               \
00151 }                                                                                                                                                       \
00152                                                                                                                                                         \
00153 extern "C" {                                                                                                                            \
00154                                                                                                                                                         \
00155 module AP_MODULE_DECLARE_DATA module_name = {                                                           \
00156         STANDARD20_MODULE_STUFF,                                                                                                \
00157         NULL,                                           /* create per-dir config structures             */      \
00158         NULL,                                           /* merge  per-dir config structures             */      \
00159         NULL,                                           /* create per-server config structures  */      \
00160         NULL,                                           /* merge  per-server config structures  */      \
00161         NULL,                                           /* table of config file commands                */      \
00162         dbp::apache_application::apache_register_hooks /* register hooks        */      \
00163 };                                                                                                                                                      \
00164                                                                                                                                                         \
00165 }
00166 
00167 #endif /*_APACHE_APPLICATION_H_*/

 
Support This Project
SourceForge.net Logo