You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tuscany.apache.org by js...@apache.org on 2010/01/30 09:06:01 UTC

svn commit: r904733 - in /tuscany/sca-cpp/trunk: ./ components/webservice/ modules/http/ modules/json/ modules/server/

Author: jsdelfino
Date: Sat Jan 30 08:06:00 2010
New Revision: 904733

URL: http://svn.apache.org/viewvc?rev=904733&view=rev
Log:
Added a Web service listener component integrating Axis2/C's mod_axis2. Consolidated a bit the HTTPD redirect functions (used to redirect to mod_axis2.) Minor updates to the README and INSTALL files.

Added:
    tuscany/sca-cpp/trunk/components/webservice/axis2-conf   (with props)
    tuscany/sca-cpp/trunk/components/webservice/axis2-dispatcher.cpp
    tuscany/sca-cpp/trunk/components/webservice/axis2-service.cpp
    tuscany/sca-cpp/trunk/components/webservice/axis2.xml
    tuscany/sca-cpp/trunk/components/webservice/module.xml
    tuscany/sca-cpp/trunk/components/webservice/server-test.scm
    tuscany/sca-cpp/trunk/components/webservice/services.xml
Modified:
    tuscany/sca-cpp/trunk/INSTALL
    tuscany/sca-cpp/trunk/README
    tuscany/sca-cpp/trunk/components/webservice/Makefile.am
    tuscany/sca-cpp/trunk/components/webservice/axis2.hpp
    tuscany/sca-cpp/trunk/components/webservice/client-test.cpp
    tuscany/sca-cpp/trunk/components/webservice/echo-test
    tuscany/sca-cpp/trunk/components/webservice/server-test
    tuscany/sca-cpp/trunk/components/webservice/webservice-listener.cpp
    tuscany/sca-cpp/trunk/components/webservice/webservice.composite
    tuscany/sca-cpp/trunk/configure.ac
    tuscany/sca-cpp/trunk/modules/http/httpd.hpp
    tuscany/sca-cpp/trunk/modules/json/json-test.cpp
    tuscany/sca-cpp/trunk/modules/server/mod-eval.hpp
    tuscany/sca-cpp/trunk/modules/server/mod-wiring.cpp

Modified: tuscany/sca-cpp/trunk/INSTALL
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/INSTALL?rev=904733&r1=904732&r2=904733&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/INSTALL (original)
+++ tuscany/sca-cpp/trunk/INSTALL Sat Jan 30 08:06:00 2010
@@ -25,10 +25,6 @@
 libapr-1-0.3.8
 libaprutil-1-0.3.9
 
-Recommended HTTPD configure options:
---with-included-apr to build HTTPD with the included APR distribution,
---with-mpm=worker to run HTTPD modules in multiple threads.
-
 XML
 libxml2-2.7.5
 
@@ -39,11 +35,11 @@
 SpiderMonkey libmozjs
 (included in xulrunner-1.9.1.7)
 
-Python (optional)
-libpython2.6
+Optional dependencies:
 
-Java (optional)
-a Java 6 development kit including jni.h and libjava
+Axis2/C 1.6.0
+Python 2.6
+a Java 6 SDK
 
 
 To configure the Tuscany SCA build do this:
@@ -88,7 +84,7 @@
 --enable-python --with-python=/usr \
 --enable-java --with-java=/usr/lib/jvm/default-java \
 --enable-webservice --with-axis2c=$HOME/axis2c-1.6.0-bin \
---enable-threads --enable-maintainer-mode
+--enable-maintainer-mode
 
 
 To build the Tuscany SCA runtime, do this:
@@ -113,3 +109,21 @@
 To install the Tuscany SCA binaries, do this:
 make install
 
+
+Building dependencies from source
+=================================
+
+Here are example build and install steps for HTTPD (including APR) and Axis2/C:
+
+./configure --enable-ssl --enable-proxy --enable-rewrite --with-included-apr \
+--with-mpm=prefork --prefix=$HOME/httpd-2.2.13-bin
+make
+make install
+export PATH=$HOME/httpd-2-2.13-bin/bin:$PATH
+
+./configure --enable-libxml2 --enable-openssl --enable-libcurl \
+--with-apache2=$HOME/httpd-2.2.13-bin/include --prefix=$HOME/axis2c-1.6.0-bin
+make
+make install
+export AXIS2C_HOME=$HOME/axis2c-1.6.0-bin
+

Modified: tuscany/sca-cpp/trunk/README
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/README?rev=904733&r1=904732&r2=904733&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/README (original)
+++ tuscany/sca-cpp/trunk/README Sat Jan 30 08:06:00 2010
@@ -36,12 +36,16 @@
  |   |   |-- java             Support for Java components
  |   |   |-- python           Support for Python components
  |   |   |-- scheme           Support for Scheme components
- |   |   |-- server           HTTPD server integration
+ |   |   |-- server           Apache HTTPD server integration
+ |   |   |-- xmpp             XMPP protocol support
  |   |
  |   |-- components           Useful SCA components
- |   |   |-- cache            Memcached-based cache component
- |   |   |-- store            Persistent store component
- |   |   |-- webservice       Web service gateway component using Axis2C
+ |   |   |-- cache            Key/value cache (requires Memcached)
+ |   |   |-- chat             XMPP chat
+ |   |   |-- log              Logger
+ |   |   |-- queue            AMQP message queue (requires Apache Qpid/C++)
+ |   |   |-- store            Persistent store
+ |   |   |-- webservice       Web service gateway (requires Apache Axis2/C)
  |   |
  |   |-- test                 Integration tests
  |   |

Modified: tuscany/sca-cpp/trunk/components/webservice/Makefile.am
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/webservice/Makefile.am?rev=904733&r1=904732&r2=904733&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/webservice/Makefile.am (original)
+++ tuscany/sca-cpp/trunk/components/webservice/Makefile.am Sat Jan 30 08:06:00 2010
@@ -22,7 +22,7 @@
 INCLUDES = -I${AXIS2C_INCLUDE}
 
 compdir=$(prefix)/components/webservice
-comp_LTLIBRARIES = libwebservice-client.la libwebservice-listener.la
+comp_LTLIBRARIES = libwebservice-client.la libwebservice-listener.la libaxis2-dispatcher.la libaxis2-service.la
 
 libwebservice_client_la_SOURCES = webservice-client.cpp
 libwebservice_client_la_LDFLAGS = -lxml2 -L${AXIS2C_LIB} -R${AXIS2C_LIB} -laxis2_engine
@@ -30,6 +30,12 @@
 libwebservice_listener_la_SOURCES = webservice-listener.cpp
 libwebservice_listener_la_LDFLAGS = -lxml2 -L${AXIS2C_LIB} -R${AXIS2C_LIB} -laxis2_engine
 
+libaxis2_dispatcher_la_SOURCES = axis2-dispatcher.cpp
+libaxis2_dispatcher_la_LDFLAGS = -lxml2 -L${AXIS2C_LIB} -R${AXIS2C_LIB} -laxis2_engine
+
+libaxis2_service_la_SOURCES = axis2-service.cpp
+libaxis2_service_la_LDFLAGS = -lxml2 -L${AXIS2C_LIB} -R${AXIS2C_LIB} -laxis2_engine
+
 axiom_test_SOURCES = axiom-test.cpp
 axiom_test_LDFLAGS = -lxml2 -L${AXIS2C_LIB} -R${AXIS2C_LIB} -laxis2_engine
 
@@ -37,7 +43,7 @@
 axis2_test_LDFLAGS = -lxml2 -L${AXIS2C_LIB} -R${AXIS2C_LIB} -laxis2_engine
 
 client_test_SOURCES = client-test.cpp
-client_test_LDFLAGS = -lxml2 -lcurl -lmozjs 
+client_test_LDFLAGS = -lxml2 -lcurl -lmozjs -L${AXIS2C_LIB} -R${AXIS2C_LIB} -laxis2_engine
 
 TESTS = axiom-test echo-test server-test
 

Added: tuscany/sca-cpp/trunk/components/webservice/axis2-conf
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/webservice/axis2-conf?rev=904733&view=auto
==============================================================================
--- tuscany/sca-cpp/trunk/components/webservice/axis2-conf (added)
+++ tuscany/sca-cpp/trunk/components/webservice/axis2-conf Sat Jan 30 08:06:00 2010
@@ -0,0 +1,51 @@
+#!/bin/sh
+
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#  
+#    http://www.apache.org/licenses/LICENSE-2.0
+#    
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+
+# Generate an Axis2 server conf
+here=`readlink -f $0`; here=`dirname $here`
+root=`readlink -f $1`
+
+# Create an Axis2 home directory
+mkdir -p $root/axis2c
+ln -f -s $AXIS2C_HOME/lib $root/axis2c/lib
+mkdir -p $root/axis2c/logs
+mkdir -p $root/axis2c/modules
+ln -f -s $AXIS2C_HOME/modules/addressing $root/axis2c/modules/addressing
+ln -f -s $AXIS2C_HOME/modules/logging $root/axis2c/modules/logging
+mkdir -p $root/axis2c/services
+
+# Install Tuscany Axis2 module and service
+mkdir -p $root/axis2c/modules/tuscany
+ln -f -s $here/.libs/libaxis2-dispatcher.so $root/axis2c/modules/tuscany/libaxis2-dispatcher.so
+ln -f -s $here/module.xml $root/axis2c/modules/tuscany/module.xml
+mkdir -p $root/axis2c/services/tuscany
+ln -f -s $here/.libs/libaxis2-service.so $root/axis2c/services/tuscany/libaxis2-service.so
+ln -f -s $here/services.xml $root/axis2c/services/tuscany/services.xml
+cp $here/axis2.xml $root/axis2c/axis2.xml
+
+# Configure HTTPD Axis2 module
+cat >>$root/conf/httpd.conf <<EOF
+LoadModule axis2_module $root/axis2c/lib/libmod_axis2.so
+Axis2RepoPath $root/axis2c
+Axis2LogFile $root/axis2c/logs/mod_axis2.log
+Axis2LogLevel debug
+<Location /axis2>
+    SetHandler axis2_module
+</Location>
+EOF

Propchange: tuscany/sca-cpp/trunk/components/webservice/axis2-conf
------------------------------------------------------------------------------
    svn:executable = *

Added: tuscany/sca-cpp/trunk/components/webservice/axis2-dispatcher.cpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/webservice/axis2-dispatcher.cpp?rev=904733&view=auto
==============================================================================
--- tuscany/sca-cpp/trunk/components/webservice/axis2-dispatcher.cpp (added)
+++ tuscany/sca-cpp/trunk/components/webservice/axis2-dispatcher.cpp Sat Jan 30 08:06:00 2010
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *   
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/* $Rev$ $Date$ */
+
+/**
+ * Axis2/C module that dispatches all server requests to the Tuscany Axis/2C service.
+ */
+
+#include "axis2.hpp"
+
+namespace tuscany {
+namespace webservice {
+
+/**
+ * Determine the service and operation to dispatch a request to.
+ */
+axis2_svc_t* AXIS2_CALL dispatchFindService(axis2_msg_ctx_t* msg_ctx, const axutil_env_t* env) {
+    const axis2_conf_ctx_t* conf_ctx = axis2_msg_ctx_get_conf_ctx(msg_ctx, env);
+    const axis2_conf_t* conf = axis2_conf_ctx_get_conf(conf_ctx, env);
+    axis2_svc_t* svc = axis2_conf_get_svc(conf, env, "TuscanyService");
+    return svc;
+}
+
+axis2_op_t *AXIS2_CALL dispatchFindOp(unused axis2_msg_ctx_t* msg_ctx, const axutil_env_t* env, axis2_svc_t* svc) {
+    axutil_qname_t* op_qname = axutil_qname_create(env, "execute", NULL, NULL);
+    axis2_op_t *op = axis2_svc_get_op_with_name(svc, env, axutil_qname_get_localpart(op_qname, env));
+    axutil_qname_free(op_qname, env);
+    return op;
+}
+
+/**
+ * Dispatcher invoke function, called by Axis2/C.
+ */
+axis2_status_t AXIS2_CALL dispatchInvoke( struct axis2_handler* handler, const axutil_env_t* env, axis2_msg_ctx_t* msg_ctx) {
+    if (!(axis2_msg_ctx_get_server_side(msg_ctx, env)))
+        return AXIS2_SUCCESS;
+    axis2_msg_ctx_set_find_svc(msg_ctx, env, dispatchFindService);
+    axis2_msg_ctx_set_find_op(msg_ctx, env, dispatchFindOp);
+    return axis2_disp_find_svc_and_op(handler, env, msg_ctx);
+}
+
+/**
+ * Create a dispatch handler.
+ */
+AXIS2_EXPORT axis2_handler_t* AXIS2_CALL dispatchHandler(const axutil_env_t* env, unused axutil_string_t* name) {
+    axis2_handler_t *handler = axis2_handler_create(env);
+    if (handler == NULL)
+        return NULL;
+    axis2_handler_set_invoke(handler, env, dispatchInvoke);
+    return handler;
+}
+
+/**
+ * Initialize dispatch module.
+ */
+axis2_status_t AXIS2_CALL dispatchInit(unused axis2_module_t * module, unused const axutil_env_t * env, unused axis2_conf_ctx_t * conf_ctx, unused axis2_module_desc_t * module_desc) {
+    return AXIS2_SUCCESS;
+}
+
+/**
+ * Initialize dispatch module function map.
+ */
+axis2_status_t AXIS2_CALL dispatchFuncMap(axis2_module_t * module, const axutil_env_t * env) {
+    module->handler_create_func_map = axutil_hash_make(env);
+    axutil_hash_set(module->handler_create_func_map, "TuscanyDispatcher", AXIS2_HASH_KEY_STRING, (const void *)dispatchHandler);
+    return AXIS2_SUCCESS;
+}
+
+/**
+ * Shutdown dispatch module.
+ */
+axis2_status_t AXIS2_CALL dispatchShutdown(axis2_module_t* module, const axutil_env_t* env) {
+    if (module->handler_create_func_map != NULL) {
+        axutil_hash_free(module->handler_create_func_map, env);
+        module->handler_create_func_map = NULL;
+    }
+    AXIS2_FREE(env->allocator, module);
+    return AXIS2_SUCCESS;
+}
+
+/**
+ * Return a new dispatch module.
+ */
+const axis2_module_ops_t dispatchOps = {
+    dispatchInit,
+    dispatchShutdown,
+    dispatchFuncMap
+};
+
+axis2_module_t * dispatchModule(const axutil_env_t* env) {
+    axis2_module_t *module = (axis2_module_t*)AXIS2_MALLOC(env->allocator, sizeof(axis2_module_t));
+    if (module == NULL)
+        return NULL;
+    module->ops = &dispatchOps;
+    module->handler_create_func_map = NULL;
+    return module;
+}
+
+}
+}
+
+extern "C"
+{
+
+/**
+ * Axis2/C module entry point functions.
+ */
+AXIS2_EXPORT int axis2_get_instance(axis2_module_t** inst, const axutil_env_t* env) {
+   *inst = tuscany::webservice::dispatchModule(env);
+    if(*inst == NULL)
+        return AXIS2_FAILURE;
+    return AXIS2_SUCCESS;
+}
+
+AXIS2_EXPORT int axis2_remove_instance(axis2_module_t* inst, const axutil_env_t* env) {
+    if (inst != NULL)
+         return tuscany::webservice::dispatchShutdown(inst, env);
+    return AXIS2_FAILURE;
+}
+
+}

Added: tuscany/sca-cpp/trunk/components/webservice/axis2-service.cpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/webservice/axis2-service.cpp?rev=904733&view=auto
==============================================================================
--- tuscany/sca-cpp/trunk/components/webservice/axis2-service.cpp (added)
+++ tuscany/sca-cpp/trunk/components/webservice/axis2-service.cpp Sat Jan 30 08:06:00 2010
@@ -0,0 +1,151 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *   
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/* $Rev$ $Date$ */
+
+/**
+ * Axis2/C service implementation that dispatches requests to SCA Web service components.
+ */
+
+#include "value.hpp"
+#include "string.hpp"
+#include "../../modules/http/httpd.hpp"
+#include "axis2.hpp"
+
+namespace tuscany {
+namespace webservice {
+
+/**
+ * Initialize the service.
+ */
+int AXIS2_CALL serviceInit(unused axis2_svc_skeleton_t* svc_skeleton, unused const axutil_env_t* env) {
+    return AXIS2_SUCCESS;
+}
+
+/**
+ * Free the service.
+ */
+int AXIS2_CALL serviceFree(axis2_svc_skeleton_t* svc_skeleton, const axutil_env_t* env) {
+    if (svc_skeleton)
+        AXIS2_FREE(env->allocator, svc_skeleton);
+    return AXIS2_SUCCESS;
+}
+
+typedef struct axis2_apache2_out_transport_info {
+    axis2_http_out_transport_info_t out_transport_info;
+    request_rec *request;
+    axis2_char_t *encoding;
+} axis2_apache2_out_transport_info_t;
+
+extern "C" {
+    extern module axis2_module;
+}
+
+/**
+ * Service invoke function, called by Axis2/C.
+ */
+axiom_node_t *AXIS2_CALL serviceInvoke(unused axis2_svc_skeleton_t* svc_skeleton, const axutil_env_t* env, axiom_node_t* node, axis2_msg_ctx_t* msg_ctx) {
+
+    // Check that we have an input node
+    if (node == NULL || axiom_node_get_node_type(node, env) != AXIOM_ELEMENT)
+        return NULL;
+    axiom_element_t *e = (axiom_element_t *) axiom_node_get_data_element(node, env);
+    if (e == NULL)
+        return NULL;
+
+    // Get the function name
+    const char* func = axiom_element_get_localname(e, env);
+    if (func == NULL)
+        return NULL;
+
+    // Get the target endpoint address
+    const axis2_endpoint_ref_t* epr = axis2_msg_ctx_get_from(msg_ctx, env);
+    if (epr == NULL)
+        return NULL;
+    string address = axis2_endpoint_ref_get_address(epr, env);
+
+    // Get the underlying HTTPD request
+    axis2_out_transport_info_t* tinfo = axis2_msg_ctx_get_out_transport_info(msg_ctx, env);
+    axis2_apache2_out_transport_info_t* httpinfo = (axis2_apache2_out_transport_info_t*)tinfo;
+    request_rec* r = httpinfo->request;
+    httpdDebugRequest(r, "webservice::serviceInvoke");
+
+    // Parse the request Axiom node and construct request expression
+    Axis2Context ax(env);
+    const failable<const list<value> > lv = axiomNodeToValues(node, ax);
+    if (!hasContent(lv))
+        return NULL;
+    const value expr = mklist<value>(func, content(lv));
+    debug(expr, "webservice::serviceInvoke::expr");
+
+    // Retrieve the target lambda function from the HTTPD request and invoke it
+    const value* rv = const_cast<const value*>((value*)ap_get_module_config(r->request_config, &axis2_module));
+    cout << "relay: " << rv << endl;
+    const lambda<value(const list<value>&)> relay = *rv;
+    const value res = relay(expr);
+    debug(res, "webservice::serviceInvoke::result");
+
+    // Construct response Axiom node
+    const failable<axiom_node_t*> rnode = valuesToAxiomNode(res, ax);
+    if (!hasContent(rnode))
+        return NULL;
+    return content(rnode);
+}
+
+/**
+ * Return a new service skeleton.
+ */
+const axis2_svc_skeleton_ops_t serviceOps = {
+    serviceInit,
+    serviceInvoke,
+    NULL,
+    serviceFree,
+    NULL
+};
+
+AXIS2_EXTERN axis2_svc_skeleton_t *AXIS2_CALL serviceSkeleton(const axutil_env_t* env) {
+    axis2_svc_skeleton_t* svc_skeleton = (axis2_svc_skeleton_t*)AXIS2_MALLOC(env->allocator, sizeof(axis2_svc_skeleton_t));
+    svc_skeleton->ops = &serviceOps;
+    svc_skeleton->func_array = NULL;
+    return svc_skeleton;
+}
+
+}
+}
+
+extern "C"
+{
+
+/**
+ * Axis2/C service entry point functions.
+ */
+AXIS2_EXPORT int axis2_get_instance(struct axis2_svc_skeleton** inst, const axutil_env_t* env) {
+    *inst = tuscany::webservice::serviceSkeleton(env);
+    if (inst == NULL)
+        return AXIS2_FAILURE;
+    return AXIS2_SUCCESS;
+}
+
+AXIS2_EXPORT int axis2_remove_instance(axis2_svc_skeleton_t* inst, const axutil_env_t* env) {
+    if (inst != NULL)
+        return AXIS2_SVC_SKELETON_FREE(inst, env);
+    return AXIS2_FAILURE;
+}
+
+}

Modified: tuscany/sca-cpp/trunk/components/webservice/axis2.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/webservice/axis2.hpp?rev=904733&r1=904732&r2=904733&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/webservice/axis2.hpp (original)
+++ tuscany/sca-cpp/trunk/components/webservice/axis2.hpp Sat Jan 30 08:06:00 2010
@@ -25,6 +25,7 @@
 /**
  * Web service invocation functions using Axis2.
  */
+#include "config.hpp"
 
 // Ignore redundant declarations in Axiom headers
 #ifdef WANT_MAINTAINER_MODE
@@ -32,6 +33,11 @@
 #endif
 #include <axiom.h>
 #include <axis2_client.h>
+#include <axis2_module.h>
+#include <axis2_addr_mod.h>
+#include <axis2_conf_ctx.h>
+#include <axis2_disp.h>
+#include <axis2_http_out_transport_info.h>
 #ifdef WANT_MAINTAINER_MODE
 #pragma GCC diagnostic warning "-Wredundant-decls"
 #endif
@@ -57,6 +63,9 @@
     Axis2Context(const Axis2Context& ax) : env(ax.env), owner(false) {
     }
 
+    Axis2Context(const axutil_env_t* env) : env(const_cast<axutil_env_t*>(env)), owner(false) {
+    }
+
     ~Axis2Context() {
         if (!owner || env == NULL)
             return;

Added: tuscany/sca-cpp/trunk/components/webservice/axis2.xml
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/webservice/axis2.xml?rev=904733&view=auto
==============================================================================
--- tuscany/sca-cpp/trunk/components/webservice/axis2.xml (added)
+++ tuscany/sca-cpp/trunk/components/webservice/axis2.xml Sat Jan 30 08:06:00 2010
@@ -0,0 +1,148 @@
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+   
+     http://www.apache.org/licenses/LICENSE-2.0
+     
+   Unless required by applicable law or agreed to in writing,
+   software distributed under the License is distributed on an
+   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+   KIND, either express or implied.  See the License for the
+   specific language governing permissions and limitations
+   under the License.
+-->
+<axisconfig name="Axis2/C">
+    <!-- ================================================= -->
+    <!-- Parameters -->
+    <!-- ================================================= -->
+    <!-- Uncomment following to enable MTOM support globally -->
+    <!--parameter name="enableMTOM" locked="false">true</parameter-->
+
+    <!-- Set the suitable size for optimum memory usage when sending large attachments -->
+    <!--parameter name="MTOMBufferSize" locked="false">10</parameter-->
+    <!--parameter name="MTOMMaxBuffers" locked="false">1000</parameter-->
+    <!--parameter name="EnableMTOMServiceCallback" locked="false">true</parameter-->
+    <!--parameter name="attachmentDIR" locked="false">/path/to/the/attachment/caching/dir/</parameter-->    
+    <!--parameter name="MTOMCachingCallback" locked="false">/path/to/the/caching_callback</parameter-->
+    <!--parameter name="MTOMSendingCallback" locked="false">/path/to/the/sending_callback</parameter-->
+
+    <!-- Enable REST -->
+    <parameter name="enableREST" locked="false">true</parameter>
+
+    <!-- Uncomment following to persist op_ctx, useful with RM -->
+    <!--parameter name="persistOperationContext" locked="false">true</parameter-->
+
+    <!--if you want to extract the service archive file and work with that please uncomment this-->
+    <!--else , it wont extract archive file or does not take into consideration if someone drop-->
+    <!--exploded directory into /service directory-->
+    <!--<parameter name="extractServiceArchive" locked="false">true</parameter>-->
+
+
+    <!-- ================================================= -->
+    <!-- Message Receivers -->
+    <!-- ================================================= -->
+    <!-- This is the Deafult Message Receiver for the Request Response style Operations -->
+    <!--messageReceiver mep="INOUT" class="axis2_receivers"/-->
+
+  
+    <!-- ================================================= -->
+    <!-- Transport Ins -->
+    <!-- ================================================= -->
+  
+    <transportReceiver name="http" class="axis2_http_receiver">
+        <parameter name="port" locked="false">6060</parameter>
+        <parameter name="exposeHeaders" locked="true">false</parameter>
+    </transportReceiver>
+  
+    <!--transportReceiver name="https" class="axis2_http_receiver">
+        <parameter name="port" locked="false">6060</parameter>
+        <parameter name="exposeHeaders" locked="true">false</parameter>
+    </transportReceiver-->
+  
+    <!--transportReceiver name="tcp" class="axis2_tcp_receiver">
+        <parameter name="port" locked="false">6060</parameter>
+    </transportReceiver-->
+
+
+    <!-- ================================================= -->
+    <!-- Transport Outs -->
+    <!-- ================================================= -->
+
+    <transportSender name="http" class="axis2_http_sender">
+        <parameter name="PROTOCOL" locked="false">HTTP/1.1</parameter>
+        <parameter name="xml-declaration" insert="false"/>
+        <!--parameter name="Transfer-Encoding">chunked</parameter-->
+        <!--parameter name="HTTP-Authentication" username="" password="" locked="true"/-->
+        <!--parameter name="PROXY" proxy_host="127.0.0.1" proxy_port="8080" proxy_username="" proxy_password="" locked="true"/-->
+    </transportSender>
+
+    <!-- Uncomment the following with appropriate parameters to enable the SSL transport sender.
+         Also make sure that the appropriate transport receiver is enabled above.-->
+    <!--transportSender name="https" class="axis2_http_sender">
+        <parameter name="PROTOCOL" locked="false">HTTP/1.1</parameter>
+        <parameter name="xml-declaration" insert="false"/>
+    </transportSender>
+    <parameter name="SERVER_CERT">/path/to/ca/certificate</parameter>
+    <parameter name="KEY_FILE">/path/to/client/certificate/chain/file</parameter>
+    <parameter name="SSL_PASSPHRASE">passphrase</parameter>
+    -->
+
+    <!-- Uncomment this one with the appropriate papameters to enable the TCP transport Sender-->
+    <!--transportSender name="tcp" class="axis2_tcp_sender">
+        <parameter name="PROTOCOL" locked="false">TCP</parameter>
+        <parameter name="xml-declaration" insert="false"/>
+    </transportSender-->
+
+
+    <!-- ================================================= -->
+    <!-- Global Modules  -->
+    <!-- ================================================= -->
+    <!-- Comment this to disable Addressing -->
+    <module ref="addressing"/>
+
+	<!-- Tuscany dispatcher module -->
+    <module ref="tuscany"/>
+
+    <!--Configuring module , providing paramters for modules whether they refer or not-->
+    <!--<moduleConfig name="addressing">-->
+    <!--<parameter name="addressingPara" locked="false">N/A</parameter>-->
+    <!--</moduleConfig>-->
+
+    <!-- ================================================= -->
+    <!-- Phases  -->
+    <!-- ================================================= -->
+    <phaseOrder type="inflow">
+        <!-- System pre defined phases       -->
+        <phase name="Transport"/>
+        <phase name="PreDispatch"/>
+        <phase name="Dispatch"/>
+        <phase name="PostDispatch"/>
+        <!--phase name="Security"/-->
+        <!-- End system pre defined phases       -->
+        <!-- After PostDispatch phase, module or service author can add any phase as required  -->
+        <!-- User defined phases could be added here -->
+        <!--phase name="userphase1"/-->
+    </phaseOrder>
+    <phaseOrder type="outflow">
+        <!-- User defined phases could be added here -->
+        <!--phase name="userphase1"/-->
+        <!--system predefined phase-->
+        <phase name="MessageOut"/>
+        <!--phase name="Security"/-->
+    </phaseOrder>
+    <phaseOrder type="INfaultflow">
+        <!-- User defined phases could be added here -->
+        <!--phase name="userphase1"/-->
+    </phaseOrder>
+    <phaseOrder type="Outfaultflow">
+        <!-- User defined phases could be added here -->
+        <!--phase name="userphase1"/-->
+        <phase name="MessageOut"/>
+    </phaseOrder>
+</axisconfig>
+

Modified: tuscany/sca-cpp/trunk/components/webservice/client-test.cpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/webservice/client-test.cpp?rev=904733&r1=904732&r2=904733&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/webservice/client-test.cpp (original)
+++ tuscany/sca-cpp/trunk/components/webservice/client-test.cpp Sat Jan 30 08:06:00 2010
@@ -32,11 +32,33 @@
 #include "monad.hpp"
 #include "perf.hpp"
 #include "../../modules/http/curl.hpp"
+#include "axis2.hpp"
 
 namespace tuscany {
 namespace webservice {
 
 
+bool testModAxis2() {
+    const Axis2Context ax;
+
+    const value func = "http://ws.apache.org/axis2/c/samples/echoString";
+    const list<value> arg = mklist<value>(
+            list<value>() + "ns1:echoString"
+            + (list<value>() + "@xmlns:ns1" + string("http://ws.apache.org/axis2/services/echo"))
+            + (list<value>() + "text" + string("Hello World!")));
+
+    const failable<value> rval = evalExpr(mklist<value>(func, arg, string("http://localhost:8090/echo-listener")), ax);
+    assert(hasContent(rval));
+
+    const list<value> r = mklist<value>(
+            list<value>() + "ns1:echoString"
+            + (list<value>() + "@xmlns:ns1" + string("http://ws.apache.org/axis2/services/echo"))
+            + (list<value>() + "text" + string("Hello World!")));
+    assert(content(rval) == r);
+
+    return true;
+}
+
 bool testEval() {
     http::CURLSession cs;
 
@@ -63,6 +85,7 @@
 int main() {
     tuscany::cout << "Testing..." << tuscany::endl;
 
+    tuscany::webservice::testModAxis2();
     tuscany::webservice::testEval();
 
     tuscany::cout << "OK" << tuscany::endl;

Modified: tuscany/sca-cpp/trunk/components/webservice/echo-test
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/webservice/echo-test?rev=904733&r1=904732&r2=904733&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/webservice/echo-test (original)
+++ tuscany/sca-cpp/trunk/components/webservice/echo-test Sat Jan 30 08:06:00 2010
@@ -18,7 +18,7 @@
 #  under the License.
 
 # Setup
-axis2="${AXIS2C_HOME}/bin/axis2_http_server"
+axis2="$AXIS2C_HOME/bin/axis2_http_server"
 pwd=`pwd`
 cd $AXIS2C_HOME/bin
 $axis2 &
@@ -30,6 +30,6 @@
 rc=$?
 
 # Cleanup
-kill `ps -f | grep -v grep | grep "${axis2}" | awk '{ print $2 }'`
+kill `ps -f | grep -v grep | grep "$axis2" | awk '{ print $2 }'`
 sleep 1
 return $rc

Added: tuscany/sca-cpp/trunk/components/webservice/module.xml
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/webservice/module.xml?rev=904733&view=auto
==============================================================================
--- tuscany/sca-cpp/trunk/components/webservice/module.xml (added)
+++ tuscany/sca-cpp/trunk/components/webservice/module.xml Sat Jan 30 08:06:00 2010
@@ -0,0 +1,25 @@
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+   
+     http://www.apache.org/licenses/LICENSE-2.0
+     
+   Unless required by applicable law or agreed to in writing,
+   software distributed under the License is distributed on an
+   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+   KIND, either express or implied.  See the License for the
+   specific language governing permissions and limitations
+   under the License.
+-->
+<module name="tuscany" class="axis2-dispatcher">
+    <inflow>
+        <handler name="TuscanyDispatcher" class="axis2-dispatcher">
+            <order phase="Dispatch"/>
+        </handler>
+    </inflow>
+</module>

Modified: tuscany/sca-cpp/trunk/components/webservice/server-test
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/webservice/server-test?rev=904733&r1=904732&r2=904733&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/webservice/server-test (original)
+++ tuscany/sca-cpp/trunk/components/webservice/server-test Sat Jan 30 08:06:00 2010
@@ -21,6 +21,7 @@
 ../../modules/http/httpd-conf tmp 8090 ../../modules/http/htdocs
 ../../modules/server/server-conf tmp
 ../../modules/server/scheme-conf tmp
+./axis2-conf tmp
 cat >>tmp/conf/httpd.conf <<EOF
 
 <Location />
@@ -31,7 +32,7 @@
 
 apachectl -k start -d `pwd`/tmp
 
-axis2="${AXIS2C_HOME}/bin/axis2_http_server"
+axis2="$AXIS2C_HOME/bin/axis2_http_server"
 pwd=`pwd`
 cd $AXIS2C_HOME/bin
 $axis2 &
@@ -43,7 +44,7 @@
 rc=$?
 
 # Cleanup
-kill `ps -f | grep -v grep | grep "${axis2}" | awk '{ print $2 }'`
+kill `ps -f | grep -v grep | grep "$axis2" | awk '{ print $2 }'`
 apachectl -k stop -d `pwd`/tmp
 sleep 2
 return $rc

Added: tuscany/sca-cpp/trunk/components/webservice/server-test.scm
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/webservice/server-test.scm?rev=904733&view=auto
==============================================================================
--- tuscany/sca-cpp/trunk/components/webservice/server-test.scm (added)
+++ tuscany/sca-cpp/trunk/components/webservice/server-test.scm Sat Jan 30 08:06:00 2010
@@ -0,0 +1,4 @@
+; Web service test case
+
+(define (echoString x) x)
+

Added: tuscany/sca-cpp/trunk/components/webservice/services.xml
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/webservice/services.xml?rev=904733&view=auto
==============================================================================
--- tuscany/sca-cpp/trunk/components/webservice/services.xml (added)
+++ tuscany/sca-cpp/trunk/components/webservice/services.xml Sat Jan 30 08:06:00 2010
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+   
+     http://www.apache.org/licenses/LICENSE-2.0
+     
+   Unless required by applicable law or agreed to in writing,
+   software distributed under the License is distributed on an
+   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+   KIND, either express or implied.  See the License for the
+   specific language governing permissions and limitations
+   under the License.
+-->
+<serviceGroup>
+<service name="TuscanyService">
+    <parameter name="ServiceClass" locked="xsd:false">axis2-service</parameter>
+    <operation name="execute"/>
+</service>
+</serviceGroup>

Modified: tuscany/sca-cpp/trunk/components/webservice/webservice-listener.cpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/webservice/webservice-listener.cpp?rev=904733&r1=904732&r2=904733&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/webservice/webservice-listener.cpp (original)
+++ tuscany/sca-cpp/trunk/components/webservice/webservice-listener.cpp Sat Jan 30 08:06:00 2010
@@ -35,17 +35,40 @@
 namespace webservice {
 
 /**
- * Handle an HTTP request.
+ * Redirect an HTTP request to the Axis2/C HTTPD module. The given relay lambda function
+ * is stored in the HTTPD request, for later retrieval by the Axis2 service to relay the request
+ * to a target component.
  */
-const failable<value> handle(const list<value>& params) {
+extern "C" {
+    extern module axis2_module;
+}
 
-    // Extract HTTPD request and relay reference
-    unused request_rec* r = httpd::request(car(params));
-    const lambda<value(const list<value>&)> relay = cadr(params);
+const value redirectToAxis2(const string& uri, request_rec* r, const value& relay) {
+    const failable<request_rec*, int> nr = httpd::internalRedirectRequest(uri, r);
+    if (!hasContent(nr))
+        return value(reason(nr));
+    ap_set_module_config(content(nr)->request_config, &axis2_module, const_cast<void*>((const void*)&relay));
+    return value(httpd::internalRedirect(content(nr)));
+}
 
-    //TODO Hook Axis2/C server module here
+/**
+ * Handle an HTTP request.
+ */
+const failable<value> handle(const list<value>& params) {
 
-    return value(true);
+    // Extract HTTPD request from the params
+    request_rec* r = httpd::request(car(params));
+    httpdDebugRequest(r, "webservice::handle");
+
+    // Extract the relay lambda from the params and store it in the HTTPD request,
+    // for later retrieval by our Axis2 service
+    const value relay = cadr(params);
+    cout << "relay: " << &relay << endl;
+
+    // Redirect HTTPD request to Mod-axis2
+    if (r->args == NULL)
+        return redirectToAxis2(httpd::redirectURI("/axis2", string(r->uri)), r, relay);
+    return redirectToAxis2(httpd::redirectURI("/axis2", string(r->uri), string(r->args)), r, relay);
 }
 
 }

Modified: tuscany/sca-cpp/trunk/components/webservice/webservice.composite
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/webservice/webservice.composite?rev=904733&r1=904732&r2=904733&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/webservice/webservice.composite (original)
+++ tuscany/sca-cpp/trunk/components/webservice/webservice.composite Sat Jan 30 08:06:00 2010
@@ -39,7 +39,7 @@
     </component>
 
     <component name="echo">
-        <t:implementation.scheme script="echo.scm"/>
+        <t:implementation.scheme script="server-test.scm"/>
         <service name="echo">
             <t:binding.jsonrpc uri="echo"/>
         </service>

Modified: tuscany/sca-cpp/trunk/configure.ac
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/configure.ac?rev=904733&r1=904732&r2=904733&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/configure.ac (original)
+++ tuscany/sca-cpp/trunk/configure.ac Sat Jan 30 08:06:00 2010
@@ -146,7 +146,6 @@
 AC_MSG_NOTICE([checking for required libraries])
 LIBS="-L${APR_LIB} ${defaultlibs}"
 AC_CHECK_LIB([apr-1], [apr_pool_initialize], [AC_MSG_NOTICE([found])], [AC_MSG_ERROR([couldn't find a suitable libapr-1, use --with-apr=PATH])])
-AC_CHECK_LIB([aprutil-1], [apr_memcache_replace], [AC_MSG_NOTICE([found])], [AC_MSG_ERROR([couldn't find a suitable libaprutil-1, use --with-apr=PATH])])
 ldflags="${ldflags} -L${APR_LIB} -R${APR_LIB} -lapr-1 -laprutil-1"
 
 # Check for libraries only required by some modules and add their search path to LD options.  

Modified: tuscany/sca-cpp/trunk/modules/http/httpd.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/http/httpd.hpp?rev=904733&r1=904732&r2=904733&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/http/httpd.hpp (original)
+++ tuscany/sca-cpp/trunk/modules/http/httpd.hpp Sat Jan 30 08:06:00 2010
@@ -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 @@
 }
 
 /**
- * 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));
 }
 
 }

Modified: tuscany/sca-cpp/trunk/modules/json/json-test.cpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/json/json-test.cpp?rev=904733&r1=904732&r2=904733&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/json/json-test.cpp (original)
+++ tuscany/sca-cpp/trunk/modules/json/json-test.cpp Sat Jan 30 08:06:00 2010
@@ -78,7 +78,6 @@
     }
     {
         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!\"}}");

Modified: tuscany/sca-cpp/trunk/modules/server/mod-eval.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/server/mod-eval.hpp?rev=904733&r1=904732&r2=904733&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/server/mod-eval.hpp (original)
+++ tuscany/sca-cpp/trunk/modules/server/mod-eval.hpp Sat Jan 30 08:06:00 2010
@@ -129,13 +129,18 @@
  * 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 @@
     // 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<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 @@
         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));

Modified: tuscany/sca-cpp/trunk/modules/server/mod-wiring.cpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/server/mod-wiring.cpp?rev=904733&r1=904732&r2=904733&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/server/mod-wiring.cpp (original)
+++ tuscany/sca-cpp/trunk/modules/server/mod-wiring.cpp Sat Jan 30 08:06:00 2010
@@ -194,17 +194,6 @@
 }
 
 /**
- * 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 @@
     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);
 }
 
 /**