apache_application.h
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
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
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 }
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 }
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, \
00158 NULL, \
00159 NULL, \
00160 NULL, \
00161 NULL, \
00162 dbp::apache_application::apache_register_hooks \
00163 }; \
00164 \
00165 }
00166
00167 #endif