summaryrefslogtreecommitdiffstats
path: root/sca-cpp/trunk/modules
diff options
context:
space:
mode:
Diffstat (limited to 'sca-cpp/trunk/modules')
-rw-r--r--sca-cpp/trunk/modules/http/httpd.hpp134
-rw-r--r--sca-cpp/trunk/modules/json/json-test.cpp1
-rw-r--r--sca-cpp/trunk/modules/server/mod-eval.hpp36
-rw-r--r--sca-cpp/trunk/modules/server/mod-wiring.cpp20
4 files changed, 157 insertions, 34 deletions
diff --git a/sca-cpp/trunk/modules/http/httpd.hpp b/sca-cpp/trunk/modules/http/httpd.hpp
index 1e8f2a80b5..43e75bf769 100644
--- a/sca-cpp/trunk/modules/http/httpd.hpp
+++ b/sca-cpp/trunk/modules/http/httpd.hpp
@@ -41,6 +41,7 @@
#include "http_main.h"
#include "util_script.h"
#include "util_md5.h"
+#include "http_config.h"
#include "mod_core.h"
@@ -265,17 +266,142 @@ const int reportStatus(const failable<int>& rc) {
}
/**
- * Convert an HTTPD request struct to a value
+ * Construct a redirect URI.
*/
-const value requestValue(request_rec* r) {
- return value((const value*)r);
+const string redirectURI(const string& file, const string& pi) {
+ return file + pi;
+}
+
+const string redirectURI(const string& file, const string& pi, const string& args) {
+ return file + pi + "?" + args;
}
/**
* Convert a value to an HTTPD request struc
*/
request_rec* request(const value& v) {
- return (request_rec*)(const value*)gc_ptr<value>(v);
+ return (request_rec*)(long)(double)v;
+}
+
+/**
+ * Convert an HTTPD request struct to a value
+ */
+const value requestValue(request_rec* r) {
+ return value((double)(long)r);
+}
+
+/**
+ * Update filters in an HTTPD redirect request.
+ * Similar to httpd/modules/http/http_request.c::update_r_in_filters.
+ */
+const bool redirectFilters(ap_filter_t* f, request_rec* from, request_rec* to) {
+ if (f == NULL)
+ return true;
+ if (f->r == from)
+ f->r = to;
+ return redirectFilters(f->next, from, to);
+}
+
+/**
+ * Create an HTTPD redirect request.
+ * Similar to httpd/modules/http/http_request.c::internal_internal_redirect.
+ */
+extern "C" {
+ AP_DECLARE(ap_conf_vector_t*) ap_create_request_config(apr_pool_t *p);
+}
+
+const failable<request_rec*, int> internalRedirectRequest(const string& nr_uri, request_rec* r) {
+ if (ap_is_recursion_limit_exceeded(r))
+ return mkfailure<request_rec*, int>(HTTP_INTERNAL_SERVER_ERROR);
+
+ // Create a new request
+ request_rec* nr = (request_rec*)apr_pcalloc(r->pool, sizeof(request_rec));
+ nr->connection = r->connection;
+ nr->server = r->server;
+ nr->pool = r->pool;
+ nr->method = r->method;
+ nr->method_number = r->method_number;
+ nr->allowed_methods = ap_make_method_list(nr->pool, 2);
+ ap_parse_uri(nr, apr_pstrdup(nr->pool, c_str(nr_uri)));
+ nr->request_config = ap_create_request_config(r->pool);
+ nr->per_dir_config = r->server->lookup_defaults;
+ nr->prev = r;
+ r->next = nr;
+
+ // Run create request hook
+ ap_run_create_request(nr);
+
+ // Inherit protocol info from the original request
+ nr->the_request = r->the_request;
+ nr->allowed = r->allowed;
+ nr->status = r->status;
+ nr->assbackwards = r->assbackwards;
+ nr->header_only = r->header_only;
+ nr->protocol = r->protocol;
+ nr->proto_num = r->proto_num;
+ nr->hostname = r->hostname;
+ nr->request_time = r->request_time;
+ nr->main = r->main;
+ nr->headers_in = r->headers_in;
+ nr->headers_out = apr_table_make(r->pool, 12);
+ nr->err_headers_out = r->err_headers_out;
+ nr->subprocess_env = r->subprocess_env;
+ nr->notes = apr_table_make(r->pool, 5);
+ nr->allowed_methods = ap_make_method_list(nr->pool, 2);
+ nr->htaccess = r->htaccess;
+ nr->no_cache = r->no_cache;
+ nr->expecting_100 = r->expecting_100;
+ nr->no_local_copy = r->no_local_copy;
+ nr->read_length = r->read_length;
+ nr->vlist_validator = r->vlist_validator;
+
+ // Setup input and output filters
+ nr->proto_output_filters = r->proto_output_filters;
+ nr->proto_input_filters = r->proto_input_filters;
+ nr->output_filters = nr->proto_output_filters;
+ nr->input_filters = nr->proto_input_filters;
+ if (nr->main)
+ ap_add_output_filter_handle(ap_subreq_core_filter_handle, NULL, nr, nr->connection);
+ redirectFilters(nr->input_filters, r, nr);
+ redirectFilters(nr->output_filters, r, nr);
+ const int rrc = ap_run_post_read_request(nr);
+ if (rrc != OK && rrc != DECLINED)
+ return mkfailure<request_rec*, int>(rrc);
+
+ return nr;
+}
+
+/**
+ * Process an HTTPD internal redirect request.
+ * Similar to httpd/modules/http/http_request.c::ap_internal_redirect.
+ */
+extern "C" {
+ AP_DECLARE(int) ap_invoke_handler(request_rec *r);
+}
+
+const int internalRedirect(request_rec* nr) {
+ int status = ap_run_quick_handler(nr, 0);
+ if (status == DECLINED) {
+ status = ap_process_request_internal(nr);
+ if (status == OK)
+ status = ap_invoke_handler(nr);
+ }
+ if (status != OK) {
+ nr->status = status;
+ return OK;
+ }
+ ap_finalize_request_protocol(nr);
+ return OK;
+}
+
+/**
+ * Create and process an HTTPD redirect request.
+ */
+const int internalRedirect(const string& uri, request_rec* r) {
+ const failable<request_rec*, int> nr = httpd::internalRedirectRequest(uri, r);
+ if (!hasContent(nr))
+ return reason(nr);
+ return httpd::internalRedirect(content(nr));
}
}
diff --git a/sca-cpp/trunk/modules/json/json-test.cpp b/sca-cpp/trunk/modules/json/json-test.cpp
index 41ac24a22e..b74f068710 100644
--- a/sca-cpp/trunk/modules/json/json-test.cpp
+++ b/sca-cpp/trunk/modules/json/json-test.cpp
@@ -78,7 +78,6 @@ bool testJSON() {
}
{
const list<value> l = mklist<value>(list<value>() + "ns1:echoString" + (list<value>() + "@xmlns:ns1" + string("http://ws.apache.org/axis2/services/echo")) + (list<value>() + "text" + string("Hello World!")));
- cout << "l: " << l << endl;
ostringstream wos;
write(content(writeJSON(valuesToElements(l), cx)), wos);
assert(str(wos) == "{\"ns1:echoString\":{\"@xmlns:ns1\":\"http://ws.apache.org/axis2/services/echo\",\"text\":\"Hello World!\"}}");
diff --git a/sca-cpp/trunk/modules/server/mod-eval.hpp b/sca-cpp/trunk/modules/server/mod-eval.hpp
index aaf31f2b18..b622283fed 100644
--- a/sca-cpp/trunk/modules/server/mod-eval.hpp
+++ b/sca-cpp/trunk/modules/server/mod-eval.hpp
@@ -129,13 +129,18 @@ const failable<int> get(request_rec* r, const lambda<value(const list<value>&)>&
* Handle an HTTP POST.
*/
const failable<int> post(request_rec* r, const lambda<value(const list<value>&)>& impl) {
- const list<string> ls = httpd::read(r);
debug(r->uri, "modeval::post::url");
- debug(ls, "modeval::post::input");
// Evaluate a JSON-RPC request and return a JSON result
const string ct = httpd::contentType(r);
if (contains(ct, "application/json-rpc") || contains(ct, "text/plain")) {
+
+ // Read the JSON request
+ const int rc = httpd::setupReadPolicy(r);
+ if(rc != OK)
+ return rc;
+ const list<string> ls = httpd::read(r);
+ debug(ls, "modeval::post::input");
json::JSONContext cx;
const list<value> json = elementsToValues(content(json::readJSON(ls, cx)));
const list<list<value> > args = httpd::postArgs(json);
@@ -157,8 +162,15 @@ const failable<int> post(request_rec* r, const lambda<value(const list<value>&)>
// Evaluate an ATOM POST request and return the location of the corresponding created resource
if (contains(ct, "application/atom+xml")) {
- // Evaluate the request expression
+ // Read the ATOM entry
+ const int rc = httpd::setupReadPolicy(r);
+ if(rc != OK)
+ return rc;
+ const list<string> ls = httpd::read(r);
+ debug(ls, "modeval::post::input");
const value entry = atom::entryValue(content(atom::readEntry(ls)));
+
+ // Evaluate the request expression
const failable<value> val = failableResult(impl(cons<value>("post", mklist<value>(entry))));
if (!hasContent(val))
return mkfailure<int>(reason(val));
@@ -174,20 +186,25 @@ const failable<int> post(request_rec* r, const lambda<value(const list<value>&)>
const failable<value> val = failableResult(impl(cons<value>("handle", mklist<value>(httpd::requestValue(r)))));
if (!hasContent(val))
return mkfailure<int>(reason(val));
- return OK;
+ return (int)content(val);
}
/**
* Handle an HTTP PUT.
*/
const failable<int> put(request_rec* r, const lambda<value(const list<value>&)>& impl) {
- const list<string> ls = httpd::read(r);
debug(r->uri, "modeval::put::url");
- debug(ls, "modeval::put::input");
- // Evaluate an ATOM PUT request and update the corresponding resource
+ // Read the ATOM entry
const list<value> path(httpd::pathValues(r->uri));
+ const int rc = httpd::setupReadPolicy(r);
+ if(rc != OK)
+ return rc;
+ const list<string> ls = httpd::read(r);
+ debug(ls, "modeval::put::input");
const value entry = atom::entryValue(content(atom::readEntry(ls)));
+
+ // Evaluate the ATOM PUT request and update the corresponding resource
const failable<value> val = failableResult(impl(cons<value>("put", mklist<value>(caddr(path), entry))));
if (!hasContent(val))
return mkfailure<int>(reason(val));
@@ -244,11 +261,6 @@ int handler(request_rec *r) {
return DECLINED;
httpdDebugRequest(r, "modeval::handler::input");
- // Set up the read policy
- const int rc = httpd::setupReadPolicy(r);
- if(rc != OK)
- return rc;
-
// Get the component implementation lambda
DirConf& dc = httpd::dirConf<DirConf>(r, &mod_tuscany_eval);
const list<value> path(httpd::pathValues(r->uri));
diff --git a/sca-cpp/trunk/modules/server/mod-wiring.cpp b/sca-cpp/trunk/modules/server/mod-wiring.cpp
index 88a57659ef..aef2f00c83 100644
--- a/sca-cpp/trunk/modules/server/mod-wiring.cpp
+++ b/sca-cpp/trunk/modules/server/mod-wiring.cpp
@@ -194,17 +194,6 @@ int translate(request_rec *r) {
}
/**
- * Construct a redirect URI.
- */
-const string redirect(const string& file, const string& pi) {
- return file + pi;
-}
-
-const string redirect(const string& file, const string& pi, const string& args) {
- return file + pi + "?" + args;
-}
-
-/**
* HTTP request handler, redirect to a target component.
*/
int handler(request_rec *r) {
@@ -220,12 +209,9 @@ int handler(request_rec *r) {
debug(r->filename, "modwiring::handler::filename");
debug(r->path_info, "modwiring::handler::path info");
- if (r->args == NULL) {
- ap_internal_redirect(apr_pstrdup(r->pool, c_str(redirect(string(r->filename + 10), string(r->path_info)))), r);
- return OK;
- }
- ap_internal_redirect(apr_pstrdup(r->pool, c_str(redirect(string(r->filename + 10), string(r->path_info), string(r->args)))), r);
- return OK;
+ if (r->args == NULL)
+ return httpd::internalRedirect(httpd::redirectURI(string(r->filename + 10), string(r->path_info)), r);
+ return httpd::internalRedirect(httpd::redirectURI(string(r->filename + 10), string(r->path_info), string(r->args)), r);
}
/**