Author: jsdelfino
Date: Mon Jun 13 07:57:13 2011
New Revision: 1135047

URL: http://svn.apache.org/viewvc?rev=1135047&view=rev
Log:
Improve support for HTTP verbs and enable calls inside a domain without having 
to repeat the domain name in all the URLs.

Added:
    tuscany/sca-cpp/trunk/components/http/content-test.scm
      - copied, changed from r1135046, 
tuscany/sca-cpp/trunk/components/http/url-test.scm
    tuscany/sca-cpp/trunk/components/http/httppatch.componentType
      - copied, changed from r1135046, 
tuscany/sca-cpp/trunk/components/http/http.composite
    tuscany/sca-cpp/trunk/components/http/httppatch.cpp
    tuscany/sca-cpp/trunk/components/http/httppost.componentType
      - copied, changed from r1135046, 
tuscany/sca-cpp/trunk/components/http/http.composite
    tuscany/sca-cpp/trunk/components/http/httppost.cpp
    tuscany/sca-cpp/trunk/components/http/httpput.componentType
      - copied, changed from r1135046, 
tuscany/sca-cpp/trunk/components/http/http.composite
    tuscany/sca-cpp/trunk/components/http/httpput.cpp
    tuscany/sca-cpp/trunk/components/http/server-test.scm
Modified:
    tuscany/sca-cpp/trunk/components/http/Makefile.am
    tuscany/sca-cpp/trunk/components/http/client-test.cpp
    tuscany/sca-cpp/trunk/components/http/http.composite
    tuscany/sca-cpp/trunk/components/http/url-test.scm
    tuscany/sca-cpp/trunk/modules/edit/apps/testhttp/app.composite
    tuscany/sca-cpp/trunk/modules/edit/palettes/http/palette.composite
    tuscany/sca-cpp/trunk/modules/http/http.hpp
    tuscany/sca-cpp/trunk/modules/http/httpd.hpp
    tuscany/sca-cpp/trunk/modules/server/mod-eval.hpp
    tuscany/sca-cpp/trunk/modules/server/mod-wiring.cpp

Modified: tuscany/sca-cpp/trunk/components/http/Makefile.am
URL: 
http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/http/Makefile.am?rev=1135047&r1=1135046&r2=1135047&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/http/Makefile.am (original)
+++ tuscany/sca-cpp/trunk/components/http/Makefile.am Mon Jun 13 07:57:13 2011
@@ -19,8 +19,8 @@ compdir=$(prefix)/components/http
 
 EXTRA_DIST = http.composite httpget.componentType httpdelete.componentType 
*.scm
 
-comp_LTLIBRARIES = libhttpget.la libhttpdelete.la
-noinst_DATA = libhttpget.so libhttpdelete.so
+comp_LTLIBRARIES = libhttpget.la libhttpdelete.la libhttppost.la libhttpput.la
+noinst_DATA = libhttpget.so libhttpdelete.so libhttppost.so libhttpput.so
 
 libhttpget_la_SOURCES = httpget.cpp
 libhttpget_la_LDFLAGS = -lxml2 -lmozjs -curl
@@ -32,6 +32,21 @@ libhttpdelete_la_LDFLAGS = -lxml2 -lmozj
 libhttpdelete.so:
        ln -s .libs/libhttpdelete.so
 
+libhttppost_la_SOURCES = httppost.cpp
+libhttppost_la_LDFLAGS = -lxml2 -lmozjs -curl
+libhttppost.so:
+       ln -s .libs/libhttppost.so
+
+libhttpput_la_SOURCES = httpput.cpp
+libhttpput_la_LDFLAGS = -lxml2 -lmozjs -curl
+libhttpput.so:
+       ln -s .libs/libhttpput.so
+
+libhttppatch_la_SOURCES = httppatch.cpp
+libhttppatch_la_LDFLAGS = -lxml2 -lmozjs -curl
+libhttppatch.so:
+       ln -s .libs/libhttppatch.so
+
 client_test_SOURCES = client-test.cpp
 client_test_LDFLAGS = -lxml2 -lcurl -lmozjs
 

Modified: tuscany/sca-cpp/trunk/components/http/client-test.cpp
URL: 
http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/http/client-test.cpp?rev=1135047&r1=1135046&r2=1135047&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/http/client-test.cpp (original)
+++ tuscany/sca-cpp/trunk/components/http/client-test.cpp Mon Jun 13 07:57:13 
2011
@@ -36,15 +36,16 @@
 namespace tuscany {
 namespace http {
 
-const string uri("http://localhost:8090/httpget";);
+const string getURI("http://localhost:8090/httpget";);
+const string postURI("http://localhost:8090/httppost";);
+const string putURI("http://localhost:8090/httpput";);
+const string deleteURI("http://localhost:8090/httpdelete";);
 
 bool testGet() {
     http::CURLSession cs("", "", "", "");
 
-    const failable<value> val = http::get(uri, cs);
+    const failable<value> val = http::get(getURI, cs);
     assert(hasContent(val));
-    assert(contains(string(car<value>(cadr<value>(content(val)))), "It 
works"));
-
     return true;
 }
 
@@ -53,9 +54,8 @@ struct getLoop {
     getLoop(http::CURLSession cs) : cs(cs) {
     }
     const bool operator()() const {
-        const failable<value> val = http::get(uri, cs);
+        const failable<value> val = http::get(getURI, cs);
         assert(hasContent(val));
-        assert(contains(string(car<value>(cadr<value>(content(val)))), "It 
works"));
         return true;
     }
 };
@@ -69,6 +69,30 @@ bool testGetPerf() {
     return true;
 }
 
+bool testPost() {
+    http::CURLSession cs("", "", "", "");
+
+    const failable<value> val = http::get(postURI, cs);
+    assert(hasContent(val));
+    return true;
+}
+
+bool testPut() {
+    http::CURLSession cs("", "", "", "");
+
+    const failable<value> val = http::get(putURI, cs);
+    assert(hasContent(val));
+    return true;
+}
+
+bool testDelete() {
+    http::CURLSession cs("", "", "", "");
+
+    const failable<value> val = http::get(deleteURI, cs);
+    assert(hasContent(val));
+    return true;
+}
+
 }
 }
 
@@ -77,6 +101,9 @@ int main() {
 
     tuscany::http::testGet();
     tuscany::http::testGetPerf();
+    tuscany::http::testPost();
+    tuscany::http::testPut();
+    tuscany::http::testDelete();
 
     tuscany::cout << "OK" << tuscany::endl;
 

Copied: tuscany/sca-cpp/trunk/components/http/content-test.scm (from r1135046, 
tuscany/sca-cpp/trunk/components/http/url-test.scm)
URL: 
http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/http/content-test.scm?p2=tuscany/sca-cpp/trunk/components/http/content-test.scm&p1=tuscany/sca-cpp/trunk/components/http/url-test.scm&r1=1135046&r2=1135047&rev=1135047&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/http/url-test.scm (original)
+++ tuscany/sca-cpp/trunk/components/http/content-test.scm Mon Jun 13 07:57:13 
2011
@@ -15,9 +15,9 @@
 ;  specific language governing permissions and limitations
 ;  under the License.
 
-; URL test case
+; Content test case
 
 (define (get id)
-    "http://localhost:8090/index.html";
+    (list (list 'entry '(title "Item") '(id "111") '(content (item (name 
"Apple") (currencyCode "USD") (currencySymbol "$") (price 2.99)))))
 )
 

Modified: tuscany/sca-cpp/trunk/components/http/http.composite
URL: 
http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/http/http.composite?rev=1135047&r1=1135046&r2=1135047&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/http/http.composite (original)
+++ tuscany/sca-cpp/trunk/components/http/http.composite Mon Jun 13 07:57:13 
2011
@@ -29,6 +29,41 @@
         <reference name="url" target="url-test"/>
     </component>
 
+    <component name="httppost">
+        <implementation.cpp path="." library="libhttppost"/>
+        <service name="httppost">
+            <binding.http uri="httppost"/>
+        </service>
+        <reference name="url" target="url-test"/>
+        <reference name="content" target="content-test"/>
+    </component>
+
+    <component name="httpput">
+        <implementation.cpp path="." library="libhttpput"/>
+        <service name="httpput">
+            <binding.http uri="httpput"/>
+        </service>
+        <reference name="url" target="url-test"/>
+        <reference name="content" target="content-test"/>
+    </component>
+
+    <component name="httppatch">
+        <implementation.cpp path="." library="libhttppatch"/>
+        <service name="httppatch">
+            <binding.http uri="httppatch"/>
+        </service>
+        <reference name="url" target="url-test"/>
+        <reference name="content" target="content-test"/>
+    </component>
+
+    <component name="httpdelete">
+        <implementation.cpp path="." library="libhttpdelete"/>
+        <service name="httpdelete">
+            <binding.http uri="httpdelete"/>
+        </service>
+        <reference name="url" target="url-test"/>
+    </component>
+
     <component name="url-test">
         <implementation.scheme script="url-test.scm"/>
         <service name="url-test">
@@ -36,4 +71,18 @@
         </service>
     </component>
 
+    <component name="content-test">
+        <implementation.scheme script="content-test.scm"/>
+        <service name="content-test">
+            <binding.http uri="content-test"/>
+        </service>
+    </component>
+
+    <component name="scheme-test">
+        <implementation.scheme script="server-test.scm"/>
+        <service name="test">
+            <binding.http uri="test"/>
+        </service>
+    </component>     
+
 </composite>

Copied: tuscany/sca-cpp/trunk/components/http/httppatch.componentType (from 
r1135046, tuscany/sca-cpp/trunk/components/http/http.composite)
URL: 
http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/http/httppatch.componentType?p2=tuscany/sca-cpp/trunk/components/http/httppatch.componentType&p1=tuscany/sca-cpp/trunk/components/http/http.composite&r1=1135046&r2=1135047&rev=1135047&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/http/http.composite (original)
+++ tuscany/sca-cpp/trunk/components/http/httppatch.componentType Mon Jun 13 
07:57:13 2011
@@ -17,23 +17,13 @@
  * specific language governing permissions and limitations
  * under the License.    
 -->
-<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912";
-  targetNamespace="http://tuscany.apache.org/xmlns/sca/components";
-  name="http">
+<componentType xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912";
+  xmlns:xsd="http://www.w3.org/2001/XMLSchema";
+  xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1";
+  targetNamespace="http://tuscany.apache.org/xmlns/sca/components";>
         
-    <component name="httpget">
-        <implementation.cpp path="." library="libhttpget"/>
-        <service name="httpget">
-            <binding.http uri="httpget"/>
-        </service>
-        <reference name="url" target="url-test"/>
-    </component>
-
-    <component name="url-test">
-        <implementation.scheme script="url-test.scm"/>
-        <service name="url-test">
-            <binding.http uri="url-test"/>
-        </service>
-    </component>
+    <service name="http"/>
+    <reference name="url"/>
+    <reference name="content"/>
 
 </composite>

Added: tuscany/sca-cpp/trunk/components/http/httppatch.cpp
URL: 
http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/http/httppatch.cpp?rev=1135047&view=auto
==============================================================================
--- tuscany/sca-cpp/trunk/components/http/httppatch.cpp (added)
+++ tuscany/sca-cpp/trunk/components/http/httppatch.cpp Mon Jun 13 07:57:13 2011
@@ -0,0 +1,93 @@
+/*
+ * 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 client component implementation.
+ */
+
+#include "string.hpp"
+#include "function.hpp"
+#include "list.hpp"
+#include "value.hpp"
+#include "monad.hpp"
+#include "../../modules/http/http.hpp"
+
+namespace tuscany {
+namespace httppatch {
+
+/**
+ * Evaluate an HTTP patch.
+ */
+const failable<value> get(const lambda<value(const list<value>&)> url, const 
lambda<value(const list<value>&)> val, http::CURLSession& ch) {
+    debug("httppatch::get");
+    const value u = url(mklist<value>("get", list<value>()));
+    const value v = val(mklist<value>("get", list<value>()));
+    debug(u, "httppatch::get::url");
+    debug(v, "httppatch::get::val");
+    return http::patch(v, u, ch);
+}
+
+/**
+ * Component implementation lambda function.
+ */
+class applyhttp {
+public:
+    applyhttp(const lambda<value(const list<value>&)> url, const 
lambda<value(const list<value>&)> val, http::CURLSession& ch) : url(url), 
val(val), ch(ch) {
+    }
+
+    const value operator()(const list<value>& params) const {
+        debug(params, "httppatch::applyhttp::params");
+        const value func(car(params));
+        if (func == "get")
+            return get(url, val, ch);
+        return tuscany::mkfailure<tuscany::value>();
+    }
+
+private:
+    const lambda<value(const list<value>&)> url;
+    const lambda<value(const list<value>&)> val;
+    http::CURLSession& ch;
+};
+
+/**
+ * Start the component.
+ */
+const failable<value> start(const list<value>& params) {
+    // Create a CURL session
+    http::CURLSession& ch = *(new (gc_new<http::CURLSession>()) 
http::CURLSession("", "", "", ""));
+
+    // Return the component implementation lambda function
+    return value(lambda<value(const list<value>&)>(applyhttp(car(params), 
cadr(params), ch)));
+}
+
+}
+}
+
+extern "C" {
+
+const tuscany::value apply(const tuscany::list<tuscany::value>& params) {
+    const tuscany::value func(car(params));
+    if (func == "start")
+        return tuscany::httppatch::start(cdr(params));
+    return tuscany::mkfailure<tuscany::value>();
+}
+
+}

Copied: tuscany/sca-cpp/trunk/components/http/httppost.componentType (from 
r1135046, tuscany/sca-cpp/trunk/components/http/http.composite)
URL: 
http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/http/httppost.componentType?p2=tuscany/sca-cpp/trunk/components/http/httppost.componentType&p1=tuscany/sca-cpp/trunk/components/http/http.composite&r1=1135046&r2=1135047&rev=1135047&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/http/http.composite (original)
+++ tuscany/sca-cpp/trunk/components/http/httppost.componentType Mon Jun 13 
07:57:13 2011
@@ -17,23 +17,13 @@
  * specific language governing permissions and limitations
  * under the License.    
 -->
-<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912";
-  targetNamespace="http://tuscany.apache.org/xmlns/sca/components";
-  name="http">
+<componentType xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912";
+  xmlns:xsd="http://www.w3.org/2001/XMLSchema";
+  xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1";
+  targetNamespace="http://tuscany.apache.org/xmlns/sca/components";>
         
-    <component name="httpget">
-        <implementation.cpp path="." library="libhttpget"/>
-        <service name="httpget">
-            <binding.http uri="httpget"/>
-        </service>
-        <reference name="url" target="url-test"/>
-    </component>
-
-    <component name="url-test">
-        <implementation.scheme script="url-test.scm"/>
-        <service name="url-test">
-            <binding.http uri="url-test"/>
-        </service>
-    </component>
+    <service name="http"/>
+    <reference name="url"/>
+    <reference name="content"/>
 
 </composite>

Added: tuscany/sca-cpp/trunk/components/http/httppost.cpp
URL: 
http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/http/httppost.cpp?rev=1135047&view=auto
==============================================================================
--- tuscany/sca-cpp/trunk/components/http/httppost.cpp (added)
+++ tuscany/sca-cpp/trunk/components/http/httppost.cpp Mon Jun 13 07:57:13 2011
@@ -0,0 +1,93 @@
+/*
+ * 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 client component implementation.
+ */
+
+#include "string.hpp"
+#include "function.hpp"
+#include "list.hpp"
+#include "value.hpp"
+#include "monad.hpp"
+#include "../../modules/http/http.hpp"
+
+namespace tuscany {
+namespace httppost {
+
+/**
+ * Evaluate an HTTP post.
+ */
+const failable<value> get(const lambda<value(const list<value>&)> url, const 
lambda<value(const list<value>&)> val, http::CURLSession& ch) {
+    debug("httppost::get");
+    const value u = url(mklist<value>("get", list<value>()));
+    const value v = val(mklist<value>("get", list<value>()));
+    debug(u, "httppost::get::url");
+    debug(v, "httppost::get::val");
+    return http::post(v, u, ch);
+}
+
+/**
+ * Component implementation lambda function.
+ */
+class applyhttp {
+public:
+    applyhttp(const lambda<value(const list<value>&)> url, const 
lambda<value(const list<value>&)> val, http::CURLSession& ch) : url(url), 
val(val), ch(ch) {
+    }
+
+    const value operator()(const list<value>& params) const {
+        debug(params, "httppost::applyhttp::params");
+        const value func(car(params));
+        if (func == "get")
+            return get(url, val, ch);
+        return tuscany::mkfailure<tuscany::value>();
+    }
+
+private:
+    const lambda<value(const list<value>&)> url;
+    const lambda<value(const list<value>&)> val;
+    http::CURLSession& ch;
+};
+
+/**
+ * Start the component.
+ */
+const failable<value> start(const list<value>& params) {
+    // Create a CURL session
+    http::CURLSession& ch = *(new (gc_new<http::CURLSession>()) 
http::CURLSession("", "", "", ""));
+
+    // Return the component implementation lambda function
+    return value(lambda<value(const list<value>&)>(applyhttp(car(params), 
cadr(params), ch)));
+}
+
+}
+}
+
+extern "C" {
+
+const tuscany::value apply(const tuscany::list<tuscany::value>& params) {
+    const tuscany::value func(car(params));
+    if (func == "start")
+        return tuscany::httppost::start(cdr(params));
+    return tuscany::mkfailure<tuscany::value>();
+}
+
+}

Copied: tuscany/sca-cpp/trunk/components/http/httpput.componentType (from 
r1135046, tuscany/sca-cpp/trunk/components/http/http.composite)
URL: 
http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/http/httpput.componentType?p2=tuscany/sca-cpp/trunk/components/http/httpput.componentType&p1=tuscany/sca-cpp/trunk/components/http/http.composite&r1=1135046&r2=1135047&rev=1135047&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/http/http.composite (original)
+++ tuscany/sca-cpp/trunk/components/http/httpput.componentType Mon Jun 13 
07:57:13 2011
@@ -17,23 +17,13 @@
  * specific language governing permissions and limitations
  * under the License.    
 -->
-<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912";
-  targetNamespace="http://tuscany.apache.org/xmlns/sca/components";
-  name="http">
+<componentType xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912";
+  xmlns:xsd="http://www.w3.org/2001/XMLSchema";
+  xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1";
+  targetNamespace="http://tuscany.apache.org/xmlns/sca/components";>
         
-    <component name="httpget">
-        <implementation.cpp path="." library="libhttpget"/>
-        <service name="httpget">
-            <binding.http uri="httpget"/>
-        </service>
-        <reference name="url" target="url-test"/>
-    </component>
-
-    <component name="url-test">
-        <implementation.scheme script="url-test.scm"/>
-        <service name="url-test">
-            <binding.http uri="url-test"/>
-        </service>
-    </component>
+    <service name="http"/>
+    <reference name="url"/>
+    <reference name="content"/>
 
 </composite>

Added: tuscany/sca-cpp/trunk/components/http/httpput.cpp
URL: 
http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/http/httpput.cpp?rev=1135047&view=auto
==============================================================================
--- tuscany/sca-cpp/trunk/components/http/httpput.cpp (added)
+++ tuscany/sca-cpp/trunk/components/http/httpput.cpp Mon Jun 13 07:57:13 2011
@@ -0,0 +1,93 @@
+/*
+ * 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 client component implementation.
+ */
+
+#include "string.hpp"
+#include "function.hpp"
+#include "list.hpp"
+#include "value.hpp"
+#include "monad.hpp"
+#include "../../modules/http/http.hpp"
+
+namespace tuscany {
+namespace httpput {
+
+/**
+ * Evaluate an HTTP put.
+ */
+const failable<value> get(const lambda<value(const list<value>&)> url, const 
lambda<value(const list<value>&)> val, http::CURLSession& ch) {
+    debug("httpput::get");
+    const value u = url(mklist<value>("get", list<value>()));
+    const value v = val(mklist<value>("get", list<value>()));
+    debug(u, "httpput::get::url");
+    debug(v, "httpput::get::val");
+    return http::put(v, u, ch);
+}
+
+/**
+ * Component implementation lambda function.
+ */
+class applyhttp {
+public:
+    applyhttp(const lambda<value(const list<value>&)> url, const 
lambda<value(const list<value>&)> val, http::CURLSession& ch) : url(url), 
val(val), ch(ch) {
+    }
+
+    const value operator()(const list<value>& params) const {
+        debug(params, "httpput::applyhttp::params");
+        const value func(car(params));
+        if (func == "get")
+            return get(url, val, ch);
+        return tuscany::mkfailure<tuscany::value>();
+    }
+
+private:
+    const lambda<value(const list<value>&)> url;
+    const lambda<value(const list<value>&)> val;
+    http::CURLSession& ch;
+};
+
+/**
+ * Start the component.
+ */
+const failable<value> start(const list<value>& params) {
+    // Create a CURL session
+    http::CURLSession& ch = *(new (gc_new<http::CURLSession>()) 
http::CURLSession("", "", "", ""));
+
+    // Return the component implementation lambda function
+    return value(lambda<value(const list<value>&)>(applyhttp(car(params), 
cadr(params), ch)));
+}
+
+}
+}
+
+extern "C" {
+
+const tuscany::value apply(const tuscany::list<tuscany::value>& params) {
+    const tuscany::value func(car(params));
+    if (func == "start")
+        return tuscany::httpput::start(cdr(params));
+    return tuscany::mkfailure<tuscany::value>();
+}
+
+}

Added: tuscany/sca-cpp/trunk/components/http/server-test.scm
URL: 
http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/http/server-test.scm?rev=1135047&view=auto
==============================================================================
--- tuscany/sca-cpp/trunk/components/http/server-test.scm (added)
+++ tuscany/sca-cpp/trunk/components/http/server-test.scm Mon Jun 13 07:57:13 
2011
@@ -0,0 +1,44 @@
+;  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.
+
+; JSON-RPC test case
+
+(define (echo x) x)
+
+; ATOMPub test case
+
+(define (get id)
+  (if (nul id)
+    '((feed (title "Sample Feed") (id "123456789") (entry
+       (((title "Item") (id "111") (content (item (name "Apple") (currencyCode 
"USD") (currencySymbol "$") (price 2.99))))
+        ((title "Item") (id "222") (content (item (name "Orange") 
(currencyCode "USD") (currencySymbol "$") (price 3.55))))
+        ((title "Item") (id "333") (content (item (name "Pear") (currencyCode 
"USD") (currencySymbol "$") (price 1.55))))))))
+    
+    (list (list 'entry '(title "Item") (list 'id (car id)) '(content (item 
(name "Apple") (currencyCode "USD") (currencySymbol "$") (price 2.99))))))
+)
+
+(define (post collection item)
+  '("123456789")
+)
+
+(define (put id item)
+  true
+)
+
+(define (delete id)
+  true
+)

Modified: tuscany/sca-cpp/trunk/components/http/url-test.scm
URL: 
http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/http/url-test.scm?rev=1135047&r1=1135046&r2=1135047&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/http/url-test.scm (original)
+++ tuscany/sca-cpp/trunk/components/http/url-test.scm Mon Jun 13 07:57:13 2011
@@ -18,6 +18,6 @@
 ; URL test case
 
 (define (get id)
-    "http://localhost:8090/index.html";
+    "http://localhost:8090/test";
 )
 

Modified: tuscany/sca-cpp/trunk/modules/edit/apps/testhttp/app.composite
URL: 
http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/edit/apps/testhttp/app.composite?rev=1135047&r1=1135046&r2=1135047&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/edit/apps/testhttp/app.composite (original)
+++ tuscany/sca-cpp/trunk/modules/edit/apps/testhttp/app.composite Mon Jun 13 
07:57:13 2011
@@ -1,22 +1,4 @@
 <?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.    
--->
 <composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912"; name="app" 
targetNamespace="http://app";>
  <service name="call" promote="call"/>
  <service name="get" promote="get"/>
@@ -25,9 +7,9 @@
  <service name="get4" promote="get4"/>
  <service name="get5" promote="get5"/>
  <service name="get6" promote="get6"/>
- <service name="parse" promote="parse"/>
  <service name="item" promote="property"/>
- <component x="36" y="287" name="call" title="call" color="green1">
+ <service name="parse" promote="parse"/>
+ <component x="20" y="300" name="call" title="call" color="green1">
   <implementation.python script="nuvem/call.py"/>
   <service name="call"/>
   <reference target="name" name="name"/>
@@ -38,32 +20,38 @@
   <service name="first"/>
   <reference target="rest" name="list"/>
  </component>
- <component x="20" y="8" name="get" title="get" color="green1">
+ <component x="750" y="320" name="format1" title="format" color="magenta1">
+  <implementation.python script="nuvem/format_.py"/>
+  <service name="format"/>
+  <reference target="text12" name="pattern"/>
+  <reference target="list2" name="values"/>
+ </component>
+ <component x="20" y="0" name="get" title="get" color="green1">
   <implementation.cpp path="lib/http" library="libhttpget"/>
   <service name="get"/>
   <reference target="text" name="url"/>
  </component>
- <component x="18" y="61" name="get2" title="get" color="green1">
+ <component x="20" y="70" name="get2" title="get" color="green1">
   <implementation.cpp path="lib/http" library="libhttpget"/>
   <service name="get"/>
   <reference target="text2" name="url"/>
  </component>
- <component x="14" y="112" name="get3" title="get" color="green1">
+ <component x="20" y="150" name="get3" title="get" color="green1">
   <implementation.cpp path="lib/http" library="libhttpget"/>
   <service name="get"/>
   <reference target="text3" name="url"/>
  </component>
- <component x="19" y="170" name="get4" title="get" color="green1">
+ <component x="370" y="0" name="get4" title="get" color="green1">
   <implementation.cpp path="lib/http" library="libhttpget"/>
   <service name="get"/>
   <reference target="text4" name="url"/>
  </component>
- <component x="241" y="6" name="get5" title="get" color="green1">
+ <component x="230" y="0" name="get5" title="get" color="green1">
   <implementation.cpp path="lib/http" library="libhttpget"/>
   <service name="get"/>
   <reference target="text5" name="url"/>
  </component>
- <component x="16" y="227" name="get6" title="get" color="green1">
+ <component x="20" y="220" name="get6" title="get" color="green1">
   <implementation.cpp path="lib/http" library="libhttpget"/>
   <service name="get"/>
   <reference target="text6" name="url"/>
@@ -73,12 +61,42 @@
   <service name="get"/>
   <reference target="text7" name="url"/>
  </component>
+ <component name="item2" title="{propval} :" color="orange1">
+  <implementation.python script="nuvem/item.py"/>
+  <service name="item"/>
+  <reference target="user" name="value"/>
+  <property>user</property>
+ </component>
+ <component name="item3" title="{propval} :" color="orange1">
+  <implementation.python script="nuvem/item.py"/>
+  <service name="item"/>
+  <reference target="params" name="value"/>
+  <property>name</property>
+ </component>
  <component name="join" title="join" color="magenta1">
   <implementation.python script="nuvem/join.py"/>
   <service name="join"/>
   <reference target="text9" name="separator"/>
   <reference target="first" name="list"/>
  </component>
+ <component x="570" y="350" name="keychain1" title="keychain" color="green1">
+  <implementation.python script="nuvem/keychain.py"/>
+  <service name="keychain"/>
+  <reference target="name1" name="name"/>
+  <reference name="account" target="Accounts" visible="false"/>
+ </component>
+ <component x="710" y="290" name="keychain2" title="keychain" color="green1">
+  <implementation.python script="nuvem/keychain.py"/>
+  <service name="keychain"/>
+  <reference target="name2" name="name"/>
+  <reference name="account" target="Accounts" visible="false"/>
+ </component>
+ <component x="720" y="310" name="keychain3" title="keychain" color="green1">
+  <implementation.python script="nuvem/keychain.py"/>
+  <service name="keychain"/>
+  <reference target="name3" name="name"/>
+  <reference name="account" target="Accounts" visible="false"/>
+ </component>
  <component name="list" title="list" color="yellow1">
   <implementation.python script="nuvem/list_.py"/>
   <service name="list"/>
@@ -86,40 +104,64 @@
   <reference target="item3" name="item" clonable="true"/>
   <reference name="item" clonable="true"/>
  </component>
+ <component name="list1" title="list" color="yellow1">
+  <implementation.python script="nuvem/list_.py"/>
+  <service name="list"/>
+  <reference target="keychain1" name="item" clonable="true"/>
+  <reference target="text10" name="item" clonable="true"/>
+  <reference name="item" clonable="true"/>
+ </component>
+ <component name="list2" title="list" color="yellow1">
+  <implementation.python script="nuvem/list_.py"/>
+  <service name="list"/>
+  <reference target="text11" name="item" clonable="true"/>
+  <reference target="text13" name="item" clonable="true"/>
+  <reference target="text14" name="item" clonable="true"/>
+  <reference name="item" clonable="true"/>
+ </component>
+ <component name="list4" title="list" color="yellow1">
+  <implementation.python script="nuvem/list_.py"/>
+  <service name="list"/>
+  <reference target="format1" name="item" clonable="true"/>
+  <reference name="item" clonable="true"/>
+ </component>
  <component name="name" title="" color="orange1">
   <implementation.python script="nuvem/name.py"/>
   <service name="name"/>
   <property>https://testhttp.sca-store.com:8453/components/property</property>
  </component>
+ <component x="630" y="350" name="name1" title="" color="orange1">
+  <implementation.python script="nuvem/name.py"/>
+  <service name="name"/>
+  <property>twilliosid</property>
+ </component>
+ <component x="780" y="280" name="name2" title="" color="orange1">
+  <implementation.python script="nuvem/name.py"/>
+  <service name="name"/>
+  <property>twilliosid</property>
+ </component>
+ <component x="780" y="320" name="name3" title="" color="orange1">
+  <implementation.python script="nuvem/name.py"/>
+  <service name="name"/>
+  <property>twilliotoken</property>
+ </component>
  <component name="params" title="?params" color="green1">
   <implementation.python script="nuvem/params.py"/>
   <service name="params"/>
   <property name="query" visible="false"/>
  </component>
- <component x="597" y="167" name="parse" title="parse" color="magenta1">
+ <component x="410" y="290" name="parse" title="parse" color="magenta1">
   <implementation.python script="nuvem/parse.py"/>
   <service name="parse"/>
   <reference target="text8" name="regexp"/>
   <reference target="join" name="string"/>
  </component>
- <component x="74" y="343" name="property" title="{propval} :" color="orange1">
+ <component x="20" y="370" name="property" title="{propval} :" color="orange1">
   <implementation.python script="nuvem/item.py"/>
   <service name="item"/>
   <reference target="list" name="value"/>
   <property>test</property>
  </component>
- <component name="item2" title="{propval} :" color="orange1">
-  <implementation.python script="nuvem/item.py"/>
-  <service name="item"/>
-  <reference target="user" name="value"/>
-  <property>user</property>
- </component>
- <component name="item3" title="{propval} :" color="orange1">
-  <implementation.python script="nuvem/item.py"/>
-  <service name="item"/>
-  <reference target="params" name="value"/>
-  <property>name</property>
- </component>
  <component name="rest" title="rest" color="yellow1">
   <implementation.python script="nuvem/rest.py"/>
   <service name="rest"/>
@@ -130,6 +172,41 @@
   <service name="text"/>
   <property>http://www.google.com</property>
  </component>
+ <component x="530" y="320" name="text1" title=" '{propval}'" color="orange1">
+  <implementation.python script="nuvem/text.py"/>
+  <service name="text"/>
+  <property>https://api.twilio.com/2010-04-01/Accounts/</property>
+ </component>
+ <component x="570" y="390" name="text10" title=" '{propval}'" color="orange1">
+  <implementation.python script="nuvem/text.py"/>
+  <service name="text"/>
+  <property>SMS/Messages</property>
+ </component>
+ <component x="580" y="480" name="text11" title=" '{propval}'" color="orange1">
+  <implementation.python script="nuvem/text.py"/>
+  <service name="text"/>
+  <property>+14155992671</property>
+ </component>
+ <component x="550" y="450" name="text12" title=" '{propval}'" color="orange1">
+  <implementation.python script="nuvem/text.py"/>
+  <service name="text"/>
+  <property>From={0}&amp;To={1}&amp;Body={2}</property>
+ </component>
+ <component x="700" y="340" name="text13" title=" '{propval}'" color="orange1">
+  <implementation.python script="nuvem/text.py"/>
+  <service name="text"/>
+  <property>+16508632924</property>
+ </component>
+ <component x="690" y="370" name="text14" title=" '{propval}'" color="orange1">
+  <implementation.python script="nuvem/text.py"/>
+  <service name="text"/>
+  <property>This is a text message</property>
+ </component>
+ <component x="710" y="290" name="text15" title=" '{propval}'" color="orange1">
+  <implementation.python script="nuvem/text.py"/>
+  <service name="text"/>
+  <property>application/x-www-form-urlencoded</property>
+ </component>
  <component name="text2" title=" '{propval}'" color="orange1">
   <implementation.python script="nuvem/text.py"/>
   <service name="text"/>

Modified: tuscany/sca-cpp/trunk/modules/edit/palettes/http/palette.composite
URL: 
http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/edit/palettes/http/palette.composite?rev=1135047&r1=1135046&r2=1135047&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/edit/palettes/http/palette.composite 
(original)
+++ tuscany/sca-cpp/trunk/modules/edit/palettes/http/palette.composite Mon Jun 
13 07:57:13 2011
@@ -7,22 +7,23 @@
  <service name="keychain" promote="keychain"/>
  <service name="param" promote="param"/>
  <service name="params" promote="params"/>
+ <service name="patch" promote="patch"/>
  <service name="path" promote="path"/>
  <service name="post" promote="post"/>
  <service name="put" promote="put"/>
  <service name="url" promote="url"/>
  <service name="user" promote="user"/>
- <component x="180" y="230" name="delete" title="delete" color="green1">
+ <component x="90" y="240" name="delete" title="delete" color="green1">
   <implementation.cpp path="lib/http" library="libhttpdelete"/>
   <service name="delete"/>
   <reference name="url"/>
  </component>
- <component x="160" y="110" name="email" title="email" color="green1">
+ <component x="250" y="60" name="email" title="email" color="green1">
   <implementation.python script="nuvem/email.py"/>
   <service name="email"/>
   <property name="email" visible="false"/>
  </component>
- <component x="150" y="160" name="get" title="get" color="green1">
+ <component x="90" y="170" name="get" title="get" color="green1">
   <implementation.cpp path="lib/http" library="libhttpget"/>
   <service name="get"/>
   <reference name="url"/>
@@ -32,47 +33,53 @@
   <service name="host"/>
   <property name="host" visible="false"/>
  </component>
- <component x="230" y="110" name="keychain" title="keychain" color="green1">
+ <component x="90" y="110" name="keychain" title="keychain" color="green1">
   <implementation.python script="nuvem/keychain.py"/>
   <service name="keychain"/>
   <reference name="name"/>
   <reference name="account" target="Accounts" visible="false"/>
  </component>
- <component x="180" y="60" name="param" title="?param" color="green1">
+ <component x="90" y="60" name="param" title="?param" color="green1">
   <implementation.python script="nuvem/param.py"/>
   <service name="param"/>
   <property>x</property>
   <property name="query" visible="false"/>
  </component>
- <component x="90" y="60" name="params" title="?params" color="green1">
+ <component x="230" y="10" name="params" title="?params" color="green1">
   <implementation.python script="nuvem/params.py"/>
   <service name="params"/>
   <property name="query" visible="false"/>
  </component>
+ <component x="170" y="240" name="patch" title="patch" color="green1">
+  <implementation.cpp path="lib/http" library="libhttppatch"/>
+  <service name="patch"/>
+  <reference name="url"/>
+  <reference name="content"/>
+ </component>
  <component x="160" y="10" name="path" title="path" color="green1">
   <implementation.python script="nuvem/path.py"/>
   <service name="path"/>
   <property name="path" visible="false"/>
  </component>
- <component x="90" y="230" name="post" title="post **" color="green1">
+ <component x="230" y="170" name="post" title="post" color="green1">
   <implementation.cpp path="lib/http" library="libhttppost"/>
   <service name="post"/>
   <reference name="url"/>
   <reference name="content"/>
  </component>
- <component x="220" y="160" name="put" title="put **" color="green1">
+ <component x="160" y="170" name="put" title="put" color="green1">
   <implementation.cpp path="lib/http" library="libhttpput"/>
   <service name="put"/>
   <reference name="url"/>
   <reference name="content"/>
  </component>
- <component x="90" y="160" name="url" title="url" color="green1">
+ <component x="190" y="110" name="url" title="url" color="green1">
   <implementation.python script="nuvem/url.py"/>
   <service name="url"/>
   <reference name="address"/>
   <reference name="args"/>
  </component>
- <component x="90" y="110" name="user" title="user" color="green1">
+ <component x="180" y="60" name="user" title="user" color="green1">
   <implementation.python script="nuvem/user.py"/>
   <service name="user"/>
   <property name="user" visible="false"/>

Modified: tuscany/sca-cpp/trunk/modules/http/http.hpp
URL: 
http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/http/http.hpp?rev=1135047&r1=1135046&r2=1135047&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/http/http.hpp (original)
+++ tuscany/sca-cpp/trunk/modules/http/http.hpp Mon Jun 13 07:57:13 2011
@@ -44,6 +44,7 @@
 #include "element.hpp"
 #include "monad.hpp"
 #include "parallel.hpp"
+#include "../scheme/io.hpp"
 #include "../atom/atom.hpp"
 #include "../rss/rss.hpp"
 #include "../json/json.hpp"
@@ -187,6 +188,13 @@ const string escapeArg(const string& arg
 }
 
 /**
+ * Return true if a URI is absolute.
+ */
+const bool isAbsolute(const string& uri) {
+    return contains(uri, "://");
+}
+
+/**
  * Parse a URI and return its host name.
  */
 const string hostName(const string& uri, const gc_pool& p) {
@@ -200,6 +208,19 @@ const string hostName(const string& uri,
 }
 
 /**
+ * Parse a URI and return its scheme.
+ */
+const string scheme(const string& uri, const gc_pool& p) {
+    apr_uri_t u;
+    const apr_status_t rc = apr_uri_parse(pool(p), c_str(uri), &u);
+    if (rc != APR_SUCCESS)
+        return "";
+    if (u.scheme == NULL)
+        return "";
+    return u.scheme;
+}
+
+/**
  * Return the first subdomain name in a host name.
  */
 const string subDomain(const string& host) {
@@ -223,6 +244,9 @@ const failable<CURL*> setup(const string
     CURL* ch = handle(cs);
     curl_easy_reset(ch);
     curl_easy_setopt(ch, CURLOPT_USERAGENT, "libcurl/1.0");
+#ifdef WANT_MAINTAINER_MODE
+    curl_easy_setopt(ch, CURLOPT_VERBOSE, true);
+#endif
 
     // Setup protocol options
     curl_easy_setopt(ch, CURLOPT_TCP_NODELAY, true);
@@ -252,6 +276,29 @@ const failable<CURL*> setup(const string
         curl_easy_setopt(ch, CURLOPT_COOKIE, c_str(cs.cookie));
     }
 
+    // Set up HTTP basic auth if requested
+    apr_uri_t u;
+    apr_pool_t* p = gc_current_pool();
+    const apr_status_t prc = apr_uri_parse(p, c_str(url), &u);
+    if (prc == APR_SUCCESS) {
+        if (u.user != NULL) {
+            debug(u.user, "http::setup::user");
+            curl_easy_setopt(ch, CURLOPT_USERNAME, u.user);
+        }
+        if (u.password != NULL) {
+            debug(u.password, "http::setup::pass");
+            curl_easy_setopt(ch, CURLOPT_PASSWORD, u.password);
+        }
+        if (u.user != NULL || u.password != NULL) {
+            curl_easy_setopt(ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
+            
+            // Set target URL, omitting the user:password part
+            curl_easy_setopt(ch, CURLOPT_URL, 
c_str(escapeURI(apr_uri_unparse(p, &u, APR_URI_UNP_OMITUSERINFO))));
+
+            return ch;
+        }
+    }
+
     // Set target URL
     curl_easy_setopt(ch, CURLOPT_URL, c_str(escapeURI(url)));
 
@@ -353,6 +400,10 @@ template<typename R> const failable<list
     } else if (verb == "PUT") {
         curl_easy_setopt(ch, CURLOPT_UPLOAD, true);
         curl_easy_setopt(ch, CURLOPT_INFILESIZE, sz);
+    } else if (verb == "PATCH") {
+        curl_easy_setopt(ch, CURLOPT_UPLOAD, true);
+        curl_easy_setopt(ch, CURLOPT_CUSTOMREQUEST, "PATCH");
+        curl_easy_setopt(ch, CURLOPT_INFILESIZE, sz);
     } else if (verb == "DELETE")
         curl_easy_setopt(ch, CURLOPT_CUSTOMREQUEST, "DELETE");
     const CURLcode rc = curl_easy_perform(ch);
@@ -424,9 +475,9 @@ const failable<string> location(const li
 /**
  * Convert a location to an entry id.
  */
-const failable<value> entryId(const failable<string> l) {
+const value entryId(const failable<string> l) {
     if (!hasContent(l))
-        return mkfailure<value>(reason(l));
+        return list<value>();
     const string ls(content(l));
     return value(mklist<value>(string(substr(ls, find_last(ls, '/') + 1))));
 }
@@ -536,26 +587,107 @@ const failable<value> get(const string& 
 }
 
 /**
+ * Form an HTTP content request.
+ */
+const failable<list<list<string> > > writeRequest(const failable<list<string> 
>& ls, const string& ct) {
+    if (!hasContent(ls))
+        return mkfailure<list<list<string> > >(reason(ls));
+    const list<list<string> > req =  mklist<list<string> 
>(mklist<string>(string("Content-Type: ") + ct), content(ls));
+    debug(req, "http::writeRequest::req");
+    return req;
+}
+
+/**
+ * Convert a value to an HTTP content request.
+ */
+const failable<list<list<string> > > contentRequest(const value& c, unused 
const string& url) {
+
+    // Check if the client requested a specific format
+    //TODO derive that from given URL
+    const list<value> fmt = assoc<value>("format", list<value>());
+
+    // Write as a scheme value if requested by the client
+    if (!isNil(fmt) && cadr(fmt) == "scheme")
+        return writeRequest(mklist<string>(scheme::writeValue(c)), 
"text/plain; charset=utf-8");
+
+    // Write a simple value as a JSON value
+    if (!isList(c)) {
+        js::JSContext cx;
+        if (isSymbol(c)) {
+            const list<value> lc = mklist<value>(mklist<value>("name", 
value(string(c))));
+            debug(lc, "http::contentRequest::symbol");
+            return writeRequest(json::writeJSON(valuesToElements(lc), cx), 
"application/json; charset=utf-8");
+        }
+        const list<value> lc = mklist<value>(mklist<value>("value", c));
+        debug(lc, "http::contentRequest::value");
+        return writeRequest(json::writeJSON(valuesToElements(lc), cx), 
"application/json; charset=utf-8");
+    }
+
+    // Write an empty list as a JSON empty value
+    if (isNil((list<value>)c)) {
+        js::JSContext cx;
+        debug(list<value>(), "http::contentRequest::empty");
+        return writeRequest(json::writeJSON(list<value>(), cx), 
"application/json; charset=utf-8");
+    }
+
+    // Write content-type / content-list pair
+    if (isString(car<value>(c)) && !isNil(cdr<value>(c)) && 
isList(cadr<value>(c)))
+        return writeRequest(convertValues<string>(cadr<value>(c)), 
car<value>(c));
+
+    // Write an assoc value as a JSON result
+    if (isSymbol(car<value>(c)) && !isNil(cdr<value>(c))) {
+        js::JSContext cx;
+        const list<value> lc = mklist<value>(c);
+        debug(lc, "http::contentRequest::assoc");
+        debug(valuesToElements(lc), "http::contentRequest::assoc::element");
+        return writeRequest(json::writeJSON(valuesToElements(lc), cx), 
"application/json; charset=utf-8");
+    }
+
+    // Write value as JSON if requested by the client
+    if (!isNil(fmt) && cadr(fmt) == "json") {
+        js::JSContext cx;
+        return writeRequest(json::writeJSON(valuesToElements(c), cx), 
"application/json; charset=utf-8");
+    }
+
+    // Convert list of values to element values
+    const list<value> e = valuesToElements(c);
+    debug(e, "http::contentRequest::elements");
+
+    // Write an ATOM feed or entry
+    if (isList(car<value>(e)) && !isNil(car<value>(e))) {
+        const list<value> el = car<value>(e);
+        if (isSymbol(car<value>(el)) && car<value>(el) == element && 
!isNil(cdr<value>(el)) && isSymbol(cadr<value>(el)) && elementHasChildren(el) 
&& !elementHasValue(el)) {
+            if (cadr<value>(el) == atom::feed)
+                return writeRequest(atom::writeATOMFeed(e), 
"application/atom+xml; charset=utf-8");
+            if (cadr<value>(el) == atom::entry)
+                return writeRequest(atom::writeATOMEntry(e), 
"application/atom+xml; charset=utf-8");
+        }
+    }
+
+    // Write any other compound value as a JSON value
+    js::JSContext cx;
+    return writeRequest(json::writeJSON(e, cx), "application/json; 
charset=utf-8");
+}
+
+/**
  * HTTP POST.
  */
 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(valuesToElements(val));
-    if (!hasContent(entry))
-        return mkfailure<value>(reason(entry));
     debug(url, "http::post::url");
-    debug(content(entry), "http::post::input");
+
+    // Convert value to a content request
+    const failable<list<list<string> > > req = contentRequest(val, url);
+    if (!hasContent(req))
+        return mkfailure<value>(reason(req));
+    debug(content(req), "http::post::input");
 
     // 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", cs);
+    const failable<list<list<string> > > res = 
apply<list<string>>(content(req), rcons<string>, list<string>(), url, "POST", 
cs);
     if (!hasContent(res))
         return mkfailure<value>(reason(res));
 
-    // Return the new entry id from the HTTP location header
-    const failable<value> eid(entryId(location(car(content(res)))));
+    // Return the new entry id from the HTTP location header, if any
+    const value eid(entryId(location(car(content(res)))));
     debug(eid, "http::post::result");
     return eid;
 }
@@ -564,18 +696,16 @@ const failable<value> post(const value& 
  * HTTP PUT.
  */
 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(valuesToElements(val));
-    if (!hasContent(entry))
-        return mkfailure<value>(reason(entry));
     debug(url, "http::put::url");
-    debug(content(entry), "http::put::input");
+
+    // Convert value to a content request
+    const failable<list<list<string> > > req = contentRequest(val, url);
+    if (!hasContent(req))
+        return mkfailure<value>(reason(req));
+    debug(content(req), "http::put::input");
 
     // 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", cs);
+    const failable<list<list<string> > > res = apply<list<string> 
>(content(req), rcons<string>, list<string>(), url, "PUT", cs);
     if (!hasContent(res))
         return mkfailure<value>(reason(res));
 
@@ -584,6 +714,27 @@ const failable<value> put(const value& v
 }
 
 /**
+ * HTTP PATCH.
+ */
+const failable<value> patch(const value& val, const string& url, const 
CURLSession& cs) {
+    debug(url, "http::put::patch");
+
+    // Convert value to a content request
+    const failable<list<list<string> > > req = contentRequest(val, url);
+    if (!hasContent(req))
+        return mkfailure<value>(reason(req));
+    debug(content(req), "http::patch::input");
+
+    // PATCH it to the URL
+    const failable<list<list<string> > > res = apply<list<string> 
>(content(req), rcons<string>, list<string>(), url, "PATCH", cs);
+    if (!hasContent(res))
+        return mkfailure<value>(reason(res));
+
+    debug(true, "http::patch::result");
+    return value(true);
+}
+
+/**
  * HTTP DELETE.
  */
 const failable<value, string> del(const string& url, const CURLSession& cs) {
@@ -778,6 +929,10 @@ struct proxy {
             const failable<value> val = put(caddr(args), uri + 
path(cadr(args)), cs);
             return content(val);
         }
+        if (fun == "patch") {
+            const failable<value> val = patch(caddr(args), uri + 
path(cadr(args)), cs);
+            return content(val);
+        }
         if (fun == "delete") {
             const failable<value> val = del(uri + path(cadr(args)), cs);
             return content(val);

Modified: tuscany/sca-cpp/trunk/modules/http/httpd.hpp
URL: 
http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/http/httpd.hpp?rev=1135047&r1=1135046&r2=1135047&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/http/httpd.hpp (original)
+++ tuscany/sca-cpp/trunk/modules/http/httpd.hpp Mon Jun 13 07:57:13 2011
@@ -152,13 +152,6 @@ const bool isVirtualHostRequest(const se
 }
 
 /**
- * Return true if a URI is absolute.
- */
-const bool isAbsolute(const string& uri) {
-    return contains(uri, "://");
-}
-
-/**
  * Return the protocol scheme for a server.
  */
 const string scheme(const server_rec* s, const string& def = "http") {
@@ -173,6 +166,20 @@ const string scheme(request_rec* r, cons
 }
 
 /**
+ * Return the port number for a server.
+ */
+const int port(const server_rec* s, const int def = 80) {
+    return s->port != 0? s->port : def;
+}
+
+/**
+ * Return the port number from an HTTP request.
+ */
+const int port(request_rec* r, const int def = 80) {
+    return r->server->port != 0? r->server->port : def;
+}
+
+/**
  * Return the content type of a request.
  */
 const string contentType(const request_rec* r) {

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=1135047&r1=1135046&r2=1135047&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/server/mod-eval.hpp (original)
+++ tuscany/sca-cpp/trunk/modules/server/mod-eval.hpp Mon Jun 13 07:57:13 2011
@@ -389,12 +389,22 @@ public:
             debug(uri, "modeval::implProxy::wiredByImpl::uri");
             debug(aparams, "modeval::implProxy::wiredByImpl::input");
 
-            // Use an HTTP proxy if the target is an absolute http:// target
-            if (httpd::isAbsolute(uri)) {
+            // Use an HTTP proxy if the target is an absolute :// target
+            if (http::isAbsolute(uri)) {
                 gc_pool p(currentRequest->pool);
+
+                // Interpret a uri in the form app://appname, convert it using 
the scheme,
+                // top level domain and port number from the current request
+                if (http::scheme(uri, p) == "app") {
+                    ostringstream appuri;
+                    appuri << httpd::scheme(currentRequest) << "://" << 
substr(uri, 6) << "." << http::topDomain(httpd::hostName(currentRequest)) << 
":" << httpd::port(currentRequest) << "/";
+                    debug(str(appuri), 
"modeval::implProxy::httpproxy::appuri");
+                    const lambda<value(const list<value>&)> px = 
lambda<value(const list<value>&)>(http::proxy(str(appuri), sc.ca, sc.cert, 
sc.key, httpd::cookie(currentRequest), p));
+                    return px(aparams);
+                }
                 
                 // Pass our certificate and the cookie from the current request
-                // if the target is in the same domain
+                // only if the target is in the same top level domain
                 if (http::topDomain(http::hostName(uri, p)) == 
http::topDomain(httpd::hostName(currentRequest))) {
                     debug(uri, "modeval::implProxy::httpproxy::samedomain");
                     const lambda<value(const list<value>&)> px = 
lambda<value(const list<value>&)>(http::proxy(uri, sc.ca, sc.cert, sc.key, 
httpd::cookie(currentRequest), p));
@@ -474,7 +484,7 @@ const value mkrefProxy(const ServerConf&
         return mkimplProxy(sc, value());
     if (isNil(target))
         return mkunwiredProxy(scdl::name(ref));
-    if (httpd::isAbsolute(target))
+    if (http::isAbsolute(target))
         return mkhttpProxy(sc, target);
     return mkimplProxy(sc, car(pathValues(target)));
 }

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=1135047&r1=1135046&r2=1135047&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/server/mod-wiring.cpp (original)
+++ tuscany/sca-cpp/trunk/modules/server/mod-wiring.cpp Mon Jun 13 07:57:13 2011
@@ -106,11 +106,10 @@ int translateReference(const ServerConf&
 
     // Route to an absolute target URI using mod_proxy or an HTTP client 
redirect
     const list<value> pathInfo = cdddr(rpath);
-    if (httpd::isAbsolute(target)) {
+    if (http::isAbsolute(target)) {
         if (useModProxy) {
             // Build proxy URI
-            // current request's protocol scheme, reference target uri and 
request path info
-            string turi = httpd::scheme(r) + substr(target, find(target, 
"://")) + path(pathInfo) + (r->args != NULL? string("?") + r->args : 
string(""));
+            string turi = target + path(pathInfo) + (r->args != NULL? 
string("?") + r->args : string(""));
             r->filename = apr_pstrdup(r->pool, c_str(string("proxy:") + turi));
             debug(r->filename, "modwiring::translateReference::filename");
             r->proxyreq = PROXYREQ_REVERSE;


Reply via email to