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/08/14 20:46:28 UTC

svn commit: r985561 [1/2] - in /tuscany/sca-cpp/trunk: ./ components/cache/ components/chat/ components/log/ components/nosqldb/ components/queue/ components/sqldb/ components/webservice/ etc/ kernel/ modules/http/ modules/json/ modules/server/ samples...

Author: jsdelfino
Date: Sat Aug 14 18:46:26 2010
New Revision: 985561

URL: http://svn.apache.org/viewvc?rev=985561&view=rev
Log:
Some refactoring of the HTTP support, tunnel Memcached requests over HTTPS and add HTTPS config to store-cluster sample.

Added:
    tuscany/sca-cpp/trunk/components/cache/memcached-ssl-test   (with props)
    tuscany/sca-cpp/trunk/modules/http/curl-connect.cpp
    tuscany/sca-cpp/trunk/modules/http/http.hpp
      - copied, changed from r981352, tuscany/sca-cpp/trunk/modules/http/curl.hpp
    tuscany/sca-cpp/trunk/modules/http/httpd-addr
      - copied, changed from r981352, tuscany/sca-cpp/trunk/components/cache/memcached-start
    tuscany/sca-cpp/trunk/modules/http/mod-ssltunnel.cpp
    tuscany/sca-cpp/trunk/modules/http/ssl-cert-find
      - copied, changed from r981352, tuscany/sca-cpp/trunk/modules/http/ssl-ls
    tuscany/sca-cpp/trunk/modules/http/tunnel-ssl-conf
      - copied, changed from r981352, tuscany/sca-cpp/trunk/modules/http/vhost-conf
    tuscany/sca-cpp/trunk/samples/store-cluster/proxy-conf
      - copied, changed from r981352, tuscany/sca-cpp/trunk/modules/http/ssl-ls
    tuscany/sca-cpp/trunk/samples/store-cluster/proxy-ssl-conf
      - copied, changed from r981352, tuscany/sca-cpp/trunk/components/cache/memcached-start
    tuscany/sca-cpp/trunk/samples/store-cluster/server-conf
      - copied, changed from r981352, tuscany/sca-cpp/trunk/modules/http/proxy-ssl-member-conf
    tuscany/sca-cpp/trunk/samples/store-cluster/server-ssl-conf
      - copied, changed from r981352, tuscany/sca-cpp/trunk/samples/store-vhost/ssl-start
    tuscany/sca-cpp/trunk/samples/store-cluster/ssl-stop
      - copied, changed from r981352, tuscany/sca-cpp/trunk/components/cache/memcached-start
    tuscany/sca-cpp/trunk/samples/store-cluster/tunnel-ssl-conf
      - copied, changed from r981352, tuscany/sca-cpp/trunk/samples/store-java/ssl-start
Removed:
    tuscany/sca-cpp/trunk/modules/http/curl.hpp
    tuscany/sca-cpp/trunk/modules/http/ssl-ls
Modified:
    tuscany/sca-cpp/trunk/INSTALL
    tuscany/sca-cpp/trunk/components/cache/Makefile.am
    tuscany/sca-cpp/trunk/components/cache/client-test.cpp
    tuscany/sca-cpp/trunk/components/cache/memcache-test.cpp
    tuscany/sca-cpp/trunk/components/cache/memcache.hpp
    tuscany/sca-cpp/trunk/components/cache/memcached-start
    tuscany/sca-cpp/trunk/components/cache/memcached-stop
    tuscany/sca-cpp/trunk/components/chat/client-test.cpp
    tuscany/sca-cpp/trunk/components/log/client-test.cpp
    tuscany/sca-cpp/trunk/components/nosqldb/client-test.cpp
    tuscany/sca-cpp/trunk/components/queue/client-test.cpp
    tuscany/sca-cpp/trunk/components/sqldb/client-test.cpp
    tuscany/sca-cpp/trunk/components/webservice/client-test.cpp
    tuscany/sca-cpp/trunk/etc/git-exclude
    tuscany/sca-cpp/trunk/kernel/gc.hpp
    tuscany/sca-cpp/trunk/modules/http/Makefile.am
    tuscany/sca-cpp/trunk/modules/http/curl-get.cpp
    tuscany/sca-cpp/trunk/modules/http/curl-test.cpp
    tuscany/sca-cpp/trunk/modules/http/httpd-auth-conf
    tuscany/sca-cpp/trunk/modules/http/httpd-conf
    tuscany/sca-cpp/trunk/modules/http/httpd-ssl-conf
    tuscany/sca-cpp/trunk/modules/http/httpd.hpp
    tuscany/sca-cpp/trunk/modules/http/proxy-member-conf
    tuscany/sca-cpp/trunk/modules/http/proxy-ssl-conf
    tuscany/sca-cpp/trunk/modules/http/proxy-ssl-member-conf
    tuscany/sca-cpp/trunk/modules/http/ssl-ca-conf
    tuscany/sca-cpp/trunk/modules/http/ssl-cert-conf
    tuscany/sca-cpp/trunk/modules/http/vhost-conf
    tuscany/sca-cpp/trunk/modules/http/vhost-ssl-conf
    tuscany/sca-cpp/trunk/modules/json/json.hpp
    tuscany/sca-cpp/trunk/modules/server/client-test.hpp
    tuscany/sca-cpp/trunk/modules/server/mod-eval.hpp
    tuscany/sca-cpp/trunk/modules/server/mod-wiring.cpp
    tuscany/sca-cpp/trunk/modules/server/server-conf
    tuscany/sca-cpp/trunk/samples/store-cluster/Makefile.am
    tuscany/sca-cpp/trunk/samples/store-cluster/ssl-start
    tuscany/sca-cpp/trunk/samples/store-cluster/start
    tuscany/sca-cpp/trunk/samples/store-cpp/ssl-start
    tuscany/sca-cpp/trunk/samples/store-java/ssl-start
    tuscany/sca-cpp/trunk/samples/store-nosql/ssl-start
    tuscany/sca-cpp/trunk/samples/store-scheme/ssl-start
    tuscany/sca-cpp/trunk/samples/store-vhost/ssl-start
    tuscany/sca-cpp/trunk/ubuntu/ubuntu-install-all

Modified: tuscany/sca-cpp/trunk/INSTALL
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/INSTALL?rev=985561&r1=985560&r2=985561&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/INSTALL (original)
+++ tuscany/sca-cpp/trunk/INSTALL Sat Aug 14 18:46:26 2010
@@ -57,7 +57,7 @@ http://svn.apache.org/repos/asf/tuscany/
 Then install the following development dependencies:
 
 Apache HTTP server and APR:
-httpd-2.2-15 (http://httpd.apache.org/)
+httpd-2.2.16 (http://httpd.apache.org/)
 with included libapr and libaprutil
 built with OpenSSL libssl-0.9.8g
 
@@ -223,14 +223,14 @@ Building dependencies from source
 Here are example build and install steps for some of the dependencies.
 
 Apache HTTPD, including APR, using the HTTP prefork MPM (recommended):
-wget http://www.apache.org/dist/httpd/httpd-2.2.15.tar.gz
-tar xzf httpd-2.2.15.tar.gz
-cd httpd-2.2.15
+wget http://www.apache.org/dist/httpd/httpd-2.2.16.tar.gz
+tar xzf httpd-2.2.16.tar.gz
+cd httpd-2.2.16
 ./configure --enable-ssl --enable-proxy --enable-mods-shared=most \
---with-included-apr --with-mpm=prefork --prefix=$HOME/httpd-2.2.15-bin
+--with-included-apr --with-mpm=prefork --prefix=$HOME/httpd-2.2.16-bin
 make
 make install
-export PATH=$HOME/httpd-2-2.15-bin/bin:$PATH
+export PATH=$HOME/httpd-2.2.16-bin/bin:$PATH
 
 Memcached:
 wget http://memcached.googlecode.com/files/memcached-1.4.4.tar.gz
@@ -277,7 +277,7 @@ wget http://www.apache.org/dist/ws/axis2
 tar xzf axis2c-src-1.6.0.tar.gz
 cd axis2c-src-1.6.0
 ./configure --enable-libxml2 --enable-openssl \
---with-apache2=$HOME/httpd-2.2.15-bin/include --prefix=$HOME/axis2c-1.6.0-bin
+--with-apache2=$HOME/httpd-2.2.16-bin/include --prefix=$HOME/axis2c-1.6.0-bin
 make
 make install
 export AXIS2C_HOME=$HOME/axis2c-1.6.0-bin
@@ -326,7 +326,7 @@ git clone git://github.com/jsdelfino/mod
 cd mod_auth_openid
 ./autogen.sh
 ./configure --prefix=$HOME/mod-auth-openid-bin \
---with-apr=$HOME/httpd-2.2.15-bin --with-httpd=$HOME/httpd-2.2.15-bin \
+--with-apr=$HOME/httpd-2.2.16-bin --with-httpd=$HOME/httpd-2.2.16-bin \
 --with-curl=$HOME/curl-7.19.5-bin --with-libopkele=$HOME/libopkele-bin
 make
 make install

Modified: tuscany/sca-cpp/trunk/components/cache/Makefile.am
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/cache/Makefile.am?rev=985561&r1=985560&r2=985561&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/cache/Makefile.am (original)
+++ tuscany/sca-cpp/trunk/components/cache/Makefile.am Sat Aug 14 18:46:26 2010
@@ -39,6 +39,6 @@ memcache_test_LDFLAGS = -lxml2
 client_test_SOURCES = client-test.cpp
 client_test_LDFLAGS = -lxml2 -lcurl -lmozjs
 
-dist_noinst_SCRIPTS = memcached-test server-test
+dist_noinst_SCRIPTS = memcached-test memcached-ssl-test server-test
 noinst_PROGRAMS = memcache-test client-test
-TESTS = memcached-test server-test
+TESTS = memcached-test memcached-ssl-test server-test

Modified: tuscany/sca-cpp/trunk/components/cache/client-test.cpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/cache/client-test.cpp?rev=985561&r1=985560&r2=985561&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/cache/client-test.cpp (original)
+++ tuscany/sca-cpp/trunk/components/cache/client-test.cpp Sat Aug 14 18:46:26 2010
@@ -31,7 +31,7 @@
 #include "value.hpp"
 #include "monad.hpp"
 #include "perf.hpp"
-#include "../../modules/http/curl.hpp"
+#include "../../modules/http/http.hpp"
 
 namespace tuscany {
 namespace cache {

Modified: tuscany/sca-cpp/trunk/components/cache/memcache-test.cpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/cache/memcache-test.cpp?rev=985561&r1=985560&r2=985561&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/cache/memcache-test.cpp (original)
+++ tuscany/sca-cpp/trunk/components/cache/memcache-test.cpp Sat Aug 14 18:46:26 2010
@@ -37,9 +37,9 @@ bool testMemCached() {
     const value k = mklist<value>("a");
 
     assert(hasContent(post(k, string("AAA"), ch)));
-    assert((get(k, ch)) == value(string("AAA")));
+    assert(get(k, ch) == value(string("AAA")));
     assert(hasContent(put(k, string("aaa"), ch)));
-    assert((get(k, ch)) == value(string("aaa")));
+    assert(get(k, ch) == value(string("aaa")));
     assert(hasContent(del(k, ch)));
     assert(!hasContent(get(k, ch)));
 
@@ -52,7 +52,7 @@ struct getLoop {
     getLoop(const value& k, MemCached& ch) : k(k), ch(ch) {
     }
     const bool operator()() const {
-        assert((get(k, ch)) == value(string("CCC")));
+        assert(get(k, ch) == value(string("CCC")));
         return true;
     }
 };

Modified: tuscany/sca-cpp/trunk/components/cache/memcache.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/cache/memcache.hpp?rev=985561&r1=985560&r2=985561&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/cache/memcache.hpp (original)
+++ tuscany/sca-cpp/trunk/components/cache/memcache.hpp Sat Aug 14 18:46:26 2010
@@ -89,7 +89,7 @@ private:
      */
     const failable<bool> addServer(const string& host, const int port) {
         apr_memcache_server_t *server;
-        const apr_status_t sc = apr_memcache_server_create(pool, c_str(host), (apr_port_t)port, 0, 1, 1, 60, &server);
+        const apr_status_t sc = apr_memcache_server_create(pool, c_str(host), (apr_port_t)port, 1, 1, 1, 600, &server);
         if (sc != APR_SUCCESS)
             return mkfailure<bool>("Could not create server");
         const apr_status_t as = apr_memcache_add_server(mc, server);
@@ -161,21 +161,13 @@ const failable<value> get(const value& k
     debug(key, "memcache::get::key");
 
     const string ks(scheme::writeValue(key));
-    apr_pool_t* vpool;
-    const apr_status_t pc = apr_pool_create(&vpool, cache.pool);
-    if (pc != APR_SUCCESS)
-        return mkfailure<value>("Could not allocate memory");
-
     char *data;
     apr_size_t size;
     const apr_status_t rc = apr_memcache_getp(cache.mc, cache.pool, nospaces(c_str(ks)), &data, &size, NULL);
     if (rc != APR_SUCCESS) {
-        apr_pool_destroy(vpool);
         return mkfailure<value>("Could not get entry");
     }
-
     const value val(scheme::readValue(string(data, size)));
-    apr_pool_destroy(vpool);
 
     debug(val, "memcache::get::result");
     return val;

Added: tuscany/sca-cpp/trunk/components/cache/memcached-ssl-test
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/cache/memcached-ssl-test?rev=985561&view=auto
==============================================================================
--- tuscany/sca-cpp/trunk/components/cache/memcached-ssl-test (added)
+++ tuscany/sca-cpp/trunk/components/cache/memcached-ssl-test Sat Aug 14 18:46:26 2010
@@ -0,0 +1,52 @@
+#!/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.
+
+# Setup
+../../modules/http/ssl-ca-conf tmp/ssl localhost
+../../modules/http/ssl-cert-conf tmp/ssl localhost server
+../../modules/http/ssl-cert-conf tmp/ssl localhost tunnel
+
+./memcached-start 11411
+./memcached-start 11412
+./memcached-start 11413
+
+../../modules/http/httpd-conf tmp/tunnel localhost 8089 htdocs
+tar -C tmp/ssl -c `../../modules/http/ssl-cert-find tmp/ssl` | tar -C tmp/tunnel -x
+../../modules/http/tunnel-ssl-conf tmp/tunnel 11211 localhost 8453 11411
+../../modules/http/tunnel-ssl-conf tmp/tunnel 11212 localhost 8453 11412
+../../modules/http/tunnel-ssl-conf tmp/tunnel 11213 localhost 8453 11413
+../../modules/http/httpd-start tmp/tunnel
+
+../../modules/http/httpd-conf tmp/server localhost 8090 htdocs
+tar -C tmp/ssl -c `../../modules/http/ssl-cert-find tmp/ssl` | tar -C tmp/server -x
+../../modules/http/httpd-ssl-conf tmp/server 8453
+../../modules/http/httpd-start tmp/server
+sleep 1
+
+# Test
+./memcache-test 2>/dev/null
+rc=$?
+
+# Cleanup
+../../modules/http/httpd-stop tmp/tunnel
+../../modules/http/httpd-stop tmp/server
+./memcached-stop 11411
+./memcached-stop 11412
+./memcached-stop 11413
+return $rc

Propchange: tuscany/sca-cpp/trunk/components/cache/memcached-ssl-test
------------------------------------------------------------------------------
    svn:executable = *

Modified: tuscany/sca-cpp/trunk/components/cache/memcached-start
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/cache/memcached-start?rev=985561&r1=985560&r2=985561&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/cache/memcached-start (original)
+++ tuscany/sca-cpp/trunk/components/cache/memcached-start Sat Aug 14 18:46:26 2010
@@ -19,11 +19,20 @@
 
 # Start memcached
 here=`readlink -f $0`; here=`dirname $here`
-port=$1
-if [ "$port" = "" ]; then
+
+addr=$1
+if [ "$addr" = "" ]; then
+    ip=""
     port="11211"
+else
+    ip=`$here/../../modules/http/httpd-addr ip $addr`
+    port=`$here/../../modules/http/httpd-addr port $addr`
 fi
 
 memcached_prefix=`cat $here/memcached.prefix`
-$memcached_prefix/bin/memcached -d -l 127.0.0.1 -m 4 -p $port
+if [ "$ip" = "" ]; then
+    $memcached_prefix/bin/memcached -d -m 4 -p $port
+else
+    $memcached_prefix/bin/memcached -d -l $ip -m 4 -p $port
+fi
 

Modified: tuscany/sca-cpp/trunk/components/cache/memcached-stop
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/cache/memcached-stop?rev=985561&r1=985560&r2=985561&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/cache/memcached-stop (original)
+++ tuscany/sca-cpp/trunk/components/cache/memcached-stop Sat Aug 14 18:46:26 2010
@@ -19,12 +19,21 @@
 
 # Stop memcached
 here=`readlink -f $0`; here=`dirname $here`
-port=$1
-if [ "$port" = "" ]; then
+
+addr=$1
+if [ "$addr" = "" ]; then
+    ip=""
     port="11211"
+else
+    ip=`$here/../../modules/http/httpd-addr ip $addr`
+    port=`$here/../../modules/http/httpd-addr port $addr`
 fi
 
 memcached_prefix=`cat $here/memcached.prefix`
-mc="$memcached_prefix/bin/memcached -d -l 127.0.0.1 -m 4 -p $port"
+if [ "$ip" = "" ]; then
+    mc="$memcached_prefix/bin/memcached -d -m 4 -p $port"
+else
+    mc="$memcached_prefix/bin/memcached -d -l $ip -m 4 -p $port"
+fi
 
 kill `ps -ef | grep -v grep | grep "${mc}" | awk '{ print $2 }'`

Modified: tuscany/sca-cpp/trunk/components/chat/client-test.cpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/chat/client-test.cpp?rev=985561&r1=985560&r2=985561&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/chat/client-test.cpp (original)
+++ tuscany/sca-cpp/trunk/components/chat/client-test.cpp Sat Aug 14 18:46:26 2010
@@ -32,7 +32,7 @@
 #include "monad.hpp"
 #include "perf.hpp"
 #include "parallel.hpp"
-#include "../../modules/http/curl.hpp"
+#include "../../modules/http/http.hpp"
 #include "xmpp.hpp"
 
 namespace tuscany {

Modified: tuscany/sca-cpp/trunk/components/log/client-test.cpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/log/client-test.cpp?rev=985561&r1=985560&r2=985561&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/log/client-test.cpp (original)
+++ tuscany/sca-cpp/trunk/components/log/client-test.cpp Sat Aug 14 18:46:26 2010
@@ -31,7 +31,7 @@
 #include "value.hpp"
 #include "monad.hpp"
 #include "perf.hpp"
-#include "../../modules/http/curl.hpp"
+#include "../../modules/http/http.hpp"
 
 namespace tuscany {
 namespace log {

Modified: tuscany/sca-cpp/trunk/components/nosqldb/client-test.cpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/nosqldb/client-test.cpp?rev=985561&r1=985560&r2=985561&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/nosqldb/client-test.cpp (original)
+++ tuscany/sca-cpp/trunk/components/nosqldb/client-test.cpp Sat Aug 14 18:46:26 2010
@@ -31,7 +31,7 @@
 #include "value.hpp"
 #include "monad.hpp"
 #include "perf.hpp"
-#include "../../modules/http/curl.hpp"
+#include "../../modules/http/http.hpp"
 
 namespace tuscany {
 namespace nosqldb {

Modified: tuscany/sca-cpp/trunk/components/queue/client-test.cpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/queue/client-test.cpp?rev=985561&r1=985560&r2=985561&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/queue/client-test.cpp (original)
+++ tuscany/sca-cpp/trunk/components/queue/client-test.cpp Sat Aug 14 18:46:26 2010
@@ -31,7 +31,7 @@
 #include "value.hpp"
 #include "monad.hpp"
 #include "perf.hpp"
-#include "../../modules/http/curl.hpp"
+#include "../../modules/http/http.hpp"
 #include "qpid.hpp"
 
 // Ignore conversion issues and redundant declarations in Qpid headers

Modified: tuscany/sca-cpp/trunk/components/sqldb/client-test.cpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/sqldb/client-test.cpp?rev=985561&r1=985560&r2=985561&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/sqldb/client-test.cpp (original)
+++ tuscany/sca-cpp/trunk/components/sqldb/client-test.cpp Sat Aug 14 18:46:26 2010
@@ -31,7 +31,7 @@
 #include "value.hpp"
 #include "monad.hpp"
 #include "perf.hpp"
-#include "../../modules/http/curl.hpp"
+#include "../../modules/http/http.hpp"
 
 namespace tuscany {
 namespace sqldb {

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=985561&r1=985560&r2=985561&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/webservice/client-test.cpp (original)
+++ tuscany/sca-cpp/trunk/components/webservice/client-test.cpp Sat Aug 14 18:46:26 2010
@@ -31,7 +31,7 @@
 #include "value.hpp"
 #include "monad.hpp"
 #include "perf.hpp"
-#include "../../modules/http/curl.hpp"
+#include "../../modules/http/http.hpp"
 #include "axis2.hpp"
 
 namespace tuscany {

Modified: tuscany/sca-cpp/trunk/etc/git-exclude
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/etc/git-exclude?rev=985561&r1=985560&r2=985561&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/etc/git-exclude (original)
+++ tuscany/sca-cpp/trunk/etc/git-exclude Sat Aug 14 18:46:26 2010
@@ -100,5 +100,6 @@ xmpp-test
 pgsql-test
 tinycdb-test
 curl-get
+curl-connect
 rss-test
 

Modified: tuscany/sca-cpp/trunk/kernel/gc.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/kernel/gc.hpp?rev=985561&r1=985560&r2=985561&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/kernel/gc.hpp (original)
+++ tuscany/sca-cpp/trunk/kernel/gc.hpp Sat Aug 14 18:46:26 2010
@@ -112,7 +112,17 @@ private:
 };
 
 /**
- * Return APR pool used by a gc_pool.
+ * Make a new APR pool.
+ */
+apr_pool_t* mkpool() {
+    apr_pool_t* p = NULL;
+    apr_pool_create(&p, NULL);
+    assert(p != NULL);
+    return p;
+}
+
+/**
+ * Return the APR pool used by a gc_pool.
  */
 apr_pool_t* pool(const gc_pool& pool) {
     return pool.apr_pool;

Modified: tuscany/sca-cpp/trunk/modules/http/Makefile.am
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/http/Makefile.am?rev=985561&r1=985560&r2=985561&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/http/Makefile.am (original)
+++ tuscany/sca-cpp/trunk/modules/http/Makefile.am Sat Aug 14 18:46:26 2010
@@ -20,7 +20,7 @@ INCLUDES = -I${HTTPD_INCLUDE}
 incl_HEADERS = *.hpp
 incldir = $(prefix)/include/modules/http
 
-dist_mod_SCRIPTS = httpd-conf httpd-start httpd-stop httpd-restart ssl-ca-conf ssl-cert-conf httpd-ssl-conf httpd-auth-conf proxy-conf proxy-ssl-conf proxy-member-conf proxy-ssl-member-conf vhost-conf vhost-ssl-conf
+dist_mod_SCRIPTS = httpd-conf httpd-start httpd-stop httpd-restart ssl-ca-conf ssl-cert-conf ssl-cert-find httpd-ssl-conf httpd-auth-conf proxy-conf proxy-ssl-conf proxy-member-conf proxy-ssl-member-conf vhost-conf vhost-ssl-conf tunnel-ssl-conf
 moddir=$(prefix)/modules/http
 
 curl_test_SOURCES = curl-test.cpp
@@ -29,6 +29,17 @@ curl_test_LDFLAGS = -lxml2 -lcurl -lmozj
 curl_get_SOURCES = curl-get.cpp
 curl_get_LDFLAGS = -lxml2 -lcurl -lmozjs
 
+curl_connect_SOURCES = curl-connect.cpp
+curl_connect_LDFLAGS = -lxml2 -lcurl -lmozjs
+
+mod_LTLIBRARIES = libmod_tuscany_ssltunnel.la
+noinst_DATA = libmod_tuscany_ssltunnel.so
+
+libmod_tuscany_ssltunnel_la_SOURCES = mod-ssltunnel.cpp
+libmod_tuscany_ssltunnel_la_LDFLAGS = -lxml2 -lcurl -lmozjs
+libmod_tuscany_ssltunnel.so:
+	ln -s .libs/libmod_tuscany_ssltunnel.so
+
 mod_DATA = httpd.prefix httpd-apachectl.prefix httpd-modules.prefix curl.prefix
 nobase_dist_mod_DATA = conf/*
 
@@ -44,6 +55,6 @@ curl.prefix: $(top_builddir)/config.stat
 	echo ${CURL_PREFIX} >curl.prefix
 
 dist_noinst_SCRIPTS = httpd-test http-test proxy-test
-noinst_PROGRAMS = curl-test curl-get
+noinst_PROGRAMS = curl-test curl-get curl-connect
 TESTS = httpd-test http-test proxy-test
 

Added: tuscany/sca-cpp/trunk/modules/http/curl-connect.cpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/http/curl-connect.cpp?rev=985561&view=auto
==============================================================================
--- tuscany/sca-cpp/trunk/modules/http/curl-connect.cpp (added)
+++ tuscany/sca-cpp/trunk/modules/http/curl-connect.cpp Sat Aug 14 18:46:26 2010
@@ -0,0 +1,98 @@
+/*
+ * 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$ */
+
+/**
+ * HTTP connect command line test tool.
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include "stream.hpp"
+#include "string.hpp"
+#include "perf.hpp"
+#include "http.hpp"
+
+namespace tuscany {
+namespace http {
+
+const bool testConnect(const string& url, const string& ca = "", const string& cert = "", const string& key = "") {
+    gc_scoped_pool p;
+
+    CURLSession cs(ca, cert, key);
+    const failable<bool> crc = connect(url, cs);
+    assert(hasContent(crc));
+
+    apr_pollset_t* pollset;
+    apr_status_t cprc = apr_pollset_create(&pollset, 2, pool(p), 0);
+    assert(cprc == APR_SUCCESS);
+    apr_socket_t* csock = sock(0, p);
+    const apr_pollfd_t* cpollfd = pollfd(csock, APR_POLLIN | APR_POLLERR | APR_POLLNVAL | APR_POLLHUP, p);
+    apr_pollset_add(pollset, cpollfd);
+    apr_socket_t* tsock = sock(cs);
+    const apr_pollfd_t* tpollfd = pollfd(tsock, APR_POLLIN | APR_POLLERR | APR_POLLNVAL | APR_POLLHUP, p);
+    apr_pollset_add(pollset, tpollfd);
+
+    const apr_pollfd_t* pollfds;
+    apr_int32_t pollcount;
+    for(;;) {
+        apr_status_t pollrc = apr_pollset_poll(pollset, -1, &pollcount, &pollfds);
+        assert(pollrc == APR_SUCCESS);
+
+        for (; pollcount > 0; pollcount--, pollfds++) {
+            if (pollfds->rtnevents & APR_POLLIN) {
+                char data[8192];
+                if (pollfds->desc.s == csock) {
+                    const int rl = ::read(0, data, sizeof(data));
+                    if (rl == -1)
+                        return false;
+                    if (rl > 0) {
+                        const failable<bool> src = http::send(data, rl, cs);
+                        assert(hasContent(src));
+                    }
+                }
+                else {
+                    const failable<int> frl = http::recv(data, sizeof(data), cs);
+                    assert(hasContent(frl));
+                    const int rl = content(frl);
+                    if (rl == 0)
+                        return true;
+                    const int wl = ::write(0, data, rl);
+                    assert(wl == rl);
+                }
+                continue;
+            }
+            assert(!(pollfds->rtnevents & (APR_POLLERR | APR_POLLHUP | APR_POLLNVAL)));
+        }
+    }
+    return true;
+}
+
+}
+}
+
+int main(unused const int argc, const char** argv) {
+    if (argc > 2)
+        tuscany::http::testConnect(tuscany::string(argv[1]), tuscany::string(argv[2]), tuscany::string(argv[3]), tuscany::string(argv[4]));
+    else
+        tuscany::http::testConnect(tuscany::string(argv[1]));
+    return 0;
+}
+

Modified: tuscany/sca-cpp/trunk/modules/http/curl-get.cpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/http/curl-get.cpp?rev=985561&r1=985560&r2=985561&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/http/curl-get.cpp (original)
+++ tuscany/sca-cpp/trunk/modules/http/curl-get.cpp Sat Aug 14 18:46:26 2010
@@ -20,20 +20,20 @@
 /* $Rev$ $Date$ */
 
 /**
- * HTTP client command line test tool.
+ * HTTP GET command line test tool.
  */
 
 #include <assert.h>
 #include "stream.hpp"
 #include "string.hpp"
 #include "perf.hpp"
-#include "curl.hpp"
+#include "http.hpp"
 
 namespace tuscany {
 namespace http {
 
-const bool testGet(const string& url) {
-    CURLSession ch;
+const bool testGet(const string& url, const string& ca = "", const string& cert = "", const string& key = "") {
+    CURLSession ch(ca, cert, key);
     const failable<value> val = get(url, ch);
     assert(hasContent(val));
     cout << val << endl;
@@ -44,7 +44,10 @@ const bool testGet(const string& url) {
 }
 
 int main(unused const int argc, const char** argv) {
-    tuscany::http::testGet(tuscany::string(argv[1]));
+    if (argc > 2)
+        tuscany::http::testGet(tuscany::string(argv[1]), tuscany::string(argv[2]), tuscany::string(argv[3]), tuscany::string(argv[4]));
+    else
+        tuscany::http::testGet(tuscany::string(argv[1]));
     return 0;
 }
 

Modified: tuscany/sca-cpp/trunk/modules/http/curl-test.cpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/http/curl-test.cpp?rev=985561&r1=985560&r2=985561&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/http/curl-test.cpp (original)
+++ tuscany/sca-cpp/trunk/modules/http/curl-test.cpp Sat Aug 14 18:46:26 2010
@@ -27,7 +27,7 @@
 #include "stream.hpp"
 #include "string.hpp"
 #include "perf.hpp"
-#include "curl.hpp"
+#include "http.hpp"
 
 namespace tuscany {
 namespace http {

Copied: tuscany/sca-cpp/trunk/modules/http/http.hpp (from r981352, tuscany/sca-cpp/trunk/modules/http/curl.hpp)
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/http/http.hpp?p2=tuscany/sca-cpp/trunk/modules/http/http.hpp&p1=tuscany/sca-cpp/trunk/modules/http/curl.hpp&r1=981352&r2=985561&rev=985561&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/http/curl.hpp (original)
+++ tuscany/sca-cpp/trunk/modules/http/http.hpp Sat Aug 14 18:46:26 2010
@@ -19,8 +19,8 @@
 
 /* $Rev$ $Date$ */
 
-#ifndef tuscany_curl_hpp
-#define tuscany_curl_hpp
+#ifndef tuscany_http_hpp
+#define tuscany_http_hpp
 
 /**
  * CURL HTTP client functions.
@@ -30,6 +30,10 @@
 #include <curl/curl.h>
 #include <curl/types.h>
 #include <curl/easy.h>
+#include <apr_network_io.h>
+#include <apr_portable.h>
+#include <apr_poll.h>
+
 #include "string.hpp"
 #include "gc.hpp"
 #include "list.hpp"
@@ -59,10 +63,10 @@ public:
  */
 class CURLSession {
 public:
-    CURLSession(const string& ca = "", const string& cert = "", const string& key = "") : h(curl_easy_init()), owner(true), ca(ca), cert(cert), key(key) {
+    CURLSession(const string& ca = "", const string& cert = "", const string& key = "") : h(curl_easy_init()), p(gc_pool(mkpool())), sock(NULL), wpollset(NULL), wpollfd(NULL), rpollset(NULL), rpollfd(NULL), owner(true), ca(ca), cert(cert), key(key) {
     }
 
-    CURLSession(const CURLSession& c) : h(c.h), owner(false), ca(c.ca), cert(c.cert), key(c.key) {
+    CURLSession(const CURLSession& c) : h(c.h), p(c.p), sock(c.sock), wpollset(c.wpollset), wpollfd(c.wpollfd), rpollset(c.rpollset), rpollfd(c.rpollfd), owner(false), ca(c.ca), cert(c.cert), key(c.key) {
     }
 
     ~CURLSession() {
@@ -71,13 +75,24 @@ public:
         if (h == NULL)
             return;
         curl_easy_cleanup(h);
+        destroy(p);
     }
 
 private:
     CURL* h;
+    gc_pool p;
+    apr_socket_t* sock;
+    apr_pollset_t* wpollset;
+    apr_pollfd_t* wpollfd;
+    apr_pollset_t* rpollset;
+    apr_pollfd_t* rpollfd;
     const bool owner;
 
-    friend CURL* handle(const CURLSession& c);
+    friend CURL* handle(const CURLSession& cs);
+    friend apr_socket_t* sock(const CURLSession& cs);
+    friend const failable<bool> connect(const string& url, CURLSession& cs);
+    friend const failable<bool> send(const char* c, const int l, const CURLSession& cs);
+    friend const failable<int> recv(char* c, const int l, const CURLSession& cs);
 
 public:
     const string ca;
@@ -88,8 +103,80 @@ public:
 /**
  * Returns the CURL handle used by a CURL session.
  */
-CURL* handle(const CURLSession& c) {
-    return c.h;
+CURL* handle(const CURLSession& cs) {
+    return cs.h;
+}
+
+/**
+ * Return an apr_socket_t for the socket used by a CURL session.
+ */
+apr_socket_t* sock(const CURLSession& cs) {
+    return cs.sock;
+}
+
+/**
+ * Convert a socket fd to an apr_socket_t.
+ */
+apr_socket_t* sock(const int sd, const gc_pool& p) {
+    int fd = sd;
+    apr_socket_t* s = NULL;
+    apr_os_sock_put(&s, &fd, pool(p));
+    return s;
+}
+
+/**
+ * Convert a CURL return code to an error string.
+ */
+const string curlreason(CURLcode rc) {
+    return curl_easy_strerror(rc);
+}
+
+/**
+ * Convert an APR status to an error string.
+ */
+const string apreason(apr_status_t rc) {
+    char buf[256];
+    return apr_strerror(rc, buf, sizeof(buf));
+}
+
+/**
+ * Setup a CURL session
+ */
+const failable<CURL*> setup(const string& url, const CURLSession& cs) {
+
+    // Init CURL session
+    CURL* ch = handle(cs);
+    curl_easy_reset(ch);
+    curl_easy_setopt(ch, CURLOPT_USERAGENT, "libcurl/1.0");
+
+    // Setup protocol options
+    curl_easy_setopt(ch, CURLOPT_TCP_NODELAY, true);
+    curl_easy_setopt(ch, CURLOPT_FOLLOWLOCATION, true);
+    curl_easy_setopt(ch, CURLOPT_POSTREDIR, CURL_REDIR_POST_ALL);
+
+    // Setup SSL options
+    if (cs.ca != "") {
+        debug(cs.ca, "http::apply::ca");
+        curl_easy_setopt(ch, CURLOPT_CAINFO, c_str(cs.ca));
+        curl_easy_setopt(ch, CURLOPT_SSL_VERIFYPEER, true);
+        curl_easy_setopt(ch, CURLOPT_SSL_VERIFYHOST, 2);
+    } else
+        curl_easy_setopt(ch, CURLOPT_SSL_VERIFYPEER, false);
+    if (cs.cert != "") {
+        debug(cs.cert, "http::apply::cert");
+        curl_easy_setopt(ch, CURLOPT_SSLCERT, c_str(cs.cert));
+        curl_easy_setopt(ch, CURLOPT_SSLCERTTYPE, "PEM");
+    }
+    if (cs.key != "") {
+        debug(cs.key, "http::apply::key");
+        curl_easy_setopt(ch, CURLOPT_SSLKEY, c_str(cs.key));
+        curl_easy_setopt(ch, CURLOPT_SSLKEYTYPE, "PEM");
+    }
+
+    // Set target URL
+    curl_easy_setopt(ch, CURLOPT_URL, c_str(url));
+
+    return ch;
 }
 
 /**
@@ -149,18 +236,25 @@ curl_slist* headers(curl_slist* cl, cons
 
 template<typename R> const failable<list<R> > apply(const list<list<string> >& hdr, const lambda<R(const string&, const R)>& reduce, const R& initial, const string& url, const string& verb, const CURLSession& cs) {
 
-    // Init the curl session
-    CURL* ch = handle(cs);
-    curl_easy_reset(ch);
-    curl_easy_setopt(ch, CURLOPT_USERAGENT, "libcurl/1.0");
+    // Setup the CURL session
+    const failable<CURL*> fch = setup(url, cs);
+    if (!hasContent(fch))
+        return mkfailure<list<R>>(reason(fch));
+    CURL* ch = content(fch);
 
-    //TODO use HTTP chunking, for now just convert request to a single string
+    // Set the request headers
+    curl_slist* hl = headers(NULL, car(hdr));
+    if (hl != NULL)
+        curl_easy_setopt(ch, CURLOPT_HTTPHEADER, hl);
+
+    // Convert request body to a string
+    // TODO use HTTP chunking instead
     ostringstream os;
     write(cadr(hdr), os);
     const string s = str(os);
     const int sz = length(s);
 
-    // Setup the read, header and write callbacks
+    // Setup the read, write header and write data callbacks
     CURLReadContext rcx(mklist(s));
     curl_easy_setopt(ch, CURLOPT_READFUNCTION, (size_t (*)(void*, size_t, size_t, void*))readCallback);
     curl_easy_setopt(ch, CURLOPT_READDATA, &rcx);
@@ -171,36 +265,7 @@ template<typename R> const failable<list
     curl_easy_setopt(ch, CURLOPT_WRITEFUNCTION, (size_t (*)(void*, size_t, size_t, void*))(writeCallback<R>));
     curl_easy_setopt(ch, CURLOPT_WRITEDATA, &wcx);
 
-    // Setup protocol options
-    curl_easy_setopt(ch, CURLOPT_TCP_NODELAY, true);
-    curl_easy_setopt(ch, CURLOPT_FOLLOWLOCATION, true);
-    curl_easy_setopt(ch, CURLOPT_POSTREDIR, CURL_REDIR_POST_ALL);
-
-    // Setup SSL options
-    if (cs.ca != "") {
-        debug(cs.ca, "http::apply::ca");
-        curl_easy_setopt(ch, CURLOPT_CAINFO, c_str(cs.ca));
-        curl_easy_setopt(ch, CURLOPT_SSL_VERIFYPEER, true);
-        curl_easy_setopt(ch, CURLOPT_SSL_VERIFYHOST, 2);
-    }
-    if (cs.cert != "") {
-        debug(cs.cert, "http::apply::cert");
-        curl_easy_setopt(ch, CURLOPT_SSLCERT, c_str(cs.cert));
-        curl_easy_setopt(ch, CURLOPT_SSLCERTTYPE, "PEM");
-    }
-    if (cs.key != "") {
-        debug(cs.key, "http::apply::key");
-        curl_easy_setopt(ch, CURLOPT_SSLKEY, c_str(cs.key));
-        curl_easy_setopt(ch, CURLOPT_SSLKEYTYPE, "PEM");
-    }
-
-    // Set the request headers
-    curl_slist* hl = headers(NULL, car(hdr));
-    if (hl != NULL)
-        curl_easy_setopt(ch, CURLOPT_HTTPHEADER, hl);
-
     // Apply the HTTP verb
-    curl_easy_setopt(ch, CURLOPT_URL, c_str(url));
     if (verb == "POST") {
         curl_easy_setopt(ch, CURLOPT_POST, true);
         curl_easy_setopt(ch, CURLOPT_POSTFIELDSIZE, sz);
@@ -211,6 +276,7 @@ template<typename R> const failable<list
         curl_easy_setopt(ch, CURLOPT_CUSTOMREQUEST, "DELETE");
     const CURLcode rc = curl_easy_perform(ch);
 
+    // Free the headers
     if (hl != NULL)
         curl_slist_free_all(hl);
 
@@ -230,7 +296,7 @@ template<typename R> const failable<list
 /**
  * Evaluate an expression remotely, at the given URL.
  */
-const failable<value> evalExpr(const value& expr, const string& url, const CURLSession& ch) {
+const failable<value> evalExpr(const value& expr, const string& url, const CURLSession& cs) {
     debug(url, "http::evalExpr::url");
     debug(expr, "http::evalExpr::input");
 
@@ -242,7 +308,7 @@ const failable<value> evalExpr(const val
 
     // POST it to the URL
     const list<string> h = mklist<string>("Content-Type: application/json-rpc");
-    const failable<list<list<string> > > res = apply<list<string> >(mklist<list<string> >(h, content(jsreq)), rcons<string>, list<string>(), url, "POST", ch);
+    const failable<list<list<string> > > res = apply<list<string> >(mklist<list<string> >(h, content(jsreq)), rcons<string>, list<string>(), url, "POST", cs);
     if (!hasContent(res))
         return mkfailure<value>(reason(res));
 
@@ -294,20 +360,20 @@ const failable<string> contentType(const
 /**
  * HTTP GET, return the resource at the given URL.
  */
-template<typename R> const failable<list<R> > get(const lambda<R(const string&, const R)>& reduce, const R& initial, const string& url, const CURLSession& ch) {
+template<typename R> const failable<list<R> > get(const lambda<R(const string&, const R)>& reduce, const R& initial, const string& url, const CURLSession& cs) {
     debug(url, "http::get::url");
     const list<list<string> > req = mklist(list<string>(), list<string>());
-    return apply(req, reduce, initial, url, "GET", ch);
+    return apply(req, reduce, initial, url, "GET", cs);
 }
 
 /**
  * HTTP GET, return a list of values representing the resource at the given URL.
  */
-const failable<value> getcontent(const string& url, const CURLSession& ch) {
+const failable<value> getcontent(const string& url, const CURLSession& cs) {
     debug(url, "http::get::url");
 
     // Get the contents of the resource at the given URL
-    const failable<list<list<string> > > res = get<list<string>>(rcons<string>, list<string>(), url, ch);
+    const failable<list<list<string> > > res = get<list<string>>(rcons<string>, list<string>(), url, cs);
     if (!hasContent(res))
         return mkfailure<value>(reason(res));
     const list<string> ls(reverse(cadr(content(res))));
@@ -321,11 +387,11 @@ const failable<value> getcontent(const s
 /**
  * HTTP GET, return a list of values representing the resource at the given URL.
  */
-const failable<value> get(const string& url, const CURLSession& ch) {
+const failable<value> get(const string& url, const CURLSession& cs) {
     debug(url, "http::get::url");
 
     // Get the contents of the resource at the given URL
-    const failable<list<list<string> > > res = get<list<string> >(rcons<string>, list<string>(), url, ch);
+    const failable<list<list<string> > > res = get<list<string> >(rcons<string>, list<string>(), url, cs);
     if (!hasContent(res))
         return mkfailure<value>(reason(res));
     const list<string> ls(reverse(cadr(content(res))));
@@ -359,7 +425,7 @@ const failable<value> get(const string& 
 /**
  * HTTP POST.
  */
-const failable<value> post(const value& val, const string& url, const CURLSession& ch) {
+const failable<value> post(const value& val, const string& url, const CURLSession& cs) {
 
     // Convert value to an ATOM entry
     const failable<list<string> > entry = atom::writeATOMEntry(atom::entryValuesToElements(val));
@@ -371,7 +437,7 @@ const failable<value> post(const value& 
     // POST it to the URL
     const list<string> h = mklist<string>("Content-Type: application/atom+xml");
     const list<list<string> > req = mklist<list<string> >(h, content(entry));
-    const failable<list<list<string> > > res = apply<list<string>>(req, rcons<string>, list<string>(), url, "POST", ch);
+    const failable<list<list<string> > > res = apply<list<string>>(req, rcons<string>, list<string>(), url, "POST", cs);
     if (!hasContent(res))
         return mkfailure<value>(reason(res));
 
@@ -384,7 +450,7 @@ const failable<value> post(const value& 
 /**
  * HTTP PUT.
  */
-const failable<value> put(const value& val, const string& url, const CURLSession& ch) {
+const failable<value> put(const value& val, const string& url, const CURLSession& cs) {
 
     // Convert value to an ATOM entry
     const failable<list<string> > entry = atom::writeATOMEntry(atom::entryValuesToElements(val));
@@ -396,7 +462,7 @@ const failable<value> put(const value& v
     // PUT it to the URL
     const list<string> h = mklist<string>("Content-Type: application/atom+xml");
     const list<list<string> > req = mklist<list<string> >(h, content(entry));
-    const failable<list<list<string> > > res = apply<list<string> >(req, rcons<string>, list<string>(), url, "PUT", ch);
+    const failable<list<list<string> > > res = apply<list<string> >(req, rcons<string>, list<string>(), url, "PUT", cs);
     if (!hasContent(res))
         return mkfailure<value>(reason(res));
 
@@ -407,11 +473,11 @@ const failable<value> put(const value& v
 /**
  * HTTP DELETE.
  */
-const failable<value, string> del(const string& url, const CURLSession& ch) {
+const failable<value, string> del(const string& url, const CURLSession& cs) {
     debug(url, "http::delete::url");
 
     const list<list<string> > req = mklist(list<string>(), list<string>());
-    const failable<list<list<string> > > res = apply<list<string> >(req, rcons<string>, list<string>(), url, "DELETE", ch);
+    const failable<list<list<string> > > res = apply<list<string> >(req, rcons<string>, list<string>(), url, "DELETE", cs);
     if (!hasContent(res))
         return mkfailure<value>(reason(res));
 
@@ -430,6 +496,109 @@ const string hostname() {
 }
 
 /**
+ * Create an APR pollfd for a socket.
+ */
+apr_pollfd_t* pollfd(apr_socket_t* s, const int e, const gc_pool& p) {
+    apr_pollfd_t* pfd = gc_new<apr_pollfd_t>(p);
+    pfd->p = pool(p);
+    pfd->desc_type = APR_POLL_SOCKET;
+    pfd->reqevents = (apr_int16_t)e;
+    pfd->rtnevents = (apr_int16_t)e;
+    pfd->desc.s = s;
+    pfd->client_data = NULL;
+    return pfd;
+}
+
+/**
+ * Connect to a URL.
+ */
+const failable<bool> connect(const string& url, CURLSession& cs) {
+
+    // Setup the CURL session
+    const failable<CURL*> fch = setup(url, cs);
+    if (!hasContent(fch))
+        return mkfailure<bool>(reason(fch));
+    CURL* ch = content(fch);
+
+    // Connect
+    curl_easy_setopt(ch, CURLOPT_CONNECT_ONLY, true);
+    const CURLcode rc = curl_easy_perform(ch);
+    if (rc)
+        return mkfailure<bool>(string(curl_easy_strerror(rc)));
+
+    // Convert the connected socket to an apr_socket_t
+    int sd;
+    const CURLcode grc = curl_easy_getinfo(ch, CURLINFO_LASTSOCKET, &sd);
+    if (grc)
+        return mkfailure<bool>(string(curl_easy_strerror(grc)));
+    cs.sock = sock(sd, cs.p);
+
+    // Create pollsets and pollfds which can be used to poll the socket
+    apr_status_t rpcrc = apr_pollset_create(&cs.rpollset, 1, pool(cs.p), 0);
+    if (rpcrc != APR_SUCCESS)
+        return mkfailure<bool>(apreason(rpcrc));
+    cs.rpollfd = pollfd(cs.sock, APR_POLLIN, cs.p);
+    apr_pollset_add(cs.rpollset, cs.rpollfd);
+    apr_status_t wpcrc = apr_pollset_create(&cs.wpollset, 1, pool(cs.p), 0);
+    if (wpcrc != APR_SUCCESS)
+        return mkfailure<bool>(apreason(wpcrc));
+    cs.wpollfd = pollfd(cs.sock, APR_POLLOUT, cs.p);
+    apr_pollset_add(cs.wpollset, cs.wpollfd);
+
+    return true;
+}
+
+/**
+ * Send an array of chars.
+ */
+const failable<bool> send(const char* c, const int l, const CURLSession& cs) {
+
+    // Send the data
+    size_t wl = 0;
+    const CURLcode rc = curl_easy_send(cs.h, c, (size_t)l, &wl);
+    if (rc == CURLE_OK && wl == (size_t)l)
+        return true;
+    if (rc != CURLE_AGAIN)
+        return mkfailure<bool>(curlreason(rc));
+
+    // If the socket was not ready, wait for it to become ready
+    const apr_pollfd_t* pollfds;
+    apr_int32_t pollcount;
+    apr_status_t pollrc = apr_pollset_poll(cs.wpollset, -1, &pollcount, &pollfds);
+    if (pollrc != APR_SUCCESS)
+        return mkfailure<bool>(apreason(pollrc));
+
+    // Send what's left
+    return send(c + wl, (int)((size_t)l - wl), cs);
+}
+
+/**
+ * Receive an array of chars.
+ */
+const failable<int> recv(char* c, const int l, const CURLSession& cs) {
+
+    // Receive data
+    size_t rl;
+    const CURLcode rc = curl_easy_recv(cs.h, c, (size_t)l, &rl);
+    if (rc == CURLE_OK)
+        return (int)rl;
+    if (rc == 1)
+        return 0;
+    if (rc != CURLE_AGAIN)
+        return mkfailure<int>(curlreason(rc));
+
+    // If the socket was not ready, wait for it to become ready
+    const apr_pollfd_t* pollfds;
+    apr_int32_t pollcount;
+    apr_status_t pollrc = apr_pollset_poll(cs.rpollset, -1, &pollcount, &pollfds);
+    if (pollrc != APR_SUCCESS)
+        return mkfailure<int>(apreason(pollrc));
+
+    // Receive again
+    return recv(c, l, cs);
+}
+
+/**
  * HTTP client proxy function.
  */
 struct proxy {
@@ -453,4 +622,4 @@ struct proxy {
 }
 }
 
-#endif /* tuscany_curl_hpp */
+#endif /* tuscany_http_hpp */

Copied: tuscany/sca-cpp/trunk/modules/http/httpd-addr (from r981352, tuscany/sca-cpp/trunk/components/cache/memcached-start)
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/http/httpd-addr?p2=tuscany/sca-cpp/trunk/modules/http/httpd-addr&p1=tuscany/sca-cpp/trunk/components/cache/memcached-start&r1=981352&r2=985561&rev=985561&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/cache/memcached-start (original)
+++ tuscany/sca-cpp/trunk/modules/http/httpd-addr Sat Aug 14 18:46:26 2010
@@ -17,13 +17,38 @@
 #  specific language governing permissions and limitations
 #  under the License.
 
-# Start memcached
-here=`readlink -f $0`; here=`dirname $here`
-port=$1
+# Parse a string in the form ip-addr:local-port/public-port
+addr=`echo $2 | awk -F "/" '{ print $1 }'`
+ip=`echo $addr | awk -F ":" '{ print $1 }'`
+port=`echo $addr | awk -F ":" '{ print $2 }'`
 if [ "$port" = "" ]; then
-    port="11211"
+    port=$ip
+    ip=""
+    listen=$port
+    vhost="*:$port"
+else
+    listen="$ip:$port"
+    vhost="$ip:$port"
+fi
+pport=`echo $2 | awk -F "/" '{ print $2 }'`
+if [ "$pport" = "" ]; then
+    pport=$port
 fi
 
-memcached_prefix=`cat $here/memcached.prefix`
-$memcached_prefix/bin/memcached -d -l 127.0.0.1 -m 4 -p $port
-
+# Return the requested part
+if [ "$1" = "ip" ]; then
+    echo $ip
+fi
+if [ "$1" = "port" ]; then
+    echo $port
+fi
+if [ "$1" = "pport" ]; then
+    echo $pport
+fi
+if [ "$1" = "listen" ]; then
+    echo $listen
+fi
+if [ "$1" = "vhost" ]; then
+    echo $vhost
+fi
+return 0

Modified: tuscany/sca-cpp/trunk/modules/http/httpd-auth-conf
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/http/httpd-auth-conf?rev=985561&r1=985560&r2=985561&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/http/httpd-auth-conf (original)
+++ tuscany/sca-cpp/trunk/modules/http/httpd-auth-conf Sat Aug 14 18:46:26 2010
@@ -20,8 +20,10 @@
 # Generate a minimal HTTPD SSL configuration
 here=`readlink -f $0`; here=`dirname $here`
 root=`readlink -f $1`
+
 conf=`cat $root/conf/httpd.conf | grep "# Generated by: httpd-conf"`
 host=`echo $conf | awk '{ print $6 }'`
+
 httpd_prefix=`cat $here/httpd.prefix`
 
 # Generate basic authentication configuration

Modified: tuscany/sca-cpp/trunk/modules/http/httpd-conf
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/http/httpd-conf?rev=985561&r1=985560&r2=985561&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/http/httpd-conf (original)
+++ tuscany/sca-cpp/trunk/modules/http/httpd-conf Sat Aug 14 18:46:26 2010
@@ -21,16 +21,19 @@
 here=`readlink -f $0`; here=`dirname $here`
 mkdir -p $1
 root=`readlink -f $1`
+
 host=$2
-port=`echo $3 | awk -F "/" '{ print $1 }'`
-pport=`echo $3 | awk -F "/" '{ print $2 }'`
-if [ "$pport" = "" ]; then
-    pport=$port
-fi
+port=`$here/httpd-addr port $3`
+pport=`$here/httpd-addr pport $3`
+listen=`$here/httpd-addr listen $3`
+vhost=`$here/httpd-addr vhost $3`
+
 mkdir -p $4
 htdocs=`readlink -f $4`
+
 user=`id -un`
 group=`id -gn`
+
 modules_prefix=`cat $here/httpd-modules.prefix`
 
 mkdir -p $root
@@ -74,6 +77,8 @@ LoadModule log_config_module ${modules_p
 </IfModule>
 LoadModule vhost_alias_module ${modules_prefix}/modules/mod_vhost_alias.so
 
+LoadModule mod_tuscany_ssltunnel $here/libmod_tuscany_ssltunnel.so
+
 # Basic security precautions
 User $user
 Group $group
@@ -124,10 +129,10 @@ Allow from all
 </Location>
 
 # Listen on HTTP port
-Listen $port
+Listen $listen
 
 # Setup HTTP virtual host
-<VirtualHost *:$port>
+<VirtualHost $vhost>
 ServerName http://$host:$pport
 
 Include conf/svhost.conf

Modified: tuscany/sca-cpp/trunk/modules/http/httpd-ssl-conf
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/http/httpd-ssl-conf?rev=985561&r1=985560&r2=985561&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/http/httpd-ssl-conf (original)
+++ tuscany/sca-cpp/trunk/modules/http/httpd-ssl-conf Sat Aug 14 18:46:26 2010
@@ -20,20 +20,21 @@
 # Generate a minimal HTTPD SSL configuration
 here=`readlink -f $0`; here=`dirname $here`
 root=`readlink -f $1`
+
 conf=`cat $root/conf/httpd.conf | grep "# Generated by: httpd-conf"`
 host=`echo $conf | awk '{ print $6 }'`
-port=`echo $conf | awk '{ print $7 }' | awk -F "/" '{ print $1 }'`
-sslport=`echo $2 | awk -F "/" '{ print $1 }'`
-sslpport=`echo $2 | awk -F "/" '{ print $2 }'`
-if [ "$sslpport" = "" ]; then
-    sslpport=$sslport
-fi
+
+sslpport=`$here/httpd-addr pport $2`
+ssllisten=`$here/httpd-addr listen $2`
+sslvhost=`$here/httpd-addr vhost $2`
+
 htdocs=`echo $conf | awk '{ print $8 }'`
 htdocs=`readlink -f $htdocs`
+
 httpd_prefix=`cat $here/httpd.prefix`
 
 # Extract organization name from our CA certificate
-org=`openssl x509 -noout -subject -nameopt multiline -in $root/conf/ca.crt | grep organizationName | awk -F "= " '{ print $2 }'`
+org=`openssl x509 -noout -subject -nameopt multiline -in $root/cert/ca.crt | grep organizationName | awk -F "= " '{ print $2 }'`
 
 # Generate HTTPD configuration
 cat >>$root/conf/httpd.conf <<EOF
@@ -41,7 +42,7 @@ cat >>$root/conf/httpd.conf <<EOF
 # Redirect all HTTP traffic to HTTPS
 <Location />
 RewriteEngine on
-RewriteCond %{SERVER_PORT} !^$sslpport$  
+RewriteCond %{HTTPS} !^on$
 RewriteRule .* https://%{SERVER_NAME}:$sslpport%{REQUEST_URI} [R,L]
 </Location>
 
@@ -56,10 +57,10 @@ SSLRandomSeed startup builtin
 SSLRandomSeed connect builtin
 
 # Listen on HTTPS port
-Listen $sslport
+Listen $ssllisten
 
 # HTTPS virtual host
-<VirtualHost *:$sslport>
+<VirtualHost $sslvhost>
 ServerName https://$host:$sslpport
 
 Include conf/svhost-ssl.conf
@@ -156,6 +157,7 @@ else
 # - another valid form of authentication as per the Satisfy directive
 SSLRequire %{SSL_CIPHER_USEKEYSIZE} >= 128 and ( \
 ( %{SSL_CLIENT_I_DN_O} == "$org" and %{SSL_CLIENT_S_DN_OU} == "server" ) or \
+( %{SSL_CLIENT_I_DN_O} == "$org" and %{SSL_CLIENT_S_DN_OU} == "tunnel" ) or \
 ( %{SSL_CLIENT_I_DN_O} == "$org" and %{SSL_CLIENT_S_DN_OU} == "proxy" and \
   %{HTTP:X-Forwarded-SSL-Issuer-DN-O} == "$org" and %{HTTP:X-Forwarded-SSL-Client-DN-OU} == "server" ) or \
 %{REQUEST_URI} =~ m/^.(login|logout|openid|unprotected).*$/ )
@@ -177,6 +179,10 @@ RewriteCond %{SSL:SSL_CLIENT_S_DN_OU} "s
 RewriteRule .* - [E=SSL_REMOTE_USER:%{SSL:SSL_CLIENT_S_DN}] 
 
 RewriteCond %{SSL:SSL_CLIENT_I_DN_O} "$org"
+RewriteCond %{SSL:SSL_CLIENT_S_DN_OU} "tunnel"
+RewriteRule .* - [E=SSL_REMOTE_USER:%{SSL:SSL_CLIENT_S_DN}] 
+
+RewriteCond %{SSL:SSL_CLIENT_I_DN_O} "$org"
 RewriteCond %{SSL:SSL_CLIENT_S_DN_OU} "proxy"
 RewriteCond %{HTTP:X-Forwarded-SSL-Issuer-DN-O} "$org"
 RewriteCond %{HTTP:X-Forwarded-SSL-Client-DN-OU} "server"
@@ -196,10 +202,10 @@ cat >$root/conf/svhost-ssl.conf <<EOF
 Include conf/vhost-ssl.conf
 
 # Declare SSL certificates used in this virtual host
-SSLCACertificateFile "$root/conf/ca.crt"
-SSLCertificateChainFile "$root/conf/ca.crt"
-SSLCertificateFile "$root/conf/server.crt"
-SSLCertificateKeyFile "$root/conf/server.key"
+SSLCACertificateFile "$root/cert/ca.crt"
+SSLCertificateChainFile "$root/cert/ca.crt"
+SSLCertificateFile "$root/cert/server.crt"
+SSLCertificateKeyFile "$root/cert/server.key"
 
 EOF
 
@@ -209,10 +215,10 @@ cat >$root/conf/dvhost-ssl.conf <<EOF
 Include conf/vhost-ssl.conf
 
 # Declare wildcard SSL certificates used in this virtual host
-SSLCACertificateFile "$root/conf/ca.crt"
-SSLCertificateChainFile "$root/conf/ca.crt"
-SSLCertificateFile "$root/conf/vhost.crt"
-SSLCertificateKeyFile "$root/conf/vhost.key"
+SSLCACertificateFile "$root/cert/ca.crt"
+SSLCertificateChainFile "$root/cert/ca.crt"
+SSLCertificateFile "$root/cert/vhost.crt"
+SSLCertificateKeyFile "$root/cert/vhost.key"
 
 EOF
 

Modified: tuscany/sca-cpp/trunk/modules/http/httpd.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/http/httpd.hpp?rev=985561&r1=985560&r2=985561&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/http/httpd.hpp (original)
+++ tuscany/sca-cpp/trunk/modules/http/httpd.hpp Sat Aug 14 18:46:26 2010
@@ -26,24 +26,25 @@
  * HTTPD module implementation functions.
  */
 
-#include "apr_strings.h"
-#include "apr_fnmatch.h"
-#include "apr_lib.h"
+#include <apr_strings.h>
+#include <apr_fnmatch.h>
+#include <apr_lib.h>
 #define APR_WANT_STRFUNC
-#include "apr_want.h"
+#include <apr_want.h>
 
-#include "httpd.h"
-#include "http_config.h"
-#include "http_core.h"
-#include "http_request.h"
-#include "http_protocol.h"
-#include "http_log.h"
-#include "http_main.h"
-#include "util_script.h"
-#include "util_md5.h"
-#include "http_config.h"
-#include "ap_mpm.h"
-#include "mod_core.h"
+#include <httpd.h>
+#include <http_config.h>
+#include <http_core.h>
+#include <http_connection.h>
+#include <http_request.h>
+#include <http_protocol.h>
+#include <http_log.h>
+#include <http_main.h>
+#include <util_script.h>
+#include <util_md5.h>
+#include <http_config.h>
+#include <ap_mpm.h>
+#include <mod_core.h>
 
 #include "string.hpp"
 #include "stream.hpp"
@@ -131,66 +132,13 @@ const bool isVirtualHostRequest(const se
 /**
  * Return the content type of a request.
  */
-const char* optional(const char* s) {
-    if (s == NULL)
-        return "";
-    return s;
-}
-
 const string contentType(const request_rec* r) {
-    return optional(apr_table_get(r->headers_in, "Content-Type"));
-}
-
-#ifdef WANT_MAINTAINER_MODE
-
-/**
- * Debug log.
- */
-int debugHeader(unused void* r, const char* key, const char* value) {
-    cerr << "  header key: " << key << ", value: " << value << endl;
-    return 1;
-}
-
-int debugEnv(unused void* r, const char* key, const char* value) {
-    cerr << "  var key: " << key << ", value: " << value << endl;
-    return 1;
-}
-
-int debugNote(unused void* r, const char* key, const char* value) {
-    cerr << "  note key: " << key << ", value: " << value << endl;
-    return 1;
-}
-
-const bool debugRequest(request_rec* r, const string& msg) {
-    cerr << msg << ":" << endl;
-    cerr << "  server: " << optional(r->server->server_hostname) << endl;
-    cerr << "  protocol: " << optional(r->protocol) << endl;
-    cerr << "  method: " << optional(r->method) << endl;
-    cerr << "  method number: " << r->method_number << endl;
-    cerr << "  content type: " << contentType(r) << endl;
-    cerr << "  content encoding: " << optional(r->content_encoding) << endl;
-    apr_table_do(debugHeader, r, r->headers_in, NULL);
-    cerr << "  unparsed uri: " << optional(r->unparsed_uri) << endl;
-    cerr << "  uri: " << optional(r->uri) << endl;
-    cerr << "  path info: " << optional(r->path_info) << endl;
-    cerr << "  filename: " << optional(r->filename) << endl;
-    cerr << "  uri tokens: " << pathTokens(r->uri) << endl;
-    cerr << "  args: " << optional(r->args) << endl;
-    cerr << "  user: " << optional(r->user) << endl;
-    cerr << "  auth type: " << optional(r->ap_auth_type) << endl;
-    apr_table_do(debugEnv, r, r->subprocess_env, NULL);
-    apr_table_do(debugEnv, r, r->notes, NULL);
-    return true;
+    const char* ct = apr_table_get(r->headers_in, "Content-Type");
+    if (ct == NULL)
+        return "";
+    return ct;
 }
 
-#define httpdDebugRequest(r, msg) httpd::debugRequest(r, msg)
-
-#else
-
-#define httpdDebugRequest(r, msg)
-
-#endif
-
 /**
  * Return the remaining part of a uri after the given path (aka the path info.)
  */
@@ -216,19 +164,6 @@ const list<list<value> > queryArgs(const
 }
 
 /**
- * Returns a list of param values other than the id and method args from a list
- * of key value pairs.
- */
-const list<value> queryParams(const list<list<value> >& a) {
-    if (isNil(a))
-        return list<value>();
-    const list<value> p = car(a);
-    if (car(p) == value("id") || car(p) == value("method"))
-        return queryParams(cdr(a));
-    return cons(cadr(p), queryParams(cdr(a)));
-}
-
-/**
  * Converts the args received in a POST to a list of key value pairs.
  */
 const list<list<value> > postArgs(const list<value>& a) {
@@ -303,7 +238,7 @@ const failable<int> writeResult(const fa
 }
 
 /**
- * Report request execution status.
+ * Report a request execution status.
  */
 const int reportStatus(const failable<int>& rc) {
     if (!hasContent(rc))
@@ -337,7 +272,7 @@ const value requestValue(request_rec* r)
 }
 
 /**
- * Update filters in an HTTPD redirect request.
+ * Update request 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) {
@@ -468,6 +403,62 @@ const void* userData(const string& k, co
     return v;
 }
 
+#ifdef WANT_MAINTAINER_MODE
+
+/**
+ * Debug log.
+ */
+const char* debugOptional(const char* s) {
+    if (s == NULL)
+        return "";
+    return s;
+}
+
+int debugHeader(unused void* r, const char* key, const char* value) {
+    cerr << "  header key: " << key << ", value: " << value << endl;
+    return 1;
+}
+
+int debugEnv(unused void* r, const char* key, const char* value) {
+    cerr << "  var key: " << key << ", value: " << value << endl;
+    return 1;
+}
+
+int debugNote(unused void* r, const char* key, const char* value) {
+    cerr << "  note key: " << key << ", value: " << value << endl;
+    return 1;
+}
+
+const bool debugRequest(request_rec* r, const string& msg) {
+    cerr << msg << ":" << endl;
+    cerr << "  server: " << debugOptional(r->server->server_hostname) << endl;
+    cerr << "  protocol: " << debugOptional(r->protocol) << endl;
+    cerr << "  method: " << debugOptional(r->method) << endl;
+    cerr << "  method number: " << r->method_number << endl;
+    cerr << "  content type: " << contentType(r) << endl;
+    cerr << "  content encoding: " << debugOptional(r->content_encoding) << endl;
+    apr_table_do(debugHeader, r, r->headers_in, NULL);
+    cerr << "  unparsed uri: " << debugOptional(r->unparsed_uri) << endl;
+    cerr << "  uri: " << debugOptional(r->uri) << endl;
+    cerr << "  path info: " << debugOptional(r->path_info) << endl;
+    cerr << "  filename: " << debugOptional(r->filename) << endl;
+    cerr << "  uri tokens: " << pathTokens(r->uri) << endl;
+    cerr << "  args: " << debugOptional(r->args) << endl;
+    cerr << "  user: " << debugOptional(r->user) << endl;
+    cerr << "  auth type: " << debugOptional(r->ap_auth_type) << endl;
+    apr_table_do(debugEnv, r, r->subprocess_env, NULL);
+    apr_table_do(debugEnv, r, r->notes, NULL);
+    return true;
+}
+
+#define httpdDebugRequest(r, msg) httpd::debugRequest(r, msg)
+
+#else
+
+#define httpdDebugRequest(r, msg)
+
+#endif
+
 }
 }
 

Added: tuscany/sca-cpp/trunk/modules/http/mod-ssltunnel.cpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/http/mod-ssltunnel.cpp?rev=985561&view=auto
==============================================================================
--- tuscany/sca-cpp/trunk/modules/http/mod-ssltunnel.cpp (added)
+++ tuscany/sca-cpp/trunk/modules/http/mod-ssltunnel.cpp Sat Aug 14 18:46:26 2010
@@ -0,0 +1,364 @@
+/*
+ * 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$ */
+
+/**
+ * HTTPD module used to tunnel traffic over an HTTPS connection.
+ */
+
+#include <sys/stat.h>
+
+#include "string.hpp"
+#include "stream.hpp"
+#include "list.hpp"
+#include "tree.hpp"
+#include "value.hpp"
+#include "monad.hpp"
+#include "httpd.hpp"
+#include "http.hpp"
+
+extern "C" {
+extern module AP_MODULE_DECLARE_DATA mod_tuscany_ssltunnel;
+}
+
+namespace tuscany {
+namespace httpd {
+namespace modssltunnel {
+
+/**
+ * Server configuration.
+ */
+class ServerConf {
+public:
+    ServerConf(server_rec* s) : server(s) {
+    }
+    server_rec* server;
+    string pass;
+    string host;
+    string path;
+    string ca;
+    string cert;
+    string key;
+};
+
+extern "C" {
+extern module AP_DECLARE_DATA core_module;
+}
+
+/**
+ * Process the module configuration.
+ */
+int M_SSLTUNNEL;
+int postConfigParse(ServerConf& mainsc, apr_pool_t* p, server_rec* s) {
+    if (s == NULL)
+        return OK;
+    ServerConf& sc = httpd::serverConf<ServerConf>(s, &mod_tuscany_ssltunnel);
+    debug(httpd::serverName(s), "modwiring::postConfigParse::serverName");
+
+    // Merge configuration from main server
+    if (length(sc.ca) == 0 && length(mainsc.ca) !=0)
+        sc.ca = mainsc.ca;
+    if (length(sc.cert) == 0 && length(mainsc.cert) !=0)
+        sc.cert = mainsc.cert;
+    if (length(sc.key) == 0 && length(mainsc.key) !=0)
+        sc.key = mainsc.key;
+
+    // Parse the configured TunnelPass URI
+    if (length(sc.pass) != 0) {
+        apr_uri_t uri;
+        apr_status_t prc = apr_uri_parse(p, c_str(sc.pass), &uri);
+        if (prc != APR_SUCCESS) {
+            mkfailure<int>("Couldn't parse TunnelPass: " + sc.pass + ", " + http::apreason(prc));
+            return prc;
+        }
+        sc.host = uri.hostname;
+        sc.path = uri.path;
+    }
+    return postConfigParse(mainsc, p, s->next);
+}
+
+int postConfig(apr_pool_t* p, unused apr_pool_t* plog, unused apr_pool_t* ptemp, server_rec* s) {
+    gc_scoped_pool pool(p);
+    ServerConf& sc = httpd::serverConf<ServerConf>(s, &mod_tuscany_ssltunnel);
+    debug(httpd::serverName(s), "modwiring::postConfig::serverName");
+
+    // Register the SSLTUNNEL method
+    M_SSLTUNNEL = ap_method_register(p, "SSLTUNNEL");
+
+    // Parse the configured TunnelPass URI
+    return postConfigParse(sc, p, s);
+}
+
+/**
+ * Close a connection.
+ */
+extern "C" {
+    AP_DECLARE(void) ap_lingering_close(conn_rec *c);
+}
+
+const int close(conn_rec* conn) {
+    debug("modssltunnel::close");
+    ap_lingering_close(conn);
+    return OK;
+}
+
+/**
+ * Abort a connection.
+ */
+const int abort(unused conn_rec* conn, const string& reason) {
+    debug("modssltunnel::abort");
+    return httpd::reportStatus(mkfailure<int>(reason));
+}
+
+/**
+ * Tunnel traffic from a client connection to a target URL.
+ */
+int tunnel(conn_rec* conn, http::CURLSession& cs, const string& url, const string& preamble, const gc_pool& p, unused ap_filter_t* ifilter, ap_filter_t* ofilter) {
+
+    // Get client connection socket
+    apr_socket_t* csock = (apr_socket_t*)ap_get_module_config(conn->conn_config, &core_module);
+
+    // Open connection to target
+    const failable<bool> crc = http::connect(url, cs);
+    if (!hasContent(crc))
+        return abort(conn, reason(crc));
+    apr_socket_t* tsock = http::sock(cs);
+
+    // Send preamble string
+    if (length(preamble) != 0) {
+        debug(preamble, "modssltunnel::tunnel::sendToTarget");
+        const failable<bool> src = http::send(c_str(preamble), length(preamble), cs);
+        if (!hasContent(src))
+            return abort(conn, string("Couldn't send to target: ") + reason(src));
+    }
+
+    // Create input/output bucket brigades
+    apr_bucket_brigade* ib = apr_brigade_create(pool(p), conn->bucket_alloc);
+    apr_bucket_brigade* ob = apr_brigade_create(pool(p), conn->bucket_alloc);
+
+    // Create a pollset for the client and target sockets
+    apr_pollset_t* pollset;
+    apr_status_t cprc = apr_pollset_create(&pollset, 2, pool(p), 0);
+    if (cprc != APR_SUCCESS)
+        return abort(conn, http::apreason(cprc));
+    const apr_pollfd_t* cpollfd = http::pollfd(csock, APR_POLLIN, p);
+    apr_pollset_add(pollset, cpollfd);
+    const apr_pollfd_t* tpollfd = http::pollfd(tsock, APR_POLLIN, p);
+    apr_pollset_add(pollset, tpollfd);
+
+    // Relay traffic in both directions until end of stream
+    const apr_pollfd_t* pollfds = cpollfd;
+    apr_int32_t pollcount = 1;
+    for(;;) {
+        for (; pollcount > 0; pollcount--, pollfds++) {
+            if (pollfds->rtnevents & APR_POLLIN) {
+                if (pollfds->desc.s == csock) {
+
+                    // Receive buckets from client
+                    const apr_status_t getrc = ap_get_brigade(conn->input_filters, ib, AP_MODE_READBYTES, APR_BLOCK_READ, HUGE_STRING_LEN);
+                    if (getrc != APR_SUCCESS)
+                        return OK;
+
+                    for (apr_bucket* bucket = APR_BRIGADE_FIRST(ib); bucket != APR_BRIGADE_SENTINEL(ib); bucket = APR_BUCKET_NEXT(bucket)) {
+                        if (APR_BUCKET_IS_FLUSH(bucket))
+                            continue;
+
+                        // Client connection closed
+                        if (APR_BUCKET_IS_EOS(bucket))
+                            return close(conn);
+
+                        const char *data;
+                        apr_size_t rl;
+                        apr_bucket_read(bucket, &data, &rl, APR_BLOCK_READ);
+                        if (rl > 0) {
+                            debug(string(data, rl), "modssltunnel::tunnel::sendToTarget");
+
+                            // Send to target
+                            const failable<bool> src = http::send(data, rl, cs);
+                            if (!hasContent(src))
+                                return abort(conn, string("Couldn't send to target: ") + reason(src));
+                        }
+                    }
+                    apr_brigade_cleanup(ib);
+                } else {
+
+                    // Receive from target
+                    char data[8192];
+                    const failable<int> frl = http::recv(data, sizeof(data), cs);
+                    if (!hasContent(frl))
+                        return abort(conn, string("Couldn't receive from target") + reason(frl));
+                    const int rl = content(frl);
+
+                    // Target connection closed
+                    if (rl == 0)
+                        return close(conn);
+
+                    // Send bucket to client
+                    APR_BRIGADE_INSERT_TAIL(ob, apr_bucket_transient_create(data, rl, conn->bucket_alloc));
+                    APR_BRIGADE_INSERT_TAIL(ob, apr_bucket_flush_create(conn->bucket_alloc));
+                    if (ap_pass_brigade(ofilter, ob) != APR_SUCCESS)
+                        return abort(conn, "Couldn't send data bucket to client");
+                    apr_brigade_cleanup(ob);
+                }
+            }
+
+            // Error
+            if (pollfds->rtnevents & (APR_POLLERR | APR_POLLHUP | APR_POLLNVAL)) {
+                if (pollfds->desc.s == csock) 
+                    return abort(conn, "Couldn't receive from client");
+                else
+                    return abort(conn, "Couldn't receive from target");
+            }
+        }
+
+        // Poll the client and target sockets
+        debug("modssltunnel::tunnel::poll");
+        apr_status_t pollrc = apr_pollset_poll(pollset, -1, &pollcount, &pollfds);
+        if (pollrc != APR_SUCCESS)
+            return abort(conn, "Couldn't poll sockets");
+        debug(pollcount, "modssltunnel::tunnel::pollfds");
+    }
+
+    // Close client connection
+    return close(conn);
+}
+
+/**
+ * Return the first connection filter in a list of filters.
+ */
+ap_filter_t* connectionFilter(ap_filter_t* f) {
+    if (f == NULL)
+        return f;
+    if (f->frec->ftype < AP_FTYPE_CONNECTION)
+        return connectionFilter(f->next);
+    return f;
+}
+
+/**
+ * Process a client connection and relay it to a tunnel.
+ */
+int processConnection(conn_rec *conn) {
+    // Only allow configured virtual hosts
+    if (!conn->base_server->is_virtual)
+        return DECLINED;
+    if (ap_get_module_config(conn->base_server->module_config, &mod_tuscany_ssltunnel) == NULL)
+        return DECLINED;
+
+    gc_scoped_pool(conn->pool);
+    const ServerConf& sc = httpd::serverConf<ServerConf>(conn->base_server, &mod_tuscany_ssltunnel);
+    if (length(sc.pass) == 0)
+        return DECLINED;
+    debug(sc.pass, "modssltunnel::processConnection::pass");
+
+    // Create the target connection
+    http::CURLSession cs(sc.ca, sc.cert, sc.key);
+
+    // Run the tunnel
+    const string preamble = string("SSLTUNNEL ") + sc.path + string(" HTTP/1.1\r\nHost: ") + sc.host + string("\r\n\r\n");
+    debug(preamble, "modssltunnel::processConnection::preamble");
+    return tunnel(conn, cs, sc.pass, preamble, gc_pool(conn->pool), connectionFilter(conn->input_filters), connectionFilter(conn->output_filters));
+}
+
+/**
+ * Tunnel a SSLTUNNEL request to a target host/port.
+ */
+int handler(request_rec* r) {
+    if (r->method_number != M_SSLTUNNEL)
+        return DECLINED;
+
+    // Only allow HTTPS
+    if (strcmp(r->server->server_scheme, "https"))
+        return DECLINED;
+
+    // Build the target URL
+    debug(r->uri, "modssltunnel::handler::uri");
+    const list<value> path(pathValues(r->uri));
+    const string url = string(cadr(path)) + ":" + caddr(path);
+    debug(url, "modssltunnel::handler::target");
+
+    // Create the target connection
+    http::CURLSession cs;
+
+    // Run the tunnel
+    return tunnel(r->connection, cs, url, "", gc_pool(r->pool), connectionFilter(r->proto_input_filters), connectionFilter(r->proto_output_filters));
+}
+
+/**
+ * Configuration commands.
+ */
+const char* confTunnelPass(cmd_parms *cmd, unused void *c, const char *arg) {
+    gc_scoped_pool pool(cmd->pool);
+    ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_ssltunnel);
+    sc.pass = arg;
+    return NULL;
+}
+const char* confCAFile(cmd_parms *cmd, unused void *c, const char *arg) {
+    gc_scoped_pool pool(cmd->pool);
+    ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_ssltunnel);
+    sc.ca = arg;
+    return NULL;
+}
+const char* confCertFile(cmd_parms *cmd, unused void *c, const char *arg) {
+    gc_scoped_pool pool(cmd->pool);
+    ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_ssltunnel);
+    sc.cert = arg;
+    return NULL;
+}
+const char* confCertKeyFile(cmd_parms *cmd, unused void *c, const char *arg) {
+    gc_scoped_pool pool(cmd->pool);
+    ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_ssltunnel);
+    sc.key = arg;
+    return NULL;
+}
+
+/**
+ * HTTP server module declaration.
+ */
+const command_rec commands[] = {
+    AP_INIT_TAKE1("TunnelPass", (const char*(*)())confTunnelPass, NULL, RSRC_CONF, "Tunnel server name"),
+    AP_INIT_TAKE1("TunnelSSLCACertificateFile", (const char*(*)())confCAFile, NULL, RSRC_CONF, "Tunnel SSL CA certificate file"),
+    AP_INIT_TAKE1("TunnelSSLCertificateFile", (const char*(*)())confCertFile, NULL, RSRC_CONF, "Tunnel SSL certificate file"),
+    AP_INIT_TAKE1("TunnelSSLCertificateKeyFile", (const char*(*)())confCertKeyFile, NULL, RSRC_CONF, "Tunnel SSL certificate key file"),
+    {NULL, NULL, NULL, 0, NO_ARGS, NULL}
+};
+
+void registerHooks(unused apr_pool_t *p) {
+    ap_hook_post_config(postConfig, NULL, NULL, APR_HOOK_MIDDLE);
+    ap_hook_handler(handler, NULL, NULL, APR_HOOK_MIDDLE);
+    ap_hook_process_connection(processConnection, NULL, NULL, APR_HOOK_MIDDLE);
+}
+
+}
+}
+}
+
+extern "C" {
+
+module AP_MODULE_DECLARE_DATA mod_tuscany_ssltunnel = {
+    STANDARD20_MODULE_STUFF,
+    // dir config and merger
+    NULL, NULL,
+    // server config and merger
+    tuscany::httpd::makeServerConf<tuscany::httpd::modssltunnel::ServerConf>, NULL,
+    // commands and hooks
+    tuscany::httpd::modssltunnel::commands, tuscany::httpd::modssltunnel::registerHooks
+};
+
+}

Modified: tuscany/sca-cpp/trunk/modules/http/proxy-member-conf
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/http/proxy-member-conf?rev=985561&r1=985560&r2=985561&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/http/proxy-member-conf (original)
+++ tuscany/sca-cpp/trunk/modules/http/proxy-member-conf Sat Aug 14 18:46:26 2010
@@ -20,8 +20,9 @@
 # Add a proxy balancer member
 here=`readlink -f $0`; here=`dirname $here`
 root=`readlink -f $1`
+
 host=$2
-port=`echo $3 | awk -F "/" '{ print $1 }'`
+port=`$here/httpd-addr port $3`
 
 cat >>$root/conf/vhost.conf <<EOF
 # Generated by: proxy-member-conf $*

Modified: tuscany/sca-cpp/trunk/modules/http/proxy-ssl-conf
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/http/proxy-ssl-conf?rev=985561&r1=985560&r2=985561&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/http/proxy-ssl-conf (original)
+++ tuscany/sca-cpp/trunk/modules/http/proxy-ssl-conf Sat Aug 14 18:46:26 2010
@@ -60,8 +60,8 @@ EOF
 cat >>$root/conf/vhost-ssl.conf <<EOF
 # Generated by: proxy-ssl-conf $*
 # Declare the proxy SSL client certificates
-SSLProxyCACertificateFile "$root/conf/ca.crt"
-SSLProxyMachineCertificateFile "$root/conf/proxy.pem"
+SSLProxyCACertificateFile "$root/cert/ca.crt"
+SSLProxyMachineCertificateFile "$root/cert/proxy.pem"
 
 EOF
 

Modified: tuscany/sca-cpp/trunk/modules/http/proxy-ssl-member-conf
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/http/proxy-ssl-member-conf?rev=985561&r1=985560&r2=985561&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/http/proxy-ssl-member-conf (original)
+++ tuscany/sca-cpp/trunk/modules/http/proxy-ssl-member-conf Sat Aug 14 18:46:26 2010
@@ -20,8 +20,9 @@
 # Add a proxy balancer member
 here=`readlink -f $0`; here=`dirname $here`
 root=`readlink -f $1`
+
 host=$2
-sslport=`echo $3 | awk -F "/" '{ print $1 }'`
+sslport=`$here/httpd-addr port $3`
 
 cat >>$root/conf/vhost-ssl.conf <<EOF
 # Generated by: proxy-ssl-member-conf $*

Modified: tuscany/sca-cpp/trunk/modules/http/ssl-ca-conf
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/http/ssl-ca-conf?rev=985561&r1=985560&r2=985561&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/http/ssl-ca-conf (original)
+++ tuscany/sca-cpp/trunk/modules/http/ssl-ca-conf Sat Aug 14 18:46:26 2010
@@ -21,17 +21,18 @@
 here=`readlink -f $0`; here=`dirname $here`
 mkdir -p $1
 root=`readlink -f $1`
+
 host=$2
 
 # Don't override existing certificate
-if [ -f $root/conf/ca.crt ]; then
+if [ -f $root/cert/ca.crt ]; then
     return 0
 fi
 
 # Generate openssl configuration
-mkdir -p $root/conf
+mkdir -p $root/cert
 umask 0007
-cat >$root/conf/openssl-ca.conf <<EOF
+cat >$root/cert/openssl-ca.conf <<EOF
 [ req ]
 default_bits = 1024
 encrypt_key = no
@@ -57,11 +58,11 @@ basicConstraints = CA:true
 default_ca = ca_default
 
 [ca_default]
-certificate = $root/conf/ca.crt
-private_key = $root/conf/ca.key
-serial = $root/conf/ca-serial
-database = $root/conf/ca-database
-new_certs_dir = $root/conf
+certificate = $root/cert/ca.crt
+private_key = $root/cert/ca.key
+serial = $root/cert/ca-serial
+database = $root/cert/ca-database
+new_certs_dir = $root/cert
 default_md = sha1
 email_in_dn = no
 default_days = 365
@@ -80,11 +81,16 @@ emailAddress = optional
 
 EOF
 
-rm -rf $root/conf/*.pem
-rm -f $root/conf/ca-database
-echo 1000 > $root/conf/ca-serial
-touch $root/conf/ca-database
+rm -rf $root/cert/*.crt $root/cert/*.pem $root/cert/hash
+rm -f $root/cert/ca-database
+echo 1000 > $root/cert/ca-serial
+touch $root/cert/ca-database
 
 # Generate the certification authority certificate
-openssl req -new -x509 -config $root/conf/openssl-ca.conf -out $root/conf/ca.crt -keyout $root/conf/ca.key
+openssl req -new -x509 -config $root/cert/openssl-ca.conf -out $root/cert/ca.crt -keyout $root/cert/ca.key
+
+# Add to the hash directory and rehash
+mkdir -p $root/cert/hash
+cp $root/cert/ca.crt $root/cert/hash
+c_rehash $root/cert/hash
 

Modified: tuscany/sca-cpp/trunk/modules/http/ssl-cert-conf
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/http/ssl-cert-conf?rev=985561&r1=985560&r2=985561&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/http/ssl-cert-conf (original)
+++ tuscany/sca-cpp/trunk/modules/http/ssl-cert-conf Sat Aug 14 18:46:26 2010
@@ -21,6 +21,7 @@
 here=`readlink -f $0`; here=`dirname $here`
 mkdir -p $1
 root=`readlink -f $1`
+
 host=$2
 if [ "$3" != "" ]; then
     certname=$3
@@ -29,14 +30,14 @@ else
 fi
 
 # Don't regenerate the certificate if it already exists
-if [ -f $root/conf/$certname.crt ]; then
+if [ -f $root/cert/$certname.crt ]; then
     return 0
 fi
 
 # Generate openssl configuration
-mkdir -p $root/conf
+mkdir -p $root/cert
 umask 0007
-cat >$root/conf/openssl-cert-$certname.conf <<EOF
+cat >$root/cert/openssl-cert-$certname.conf <<EOF
 [ req ]
 default_bits = 1024
 encrypt_key = no
@@ -54,16 +55,22 @@ emailAddress = admin@$host
 EOF
 
 # Generate a certificate request
-openssl req -new -config $root/conf/openssl-cert-$certname.conf -out $root/conf/$certname-req.crt -keyout $root/conf/$certname.key
+openssl req -new -config $root/cert/openssl-cert-$certname.conf -out $root/cert/$certname-req.crt -keyout $root/cert/$certname.key
 
 # Generate a certificate, signed with our test certification authority certificate
-openssl ca -batch -config $root/conf/openssl-ca.conf -out $root/conf/$certname.crt -infiles $root/conf/$certname-req.crt
+openssl ca -batch -config $root/cert/openssl-ca.conf -out $root/cert/$certname.crt -infiles $root/cert/$certname-req.crt
 
 # Export it to PKCS12 format, that's the format Web browsers want to import
-openssl pkcs12 -export -passout pass: -out $root/conf/$certname.p12 -inkey $root/conf/$certname.key -in $root/conf/$certname.crt -certfile $root/conf/ca.crt
+openssl pkcs12 -export -passout pass: -out $root/cert/$certname.p12 -inkey $root/cert/$certname.key -in $root/cert/$certname.crt -certfile $root/cert/ca.crt
 
 # Convert the certificate to PEM format and concatenate the key to it, for use
 # by mod_proxy
-openssl x509 -in $root/conf/$certname.crt -out $root/conf/$certname.pem
-cat $root/conf/$certname.key >> $root/conf/$certname.pem
+openssl x509 -in $root/cert/$certname.crt -out $root/cert/$certname.pem
+cat $root/cert/$certname.key >> $root/cert/$certname.pem
+
+# Add to the hash directory and rehash
+mkdir -p $root/cert/hash
+cp $root/cert/$certname.crt $root/cert/hash
+cp $root/cert/$certname.pem $root/cert/hash
+c_rehash $root/cert/hash
 

Copied: tuscany/sca-cpp/trunk/modules/http/ssl-cert-find (from r981352, tuscany/sca-cpp/trunk/modules/http/ssl-ls)
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/http/ssl-cert-find?p2=tuscany/sca-cpp/trunk/modules/http/ssl-cert-find&p1=tuscany/sca-cpp/trunk/modules/http/ssl-ls&r1=981352&r2=985561&rev=985561&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/http/ssl-ls (original)
+++ tuscany/sca-cpp/trunk/modules/http/ssl-cert-find Sat Aug 14 18:46:26 2010
@@ -17,9 +17,10 @@
 #  specific language governing permissions and limitations
 #  under the License.
 
-# Generate a test certification authority certificate
+# List certificate files, useful to distribute them to another host
 here=`readlink -f $0`; here=`dirname $here`
 root=`readlink -f $1`
 
-ls $root/conf/*.crt $root/conf/*.key $root/conf/*.pem $root/conf/*.p12 2>/dev/null
+cd $root
+find -regex '.*\.\(\(crt\)\|\(pem\)\|\(p12\)\|\(key\)\|\(0\)\)' 2>/dev/null
 

Copied: tuscany/sca-cpp/trunk/modules/http/tunnel-ssl-conf (from r981352, tuscany/sca-cpp/trunk/modules/http/vhost-conf)
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/http/tunnel-ssl-conf?p2=tuscany/sca-cpp/trunk/modules/http/tunnel-ssl-conf&p1=tuscany/sca-cpp/trunk/modules/http/vhost-conf&r1=981352&r2=985561&rev=985561&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/http/vhost-conf (original)
+++ tuscany/sca-cpp/trunk/modules/http/tunnel-ssl-conf Sat Aug 14 18:46:26 2010
@@ -17,30 +17,39 @@
 #  specific language governing permissions and limitations
 #  under the License.
 
-# Generate mass dynamic virtual hosting configuration
+# Generate an SSL tunnel configuration
 here=`readlink -f $0`; here=`dirname $here`
 root=`readlink -f $1`
+
 conf=`cat $root/conf/httpd.conf | grep "# Generated by: httpd-conf"`
 host=`echo $conf | awk '{ print $6 }'`
-port=`echo $conf | awk '{ print $7 }' | awk -F "/" '{ print $1 }'`
-pport=`echo $conf | awk '{ print $7 }' | awk -F "/" '{ print $2 }'`
-if [ "$pport" = "" ]; then
-    pport=$port
-fi
-htdocs=`echo $conf | awk '{ print $8 }'`
-htdocs=`readlink -f $htdocs`
 
+port=`$here/httpd-addr port $2`
+sslhost=$3
+sslport=$4
+tport=$5
+
+httpd_prefix=`cat $here/httpd.prefix`
+
+# Generate HTTPD configuration
 cat >>$root/conf/httpd.conf <<EOF
-# Generated by: vhost-conf $*
-# Enable mass dynamic virtual hosting
-NameVirtualHost *:$port
-
-<VirtualHost *:$port>
-ServerName http://vhost.$host:$pport
-ServerAlias *.$host
-VirtualDocumentRoot $htdocs/domains/%1/
+# Generated by: tunnel-ssl-conf $*
+# Tunnel TCP/IP traffic over HTTPS
+
+# Listen on local port
+Listen 127.0.0.1:$port
+
+# Tunnel virtual host
+<VirtualHost 127.0.0.1:$port>
+ServerName http://localhost:$port
+
+TunnelPass https://$sslhost:$sslport/tunnel/localhost/$tport
+
+# Declare SSL certificates used in this virtual host
+#TunnelSSLCACertificateFile "$root/cert/ca.crt"
+TunnelSSLCertificateFile "$root/cert/tunnel.crt"
+TunnelSSLCertificateKeyFile "$root/cert/tunnel.key"
 
-Include conf/dvhost.conf
 </VirtualHost>
 
 EOF

Modified: tuscany/sca-cpp/trunk/modules/http/vhost-conf
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/http/vhost-conf?rev=985561&r1=985560&r2=985561&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/http/vhost-conf (original)
+++ tuscany/sca-cpp/trunk/modules/http/vhost-conf Sat Aug 14 18:46:26 2010
@@ -20,22 +20,23 @@
 # Generate mass dynamic virtual hosting configuration
 here=`readlink -f $0`; here=`dirname $here`
 root=`readlink -f $1`
+
 conf=`cat $root/conf/httpd.conf | grep "# Generated by: httpd-conf"`
 host=`echo $conf | awk '{ print $6 }'`
-port=`echo $conf | awk '{ print $7 }' | awk -F "/" '{ print $1 }'`
-pport=`echo $conf | awk '{ print $7 }' | awk -F "/" '{ print $2 }'`
-if [ "$pport" = "" ]; then
-    pport=$port
-fi
+addr=`echo $conf | awk '{ print $7 }'`
+port=`$here/httpd-addr port $addr`
+pport=`$here/httpd-addr pport $addr`
+vhost=`$here/httpd-addr vhost $addr`
+
 htdocs=`echo $conf | awk '{ print $8 }'`
 htdocs=`readlink -f $htdocs`
 
 cat >>$root/conf/httpd.conf <<EOF
 # Generated by: vhost-conf $*
 # Enable mass dynamic virtual hosting
-NameVirtualHost *:$port
+NameVirtualHost $vhost
 
-<VirtualHost *:$port>
+<VirtualHost $vhost>
 ServerName http://vhost.$host:$pport
 ServerAlias *.$host
 VirtualDocumentRoot $htdocs/domains/%1/

Modified: tuscany/sca-cpp/trunk/modules/http/vhost-ssl-conf
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/http/vhost-ssl-conf?rev=985561&r1=985560&r2=985561&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/http/vhost-ssl-conf (original)
+++ tuscany/sca-cpp/trunk/modules/http/vhost-ssl-conf Sat Aug 14 18:46:26 2010
@@ -20,24 +20,26 @@
 # Generate mass dynamic virtual hosting configuration
 here=`readlink -f $0`; here=`dirname $here`
 root=`readlink -f $1`
+
 conf=`cat $root/conf/httpd.conf | grep "# Generated by: httpd-conf"`
 host=`echo $conf | awk '{ print $6 }'`
+
 sslconf=`cat $root/conf/httpd.conf | grep "# Generated by: httpd-ssl-conf"`
-sslport=`echo $sslconf | awk '{ print $6 }' | awk -F "/" '{ print $1 }'`
-sslpport=`echo $sslconf | awk '{ print $6 }' | awk -F "/" '{ print $2 }'`
-if [ "$sslpport" = "" ]; then
-    sslpport=$sslport
-fi
+ssladdr=`echo $sslconf | awk '{ print $6 }'`
+sslport=`$here/httpd-addr port $ssladdr`
+sslpport=`$here/httpd-addr pport $ssladdr`
+sslvhost=`$here/httpd-addr vhost $ssladdr`
+
 htdocs=`echo $conf | awk '{ print $8 }'`
 htdocs=`readlink -f $htdocs`
 
 cat >>$root/conf/httpd.conf <<EOF
 # Generated by: vhost-ssl-conf $*
 # Enable mass dynamic virtual hosting over HTTPS
-NameVirtualHost *:$sslport
+NameVirtualHost $sslvhost
 SSLStrictSNIVHostCheck Off
 
-<VirtualHost *:$sslport>
+<VirtualHost $sslvhost>
 ServerName https://vhost.$host:$sslpport
 ServerAlias *.$host
 VirtualDocumentRoot $htdocs/domains/%1/

Modified: tuscany/sca-cpp/trunk/modules/json/json.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/json/json.hpp?rev=985561&r1=985560&r2=985561&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/json/json.hpp (original)
+++ tuscany/sca-cpp/trunk/modules/json/json.hpp Sat Aug 14 18:46:26 2010
@@ -397,6 +397,19 @@ const string funcName(const string& f) {
     return f;
 }
 
+/**
+ * Returns a list of param values other than the id and method args from a list
+ * of key value pairs.
+ */
+const list<value> queryParams(const list<list<value> >& a) {
+    if (isNil(a))
+        return list<value>();
+    const list<value> p = car(a);
+    if (car(p) == value("id") || car(p) == value("method"))
+        return queryParams(cdr(a));
+    return cons(cadr(p), queryParams(cdr(a)));
+}
+
 }
 }
 

Modified: tuscany/sca-cpp/trunk/modules/server/client-test.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/server/client-test.hpp?rev=985561&r1=985560&r2=985561&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/server/client-test.hpp (original)
+++ tuscany/sca-cpp/trunk/modules/server/client-test.hpp Sat Aug 14 18:46:26 2010
@@ -31,7 +31,7 @@
 #include "string.hpp"
 #include "parallel.hpp"
 #include "perf.hpp"
-#include "../http/curl.hpp"
+#include "../http/http.hpp"
 
 namespace tuscany {
 namespace server {