← Back to team overview

zorba-coders team mailing list archive

[Merge] lp:~zorba-coders/zorba/http-module into lp:zorba

 

Federico Cavalieri has proposed merging lp:~zorba-coders/zorba/http-module into lp:zorba.

Requested reviews:
  Cezar Andrei (cezar-andrei)

For more details, see:
https://code.launchpad.net/~zorba-coders/zorba/http-module/+merge/169579

JSON HTTP Client Module
-- 
https://code.launchpad.net/~zorba-coders/zorba/http-module/+merge/169579
Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'modules/CMakeLists.txt'
--- modules/CMakeLists.txt	2013-02-07 17:24:36 +0000
+++ modules/CMakeLists.txt	2013-06-15 00:58:33 +0000
@@ -17,6 +17,7 @@
 ADD_SUBDIRECTORY(functx)
 ADD_SUBDIRECTORY(xqxq)
 ADD_SUBDIRECTORY(w3c)
+ADD_SUBDIRECTORY(io)
 
 # Add external module projects - any subdirectories of a directory
 # named "zorba_modules" as a sibling to the main Zorba source

=== added directory 'modules/io'
=== added file 'modules/io/CMakeLists.txt'
--- modules/io/CMakeLists.txt	1970-01-01 00:00:00 +0000
+++ modules/io/CMakeLists.txt	2013-06-15 00:58:33 +0000
@@ -0,0 +1,14 @@
+# Copyright 2006-2013 The FLWOR Foundation.
+# 
+# Licensed 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.
+ADD_SUBDIRECTORY(zorba)

=== added directory 'modules/io/zorba'
=== added file 'modules/io/zorba/CMakeLists.txt'
--- modules/io/zorba/CMakeLists.txt	1970-01-01 00:00:00 +0000
+++ modules/io/zorba/CMakeLists.txt	2013-06-15 00:58:33 +0000
@@ -0,0 +1,14 @@
+# Copyright 2006-2013 The FLWOR Foundation.
+# 
+# Licensed 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.
+ADD_SUBDIRECTORY(modules)

=== added directory 'modules/io/zorba/modules'
=== added file 'modules/io/zorba/modules/CMakeLists.txt'
--- modules/io/zorba/modules/CMakeLists.txt	1970-01-01 00:00:00 +0000
+++ modules/io/zorba/modules/CMakeLists.txt	2013-06-15 00:58:33 +0000
@@ -0,0 +1,58 @@
+# Copyright 2006-2013 The FLWOR Foundation.
+# 
+# Licensed 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.
+
+
+#
+# cURL
+#
+SET (CURL_FOUND)
+IF(ZORBA_SUPPRESS_CURL)
+  MESSAGE(STATUS "ZORBA_SUPPRESS_CURL is true - not searching for cURL library")
+ELSE(ZORBA_SUPPRESS_CURL)
+  MESSAGE(STATUS "Looking for cURL")
+  FIND_PACKAGE(CURL)
+
+  IF(CURL_FOUND)
+    MESSAGE(STATUS "Found cURL library -- " ${CURL_LIBRARIES})
+    INCLUDE_DIRECTORIES(${CURL_INCLUDE_DIR})
+    #DECLARE_ZORBA_MODULE(FILE http-client-error.xq
+      #URI "http://expath.org/ns/error";)
+    DECLARE_ZORBA_MODULE(FILE http-client.xq VERSION 1.0
+      URI "http://zorba.io/modules/http-client";
+      LINK_LIBRARIES ${CURL_LIBRARIES})
+    
+    IF (WIN32) # Copy certificates for windows only
+      IF (MSVC_IDE)
+        SET(CACERT_DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/../../../../../bin/${CMAKE_BUILD_TYPE}/cacert.pem")
+      ELSE (MSVC_IDE)
+        SET(CACERT_DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/../../../../../bin/cacert.pem")       
+      ENDIF (MSVC_IDE)
+      CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/cacert.pem" ${CACERT_DESTINATION} COPYONLY)
+      INSTALL(FILES ${CACERT_DESTINATION} DESTINATION bin)
+    ENDIF (WIN32) 
+    
+  ELSE(CURL_FOUND)
+    MESSAGE(STATUS "The cURL library was not found - http-client will not be built")
+  ENDIF(CURL_FOUND)
+ENDIF(ZORBA_SUPPRESS_CURL)
+SET(ZORBA_HAVE_CURL ${CURL_FOUND} CACHE BOOL "Whether Zorba found cURL" FORCE)
+MARK_AS_ADVANCED(ZORBA_HAVE_CURL)
+
+# error and warning modules
+#DECLARE_ZORBA_MODULE (FILE pregenerated/errors.xq
+  #URI "http://www.zorba-xquery.com/errors";
+#)
+#DECLARE_ZORBA_MODULE (FILE pregenerated/warnings.xq
+  #URI "http://www.zorba-xquery.com/warnings";
+#)

=== added file 'modules/io/zorba/modules/http-client.jsound'
--- modules/io/zorba/modules/http-client.jsound	1970-01-01 00:00:00 +0000
+++ modules/io/zorba/modules/http-client.jsound	2013-06-15 00:58:33 +0000
@@ -0,0 +1,215 @@
+{
+  "$namespace": "http://zorba.io/modules/http-client";,
+  "$about": "This JSound schema defines the types of requests and
+             responses used in the http://28.io/http-client module",
+  "$types": [
+    {
+	  "$kind": "object",
+	  "$name": "headers",
+	  "$about": "This type represents a set of headers. Each header is represented
+	             by a different name-value pair.",
+	  "$constraints" : "every $key in keys($$) satisfies $$.$key instance of string"
+	  
+    },
+    {
+	  "$kind": "object",
+	  "$name": "body",
+	  "$about": "This type represents the body of an HTTP request or an HTTP 
+	             response. In multi-part requests and responses, it represents the
+				 body of a single part.",
+	  "$content": {
+	    "media-type": {
+		   "$type": "string",
+		   "$about": "This field is the media type of the body."
+		 },
+        "src": {
+		   "$type": "anyURI",
+		   "$about": "This field, used only in HTTP requests, is used to specify the URL at
+		              which the request can be found. It is mutually exclusive with the content
+		              field.",
+		   "$optional": true
+		 },
+ 		"content": {
+		  "$type": "string",
+		  "$about": "The HTTP request or response body.  It is mutually exclusive with the src
+		              field.",
+		  "$optional": true
+		  }
+	   },
+	   "$constraints" : "count($$.src) + count($$.content) le 1"      
+    },
+	{
+	  "$kind": "object",
+	  "$name": "part",
+	  "$about": "This type represents each single part of a multipart HTTP request or 
+                 response.",
+	  "$content": {
+	    "headers": {
+		  "$type": "headers",		  
+		  "$optional": true,
+		  "$about": "This field specifies the part headers."
+		},
+		"body": {"$type": "body"}
+	  }
+	},
+	{
+	   "$kind": "object",
+	   "$name": "multipart",
+	   "$about": "This type represents a multipart HTTP request or response.",
+	   "$content": {
+	     "media-type": {
+		   "$type": "string"
+		   "$about": "The media-type attribute is the media type of the request or 
+		              response, and has to be a multipart media type (that is, its
+                      main type must be multipart)."
+		},
+		 "boundary": {
+		   "$type": "string",
+		   "$optional": true,
+		   "$about": "The boundary attribute is the boundary marker used to separate 
+		              the several parts in the message (the value of the attribute is
+					  prefixed with "--" to form the actual boundary marker in the 
+					  request; on the other way, this prefix is removed from the boundary 
+					  marker in the response to set the value of the attribute."
+		 },		 
+		 "parts": {
+	        "$kind": "array",
+	        "$content": ["part"],
+			"$about": "The parts of the multipart request.",
+			"$optional": true
+		 }		
+	  }      
+    },
+    {
+      "$kind": "object",
+      "$name": "options",
+	  "$about": "This type represents an HTTP request options.",
+      "$content": {
+        "status-only": {
+		  "$type": "boolean",
+		  "$optional": true,
+		  "$about": "Controls how the response will look like; if true, only the status code
+                     and the headers are returned, the content is not."
+		},
+		"override-media-type": {
+		  "$type": "string",
+		  "$about": "Is a MIME type that will override the Content-Type header returned
+                     by the server.",
+		  "$optional": true
+		},
+		"follow-redirect": {
+		  "$type": "boolean",
+		  "$optional": true,
+          "$about": "Control whether an http redirect is automatically followed or not. If
+                     it is false, the http redirect is returned as the response. If it is
+                     true (the default) the function tries to follow the redirect, by
+                     sending the same request to the new address (including body, headers,
+                     and authentication credentials.) Maximum one redirect is followed
+                     (there is no attempt to follow a redirect in response to following a
+                     first redirect.)"
+		},
+		"timeout": {
+		  "$type": "integer",
+		  "$optional": true,
+		  "$about": "Is the maximum number of seconds to wait for the server to respond. If
+                     this time duration is reached, an error is thrown."
+		},
+        "user-agent": {
+		  "$type": "string",
+		  "$optional": true,
+		  "$about": "The user agent sent to the server when issuing the request."
+		},
+	  }	 
+    },	
+	{
+      "$kind": "object",
+      "$name": "authentication",
+	  "$about": "This type represents an HTTP authentication.",
+      "$content": {
+        "username": {
+		  "$type": "string",
+		  "$about": "The authentication username."
+		},	   
+		"password": {
+		  "$type": "string",
+		  "$about": "The authentication password."
+		},
+		"auth-method": {
+		  "$type": "string",
+		  "$about": "The authentication method."
+		}
+	  }
+	},
+	{
+	  "$kind": "object",
+	  "$name": "request",
+	  "$content": {
+	    "method": {
+		  "$type": "string",
+		  "$about: "Is the http verb to use, as GET, POST, etc. It is case insensitive."
+		},
+		"href": {
+		  "$type": "anyURI",		  
+		  "$about": "Is the URI the request has to be sent to. It can be overridden by the
+                     parameter $href."
+		},
+		"authentication": {
+		  "$type": "authentication",
+		  "$optional": true,
+		  "$about": "Specifies the HTTP authentication when sending the request."
+		},
+		"options": {
+		  "$type": "options",
+		  "$optional": true,
+		  "$about": "Specifies the HTTP request options."
+		},
+		"headers": {
+		  "$type": "headers",
+		  "$optional": true,
+		  "$about": "Specifies the HTTP request headers."
+		},
+		"body": {
+          "$type": "body",
+		  "$optional": true,
+		  "$about": "Specifies the body of a non-multipart HTTP request."
+		},
+	    "multipart": {
+          "$type": "multipart",
+		  "$optional": true,
+		  "$about": "Specifies a multipart HTTP request."
+		}
+	  },
+	  "$constraints" : "count($$.body) + count($$.multipart) le 1"
+	},
+	{
+	  "$kind": "object",
+	  "$name": "response",
+	  "$content": {
+	    "status": {
+		  "$type": "integer",
+		  "$about": "This is the HTTP status code returned by the server."
+		},
+		"message": {
+		  "$type": "string",
+		  "$about": "This is the message returned by the server on the status line."
+		},
+		"headers": {
+		  "$type": "headers",
+		  "$optional": true,
+		  "$about": "The reponse headers returned by the server."
+		},
+		"body": {
+          "$type": "body",
+		  "$optional": true,
+		  "$about": "The body of a non-multipart HTTP response."
+		},
+	    "multipart": {
+          "$type": "multipart",
+		  "$optional": true,
+		  "$about": "Specifies a multipart HTTP response."
+		}
+	  },
+	  "$constraints" : "count($$.body) + count($$.multipart) le 1"
+	}
+  ]
+}
\ No newline at end of file

=== added file 'modules/io/zorba/modules/http-client.xq'
--- modules/io/zorba/modules/http-client.xq	1970-01-01 00:00:00 +0000
+++ modules/io/zorba/modules/http-client.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,698 @@
+jsoniq version "1.0";
+
+(:
+ : Copyright 2006-2013 The FLWOR Foundation.
+ :
+ : Licensed 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.
+ :)
+
+
+(:~
+ : <p>
+ : This module provides functions for performing HTTP requests.
+ : </p>
+ :
+ : <h2>A simple GET request using the get#1 convenience function</h2>
+ :
+ : <pre>
+ : import module namespace http="http://www.zorba.io/modules/http-client";;
+ : http:get("http://www.example.com";)
+ : </pre>
+ :
+ : <p>
+ : This example makes a GET request to example.com and returns the server's response
+ : as a JSON object.
+ : </p>
+ :
+ : <pre>
+ : {
+ :   "status" : 200, 
+ :   "message" : "OK", 
+ :   "headers" : {
+ :     "Content-Length" : "1270", 
+ :     "Date" : "Tue, 11 Jun 2013 22:27:10 GMT", 
+ :     ...
+ :   }, 
+ :   "body" : {
+ :     "media-type" : "text/html", 
+ :     "content" : "..."
+ :   }
+ : }
+ : </pre>
+ :
+ : <h2 id="standard_return">Response format</h2>
+ :
+ : <p>Most functions in this module (all except <a href="#options-1">options#1</a>)
+ : return a single JSON item, describing the server's response, as in the previous
+ : example.
+ : The server status (integer) and message (string) fields are always present.
+ : If the server replied sending one or more headers, they are reported 
+ : in an optional headers object. Each header is represented as a single (string) 
+ : field.</p>
+ :
+ : <p>For non-multipart responses, as in the previous example, the response body, 
+ : if any, is reported as a body object. This object contains both the (string) 
+ : media-type returned by the server and its content.
+ : The type of the content field is determined by the media-type returned by the
+ : server. If the media-type indicates that the body content is textual,
+ : then the content has type string, base64Binary otherwise. 
+ : Specifically, the body content is considered textual only if the MIME-type specified in 
+ : the media-type is one of:
+ : <ul>
+ :   <li>"application/json"</li>
+ :   <li>"application/x-javascript"</li>
+ :   <li>"application/xml"</li>
+ :   <li>"application/xml-external-parsed-entity"</li>
+ : </ul>
+ : or if the MIME-type starts with "text/" or ends with "+xml".</p>
+ :
+ : <p>For multipart responses, multiple bodies are returned, as in the following example: </p> 
+ :
+ : <pre>
+ : {
+ :   "status" : 200, 
+ :   "message" : "OK", 
+ :   "headers" : { 
+ :     "Date" : "Tue, 11 Jun 2013 22:34:13 GMT", 
+ :     ...
+ :   }, 
+ :   "multipart" : {
+ :     "boundary": "--AaB03x",  
+ :     "parts": [
+ :       {
+ :         "headers" : {
+ :            "Content Disposition: file",
+ :            ...
+ :         },
+ :         "body": {
+ :           "media-type" : "image/gif", 
+ :           "content" : "..."
+ :         }  
+ :       },
+ :       {
+ :         "body" : {
+ :           "media-type" : "text/html", 
+ :           "content" : "..."
+ :         }
+ :       }
+ :    ]
+ : }
+ : </pre>
+ : 
+ : <p>The multipart field contains both the boundary used to separate parts
+ : and an array containing all parts. Each part contains its specific headers,
+ : if any, and the corresponding body.</p>
+ :
+ : <h2 id="nondeterministic_warning">Important Notice Regarding Nondeterministic Functions</h2>
+ : 
+ : <p>
+ : The following functions in this module -
+ : <a href="#get-1">get#1</a>,
+ : <a href="#get-text-1">get-text#1</a>,
+ : <a href="#get-binary-1">get-binary#1</a>, 
+ : <a href="#send-nondeterministic-request-1">send-nondeterministic-request-1</a>,
+ : <a href="#head-1">head#1</a>, and
+ : <a href="#options-1">options#1</a> 
+ : are declared to be <i>nondeterministic</i>, which means that their results 
+ : will not be cached. 
+ : However, they are <b>not</b> declared to be
+ : <i>sequential</i>, which means that they may be re-ordered during query optimization.
+ : According to the HTTP RFC, GET, HEAD an OPTIONS requests should not have any side-effects. 
+ : However, in practice it is not uncommon, especially for GET requests, to have side-effects. 
+ : If your application depends on the ordering of side-effects from requests issued through
+ : these functions, you should either use the <a href="#send-request-3">send-request()</a>
+ : function (which is declared <i>sequential</i>), or alternatively
+ : wrap each call to get() in your own sequential function, to ensure
+ : that the requests are not reordered.
+ : </p>
+ :
+ : <h1 id="url_string">$href Arguments to Functions</h1>
+ :
+ : <p>Several functions in this module accept a URL argument named $href. In
+ : all cases, the value passed to $href must be a valid xs:anyURI.
+ : However, all functions declare $href to be of type xs:string. This
+ : is for convenience, since you can pass a string literal value (that
+ : is, a URL in double-quotes spelled out explicitly in your query)
+ : to an xs:string parameter.</p>
+ : 
+ : <h1 id="expath_relation">Relation to the EXPath http-client module</h1>
+ : 
+ : <p><a href="http://expath.org/";>EXPath</a> defines its own http-client
+ : module, which is available separately.
+ : There are two primary differences between EXPath's http-client and
+ : this module:
+ : 
+ : <ol>
+ :   <li>EXPath defines only the send-request() function, although it
+ : does include convenient 1- and 2-argument forms in addition to the
+ : full 3-argument form. EXPath does not include the simpler get(),
+ : post(), put(), delete(), head(), and options() functions defined by
+ : this module.</li>
+ : <li>EXPath uses XML to represent request for its send-request() function, 
+ : whereas this module uses JSON.</li>
+ : <li>EXPath specifies that all XML content returned by an HTTP server
+ : will be parsed and returned as an XML document, whereas all HTML content 
+ : will be <i>tidied up</i> into valid XML, and then parsed into an element. 
+ : This module returns any textual content as string and any binary content 
+ : as base6Binary.</li>
+ : <li>EXPath accepts XML nodes as body in the send-request() function and 
+ : automatically serializes them into a string. The send-request() function
+ : defined in this module only allows string and base64Binary as body types.
+ : </li>
+ : </ol>
+ : </p>
+ :
+ : <p>
+ : See <a href="http://www.expath.org/spec/http-client";>the full spec
+ : of the EXPath http-client module</a> for more information.
+ : </p>
+ : 
+ : @author Federico Cavalieri, Markus Pilman
+ : @see <a href="http://www.w3.org/TR/xquery-11/#FunctionDeclns";>XQuery 1.1: Function Declaration</a>
+ : @library <a href="http://curl.haxx.se/";>cURL Library</a>
+ : @project external
+ :)
+module namespace http = "http://zorba.io/modules/http-client";;
+
+import module namespace libjn = "http://jsoniq.org/function-library";;
+
+declare namespace an = "http://www.zorba-xquery.com/annotations";;
+declare namespace ver = "http://www.zorba-xquery.com/options/versioning";;
+declare namespace err = "http://www.w3.org/2005/xqt-errors";;
+
+declare option ver:module-version "1.0";
+
+(:~
+ : <p>
+ : This function sends an HTTP request and returns the corresponding response.
+ : </p>
+ :
+ : <p>
+ : This function is declared as sequential and should be used whenever the 
+ : request may have side-effects.
+ : </p>
+ :
+ : <p>
+ : The request parameters are specified in the $request JSON object, which 
+ : has the following minimal structure:
+ : 
+ : <pre>
+ :   {
+ :     "href": "http://www.example.com";
+ :   }
+ : </pre>
+ : </p>
+ :
+ : <p>This object specifies a GET request of the URI "http://www.example.com";</p> 
+ :
+ : <p>Additional optional parameters can be specified when issuing a request, 
+ : using the following structure:</p>
+ : <pre>
+ :  {
+ :    "method": "POST", 
+ :    "href": "http://www.example.com";,
+ :    "authentication": 
+ :    {
+ :      "username" : "user",
+ :      "password" : "pass",
+ :      "auth-method" : "Basic"
+ :    },
+ :    "options": 
+ :    {
+ :      "status-only": true,
+ :      "override-media-type": "text/plain",
+ :      "follow-redirect": false,
+ :      "timeout": 30,
+ :      "user-agent": "Mozilla/5.0"
+ :    },   
+ :    "headers":
+ :    {
+ :      "name": "value",
+ :      ...
+ :    },    
+ :    "body":
+ :    {
+ :      "media-type": "text/plain", 
+ :      "content": "..." 
+ :    }
+ :  }
+ :</pre>
+ : <p>
+ : The method field (string) defines the HTTP verb to use in the HTTP request (i.e., GET, HEAD, OPTIONS,
+ : POST, PUT, DELETE). If not specified GET will be used. 
+ : The authentication field can be used to specify the credentials and authentication method
+ : used when issuing a request (e.g, Basic). If the authentication field is specified, all its (string) 
+ : subfields must be specified. If an authentication object is provided, it overrides any 
+ : Authorization header specified in the request. 
+ : Additionally, the following options can be specified:
+ : <ul>
+ :    <li>status-only. If true, the response body contents are omitted from the response object.</li>
+ :    <li>override-media-type. Is a MIME type that will override the Content-Type header returned
+ :        by the server. It affects the type of the result body content.</li>
+ :    <li>follow-redirect. Control whether an http redirect is automatically followed or not. If
+ :        it is false, the http redirect is returned as the response. If it is
+ :        true (the default) the function tries to follow the redirect, by
+ :        sending the same request to the new address (including body, headers,
+ :         and authentication credentials.) Maximum one redirect is followed
+ :        (there is no attempt to follow a redirect in response to following a
+ :          first redirect).</li>
+ :    <li>timeout. Is the maximum number of seconds to wait for the server to respond. 
+ :         If no response is received withing this time duration, an error is thrown.</li>
+ :    <li>user-agent. The user agent sent to the server when issuing the request.
+ :        If not specified libcurl-agent/1.0 is used.</li>
+ : </ul>
+ : </p>
+ :
+ : <p>One or more headers can be sent to the server, specifying them in an optional headers object. 
+ : Each header is represented as a single (string) field. These headers are overridden if the corresponding
+ : option/authentication has been specified in the request.</p>
+ :
+ : <p>For non-multipart request a body object can be specified. 
+ : This object must contain both the desired (string) media-type and its content.
+ : The type of the content field must be either string or base64Binary. </p> 
+ :
+ : <p>For multipart requests, multipart object can be specified in place of the body object.
+ : The multipart object has the following structure: </p> 
+ :
+ : <pre>
+ :  "multipart" : {
+ :    "boundary": "--AaB03x",  
+ :    "parts": [
+ :      {
+ :        "headers" : {
+ :           "Content Disposition: file",
+ :           ...
+ :        },
+ :        "body": {
+ :          "media-type" : "image/gif", 
+ :          "content" : "..."
+ :        }  
+ :      },
+ :      {
+ :        "body" : {
+ :          "media-type" : "text/html", 
+ :          "content" : "..."
+ :        }
+ :      }
+ :   ]
+ : }
+ : </pre>
+ : 
+ : <p>The multipart field contains an optional (string) field which specifies
+ : the boundary used to separate each part and an array containing all parts. 
+ : Each part contains its specific headers, if any, and the corresponding body.
+ : </p>
+ :
+ :
+ : @param $request a JSON http-client request object
+ : @return <a href="#standard_return">standard http-client return type</a>.
+ :
+ : @error http:HC001 An HTTP error occurred.
+ : @error http:HC004 The src attribute on the body element is mutually exclusive with all other 
+ :    attributes (except media-type).
+ : @error http:HC005 The specified request object is not valid.
+ : @error http:HC006 A timeout occurred waiting for the response.
+ : @error http:HCV02 Trying to follow a redirect of a POST, PUT, or DELETE request.
+ : @error http:HCV03 The specified charset is unsupported.
+ : @error http:HCV04 The type of the request body must be string or xs:base64Binary.
+ :
+ :)
+declare %an:sequential function http:send-request($request as object) as object
+{
+  if (http:check-request($request))
+  then http:http-sequential-impl($request)
+  else ()   
+};
+
+(:~
+ : <p> 
+ : This function sends an HTTP request and returns the corresponding response.
+ : </p>
+ : <p>
+ : This function has the same semantics of <a href="#send-request-1">send-request-1</a>, 
+ : but is declared as nondeterministic and thus should only be used when
+ : the request has no side-effects.
+ : </p>
+ :
+ : @see <a href="#nondeterministic_warning">Notice about nondeterministic functions</a>
+ : @param $request see request parameter of <a href="#send-request-1">send-request#1</a>
+ : @return <a href="#standard_return">standard http-client return type</a>.
+ :
+ : @error http:HC001 An HTTP error occurred.
+ : @error http:HC004 The src attribute on the body element is mutually exclusive with all other 
+ :    attributes (except media-type).
+ : @error http:HC005 The specified request object is not valid.
+ : @error http:HC006 A timeout occurred waiting for the response.
+ : @error http:HCV02 Trying to follow a redirect of a POST, PUT, or DELETE request.
+ : @error http:HCV03 The specified charset is unsupported.
+ : @error http:HCV04 The type of the request body must be string or xs:base64Binary.
+ :)
+declare %an:nondeterministic function http:send-nondeterministic-request($request as object) as object
+{
+  if (http:check-request($request))
+  then http:http-nondeterministic-impl($request)
+  else ()
+};
+
+
+(:~
+ : <p>
+ : This function makes a GET request to a given URL.
+ : </p>
+ :
+ : @see <a href="#nondeterministic_warning">Notice about nondeterministic functions</a>
+ : @param $href The URL to which the request will be made (see 
+ :  <a href="#url_string">note</a> above).
+ : @return <a href="#standard_return">standard http-client return type</a>.
+ :
+ : @error http:HC001 An HTTP error occurred.
+ : @error http:HC005 The specified href is not valid.
+ : @error http:HC006 A timeout occurred waiting for the response.
+ :)
+declare %an:nondeterministic function http:get($href as string) as object
+{
+  http:send-nondeterministic-request(
+  {
+    "method" : "GET",
+    "href": $href
+  })
+};
+
+(:~
+ : <p>
+ : This function makes a GET request to a given URL. All returned bodies
+ : are forced to be interpreted as textual, with a UTF-8 charset and will
+ : be returned as string items.
+ : </p>
+ :
+ : @see <a href="#nondeterministic_warning">Notice about nondeterministic functions</a>
+ : @param $href The URL to which the request will be made (see
+ :  <a href="#url_string">note</a> above).
+ : @return <a href="#standard_return">standard http-client return type</a>.
+ :
+ : @error http:HC001 An HTTP error occurred.
+ : @error http:HC005 The specified href is not valid.
+ : @error http:HC006 A timeout occurred waiting for the response.
+ :
+ :)
+declare %an:nondeterministic function http:get-text($href as string) as object
+{
+  http:send-nondeterministic-request(
+  {
+    "method": "GET",
+    "href": $href,
+    "options": {
+      "override-media-type": "text/plain; charset=utf-8"
+    }
+  })
+};
+
+(:~
+ : <p>
+ : This function makes a GET request on a given URL. All returned bodies
+ : are forced to be interpreted as binary data, and will be returned
+ : as base64Binary items.
+ : </p>
+ :
+ : @see <a href="#nondeterministic_warning">Notice about nondeterministic functions</a>
+ : @param $href The URL to which the request will be made (see
+ :  <a href="#url_string">note</a> above).
+ : @return <a href="#standard_return">standard http-client return type</a>.
+ :
+ : @error http:HC001 An HTTP error occurred.
+ : @error http:HC005 The specified href is not valid.
+ : @error http:HC006 A timeout occurred waiting for the response.
+ :
+ :)
+declare %an:nondeterministic function http:get-binary($href as string) as object
+{
+  http:send-nondeterministic-request(
+  {
+    "method": "GET",
+    "href": $href,
+    "options": {
+      "override-media-type": "binary"      
+    }
+  })
+};
+
+(:~
+ : <p>
+ : This function makes an HTTP HEAD request on a given URL.
+ : </p>
+ :
+ : @see <a href="#nondeterministic_warning">Notice about nondeterministic functions</a>
+ : @param $href The URL to which the request will be made (see
+ :  <a href="#url_string">note</a> above).
+ : @return <a href="#standard_return">standard http-client return type</a>.
+ :
+ : @error http:HC001 An HTTP error occurred.
+ : @error http:HC005 The specified href is not valid.
+ : @error http:HC006 A timeout occurred waiting for the response.
+ :
+ : @example test/rbkt/Queries/zorba/http-client/head/head_status.xq
+ :)
+declare %an:nondeterministic function http:head($href as string) as object 
+{
+  http:send-nondeterministic-request(
+  {
+    "method": "HEAD",
+    "href": $href    
+  })
+};
+
+(:~
+ : <p>
+ : This function makes an HTTP OPTIONS request, which asks the server
+ : which operations it supports.
+ : </p>
+ :
+ : @see <a href="#nondeterministic_warning">Notice about nondeterministic functions</a>
+ : @param $href The URL to which the request will be made (see
+ :  <a href="#url_string">note</a> above).
+ : @return A sequence of string values of the allowed operations.
+ :
+ : @error http:HC001 An HTTP error occurred.
+ : @error http:HC005 The specified href is not valid.
+ : @error http:HC006 A timeout occurred waiting for the response.
+ :
+ : @example test/rbkt/Queries/zorba/http-client/options/options.xq
+ :)
+declare %an:nondeterministic function http:options($href as string) as string* 
+{
+  let $resp := http:send-nondeterministic-request(
+    {
+      "method": "OPTIONS",
+      "href": $href      
+    })[1]
+  return
+    fn:tokenize($resp.headers.Allow, ",")
+};
+
+
+(:~
+ : <p>
+ : This function makes an HTTP PUT request to a given URL.
+ : </p>
+ : <p>
+ : The body passed to this function must be either a string or a base64Binary.
+ : If it is a string, the Content-Type sent to the server will be "text/plain",
+ : "application/octet-stream" otherwise.
+ : </p>
+ :
+ : @param $href The URL to which the request will be made (see
+ :  <a href="#url_string">note</a> above).
+ : @param $body The body which will be sent to the server.
+ : @return <a href="#standard_return">standard http-client return type</a>.
+ :
+ : @error http:HC001 An HTTP error occurred.
+ : @error http:HC005 The specified href is not valid.
+ : @error http:HC006 A timeout occurred waiting for the response.
+ : @error http:HCV04 The type of the request body must be string or xs:base64Binary.
+ :
+ :)
+declare %an:sequential function http:put($href as string, $body as atomic) as object
+{
+  variable $media-type as xs:string :=
+    typeswitch($body)
+      case string return "text/plain"
+      case xs:base64Binary return "application/octet-stream"
+      default return fn:error(xs:QName("http:HCV04"), "The type of the request body must be string or xs:base64Binary.");
+  http:put($href, $body, $media-type)
+};
+
+(:~
+ : <p>
+ : This function makes an HTTP PUT request to a given URL.
+ : </p>
+ : <p>
+ : The body passed to this function must be either a string or a base64Binary.
+ : In any case, Content-Type of the request sent to the server will
+ : be $content-type.
+ : </p>
+ :
+ : @param $href The URL to which the request will be made (see
+ :  <a href="#url_string">note</a> above).
+ : @param $body The body which will be sent to the server.
+ : @param $content-type The content type of $body to send to the server.
+ : @return <a href="#standard_return">standard http-client return type</a>.
+ :
+ : @error http:HC001 An HTTP error occurred.
+ : @error http:HC005 The specified request object is not valid.
+ : @error http:HC006 A timeout occurred waiting for the response.
+ : @error http:HCV03 The specified charset is unsupported.
+ : @error http:HCV04 The type of the request body must be string or xs:base64Binary.
+ : 
+ :)
+declare %an:sequential function http:put($href as string, $body as atomic, $content-type as string) as object
+{
+  http:send-request(
+  {
+    "method": "PUT",
+    "href": $href,
+    "body": {
+      "media-type": $content-type,
+      "content": $body
+    }
+  })
+};
+
+(:~
+ : <p>
+ : This function makes an HTTP DELETE request to a given URL.
+ : </p>
+ :
+ : @param $href The URL to which the request will be made (see
+ :  <a href="#url_string">note</a> above).
+ : @return <a href="#standard_return">standard http-client return type</a>.
+ :
+ : @error http:HC001 An HTTP error occurred.
+ : @error http:HC005 The specified request is not valid.
+ : @error http:HC006 A timeout occurred waiting for the response.
+ :
+ :)
+declare %an:sequential function http:delete($href as xs:string) as object
+{
+  http:send-request(
+  {
+      "method": "DELETE",
+      "href": $href      
+  })
+};
+
+(:~
+ : <p>
+ : This function makes an HTTP POST request to a given URL.
+ : </p>
+ : <p> 
+ : The body passed to this function must be either a string or a base64Binary.
+ : If it is a string, the Content-Type sent to the server will be "text/plain",
+ : "application/octet-stream" otherwise.
+ : </p>
+ :
+ : @param $href The URL to which the request will be made (see
+ :  <a href="#url_string">note</a> above).
+ : @param $body The body which will be sent to the server.
+ : @return <a href="#standard_return">standard http-client return type</a>.
+ :
+ : @error http:HC001 An HTTP error occurred.
+ : @error http:HC005 The specified request is not valid.
+ : @error http:HC006 A timeout occurred waiting for the response.
+ : @error http:HCV04 The type of the request body must be string or xs:base64Binary.
+ : 
+ :)
+declare %an:sequential function http:post($href as string, $body as atomic) as object
+{
+  variable $media-type as xs:string :=
+    typeswitch($body)
+      case string return "text/plain"
+      case base64Binary return "application/octet-stream"
+      default return fn:error(xs:QName("http:HCV04"), "The type of the request body must be string or xs:base64Binary.");
+
+  http:post($href, $body, $media-type)
+};
+
+(:~
+ : <p>
+ : This function makes an HTTP POST request to a given URL.
+ : </p>
+ : <p> 
+ : The body passed to this function must be either a string or a base64Binary.
+ : In any case, Content-Type of the request sent to the server will
+ : be $content-type.
+ : </p>
+ :
+ : @param $href The URL to which the request will be made (see
+ :  <a href="#url_string">note</a> above).
+ : @param $body The body which will be sent to the server
+ : @param $content-type The content type of the body as described above.
+ : @return <a href="#standard_return">standard http-client return type</a>.
+ :
+ : @error http:HC001 An HTTP error occurred.
+ : @error http:HC005 The specified request is not valid.
+ : @error http:HC006 A timeout occurred waiting for the response.
+ : @error http:HCV03 The specified charset is unsupported.
+ : @error http:HCV04 The type of the request body must be string or xs:base64Binary.
+ :
+ :)
+declare %an:sequential function http:post($href as string, $body as atomic, $content-type as string) as object
+{
+  http:send-request(
+  {
+    "method": "POST",
+    "href": $href,
+    "body": {
+      "media-type": $content-type,
+      "content": $body
+    }
+  })  
+};
+
+
+(:~
+ : Private function used internally by this module.
+ :
+ : This function checks if the request, href, and bodies parameters
+ : are consistent.
+ : 
+ : @error http:HC004 The src attribute on the body element is mutually exclusive with all other attribute (except the media-type).
+ : @error http:HC005 The specified request object is not valid.
+ : @error http:HCV04 The type of the request body must be string or xs:base64Binary.
+ :)
+declare %private function http:check-request($request as object) as boolean
+{  
+  for $body in libjn:descendant-objects($request).body
+  return
+  (
+    if (exists($body.src) and exists($body.content))
+    then fn:error(xs:QName("http:HC004"), "The src and content fields of a body are mutually exclusive.")
+    else (),
+    if (exists($body.content))
+    then 
+      typeswitch($body.content)
+      case string return ()
+      case xs:base64Binary return ()
+      default return fn:error(xs:QName("http:HCV04"), "The type of the body content must be string or xs:base64Binary.")
+    else ()    
+  ),    
+  if (count(libjn:descendant-objects($request).body[exists($$.src) and exists($$.content)]) gt 1)
+  then fn:error(xs:QName("http:HC004"), "The src and content fields of a body are mutually exclusive.")
+  else if (exists($request.href) and not($request.href castable as xs:anyURI))
+       then fn:error(xs:QName("http:HC005"), "The specified href is not a valid anyURI.")
+       else (),
+  fn:true()
+};
+
+declare %private %an:sequential function http:http-sequential-impl($request as object) as object external;
+
+declare %private %an:nondeterministic function http:http-nondeterministic-impl($request as object) as object external;

=== added directory 'modules/io/zorba/modules/http-client.xq.src'
=== added file 'modules/io/zorba/modules/http-client.xq.src/curl_overwrite.h'
--- modules/io/zorba/modules/http-client.xq.src/curl_overwrite.h	1970-01-01 00:00:00 +0000
+++ modules/io/zorba/modules/http-client.xq.src/curl_overwrite.h	2013-06-15 00:58:33 +0000
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2006-2013 The FLWOR Foundation.
+ *
+ * Licensed 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.
+ */
+
+#ifndef CURL_OVERWRITE_H
+#define CURL_OVERWRITE_H
+
+#include "curl_wrappers.h"
+#include "curl_redefines.h"
+
+#endif // CURL_OVERWRITE_H

=== added file 'modules/io/zorba/modules/http-client.xq.src/curl_redefines.h'
--- modules/io/zorba/modules/http-client.xq.src/curl_redefines.h	1970-01-01 00:00:00 +0000
+++ modules/io/zorba/modules/http-client.xq.src/curl_redefines.h	2013-06-15 00:58:33 +0000
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2006-2013 The FLWOR Foundation.
+ *
+ * Licensed 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.
+ */
+
+#ifndef CURL_REDEFINES_H
+#define CURL_REDEFINES_H
+
+#define curl_easy_init() curl_easy_init_wrapped(__FILE__, __LINE__)
+#define curl_multi_init() curl_multi_init_wrapped(__FILE__, __LINE__)
+#define curl_easy_setopt(x, y, z) curl_easy_setopt_wrapped(__FILE__, __LINE__, x, y, z)
+//#define curl_multi_perform(x,y) curl_multi_perform_wrapped(__FILE__, __LINE__, x, y)
+//#define curl_multi_info_read(x,y) curl_multi_info_read_wrapped(__FILE__, __LINE__, x, y)
+#define curl_slist_free_all(x) curl_slist_free_all_wrapped(__FILE__, __LINE__, x)
+#define curl_formfree(x) curl_formfree_wrapped(__FILE__, __LINE__, x)
+#define curl_slist_append(x,y) curl_slist_append_wrapped(__FILE__, __LINE__, x, y)
+#define curl_multi_add_handle(x,y) curl_multi_add_handle_wrapped(__FILE__, __LINE__, x, y)
+
+#endif // CURL_REDEFINES_H

=== added file 'modules/io/zorba/modules/http-client.xq.src/curl_stream_buffer.cpp'
--- modules/io/zorba/modules/http-client.xq.src/curl_stream_buffer.cpp	1970-01-01 00:00:00 +0000
+++ modules/io/zorba/modules/http-client.xq.src/curl_stream_buffer.cpp	2013-06-15 00:58:33 +0000
@@ -0,0 +1,379 @@
+/*
+ * Copyright 2006-2013 The FLWOR Foundation.
+ *
+ * Licensed 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.
+ */
+
+#include <zorba/config.h>
+
+#include <cstdlib>
+#include <cstring>                      /* for memcpy(3) */
+#include <iostream>
+#include <cassert>
+#ifndef WIN32
+#include <cerrno>
+#include <sys/time.h>
+#endif /* WIN32 */
+
+#include <curl/multi.h>
+
+#include "curl_stream_buffer.h"
+#include "inform_data_read.h"
+
+using namespace std;
+
+namespace zorba {
+namespace curl {
+  
+///////////////////////////////////////////////////////////////////////////////
+  
+#define ZORBA_CURL_ASSERT(expr)                         \
+  do {                                                  \
+    if ( CURLcode const code##__LINE__ = (expr) )       \
+      throw exception( #expr, "", code##__LINE__ );     \
+  } while (0)
+
+#define ZORBA_CURLM_ASSERT(expr)                        \
+  do {                                                  \
+    if ( CURLMcode const code##__LINE__ = (expr) )      \
+      if ( code##__LINE__ != CURLM_CALL_MULTI_PERFORM ) \
+        throw exception( #expr, "", code##__LINE__ );   \
+  } while (0)
+
+exception::exception( char const *function, char const *uri, char const *msg ) :
+  std::exception(), msg_( msg )
+{
+}
+
+exception::exception( char const *function, char const *uri, CURLcode code ) :
+  std::exception(),
+  msg_( curl_easy_strerror( code ) )
+{
+}
+
+exception::exception( char const *function, char const *uri, CURLMcode code ) :
+  std::exception(),
+  msg_( curl_multi_strerror( code ) )
+{
+}
+
+exception::~exception() throw() {
+  // out-of-line since it's virtual
+}
+
+const char* exception::what() const throw() {
+  return msg_.c_str();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+CURL* create( char const *uri, write_fn_t fn, void *data ) {
+  //
+  // Having cURL initialization wrapped by a class and using a singleton static
+  // instance guarantees that cURL is initialized exactly once before use and
+  // and also is cleaned-up at program termination (when destructors for static
+  // objects are called).
+  //
+  struct curl_initializer {
+    curl_initializer() {
+      ZORBA_CURL_ASSERT( curl_global_init( CURL_GLOBAL_ALL ) );
+    }
+    ~curl_initializer() {
+      curl_global_cleanup();
+    }
+  };
+  static curl_initializer initializer;
+  
+  CURL *const curl = curl_easy_init();
+  if ( !curl )
+    throw exception( "curl_easy_init()", uri, "" );
+  
+  try {
+    ZORBA_CURL_ASSERT( curl_easy_setopt( curl, CURLOPT_URL, uri ) );
+    ZORBA_CURL_ASSERT( curl_easy_setopt( curl, CURLOPT_WRITEDATA, data ) );
+    ZORBA_CURL_ASSERT( curl_easy_setopt( curl, CURLOPT_WRITEFUNCTION, fn ) );
+    
+    // Tells cURL to follow redirects. CURLOPT_MAXREDIRS is by default set to -1
+    // thus cURL will do an infinite number of redirects.
+    ZORBA_CURL_ASSERT( curl_easy_setopt( curl, CURLOPT_FOLLOWLOCATION, 1 ) );
+    
+#ifndef ZORBA_VERIFY_PEER_SSL_CERTIFICATE
+    ZORBA_CURL_ASSERT( curl_easy_setopt( curl, CURLOPT_SSL_VERIFYPEER, 0 ) );
+    //
+    // CURLOPT_SSL_VERIFYHOST is left default, value 2, meaning verify that the
+    // Common Name or Subject Alternate Name field in the certificate matches
+    // the name of the server.
+    //
+    // Tested with https://www.npr.org/rss/rss.php?id=1001
+    // About using SSL certs in curl: http://curl.haxx.se/docs/sslcerts.html
+#else
+# ifdef WIN32
+    // set the root CA certificates file path
+    if ( GENV.g_curl_root_CA_certificates_path[0] )
+      ZORBA_CURL_ASSERT(
+        curl_easy_setopt(
+          curl, CURLOPT_CAINFO, GENV.g_curl_root_CA_certificates_path
+        )
+      );
+# endif /* WIN32 */
+#endif /* ZORBA_VERIFY_PEER_SSL_CERTIFICATE */
+    
+    //
+    // Some servers don't like requests that are made without a user-agent
+    // field, so we provide one.
+    //
+    //ZORBA_CURL_ASSERT(
+      //curl_easy_setopt( curl, CURLOPT_USERAGENT, "libcurl-agent/1.0" )
+    //);
+    
+    return curl;
+  }
+  catch ( ... ) {
+    destroy( curl );
+    throw;
+  }
+}
+
+void destroy( CURL *curl ) {
+  if ( curl ) {
+    curl_easy_reset( curl );
+    curl_easy_cleanup( curl );
+  }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+streambuf::streambuf() {
+  init();
+}
+
+streambuf::streambuf( char const *uri ) {
+  init();
+  open( uri );
+}
+
+streambuf::streambuf( CURL *curl ) {
+  init();
+  curl_ = curl;
+  ZORBA_CURL_ASSERT( curl_easy_setopt( curl, CURLOPT_WRITEDATA, this ) );
+  ZORBA_CURL_ASSERT( curl_easy_setopt( curl, CURLOPT_WRITEFUNCTION, curl_write_callback ) );
+  init_curlm();
+}
+
+streambuf::~streambuf() {
+  free( buf_ );
+  close();
+#ifdef WIN32
+  closesocket( dummy_socket_ );
+#endif
+  // If we have been assigned memory ownership of theInformer, delete it now.
+  if ( theOwnInformer )
+    delete theInformer;
+}
+
+void streambuf::close() {
+  if ( curl_ ) {
+    if ( curlm_ ) {
+      curl_multi_remove_handle( curlm_, curl_ );
+      curl_multi_cleanup( curlm_ );
+      curlm_ = 0;
+    }
+    destroy( curl_ );
+    curl_ = 0;
+  }
+}
+
+void streambuf::curl_read() {
+  buf_len_ = 0;
+  while ( curl_running_ && !buf_len_ ) {
+    fd_set fd_read, fd_write, fd_except;
+    FD_ZERO( &fd_read );
+    FD_ZERO( &fd_write );
+    FD_ZERO( &fd_except );
+    int max_fd = -1;
+#ifdef WIN32
+    //
+    // Windows does not like a call to select where all arguments are 0, so we
+    // just add a dummy socket to make the call to select happy.
+    //
+    FD_SET( dummy_socket_, &fd_read );
+#endif /* WIN32 */
+    ZORBA_CURLM_ASSERT(
+      curl_multi_fdset( curlm_, &fd_read, &fd_write, &fd_except, &max_fd )
+    );
+    
+    //
+    // Note that the fopen.c sample code is unnecessary at best or wrong at
+    // worst; see: http://curl.haxx.se/mail/lib-2011-05/0011.html
+    //
+    timeval timeout;
+    long curl_timeout_ms;
+    ZORBA_CURLM_ASSERT( curl_multi_timeout( curlm_, &curl_timeout_ms ) );
+    if ( curl_timeout_ms > 0 ) {
+      timeout.tv_sec  = curl_timeout_ms / 1000;
+      timeout.tv_usec = curl_timeout_ms % 1000 * 1000;
+    } else {
+      //
+      // From curl_multi_timeout(3):
+      //
+      //    Note: if libcurl returns a -1 timeout here, it just means that
+      //    libcurl currently has no stored timeout value. You must not wait
+      //    too long (more than a few seconds perhaps) before you call
+      //    curl_multi_perform() again.
+      //
+      // So we just pick some not-too-long default.
+      //
+      timeout.tv_sec  = 1;
+      timeout.tv_usec = 0;
+    }
+    
+    switch ( select( max_fd + 1, &fd_read, &fd_write, &fd_except, &timeout ) ) {
+      case -1:                          // select error
+#ifdef WIN32
+        char err_buf[8];
+        sprintf( err_buf, "%d", WSAGetLastError() );
+        throw exception( "select()", "", err_buf );
+#else
+        throw exception( "select()", "", strerror( errno ) );
+#endif
+      case 0:                           // timeout
+        // no break;
+      default:
+        CURLMcode code;
+        do {
+          code = curl_multi_perform( curlm_, &curl_running_ );
+        } while ( code == CURLM_CALL_MULTI_PERFORM );
+        ZORBA_CURLM_ASSERT( code );
+    }
+  }
+  if ( theInformer )
+    theInformer->afterRead();
+}
+
+size_t streambuf::curl_write_callback( void *ptr, size_t size, size_t nmemb,
+                                       void *data ) {
+  size *= nmemb;
+  streambuf *const that = static_cast<streambuf*>( data );
+  
+  if ( that->theInformer )
+    that->theInformer->beforeRead();
+
+  size_t const buf_free = that->buf_capacity_ - that->buf_len_;
+  if ( size > buf_free ) {
+    streamoff new_capacity = that->buf_capacity_ + size - buf_free;
+    if ( void *const new_buf =
+          realloc( that->buf_, static_cast<size_t>( new_capacity ) ) ) {
+      that->buf_ = static_cast<char*>( new_buf );
+      that->buf_capacity_ = new_capacity;
+    } else
+      throw exception( "realloc()", "" );
+  }
+  ::memcpy( that->buf_ + that->buf_len_, ptr, size );
+  that->buf_len_ += size;
+  return size;
+}
+
+void streambuf::init() {
+  buf_ = 0;
+  buf_capacity_ = 0;
+  buf_len_ = 0;
+  curl_ = 0;
+  curlm_ = 0;
+  curl_running_ = 0;
+  theInformer = 0;
+  theOwnInformer = false;
+#ifdef WIN32
+  dummy_socket_ = socket( AF_INET, SOCK_DGRAM, 0 );
+  if ( dummy_socket_ == CURL_SOCKET_BAD || dummy_socket_ == INVALID_SOCKET )
+    throw exception( "socket()", "" );
+#endif /* WIN32 */
+}
+
+void streambuf::init_curlm() {
+  //
+  // Lie about cURL running initially so the while-loop in curl_read() will run
+  // at least once.
+  //
+  curl_running_ = 1;
+  
+  //
+  // Set the "get" pointer to the end (gptr() == egptr()) so a call to
+  // underflow() and initial data read will be triggered.
+  //
+  buf_len_ = buf_capacity_;
+  setg( buf_, buf_ + buf_len_, buf_ + buf_capacity_ );
+  
+  //
+  // Clean-up has to be done here with try/catch (as opposed to relying on the
+  // destructor) because open() can be called from the constructor.  If an
+  // exception is thrown, the constructor will not have completed, hence the
+  // object will not have been fully constructed; therefore the destructor will
+  // not be called.
+  //
+  try {
+    if ( !(curlm_ = curl_multi_init()) )
+      throw exception( "curl_multi_init()", "" );
+    try {
+      ZORBA_CURLM_ASSERT( curl_multi_add_handle( curlm_, curl_ ) );
+    }
+    catch ( ... ) {
+      curl_multi_cleanup( curlm_ );
+      curlm_ = 0;
+      throw;
+    }
+  }
+  catch ( ... ) {
+    destroy( curl_ );
+    curl_ = 0;
+    throw;
+  }
+}
+
+int streambuf::multi_perform() {
+  underflow();
+  CURLMsg *msg;
+  int msgInQueue;
+  int error = 0;
+  while ( (msg = curl_multi_info_read( curlm_, &msgInQueue )) ) {
+    if ( msg->msg == CURLMSG_DONE )
+      error = msg->data.result;
+  }
+  return error;
+}
+
+void streambuf::open( char const *uri ) {
+  curl_ = create( uri, curl_write_callback, this );
+  
+  init_curlm();
+}
+
+streamsize streambuf::showmanyc() {
+  return egptr() - gptr();
+}
+
+streambuf::int_type streambuf::underflow() {
+  while ( true ) {
+    if ( gptr() < egptr() )
+      return traits_type::to_int_type( *gptr() );
+    curl_read();
+    if ( !buf_len_ )
+      return traits_type::eof();
+    setg( buf_, buf_, buf_ + buf_len_ );
+  }
+}
+  
+///////////////////////////////////////////////////////////////////////////////
+  
+} // namespace curl
+} // namespace zorba
+/* vim:set et sw=2 ts=2: */

=== added file 'modules/io/zorba/modules/http-client.xq.src/curl_stream_buffer.h'
--- modules/io/zorba/modules/http-client.xq.src/curl_stream_buffer.h	1970-01-01 00:00:00 +0000
+++ modules/io/zorba/modules/http-client.xq.src/curl_stream_buffer.h	2013-06-15 00:58:33 +0000
@@ -0,0 +1,193 @@
+/*
+ * Copyright 2006-2013 The FLWOR Foundation.
+ *
+ * Licensed 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.
+ */
+#pragma once
+#ifndef ZORBA_CURL_UTIL_H
+#define ZORBA_CURL_UTIL_H
+
+#include <zorba/config.h>
+
+#include <exception>
+#include <istream>
+#include <streambuf>
+#include <string>
+#include <curl/curl.h>
+
+namespace zorba {
+
+namespace http_client {
+  class InformDataRead;
+}
+
+namespace curl {
+
+///////////////////////////////////////////////////////////////////////////////
+
+class exception : public std::exception {
+public:
+  exception( char const *function, char const *uri, char const *msg = 0 );
+  exception( char const *function, char const *uri, CURLcode code );
+  exception( char const *function, char const *uri, CURLMcode code );
+  ~exception() throw();
+
+  virtual const char* what() const throw();
+
+private:
+  std::string msg_;
+};
+
+////////// create & destroy ///////////////////////////////////////////////////
+
+/**
+  * The signature type of cURL's write function callback.
+  */
+typedef size_t (*write_fn_t)( void*, size_t, size_t, void* );
+
+/**
+  * Creates a new, initialized cURL instance.
+  *
+  * @throws exception upon failure.
+  */
+CURL* create( char const *uri, write_fn_t fn, void *data );
+
+/**
+  * Destroys a cURL instance.
+  *
+  * @param instance A cURL instance.  If \c NULL, does nothing.
+  */
+void destroy( CURL *instance );
+
+////////// streambuf //////////////////////////////////////////////////////////
+
+/**
+  * A curl::streambuf is-a std::streambuf for streaming the contents of URI
+  * using cURL.  However, do not use this class directly.  Use uri::streambuf
+  * instead.
+  */
+class streambuf : public std::streambuf {
+public:
+  /**
+   * Constructs a %streambuf.
+   */
+  streambuf();
+
+  /**
+   * Constructs a %streambuf and opens a connection to the server hosting the
+   * given URI for subsequent streaming.
+   *
+   * @param uri The URI to stream.
+   */
+  streambuf( char const *uri );
+
+  /**
+   * Constructs a %streambuf using an existing CURL object.
+   *
+   * @param curl The CURL object to use.  This %streambuf takes ownership of
+   * it.
+   */
+  streambuf( CURL *curl );
+
+  /**
+   * Destroys a %streambuf.
+   */
+  ~streambuf();
+
+  /**
+   * Opens a connection to the server hosting the given URI for subsequent
+   * streaming.
+   *
+   * @param uri The URI to stream.
+   * @throws exception upon failure.
+   */
+  void open( char const *uri );
+
+  /**
+   * Tests whether the buffer is open.
+   *
+   * @return Returns \c true only if the buffer is open.
+   */
+  bool is_open() const {
+    return !!curl_;
+  }
+
+  /**
+   * Closes this %streambuf.
+   */
+  void close();
+
+  /**
+   * Gets the CURL object in use.
+   *
+   * @return Return said CURL object.
+   */
+  CURL* curl() const {
+    return curl_;
+  }
+
+  /**
+   * Provide a InformDataRead that will get callbacks about read events.
+   */
+  void setInformer( http_client::InformDataRead *aInformer ) {
+    theInformer = aInformer;
+  }
+
+  /**
+   * Specify whether this streambuf has memory ownership over the
+   * InformDataRead it has been passed. You can use this if, for example,
+   * the lifetime of the streambuf will extend past the lifetime of the
+   * object which created the InformDataRead.
+   */
+  void setOwnInformer( bool aOwnInformer ) {
+    theOwnInformer = aOwnInformer;
+  }
+
+  int multi_perform();
+
+protected:
+  // inherited
+  std::streamsize showmanyc();
+  int_type underflow();
+
+private:
+  void curl_read();
+  static size_t curl_write_callback( void*, size_t, size_t, void* );
+
+  void init();
+  void init_curlm();
+
+  char *buf_;
+  std::streamsize buf_capacity_;
+  std::streamoff buf_len_;
+
+  CURL *curl_;
+  CURLM *curlm_;
+  int curl_running_;
+  http_client::InformDataRead *theInformer;
+  bool theOwnInformer;
+
+  // forbid
+  streambuf( streambuf const& );
+  streambuf& operator=( streambuf const& );
+#ifdef WIN32
+  SOCKET dummy_socket_;
+#endif /* WIN32 */
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+} // namespace curl
+} // namespace zorba
+#endif /* ZORBA_CURL_UTIL_H */
+/* vim:set et sw=2 ts=2: */

=== added file 'modules/io/zorba/modules/http-client.xq.src/curl_wrappers.h'
--- modules/io/zorba/modules/http-client.xq.src/curl_wrappers.h	1970-01-01 00:00:00 +0000
+++ modules/io/zorba/modules/http-client.xq.src/curl_wrappers.h	2013-06-15 00:58:33 +0000
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2006-2013 The FLWOR Foundation.
+ *
+ * Licensed 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.
+ */
+
+#ifndef CURL_WRAPPERS_H
+#define CURL_WRAPPERS_H
+
+#include <curl/curl.h>
+#include <iostream>
+
+#define LOC_INFO  << __FILE__ << ":" << __LINE__ << std::endl
+
+CURL* curl_easy_init_wrapped(const char* file, const int line);
+
+CURLcode curl_easy_setopt_wrapped(const char* file, const int line, CURL* curl, CURLoption option, char* char_args);
+
+CURLcode curl_easy_setopt_wrapped(const char* file, const int line, CURL* curl, CURLoption option, const char* args);
+CURLcode curl_easy_setopt_wrapped(const char* file, const int line, CURL* curl, CURLoption option, void* args);
+CURLcode curl_easy_setopt_wrapped(const char* file, const int line, CURL* curl, CURLoption option, size_t(*)(char*, size_t, size_t, void*));
+CURLcode curl_easy_setopt_wrapped(const char* file, const int line, CURL* curl, CURLoption option, size_t(*)(void*, size_t, size_t, void*));
+CURLcode curl_easy_setopt_wrapped(const char* file, const int line, CURL* curl, CURLoption option, int args);
+
+CURLMcode curl_multi_perform_wrapped(const char*file, const int line, CURLM *multi_handle, int *running_handles);
+CURLMsg* curl_multi_info_read_wrapped(const char* file, const int line, CURLM *multi_handle, int *msgs_in_queue);
+CURLMcode curl_multi_add_handle_wrapped(const char* file, const int line, CURLM *multi_handle, CURL *curl_handle);
+CURLMcode curl_multi_remove_handle_wrapped(const char* file, const int line, CURLM *multi_handle, CURL *curl_handle);
+
+void curl_slist_free_all_wrapped(const char* file, const int line, curl_slist *list);
+void curl_formfree_wrapped(const char*file, const int line, curl_httppost *form);
+
+curl_slist* curl_slist_append_wrapped(const char* file, const int line, curl_slist *list, const char *value);
+
+#endif // CURL_WRAPPERS_H

=== added file 'modules/io/zorba/modules/http-client.xq.src/error_thrower.h'
--- modules/io/zorba/modules/http-client.xq.src/error_thrower.h	1970-01-01 00:00:00 +0000
+++ modules/io/zorba/modules/http-client.xq.src/error_thrower.h	2013-06-15 00:58:33 +0000
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2006-2013 The FLWOR Foundation.
+ *
+ * Licensed 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.
+ */
+
+#pragma once
+#include <zorba/zorba.h>
+#include <zorba/user_exception.h>
+#include <curl/curl.h>
+
+namespace zorba {
+namespace http_client {
+
+class ErrorThrower 
+{
+private:
+  ItemFactory* theFactory;
+  struct curl_slist** theHeaderList;
+  const String& theModuleURI;
+
+public:
+  ErrorThrower(ItemFactory* aFactory, struct curl_slist** aHeaderList, const String& aModuleURI)
+    :
+    theFactory(aFactory),
+    theHeaderList(aHeaderList),
+    theModuleURI(aModuleURI)
+  {
+  }
+
+  void raiseException( String const &aNamespace, String const &aLocalName,
+                       String const &aDescription )
+  {
+    if (*theHeaderList) 
+      curl_slist_free_all(*theHeaderList);
+
+    throw USER_EXCEPTION(
+      theFactory->createQName(aNamespace, aLocalName), aDescription
+    );
+  }
+
+  void raiseException( String const &aLocalName,
+                         String const &aDescription )
+    {
+      if (*theHeaderList)
+        curl_slist_free_all(*theHeaderList);
+
+      throw USER_EXCEPTION(
+        theFactory->createQName(theModuleURI, aLocalName), aDescription
+      );
+    }
+};
+  
+} // namespace http_client
+} // namespace zorba
+/* vim:set et sw=2 ts=2: */

=== added file 'modules/io/zorba/modules/http-client.xq.src/http_client.cpp'
--- modules/io/zorba/modules/http-client.xq.src/http_client.cpp	1970-01-01 00:00:00 +0000
+++ modules/io/zorba/modules/http-client.xq.src/http_client.cpp	2013-06-15 00:58:33 +0000
@@ -0,0 +1,255 @@
+/*
+ * Copyright 2006-2013 The FLWOR Foundation.
+ * 
+ * Licensed 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.
+ */
+#include <curl/curl.h>
+#include <map>
+#include <zorba/zorba.h>
+#include <zorba/serializer.h>
+#include <zorba/external_module.h>
+#include <zorba/function.h>
+#include <zorba/empty_sequence.h>
+#include <zorba/user_exception.h>
+
+#include "http_request_handler.h"
+#include "request_parser.h"
+#include "http_response_handler.h"
+#include "http_response_parser.h"
+
+#ifdef WIN32
+# include <Windows.h>
+# define MAX_BUF_SIZE 2048
+#endif
+
+namespace zorba {
+
+  namespace http_client {
+#ifdef WIN32
+static void set_cacert(CURL* lCurl, std::string aPath)
+{
+  TCHAR path[MAX_BUF_SIZE];
+  int r = GetModuleFileName(NULL, path, 2048);
+  if (r == -1)
+  return;
+#	ifdef UNICODE
+  char buf[MAX_BUF_SIZE];
+  memset(buf, 0, MAX_BUF_SIZE);
+  for (int i = 0; i <= r; ++i)
+  {
+    buf[i] = (char) path[i];
+  }
+  std::string lPath(buf);
+#	else
+  std::string lPath(path);
+#	endif
+  aPath = lPath.substr(0, lPath.rfind('\\'));
+  aPath += "\\cacert.pem";
+  if(GetFileAttributesA(aPath.c_str()) != INVALID_FILE_ATTRIBUTES)
+  curl_easy_setopt(lCurl, CURLOPT_CAINFO, aPath.c_str());
+  else
+  curl_easy_setopt(lCurl, CURLOPT_SSL_VERIFYPEER, 0L);
+}
+#endif //WIN32
+
+    class HttpSendFunction : public ContextualExternalFunction {
+    protected:
+      const ExternalModule*     theModule;
+      ItemFactory*              theFactory;
+      
+    public:
+      HttpSendFunction(const ExternalModule* aModule) 
+      : theModule(aModule),
+      theFactory(Zorba::getInstance(0)->getItemFactory()) {}
+      
+      virtual ~HttpSendFunction() {}
+      
+    public:
+      virtual String
+      getURI() const { return theModule->getURI(); }
+      
+      virtual String
+      getLocalName() const { return "http-sequential-impl"; }
+      
+      virtual ItemSequence_t 
+      evaluate(const ExternalFunction::Arguments_t& args,
+               const StaticContext* aStaticContext, const DynamicContext* aDynamicContext)
+      const;
+    };
+    
+    class HttpReadFunction : public HttpSendFunction {
+    public:
+      HttpReadFunction(const ExternalModule* aModule) 
+      : HttpSendFunction(aModule) {}
+      
+      virtual ~HttpReadFunction() {}
+      
+    public:
+      virtual String
+      getLocalName() const { return "http-nondeterministic-impl"; }
+      
+    }; 
+    
+    class HttpClientModule : public ExternalModule {
+    protected:
+      class ltstr
+      {
+      public:
+        bool operator()(const String& s1, const String& s2) const
+        {
+          return s1.compare(s2) < 0;
+        }
+      };
+      
+      typedef std::map<String, ExternalFunction*, ltstr> FuncMap_t;
+      
+      FuncMap_t theFunctions;
+      
+    public:
+      virtual ~HttpClientModule();
+      
+      HttpClientModule() : theModuleUri("http://zorba.io/modules/http-client";)
+      {
+        for (FuncMap_t::const_iterator lIter = theFunctions.begin();
+             lIter != theFunctions.end(); ++lIter) {
+          delete lIter->second;
+        }
+        theFunctions.clear();
+      }
+      
+      virtual String
+      getURI() const { return theModuleUri; }
+      
+      virtual ExternalFunction*
+      getExternalFunction(const String& aLocalname)
+      {
+        ExternalFunction*& lFunc = theFunctions[aLocalname];
+        if (!lFunc) {
+          if (aLocalname == "http-sequential-impl") {
+            lFunc = new HttpSendFunction(this);
+          } else if (aLocalname == "http-nondeterministic-impl") {
+            lFunc = new HttpReadFunction(this);
+          } 
+        }
+        return lFunc;
+      }
+      
+      virtual void
+      destroy()
+      {
+        if (!dynamic_cast<HttpClientModule*>(this)) {
+          return;
+        }
+        delete this;
+      }
+      
+    private:
+      String theModuleUri;
+    };
+
+    ItemSequence_t
+    general_evaluate(
+        const ExternalFunction::Arguments_t& args,
+        const StaticContext* aStaticContext,
+        const DynamicContext* aDynamicContext,
+        ItemFactory* aFactory,
+        const String& aTheModuleURI)
+    {
+      CURL* lCURL = curl_easy_init();
+      
+      Item lRequest;
+      Item lHref;
+      Item lContent;
+
+      Iterator_t arg0_iter = args[0]->getIterator();
+      arg0_iter->open();
+      bool lReqSet = arg0_iter->next(lRequest);
+      arg0_iter->close();
+
+      std::string lData;
+
+      std::auto_ptr<HttpRequestHandler> lHandler;
+      std::auto_ptr<RequestParser> lParser;
+      struct curl_slist* lHeaderList = 0;
+
+      ErrorThrower thrower(aFactory, &lHeaderList,aTheModuleURI);
+
+      if (lReqSet) {
+        lHandler.reset(new HttpRequestHandler(lCURL));
+        lParser.reset(new RequestParser(lHandler.get(), thrower, aFactory));
+        lParser->parseRequest(lRequest);
+      }
+      //curl_easy_setopt(lCURL, CURLOPT_USERAGENT, "libcurl-agent/1.0");
+      //curl_easy_setopt(lCURL, CURLOPT_PROXY, "localhost:8888");
+#ifdef WIN32
+      std::string caCertPath;
+      set_cacert(lCURL, caCertPath);
+#endif
+      HttpResponseHandler lRespHandler(aFactory, lHeaderList);
+      String lOverrideContentType;
+      if (lHandler.get())
+        lHandler->getOverrideContentType(lOverrideContentType);
+      bool lStatusOnly =
+          lHandler.get() == NULL ? false : (lHandler->isStatusOnly() || lHandler->isHeadRequest());
+      // This gives the ownership of lCurl to the HttpResponseParser
+      std::auto_ptr<HttpResponseParser> lRespParser(new HttpResponseParser(lRespHandler, lCURL, thrower,
+        lOverrideContentType.c_str(), lStatusOnly));
+      int lRetCode = lRespParser->parse();
+
+      if (lRetCode == CURLE_OPERATION_TIMEDOUT)
+        thrower.raiseException("HC006", "A timeout occurred waiting for the response");
+      else if (lRetCode)
+      {
+        thrower.raiseException("HC001", "An HTTP error occurred");
+      }
+
+      // If the Parser is "self contained", that means it didn't create any
+      // objects with a lifecycle longer than itself; therefore we should free
+      // it (by letting auto_ptr delete it). If the Parser is not self contained,
+      // then it will have arranged for some other memory manager to free it
+      // later when appropriate; therefore we should NOT let auto_ptr delete it
+      // now.
+      if ( ! lRespParser->selfContained()) {
+        lRespParser.release();
+      }
+      return ItemSequence_t(lRespHandler.releaseResult());
+    }
+
+    ItemSequence_t 
+    HttpSendFunction::evaluate(const ExternalFunction::Arguments_t& args,
+      const StaticContext* aStaticContext, const DynamicContext* aDynamicContext) const 
+    {
+      return general_evaluate(args, aStaticContext, aDynamicContext, theFactory, getURI());
+    }
+
+    HttpClientModule::~HttpClientModule()
+    {
+      for (FuncMap_t::const_iterator lIter = theFunctions.begin();
+           lIter != theFunctions.end(); ++lIter) {
+        delete lIter->second;
+      }
+      theFunctions.clear();
+    }
+  } // namespace http_request
+} // namespace zorba
+
+#ifdef WIN32
+#  define DLL_EXPORT __declspec(dllexport)
+#else
+#  define DLL_EXPORT __attribute__ ((visibility("default")))
+#endif
+
+extern "C" DLL_EXPORT zorba::ExternalModule* createModule() {
+  return new zorba::http_client::HttpClientModule();
+}
+

=== added file 'modules/io/zorba/modules/http-client.xq.src/http_request_handler.cpp'
--- modules/io/zorba/modules/http-client.xq.src/http_request_handler.cpp	1970-01-01 00:00:00 +0000
+++ modules/io/zorba/modules/http-client.xq.src/http_request_handler.cpp	2013-06-15 00:58:33 +0000
@@ -0,0 +1,421 @@
+/*
+ * Copyright 2006-2013 The FLWOR Foundation.
+ * 
+ * Licensed 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.
+ */
+
+#include <iostream>
+#include <cassert>
+
+#include <zorba/zorba.h>
+#include <zorba/singleton_item_sequence.h>
+#include <zorba/serializer.h>
+#include <zorba/api_shared_types.h>
+#include <zorba/xquery_functions.h>
+#include <zorba/zorba_functions.h>
+#include <zorba/base64.h>
+#include <zorba/base64_stream.h>
+#include <zorba/xquery_functions.h>
+#include <zorba/transcode_stream.h>
+
+#include "http_request_handler.h"
+
+namespace zorba { namespace http_client {
+
+  HttpRequestHandler::HttpRequestHandler(CURL* aCurl)
+    : theCurl(aCurl),
+      theStatusOnly(false),
+      theInsideMultipart(false),
+      theLastBodyHadContent(false),
+      theSerStream(NULL),
+      thePost(NULL),
+      theLast(NULL),
+      theIsHeadRequest(false)
+  {
+    theHeaderLists.push_back(NULL);
+  }
+
+  HttpRequestHandler::~HttpRequestHandler()
+  {
+    std::vector<struct curl_slist*>::iterator lIter;
+    for (lIter = theHeaderLists.begin(); lIter != theHeaderLists.end(); ++lIter)
+    {
+      if (*lIter) {
+        curl_slist_free_all(*lIter);
+      }
+    }
+
+    if (thePost != NULL) {
+      curl_formfree(thePost);
+    }
+    delete theSerStream;
+  }
+
+  void HttpRequestHandler::begin()
+  {
+  }
+
+  void HttpRequestHandler::beginResponse(int aStatus, String aMessage)
+  {
+  }
+
+  void HttpRequestHandler::endResponse()
+  {
+  }
+
+  void HttpRequestHandler::beginRequest(String aMethod,
+                                        String href,
+                                        bool aStatusOnly,
+                                        String aUsername,
+                                        String aPassword,
+                                        String aAuthMethod,
+                                        bool aSendAuthorization,
+                                        String aOverrideContentType,
+                                        bool aFollowRedirect,
+                                        String aUserAgent,
+                                        int aTimeout /*= -1*/ )
+  {
+    aMethod = fn::upper_case(aMethod);
+    const char* lStr = aMethod.c_str();
+    theMethodString = lStr;
+    String const lAuthMethod = fn::lower_case(aAuthMethod);
+    if (theMethodString == "HEAD" || theMethodString == "OPTIONS") {
+      curl_easy_setopt(theCurl, CURLOPT_NOBODY, 1L);
+      theIsHeadRequest = true;
+    }
+    curl_easy_setopt(theCurl, CURLOPT_CUSTOMREQUEST, theMethodString.c_str());
+    if (href != "") {
+      curl_easy_setopt(theCurl, CURLOPT_URL, href.c_str());
+    }
+    if (aFollowRedirect) {
+      curl_easy_setopt(theCurl, CURLOPT_FOLLOWLOCATION, 1);
+    }
+    theStatusOnly = aStatusOnly;
+    theOverrideContentType = aOverrideContentType;
+    if (aTimeout != -1) {
+      curl_easy_setopt(theCurl, CURLOPT_TIMEOUT, aTimeout);
+    }
+    if (aUserAgent != "")
+      curl_easy_setopt( theCurl, CURLOPT_USERAGENT, aUserAgent.c_str() );
+    else
+      curl_easy_setopt( theCurl, CURLOPT_USERAGENT, "libcurl-agent/1.0" );
+
+    if (aUsername != "" && !aSendAuthorization) {
+      String lUserPw = aUsername + ":" + aPassword;
+      theUserPW = lUserPw.c_str();
+      curl_easy_setopt(theCurl, CURLOPT_USERPWD, theUserPW.c_str());
+      if (lAuthMethod == "basic") {
+        curl_easy_setopt(theCurl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
+      } else if (lAuthMethod == "digest") {
+        curl_easy_setopt(theCurl, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
+      }
+    }
+    if (aUsername != "" && aSendAuthorization) {
+      if (lAuthMethod == "digest") {
+        String lUserPw = aUsername + ":" + aPassword;
+        theUserPW = lUserPw.c_str();
+        curl_easy_setopt(theCurl, CURLOPT_USERPWD, theUserPW.c_str());
+        curl_easy_setopt(theCurl, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
+      } else {
+        String lAuthString = aUsername + ":" + aPassword;
+        String lAuth = "Authorization: ";
+        if (lAuthMethod == "basic")
+        {
+          lAuth += "Basic ";
+        }
+        else
+        {
+          lAuth += aAuthMethod + " ";
+        }
+        lAuth += encoding::Base64::encode(lAuthString);
+        theAuthMethod = lAuth.c_str();
+        theHeaderLists[0] = curl_slist_append(theHeaderLists[0], theAuthMethod.c_str());
+      }
+    }
+  }
+
+  void HttpRequestHandler::endRequest()
+  {
+  }
+
+  void HttpRequestHandler::header(String aName, String aValue)
+  {
+    std::string lValue = aName.c_str();
+    lValue += ":";
+    lValue += aValue.c_str();
+    theHeaderStrings.push_back(lValue);
+    if (!theInsideMultipart) {
+      theHeaderLists[0] = curl_slist_append(theHeaderLists[0], lValue.c_str());
+    } else {
+      if (aName == "Content-Disposition") {
+        Sequence<String> lTokens(fn::tokenize(aValue, ";"));
+        for (String lNextToken; lTokens.next( &lNextToken );) {
+          std::pair<String, String> lKeyValue = twinSplit(lNextToken);
+          if (lKeyValue.first == "name") {
+            theMultipartName = lKeyValue.second;
+            zfn::trim(theMultipartName, "\"\'");
+          }
+          else if (lKeyValue.first == "filename") {
+            theMultiPartFileName = lKeyValue.second;
+            zfn::trim(theMultiPartFileName, "\"\'");
+          }
+        }
+      } else {
+        theHeaderLists.back() = curl_slist_append(theHeaderLists.back(), (lValue).c_str());
+      }
+    }
+  }
+
+  void HttpRequestHandler::beginBody(String aContentType,
+                                     String aSrc,
+                                     ItemSequence* aSerializerOptions)
+  {
+    theLastSerializerOptions = aSerializerOptions;
+    theSerStream = new std::ostringstream();
+    theCurrentContentType = aContentType;
+    theContentType = "Content-Type: ";
+    theContentType += aContentType.c_str();
+    if (!theInsideMultipart) {
+      theHeaderLists[0] = curl_slist_append(theHeaderLists[0], theContentType.c_str());
+    } else {
+      theHeaderLists.back() = curl_slist_append(theHeaderLists.back(), theContentType.c_str());
+    }
+  }
+    void HttpRequestHandler::any(Item aItem, std::string& charset)
+    {
+      theLastBodyHadContent = true;
+      bool lTranscoderAttached = false;
+
+      switch (aItem.getTypeCode())
+      {
+        case store::XS_STRING:
+          if (!charset.empty() && transcode::is_necessary(charset.c_str()))
+          {
+            transcode::attach(*theSerStream,charset.c_str());
+            lTranscoderAttached = true;
+          }
+
+          try
+          {
+            if (aItem.isStreamable())
+              emitStreamableString(aItem);
+            else
+              emitString(aItem);
+          }
+          catch ( ... )
+          {
+            if (lTranscoderAttached)
+              transcode::detach(*theSerStream);
+          }
+
+          if (lTranscoderAttached)
+            transcode::detach(*theSerStream);
+          break;
+        case store::XS_BASE64BINARY:
+          if (aItem.isStreamable())
+            emitStreamableBase64Binary(aItem);
+          else
+            emitBase64Binary(aItem);
+          break;
+        default:
+          assert(false);
+      }
+    }
+
+  void HttpRequestHandler::emitStreamableString(Item aItem)
+  {
+    char buffer[1024];
+    std::streambuf *  pbuf;
+    std::streamsize   read_bytes;
+    std::istream& is = aItem.getStream();
+    std::streampos pos;
+    std::ios::iostate const old_exceptions = is.exceptions();
+
+      if (aItem.isSeekable())
+      {
+        // prepare the stream
+        is.exceptions( std::ios::badbit | std::ios::failbit );
+        pos = is.tellg();
+        if (pos)
+          is.seekg(0, std::ios::beg);
+        is.exceptions(is.exceptions() & ~std::ios::failbit);
+      }
+
+      // read bytes and do string expansion
+      do
+      {
+        //std::istream::read uses a try/catch internally so the Zorba_Exception is
+        //lost: that is why we are using std::streambuf::sgetn
+        pbuf = is.rdbuf();
+        read_bytes = pbuf->sgetn(buffer, 1024);
+        theSerStream->write(buffer, read_bytes);
+      }
+      while (read_bytes > 0);
+
+      // restore stream's state
+      is.clear();                   // clear eofbit
+      if (aItem.isSeekable())
+      {
+        if (pos)
+        {
+          is.exceptions(is.exceptions() | std::ios::failbit);
+          is.seekg(pos, std::ios::beg);
+        }
+        is.exceptions(old_exceptions);
+      }
+  }
+
+  void HttpRequestHandler::emitString(Item aItem)
+  {
+    *theSerStream << aItem.getStringValue();
+  }
+
+  void HttpRequestHandler::emitStreamableBase64Binary(Item aItem)
+  {
+    std::istream& stream = aItem.getStream();
+    bool lDecoderAttached = false;
+
+    if (aItem.isEncoded())
+    {
+      base64::attach(stream);
+      lDecoderAttached = true;
+    }
+
+    char buf[1024];
+    while (!stream.eof())
+    {
+      stream.read(buf, 1024);
+      theSerStream->write(buf, stream.gcount());
+    }
+
+    if (lDecoderAttached)
+      base64::detach(stream);
+  }
+
+  void HttpRequestHandler::emitBase64Binary(Item aItem)
+  {
+    size_t lLen = 0;
+    const char * lData = aItem.getBase64BinaryValue(lLen);
+    if (aItem.isEncoded())
+    {
+      String lEncoded(lData,lLen);
+      String lDecodedData = encoding::Base64::decode(lEncoded);
+      *theSerStream << lDecodedData;
+    }
+    else
+    {
+      theSerStream->write(lData,lLen);
+    }
+  }
+
+  void HttpRequestHandler::endBody()
+  {
+    if (!theLastBodyHadContent)
+    {
+        cleanUpBody();
+        return;
+    }
+    thePostDataString = theSerStream->str();
+    thePostData = thePostDataString.c_str();
+    if (!theInsideMultipart) {
+      curl_easy_setopt(theCurl, CURLOPT_POSTFIELDSIZE, thePostDataString.length());
+      curl_easy_setopt(theCurl, CURLOPT_POSTFIELDS, thePostData);
+    } else {
+      if (theMultiPartFileName == "")
+        curl_formadd(&thePost, &theLast,
+                     CURLFORM_COPYNAME, theMultipartName.c_str(),
+                     CURLFORM_COPYCONTENTS, thePostData,
+                     CURLFORM_CONTENTSLENGTH, thePostDataString.length(),
+                     CURLFORM_CONTENTHEADER, theHeaderLists.back(),
+                     CURLFORM_END);
+      else
+        curl_formadd(&thePost, &theLast,
+                     CURLFORM_COPYNAME, theMultipartName.c_str(),
+                     CURLFORM_BUFFER, theMultiPartFileName.c_str(),
+                     CURLFORM_BUFFERPTR, thePostData,
+                     CURLFORM_BUFFERLENGTH, thePostDataString.length(),
+                     CURLFORM_CONTENTHEADER, theHeaderLists.back(),
+                     CURLFORM_END);
+      theHeaderLists.push_back(NULL);
+    }
+  }
+
+  void HttpRequestHandler::beginMultipart(String aContentType, String aBoundary)
+  {
+    theMultiPartFileName = "";
+    theMultipartName = "zorba-default";
+    theInsideMultipart = true;
+    std::string lValue = "Content-Type: ";
+    lValue += aContentType.c_str();
+    theHeaderStrings.push_back (lValue);
+    theHeaderLists[0] = curl_slist_append(theHeaderLists[0], lValue.c_str());
+    theHeaderLists.push_back(NULL);
+  }
+
+  void HttpRequestHandler::endMultipart()
+  {
+    theInsideMultipart = false;
+    curl_easy_setopt(theCurl, CURLOPT_HTTPPOST, thePost);
+  }
+
+  void HttpRequestHandler::end()
+  {
+    if (theHeaderLists[0]) {
+      curl_easy_setopt(theCurl, CURLOPT_HTTPHEADER, theHeaderLists[0]);
+    }
+  }
+
+  bool HttpRequestHandler::getOverrideContentType( String& aResult )
+  {
+    if (theOverrideContentType == "") {
+      return false;
+    }
+    aResult = theOverrideContentType;
+    return true;
+  }
+
+  void HttpRequestHandler::cleanUpBody()
+  {
+    delete theSerStream;
+    theSerStream = 0;
+    theLastBodyHadContent = false;
+  }
+
+  void HttpRequestHandler::serializeItem( Item aItem )
+  {
+    theLastBodyHadContent = true;
+    Serializer_t lSerializer =
+    Serializer::createSerializer(theLastSerializerOptions);
+    SingletonItemSequence lSequence(aItem);
+    lSerializer->serialize(&lSequence, *theSerStream);
+  }
+
+  std::pair<String, String>
+  HttpRequestHandler::twinSplit(const String& aStr)
+  {
+    String lKey, lValue;
+
+    String::size_type const equals = aStr.find('=');
+    if (equals != String::npos) {
+      lKey = aStr.substr(0, equals);
+      lValue = aStr.substr(equals + 1);
+      zfn::trim(lKey);
+      zfn::trim(lValue);
+    }
+
+    return std::pair<String, String>(lKey, lValue);
+  }
+
+} // namespace http_client
+} // namespace zorba
+/* vim:set et sw=2 ts=2: */

=== added file 'modules/io/zorba/modules/http-client.xq.src/http_request_handler.h'
--- modules/io/zorba/modules/http-client.xq.src/http_request_handler.h	1970-01-01 00:00:00 +0000
+++ modules/io/zorba/modules/http-client.xq.src/http_request_handler.h	2013-06-15 00:58:33 +0000
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2006-2013 The FLWOR Foundation.
+ * 
+ * Licensed 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.
+ */
+#ifndef HTTP_REQUEST_HANDLER_H
+#define HTTP_REQUEST_HANDLER_H
+
+#include <sstream>
+#include <vector>
+#include <string>
+
+#include <curl/curl.h>
+#include <zorba/zorba.h>
+
+#include "request_handler.h"
+
+namespace zorba { namespace http_client {
+
+  class HttpRequestHandler : public RequestHandler {
+  private:
+    CURL* theCurl;
+    bool theStatusOnly;
+    String theOverrideContentType;
+    bool theInsideMultipart;
+    std::vector<struct curl_slist*> theHeaderLists;
+    bool theLastBodyHadContent;
+    std::ostringstream* theSerStream;
+    struct curl_httppost* thePost;
+    struct curl_httppost* theLast;
+    String theCurrentContentType;
+    ItemSequence* theLastSerializerOptions;
+    std::string thePostDataString;
+    const char* thePostData;
+    long thePostDataSize;
+    String theMultipartName;
+    String theMultiPartFileName;
+    // saved strings which won't be copied by curl
+    std::string theMethodString;
+    std::string theUserPW;
+    std::string theAuthMethod;
+    std::vector<std::string> theHeaderStrings;
+    std::string theContentType;
+    bool theIsHeadRequest;
+
+  public: //Constructions
+    HttpRequestHandler(CURL* aCurl);
+    virtual ~HttpRequestHandler();
+
+  public: //Interfaces
+    /**
+     * @brief Get the override-content-type option.
+     *
+     * If the user set the override-content-type option, this method will
+     * set the result to the user specified value and will return true.
+     * Otherwise it will return false.
+     *
+     * @param aResult The override-content-type option, if set.
+     * @return A boolean indicating if the override-content-type is set.
+     */
+    bool getOverrideContentType(String& aResult);
+
+  public: //Implementation of parent interface
+    virtual void begin();
+    virtual void beginResponse(int aStatus, String aMessage);
+    virtual void endResponse();
+    virtual void beginRequest(
+      String aMethod,
+      String href,
+      bool aStatusOnly,
+      String aUsername,
+      String aPassword,
+      String aAuthMethod,
+      bool aSendAuthorization,
+      String aOverrideContentType,
+      bool aFollowRedirect,
+      String aUserAgent,
+      int aTimeout = -1);
+    virtual void endRequest();
+    virtual void header(String aName, String aValue);
+    virtual void beginBody(
+      String aContentType,
+      String aSrc,
+      ItemSequence* aSerializerOptions);
+    virtual void any(Item aItem, std::string& charset);
+
+    virtual void emitStreamableString(Item aItem);
+    virtual void emitString(Item aItem);
+    virtual void emitStreamableBase64Binary(Item aItem);
+    virtual void emitBase64Binary(Item aItem);
+
+
+    void serializeItem( Item aItem );
+    virtual void endBody();
+    virtual void beginMultipart(String aContentType, String aBoundary);
+    virtual void endMultipart();
+    virtual void end();
+
+    bool isStatusOnly() const { return theStatusOnly; }
+    virtual bool isHeadRequest() const { return theIsHeadRequest; }
+
+  private: //Helper functions
+    void cleanUpBody();
+    static std::pair<String, String> twinSplit(const String& aStr);
+  };
+
+}}
+
+#endif //HTTP_REQUEST_HANDLER_H

=== added file 'modules/io/zorba/modules/http-client.xq.src/http_response_handler.cpp'
--- modules/io/zorba/modules/http-client.xq.src/http_response_handler.cpp	1970-01-01 00:00:00 +0000
+++ modules/io/zorba/modules/http-client.xq.src/http_response_handler.cpp	2013-06-15 00:58:33 +0000
@@ -0,0 +1,294 @@
+/*
+ * Copyright 2006-2013 The FLWOR Foundation.
+ * 
+ * Licensed 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.
+ */
+
+#include <zorba/xquery_exception.h>
+#include <zorba/item.h>
+#include <zorba/item_factory.h>
+#include <zorba/zorba_string.h>
+
+#include "http_response_handler.h"
+#include "http_response_parser.h"
+
+namespace zorba { namespace http_client {
+
+  //////////////////////////////////////////////////////////////////////////
+  // HttpResponseIterator
+  //////////////////////////////////////////////////////////////////////////
+
+  const char* theNamespace = "http://expath.org/ns/http-client";;
+
+  HttpResponseIterator::HttpResponseIterator(curl_slist* aHeaderList)
+    : theResponseSet(false), theHeaderList(aHeaderList)
+  {
+    // Set an empty item as the response item
+    theItems.push_back(Item());
+  }
+
+  HttpResponseIterator::~HttpResponseIterator()
+  {
+    if (theHeaderList)
+      curl_slist_free_all(theHeaderList);
+  }
+
+  Iterator_t HttpResponseIterator::getIterator()
+  {
+    return new InternalIterator(this);
+  }
+
+  HttpResponseIterator::InternalIterator::InternalIterator(HttpResponseIterator *item_sequence) : 
+    theItemSequence(item_sequence),
+    theIndex(0)
+  {
+    is_open = false;
+  }
+
+  void HttpResponseIterator::InternalIterator::open()
+  {
+     theIndex = 0;
+    is_open = true;
+  }
+
+  void HttpResponseIterator::InternalIterator::close()
+  {
+    is_open = false;
+  }
+
+  bool HttpResponseIterator::InternalIterator::isOpen() const
+  {
+    return is_open;
+  }
+
+  bool HttpResponseIterator::InternalIterator::next( Item& aItem )
+  {
+    if (!theItemSequence->theResponseSet) {
+      return false;
+    }
+    if (theIndex < theItemSequence->theItems.size()) {
+      aItem = theItemSequence->theItems[theIndex];
+      ++theIndex;
+      return !aItem.isNull();
+    }
+    return false;
+  }
+
+  void HttpResponseIterator::addItem(const Item& aItem)
+  {
+    theItems.push_back(aItem);
+  }
+
+  void HttpResponseIterator::setResponseItem(const Item& aItem)
+  {
+    theItems[0] = aItem;
+    theResponseSet = true;
+  }
+        
+  //////////////////////////////////////////////////////////////////////////
+  // HttpResponseHandler
+  //////////////////////////////////////////////////////////////////////////
+
+  HttpResponseHandler::HttpResponseHandler(ItemFactory* aFactory, curl_slist* aHeaderList)
+    :
+  theResult(new HttpResponseIterator(aHeaderList)),
+  theFactory(aFactory),
+  theIsInsideMultipart(false),
+  theDeleteResponse(true)
+  {
+    theUntypedQName = theFactory->createQName("http://www.w3.org/2001/XMLSchema";, "untyped");
+  }
+
+  HttpResponseHandler::~HttpResponseHandler() {
+    if (theDeleteResponse) {
+      delete theResult;
+    }
+  }
+
+  void HttpResponseHandler::begin()
+  {
+  }
+
+  void HttpResponseHandler::beginResponse(int aStatus, String aMessage)
+  {
+    Item lStatusName = theFactory->createString("status");
+    Item lStatusValue = theFactory->createInteger(aStatus);
+
+    Item lMessageName = theFactory->createString("message");
+    Item lMessageValue = theFactory->createString(aMessage);
+
+    theResponsePairs.push_back(std::pair<Item, Item>(lStatusName, lStatusValue));
+    theResponsePairs.push_back(std::pair<Item, Item>(lMessageName, lMessageValue));
+  }
+
+  void HttpResponseHandler::endResponse()
+  {
+    if (theResponseHeaderMap.size()>0)
+    {
+      Item lHeadersName = theFactory->createString("headers");
+      std::vector<std::pair<Item,Item> > lHeadersPairs;
+
+      std::map<String,String>::iterator it = theResponseHeaderMap.begin();
+      std::map<String,String>::iterator end = theResponseHeaderMap.end();
+      Item lName;
+      Item lValue;
+      for (;it!=end;++it)
+      {
+        lName = theFactory->createString(it->first);
+        lValue = theFactory->createString(it->second);
+        lHeadersPairs.push_back(std::pair<Item,Item>(lName,lValue));
+      }
+      Item lHeaders = theFactory->createJSONObject(lHeadersPairs);
+      theResponsePairs.push_back(std::pair<Item,Item>(lHeadersName,lHeaders));
+    }
+
+    Item lResponse = theFactory->createJSONObject(theResponsePairs);
+    theResult->setResponseItem(lResponse);
+  }
+
+  // Since this class is only used to handle responses, beginRequest and
+  // endRequest are not implemented.
+  void HttpResponseHandler::beginRequest(String aMethod,
+                                         String href,
+                                         bool aStatusOnly,
+                                         String aUsername,
+                                         String aPassword,
+                                         String aAuthMethod,
+                                         bool aSendAuthorization,
+                                         String aOverrideContentType,
+                                         bool aFollowRedirect,
+                                         String aUserAgent,
+                                         int aTimeout /*= -1*/)
+  {
+  }
+
+  void HttpResponseHandler::endRequest()
+  {
+  }
+
+  void HttpResponseHandler::header(String aName, String aValue)
+  {
+    std::map<String, String>& lHeaderMap =
+      theIsInsideMultipart ? theMultipartHeaderMap : theResponseHeaderMap;
+
+    if (lHeaderMap.find(aName)!=lHeaderMap.end())
+      lHeaderMap[aName] = lHeaderMap[aName] + ","  +aValue;
+    else
+      lHeaderMap[aName] = aValue;
+  }
+
+  void HttpResponseHandler::beginBody(String aContentType,
+                                      String aSrc,
+                                      ItemSequence* aSerializerOptions)
+  {
+    std::vector<std::pair<Item, Item> >& lBodyPairs =
+      theIsInsideMultipart ? theMultipartBodyPairs : theBodyPairs;
+
+    Item lName = theFactory->createString("media-type");
+    Item lValue = theFactory->createString(aContentType);
+
+    lBodyPairs.push_back(std::pair<Item, Item>(lName,lValue));
+  }
+
+  void HttpResponseHandler::any(Item aItem, std::string& charset)
+  {
+    std::vector<std::pair<Item, Item> >& lBodyPairs =
+          theIsInsideMultipart ? theMultipartBodyPairs : theBodyPairs;
+    Item lContentName = theFactory->createString("content");
+    lBodyPairs.push_back(std::pair<Item,Item>(lContentName,aItem));
+  }
+
+  void HttpResponseHandler::endBody()
+  {
+    std::vector<std::pair<Item, Item> >& lBodyPairs =
+      theIsInsideMultipart ? theMultipartBodyPairs : theBodyPairs;
+
+    Item lBody = theFactory->createJSONObject(lBodyPairs);
+    if (theIsInsideMultipart)
+    {
+      std::vector<std::pair<Item,Item> > lPartsPairs;
+      if (theMultipartHeaderMap.size()>0)
+      {
+        Item lHeadersName = theFactory->createString("headers");
+        std::vector<std::pair<Item,Item> > lHeadersPairs;
+
+        std::map<String,String>::iterator it = theMultipartHeaderMap.begin();
+        std::map<String,String>::iterator end = theMultipartHeaderMap.end();
+        Item lName;
+        Item lValue;
+        for (; it != end; ++it)
+        {
+          lName = theFactory->createString(it->first);
+          lValue = theFactory->createString(it->second);
+          lHeadersPairs.push_back(std::pair<Item, Item>(lName, lValue));
+        }
+
+        Item lHeaders = theFactory->createJSONObject(lHeadersPairs);
+        lPartsPairs.push_back(std::pair<Item,Item>(lHeadersName,lHeaders));
+        theMultipartHeaderMap = std::map<String, String>();
+      }
+
+      Item lBodyName = theFactory->createString("body");
+      lPartsPairs.push_back(std::pair<Item,Item>(lBodyName,lBody));
+      Item lPart = theFactory->createJSONObject(lPartsPairs);
+      theMultipartBodyVector.push_back(lPart);
+    }
+    else
+    {
+      Item lName = theFactory->createString("body");
+      theResponsePairs.push_back(std::pair<Item,Item>(lName,lBody));
+    }
+  }
+
+  void HttpResponseHandler::beginMultipart(String aContentType, String aBoundary)
+  {
+    theIsInsideMultipart = true;
+
+    Item lContentTypeName = theFactory->createString("content-type");
+    Item lContentTypeValue = theFactory->createString(aContentType);
+
+    theMultipartPairs.push_back(std::pair<Item,Item>(lContentTypeName, lContentTypeValue));
+
+    Item lBoundaryName = theFactory->createString("boundary");
+    Item lBoundaryValue = theFactory->createString(aBoundary);
+
+    theMultipartPairs.push_back(std::pair<Item,Item>(lBoundaryName, lBoundaryValue));
+  }
+
+  void HttpResponseHandler::endMultipart()
+  {
+    theIsInsideMultipart = false;
+    Item lBodyName = theFactory->createString("parts");
+    Item lBodyArray = theFactory->createJSONArray(theMultipartBodyVector);
+
+    theMultipartPairs.push_back(std::pair<Item,Item>(lBodyName,lBodyArray));
+    Item lName = theFactory->createString("multipart");
+    Item lMultipart = theFactory->createJSONObject(theMultipartBodyPairs);
+    theResponsePairs.push_back(std::pair<Item,Item>(lName,lMultipart));
+  }
+
+  void HttpResponseHandler::end()
+  {
+  }
+
+  HttpResponseIterator* HttpResponseHandler::getResult()
+  {
+    return theResult;
+  }
+
+  HttpResponseIterator* HttpResponseHandler::releaseResult()
+  {
+    theDeleteResponse = false;
+    return theResult;
+  }
+}} //namespace zorba, namespace http_client

=== added file 'modules/io/zorba/modules/http-client.xq.src/http_response_handler.h'
--- modules/io/zorba/modules/http-client.xq.src/http_response_handler.h	1970-01-01 00:00:00 +0000
+++ modules/io/zorba/modules/http-client.xq.src/http_response_handler.h	2013-06-15 00:58:33 +0000
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2006-2013 The FLWOR Foundation.
+ * 
+ * Licensed 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.
+ */
+#ifndef HTTP_RESPONSE_HANDLER_H
+#define HTTP_RESPONSE_HANDLER_H
+
+#include <vector>
+#include <string>
+#include <map>
+#include <curl/curl.h>
+
+#include <zorba/item_sequence.h>
+#include <zorba/iterator.h>
+
+#include "request_handler.h"
+
+namespace zorba {
+class Item;
+class ItemFactory;
+namespace http_client {
+  class HttpResponseParser;
+
+  class HttpResponseIterator : public ItemSequence {
+    class InternalIterator : public Iterator
+    {
+    private:
+      HttpResponseIterator*   theItemSequence;
+      std::vector<Item>::size_type theIndex;
+      bool is_open;
+    public:
+      InternalIterator(HttpResponseIterator *item_sequence);
+
+      virtual void open();
+      virtual bool next(Item& aItem);
+      virtual void close();
+      virtual bool isOpen() const;
+    };
+  private:
+    std::vector<Item> theItems;
+    bool theResponseSet;
+  public:
+    HttpResponseIterator(curl_slist* aHeaderList);
+    virtual ~HttpResponseIterator();
+
+  public:
+    virtual Iterator_t getIterator();
+
+  public: //Implementation specific functions
+    void addItem(const Item& aItem);
+    void setResponseItem(const Item& aItem);
+    
+  public:
+    static void streamReleaser(std::istream* aStream);
+    
+  private:
+    curl_slist* theHeaderList;
+  };
+
+  class HttpResponseHandler : public RequestHandler {
+  private:
+    HttpResponseIterator* theResult;
+    std::vector<std::pair<Item, Item> > theResponsePairs;
+
+    std::map<String, String> theResponseHeaderMap;
+    std::map<String, String> theMultipartHeaderMap;
+
+    std::vector<std::pair<Item, Item> > theMultipartPairs;
+
+    std::vector<std::pair<Item, Item> > theBodyPairs;
+    std::vector<std::pair<Item, Item> > theMultipartBodyPairs;
+
+    std::vector<Item> theMultipartBodyVector;
+
+    ItemFactory* theFactory;
+    bool theIsInsideMultipart;
+    bool theDeleteResponse;
+    Item theUntypedQName;
+  public:
+    HttpResponseHandler(ItemFactory* aFactory, curl_slist* theHeaderList);
+    virtual ~HttpResponseHandler();
+  public:
+    HttpResponseIterator* getResult();
+    HttpResponseIterator* releaseResult();
+  public: //Interface implementation
+    virtual void begin();
+    virtual void beginResponse(int aStatus, String aMessage);
+    virtual void endResponse();
+    virtual void beginRequest(
+      String aMethod,
+      String href,
+      bool aStatusOnly,
+      String aUsername,
+      String aPassword,
+      String aAuthMethod,
+      bool aSendAuthorization,
+      String aOverrideContentType,
+      bool aFollowRedirect,
+      String aUserAgent,
+      int aTimeout = -1);
+    virtual void endRequest();
+    virtual void header(String aName, String aValue);
+    virtual void beginBody(
+      String aContentType,
+      String aSrc,
+      ItemSequence* aSerializerOptions);
+    virtual void any(Item aItem, std::string& charset);
+    virtual void endBody();
+    virtual void beginMultipart(String aContentType, String aBoundary);
+    virtual void endMultipart();
+    virtual void end();
+    virtual bool isHeadRequest() const { return false; }
+  };
+}} //namespace zorba, namespace http_client
+
+#endif //HTTP_RESPONSE_HANDLER_H

=== added file 'modules/io/zorba/modules/http-client.xq.src/http_response_parser.cpp'
--- modules/io/zorba/modules/http-client.xq.src/http_response_parser.cpp	1970-01-01 00:00:00 +0000
+++ modules/io/zorba/modules/http-client.xq.src/http_response_parser.cpp	2013-06-15 00:58:33 +0000
@@ -0,0 +1,349 @@
+/*
+ * Copyright 2006-2013 The FLWOR Foundation.
+ * 
+ * Licensed 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.
+ */
+
+#include <cassert>
+#include <cstring>
+#include <iostream>
+#include <sstream>
+#include <stdexcept>
+#include <string>
+
+#include <zorba/base64.h>
+#include <zorba/config.h>
+#include <zorba/diagnostic_list.h>
+#include <zorba/error.h>
+#include <zorba/item.h>
+#include <zorba/item_factory.h>
+#include <zorba/transcode_stream.h>
+#include <zorba/xmldatamanager.h>
+#include <zorba/xquery_exception.h>
+#include <zorba/xquery_exception.h>
+#include <zorba/xquery_functions.h>
+
+#include "http_response_parser.h"
+#include "http_request_handler.h"
+#include "curl_stream_buffer.h"
+
+namespace zorba {
+
+namespace http_client {
+
+void parse_content_type( std::string const &s, std::string *mime_type,
+                                std::string *charset ) {
+  std::string::size_type pos = s.find( ';' );
+  *mime_type = s.substr( 0, pos );
+
+  if ( std::strncmp( mime_type->c_str(), "text/", 5 ) == 0 ) {
+    //
+    // RFC 2616: "Hypertext Transfer Protocol -- HTTP/1.1," section 3.7.1,
+    // "Canonicalization and Text Defaults":
+    //
+    //    The "charset" parameter is used with some media types to define the
+    //    character set (section 3.4) of the data. When no explicit charset
+    //    parameter is provided by the sender, media subtypes of the "text"
+    //    type are defined to have a default charset value of "ISO-8859-1" when
+    //    received via HTTP.
+    //
+    *charset = "ISO-8859-1";
+  } else
+    charset->clear();
+
+  if ( pos != std::string::npos ) {
+    //
+    // Parse: charset="?XXXXX"?[ (comment)]
+    //
+    if ( (pos = s.find( '=' )) != std::string::npos ) {
+      std::string t = s.substr( pos + 1 );
+      if ( !t.empty() ) {
+        if ( t[0] == '"' ) {
+          t.erase( 0, 1 );
+          if ( (pos = t.find( '"' )) != std::string::npos )
+            t.erase( pos );
+        } else {
+          if ( (pos = t.find( ' ' )) != std::string::npos )
+            t.erase( pos );
+        }
+        *charset = t;
+      } 
+    }
+  }
+}
+
+
+  
+  HttpResponseParser::HttpResponseParser(RequestHandler& aHandler, CURL* aCurl,
+                                         ErrorThrower& aErrorThrower,
+                                         std::string aOverridenContentType,
+                                         bool aStatusOnly) : 
+  theHandler(aHandler),
+  theCurl(aCurl),
+  theErrorThrower(aErrorThrower),
+  theStatus(-1),
+  theStreamBuffer(0),
+  theInsideRead(false),
+  theOverridenContentType(aOverridenContentType),
+  theStatusOnly(aStatusOnly),
+  theSelfContained(true)
+  {
+    registerHandler();
+    theStreamBuffer = new zorba::curl::streambuf(theCurl);
+  }
+
+  HttpResponseParser::~HttpResponseParser()
+  {
+    delete theStreamBuffer;
+  }
+
+  int HttpResponseParser::parse()
+  {
+    theStreamBuffer->setInformer(this);
+    theHandler.begin();
+    bool lStatusAndMesssageParsed = false;
+    int lCode = 0;
+    lCode = theStreamBuffer->multi_perform();
+    if (lCode)
+      return lCode; 
+    if (!theStatusOnly) {
+
+      if (!theOverridenContentType.empty()) {
+        parse_content_type(
+          theOverridenContentType, &theCurrentContentType, &theCurrentCharset
+        );
+      }
+
+      std::auto_ptr<std::istream> lStream;
+      try {
+        if ( !theCurrentCharset.empty() &&
+             transcode::is_necessary( theCurrentCharset.c_str() ) ) {
+          lStream.reset(
+            new transcode::stream<std::istream>(
+              theCurrentCharset.c_str(), theStreamBuffer
+            )
+          );
+        } else
+          lStream.reset(new std::istream(theStreamBuffer));
+      }
+      catch ( std::invalid_argument const &e ) {
+        theErrorThrower.raiseException(
+          "http://www.zorba-xquery.com/errors";, "ZXQP0006", e.what()
+        );
+      }
+
+      Item lItem;
+      if (theCurrentContentType == "application/xml" ||
+          theCurrentContentType == "application/xml-external-parsed-entity" ||
+          theCurrentContentType == "application/json" ||
+          theCurrentContentType == "application/x-javascript" ||
+          theCurrentContentType == "text/javascript" ||
+          theCurrentContentType == "text/x-javascript" ||
+          theCurrentContentType == "text/x-json" ||
+          theCurrentContentType.find("+xml") == theCurrentContentType.size()-4 ||
+          theCurrentContentType.find("text/") == 0)
+      {
+        lItem = createTextItem(lStream.release());
+      }
+      else
+      {
+        lItem = createBase64Item(*lStream.get());
+      }
+
+      if (!lItem.isNull()) {
+        std::string empty;
+        theHandler.any(lItem, empty);
+      }
+      if (!theInsideRead) {
+        theHandler.beginResponse(theStatus, theMessage);
+        lStatusAndMesssageParsed = true;
+      } else {
+        theHandler.endBody();
+      }
+    }
+    if (!theInsideRead) {
+      if (!lStatusAndMesssageParsed)
+        theHandler.beginResponse(theStatus, theMessage);
+      for (std::vector<std::pair<std::string, std::string> >::iterator i = theHeaders.begin();
+          i != theHeaders.end(); ++i) {
+        theHandler.header(i->first, i->second);
+      }
+    }
+    theHandler.endResponse();
+    theHandler.end();
+    return lCode;
+  }
+
+  void HttpResponseParser::beforeRead()
+  {
+    if (theInsideRead) {
+      return;
+    }
+    theInsideRead = true;
+    theHandler.beginResponse(theStatus, theMessage);
+    for ( headers_type::const_iterator
+          lIter = theHeaders.begin(); lIter != theHeaders.end(); ++lIter) {
+      theHandler.header(lIter->first, lIter->second);
+    }
+    if (!theStatusOnly)
+      theHandler.beginBody(theCurrentContentType, "", NULL);
+  }
+
+  void HttpResponseParser::afterRead()
+  {
+  }
+
+  void HttpResponseParser::registerHandler()
+  {
+    curl_easy_setopt(theCurl, CURLOPT_HEADERFUNCTION, &curl_headerfunction);
+    curl_easy_setopt(theCurl, CURLOPT_HEADERDATA, this);
+  }
+
+  size_t HttpResponseParser::curl_headerfunction( void *ptr, size_t size,
+                                                  size_t nmemb, void *data )
+  {
+    size_t lSize = size*nmemb;
+    size_t lResult = lSize;
+    HttpResponseParser* lParser = static_cast<HttpResponseParser*>(data);
+    if (lParser->theInsideRead) {
+      lParser->theHandler.endBody();
+      lParser->theInsideRead = false;
+    }
+    const char* lDataChar = (const char*) ptr;
+    while (lSize != 0 && (lDataChar[lSize - 1] == 10
+          || lDataChar[lSize - 1] == 13)) {
+      lSize--;
+    }
+    if (lSize == 0) {
+      return lResult;
+    }
+    std::string lData(lDataChar, lSize);
+
+    if (lData.find("HTTP") == 0) {
+      lParser->parseStatusAndMessage(lData);
+      return lResult;
+    }
+    std::string::size_type lPos = lData.find(':');
+    if (lPos == std::string::npos) {
+      return lResult;
+    }
+    std::string lName = lData.substr(0, lPos);
+    std::string lValue = lData.substr(lPos + 2);
+    {
+      std::string::size_type lPosition = lValue.size() - 1;
+      while (true) {
+        if (lPosition != std::string::npos) {
+          break;
+        }
+        if (lValue[lPosition] == '\n' || lValue[lPosition] == '\r') {
+          --lPosition;
+        } else {
+          break;
+        }
+      }
+      lValue = lValue.substr(0, lPosition + 1);
+    }
+    String lNameS = fn::lower_case( lName );
+    if (lNameS == "content-type") {
+      parse_content_type(
+        lValue, &lParser->theCurrentContentType, &lParser->theCurrentCharset
+      );
+    } else if (lNameS == "content-id") {
+      lParser->theId = lValue;
+    } else if (lNameS == "content-description") {
+      lParser->theDescription = lValue;
+    }
+    lParser->theHeaders.push_back(
+      std::pair<std::string, std::string>(lName, lValue));
+    return lResult;
+  }
+
+  void HttpResponseParser::parseStatusAndMessage(std::string const &aHeader)
+  {
+    std::string::size_type lPos = aHeader.find(' ');
+    assert(lPos != std::string::npos);
+    std::string lStatus = aHeader.substr(lPos, aHeader.find(' ', lPos + 1));
+    theMessage = aHeader.substr(aHeader.find(' ', lPos + 1) + 1);
+    {
+      std::string::size_type lPosition = theMessage.size() - 1;
+      while (true) {
+        if (lPosition != std::string::npos) {
+          break;
+        }
+        if (theMessage[lPosition] == '\n' || theMessage[lPosition] == '\r') {
+          --lPosition;
+        } else {
+          break;
+        }
+      }
+      theMessage = theMessage.substr(0, lPosition + 1);
+    }
+    std::stringstream lStream(lStatus);
+    lStream >> theStatus;
+    // everything that is not a valid http status is an error
+    if (theStatus < 100) {
+      theErrorThrower.raiseException("HC001", "An HTTP error occurred");
+    }
+  }
+
+  static void streamReleaser(std::istream* aStream)
+  {
+    if (!aStream)
+      return;
+
+    // This istream contains our curl stream buffer, so we have to delete it too
+    std::streambuf *const sbuf = aStream->rdbuf();
+    if ( transcode::streambuf *tbuf =
+          dynamic_cast<transcode::streambuf*>( sbuf ) )
+      delete tbuf->orig_streambuf();
+    else
+      delete sbuf;
+    delete aStream;
+  }
+
+  zorba::Item HttpResponseParser::createTextItem(std::istream* aStream)
+  {
+    ItemFactory* lFactory = Zorba::getInstance(0)->getItemFactory();
+
+    // When we create a StreamableString, memory ownership gets very convoluted
+    // because the StreamableString object has a longer lifecycle than the
+    // iterator which creates it. The StreamableString object depends on its
+    // istream, which in turn depends on its read buffer. For us, the read
+    // buffer in turn depends on the HttpResponseParser (this object) because
+    // it is registered as the "informer" (callback object) for
+    // theStreamBuffer. Therefore, this HttpResponseParser object is no longer
+    // "self-contained". We delegate ownership of ourself to theStreamBuffer
+    // and mark ourselves as no longer being self-contained.
+    theStreamBuffer->setOwnInformer(true);
+    theSelfContained = false;
+
+    // The ownership of theStreamBuffer, in turn, is delegated to the
+    // StreamableString object (via streamReleaser, which will free the
+    // istream's rdbuf).
+    theStreamBuffer = NULL;
+    return lFactory->createStreamableString(*aStream, &streamReleaser, false);
+  }
+
+  zorba::Item HttpResponseParser::createBase64Item( std::istream& aStream )
+  {
+    ItemFactory* lFactory = Zorba::getInstance(0)->getItemFactory();
+    // TODO: once a proper streaming implementation is in place this can be
+    // changed. This required a Base64 encoding stream since the item factory
+    // work only builds base64binary and assumes the data is already encoded.
+    String lEncoded = encoding::Base64::encode(aStream);
+    return lFactory->createBase64Binary(lEncoded.data(), lEncoded.size());
+  }
+
+} // namespace http_client
+} // namespace zorba
+/* vim:set et sw=2 ts=2: */

=== added file 'modules/io/zorba/modules/http-client.xq.src/http_response_parser.h'
--- modules/io/zorba/modules/http-client.xq.src/http_response_parser.h	1970-01-01 00:00:00 +0000
+++ modules/io/zorba/modules/http-client.xq.src/http_response_parser.h	2013-06-15 00:58:33 +0000
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2006-2013 The FLWOR Foundation.
+ * 
+ * Licensed 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.
+ */
+#ifndef HTTP_RESPONSE_PARSER_H
+#define HTTP_RESPONSE_PARSER_H
+#include <vector>
+#include <string>
+#include <map>
+
+#include <curl/curl.h>
+
+#include "inform_data_read.h"
+#include "error_thrower.h"
+#include "http_response_handler.h"
+
+namespace zorba {
+class Item;
+
+namespace curl {
+  class streambuf;
+}
+
+namespace http_client
+{
+  void parse_content_type( std::string const &s, std::string *mime_type, std::string *charset );
+
+  class RequestHandler;
+
+  class HttpResponseParser : public InformDataRead {
+  private:
+    RequestHandler& theHandler;
+    CURL* theCurl;
+    ErrorThrower& theErrorThrower;
+    std::string theCurrentContentType;
+    std::string theCurrentCharset;
+    typedef std::vector<std::pair<std::string, std::string> > headers_type;
+    headers_type theHeaders;
+    int theStatus;
+    std::string theMessage;
+    zorba::curl::streambuf* theStreamBuffer;
+    std::string theId;
+    std::string theDescription;
+    bool theInsideRead;
+    std::map<std::string, std::string> theCodeMap;
+    std::string theOverridenContentType;
+    bool theStatusOnly;
+    bool theSelfContained;
+  public:
+    HttpResponseParser(
+      RequestHandler& aHandler,
+      CURL* aCurl,
+      ErrorThrower& aErrorThrower,
+      std::string aOverridenContentType = "",
+      bool aStatusOnly = false);
+    virtual ~HttpResponseParser();
+    int parse();
+    /**
+     * After calling parse(), it is possible that HttpResponseParser will have
+     * created some long-lived objects that depend on it. In that case, it will
+     * also have arranged for itself to be de-allocated at some future time
+     * when it is appropriate to do so. Therefore, in this case, the code which
+     * created the HttpResponseParser should NOT free it. HttpResponseParser
+     * refers to itself as "not self-contained" in this case, and this method
+     * will return false.
+     */
+    bool selfContained() { return theSelfContained; }
+    virtual void beforeRead();
+    virtual void afterRead();
+  private:
+    void registerHandler();
+    void parseStatusAndMessage(std::string const &aHeader);
+    Item createTextItem(std::istream* aStream);
+    Item createBase64Item(std::istream& aStream);
+
+    static size_t curl_headerfunction( void*, size_t, size_t, void* );
+  };
+
+} // namespace http_client
+} // namespace zorba
+
+#endif //HTTP_RESPONSE_PARSER_H

=== added file 'modules/io/zorba/modules/http-client.xq.src/inform_data_read.cpp'
--- modules/io/zorba/modules/http-client.xq.src/inform_data_read.cpp	1970-01-01 00:00:00 +0000
+++ modules/io/zorba/modules/http-client.xq.src/inform_data_read.cpp	2013-06-15 00:58:33 +0000
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2006-2013 The FLWOR Foundation.
+ * 
+ * Licensed 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.
+ */
+#include "inform_data_read.h"
+
+namespace zorba { namespace http_client {
+  InformDataRead::~InformDataRead()
+  {
+  }
+}} //namespace zorba, http_client

=== added file 'modules/io/zorba/modules/http-client.xq.src/inform_data_read.h'
--- modules/io/zorba/modules/http-client.xq.src/inform_data_read.h	1970-01-01 00:00:00 +0000
+++ modules/io/zorba/modules/http-client.xq.src/inform_data_read.h	2013-06-15 00:58:33 +0000
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2006-2013 The FLWOR Foundation.
+ * 
+ * Licensed 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.
+ */
+#ifndef INFORM_DATA_READ_H
+#define INFORM_DATA_READ_H
+namespace zorba { namespace http_client {
+  class InformDataRead {
+  public:
+    virtual ~InformDataRead();
+  public:
+    virtual void beforeRead() = 0;
+    virtual void afterRead() = 0;
+  };
+}} //namespace zorba, http_client
+#endif //INFORM_DATA_READ_H

=== added file 'modules/io/zorba/modules/http-client.xq.src/request_handler.cpp'
--- modules/io/zorba/modules/http-client.xq.src/request_handler.cpp	1970-01-01 00:00:00 +0000
+++ modules/io/zorba/modules/http-client.xq.src/request_handler.cpp	2013-06-15 00:58:33 +0000
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2006-2013 The FLWOR Foundation.
+ * 
+ * Licensed 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.
+ */
+#include "request_handler.h"
+
+namespace zorba { namespace http_client {
+  RequestHandler::~RequestHandler()
+  {
+  }
+}} //namespace zorba, http_client

=== added file 'modules/io/zorba/modules/http-client.xq.src/request_handler.h'
--- modules/io/zorba/modules/http-client.xq.src/request_handler.h	1970-01-01 00:00:00 +0000
+++ modules/io/zorba/modules/http-client.xq.src/request_handler.h	2013-06-15 00:58:33 +0000
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2006-2013 The FLWOR Foundation.
+ * 
+ * Licensed 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.
+ */
+#ifndef REQUEST_HANDLER_H
+#define REQUEST_HANDLER_H
+
+#include<string>
+
+namespace zorba {
+class String;
+class Item;
+class ItemSequence;
+
+namespace http_client {
+  class RequestHandler {
+  public:
+    virtual ~RequestHandler();
+  public:
+    virtual void begin() = 0;
+    virtual void beginResponse(int aStatus, String aMessage) = 0;
+    virtual void endResponse() = 0;
+    virtual void beginRequest(
+      String aMethod,
+      String href,
+      bool aStatusOnly,
+      String aUsername,
+      String aPassword,
+      String aAuthMethod,
+      bool aSendAuthorization,
+      String aOverrideContentType,
+      bool aFollowRedirect,
+      String aUserAgent,
+      int aTimeout = -1) = 0;
+    virtual void endRequest() = 0;
+    virtual void header(String aName, String aValue) = 0;
+    virtual void beginBody(
+      String aContentType,
+      String aSrc,
+      ItemSequence* aSerializerOptions) = 0;
+    virtual void any(Item aItem, std::string& charset) = 0;
+    virtual void endBody() = 0;
+    virtual void beginMultipart(String aContentType, String aBoundary) = 0;
+    virtual void endMultipart() = 0;
+    virtual void end() = 0;
+  public: // status
+    virtual bool isHeadRequest() const = 0;
+  };
+}
+}
+
+#endif //REQUEST_HANDLER_H

=== added file 'modules/io/zorba/modules/http-client.xq.src/request_parser.cpp'
--- modules/io/zorba/modules/http-client.xq.src/request_parser.cpp	1970-01-01 00:00:00 +0000
+++ modules/io/zorba/modules/http-client.xq.src/request_parser.cpp	2013-06-15 00:58:33 +0000
@@ -0,0 +1,343 @@
+/*
+ * Copyright 2006-2013 The FLWOR Foundation.
+ * 
+ * Licensed 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.
+ */
+#include "request_parser.h"
+#include "request_handler.h"
+#include "http_response_parser.h"
+#include "error_thrower.h"
+
+#include <cassert>
+#include <iostream>
+
+#include <zorba/zorba.h>
+#include <zorba/api_shared_types.h>
+#include <zorba/item.h>
+#include <zorba/zorba_string.h>
+#include <zorba/iterator.h>
+#include <zorba/store_consts.h>
+#include <zorba/vector_item_sequence.h>
+#include <zorba/xquery_functions.h>
+#include <zorba/transcode_stream.h>
+
+namespace zorba
+{
+namespace http_client
+{
+
+bool RequestParser::getString(const Item& aItem, const String& aName, const bool aMandatory, String& aResult)
+{
+  Item lOption = aItem.getObjectValue(aName);
+  if (lOption.isNull())
+  {
+    if (aMandatory)
+      raiseMissingError(aName);
+    return false;
+  }
+  else
+  {
+    if (lOption.getTypeCode() != store::XS_STRING &&
+        lOption.getTypeCode() != store::XS_NORMALIZED_STRING &&
+        lOption.getTypeCode() != store::XS_NAME &&
+        lOption.getTypeCode() != store::XS_NCNAME &&
+        lOption.getTypeCode() != store::XS_ANY_URI
+        )
+      raiseTypeError(aName,lOption.getType().getLocalName(), "string");
+    aResult = lOption.getStringValue();
+    return true;
+  }
+}
+
+bool RequestParser::getInteger(const Item& aItem, const String& aName, const bool aMandatory, int& aResult)
+{
+  Item lOption = aItem.getObjectValue(aName);
+  if (lOption.isNull())
+  {
+    if (aMandatory)
+      raiseMissingError(aName);
+    return false;
+  }
+  else
+  {
+    if (lOption.getTypeCode() != store::XS_INTEGER)
+      raiseTypeError(aName,lOption.getType().getLocalName(), "integer");
+    aResult = lOption.getIntValue();
+    return true;
+  }
+}
+
+bool RequestParser::getBoolean(const Item& aItem, const String& aName, const bool aMandatory, bool& aResult)
+{
+  Item lOption = aItem.getObjectValue(aName);
+  if (lOption.isNull())
+  {
+    if (aMandatory)
+      raiseMissingError(aName);
+    return false;
+  }
+  else
+  {
+    if (lOption.getTypeCode() != store::XS_BOOLEAN)
+      raiseTypeError(aName, lOption.getType().getLocalName(), "boolean");
+    aResult = lOption.getBooleanValue();
+    return true;
+  }
+}
+
+bool RequestParser::getObject(const Item& aItem, const String& aName, const bool aMandatory, Item& aResult)
+{
+  aResult = aItem.getObjectValue(aName);
+  if (aResult.isNull())
+  {
+    if (aMandatory)
+      raiseMissingError(aName);
+    return false;
+  }
+  else
+  {
+    if (aResult.isAtomic() || !aResult.isJSONItem() || aResult.getJSONItemKind() != store::StoreConsts::jsonObject)
+      raiseTypeError(aName, aResult.getType().getLocalName(), store::StoreConsts::toString(store::StoreConsts::jsonObject));
+    return true;
+  }
+}
+
+bool RequestParser::getItem(const Item& aItem, const String& aName, const bool aMandatory, Item& aResult)
+{
+  aResult = aItem.getObjectValue(aName);
+  if (aResult.isNull())
+  {
+    if (aMandatory)
+      raiseMissingError(aName);
+    return false;
+  }
+  return true;
+}
+
+bool RequestParser::getArray(const Item& aItem, const String& aName, const bool aMandatory, Item& aResult)
+{
+  aResult = aItem.getObjectValue(aName);
+  if (aResult.isNull())
+  {
+    if (aMandatory)
+      raiseMissingError(aName);
+    return false;
+  }
+  else
+  {
+    if (aResult.isAtomic() || !aResult.isJSONItem() || aResult.getJSONItemKind() != store::StoreConsts::jsonArray)
+      raiseTypeError(aName, store::StoreConsts::toString(aResult.getJSONItemKind()), store::StoreConsts::toString(store::StoreConsts::jsonArray));
+    return true;
+  }
+}
+
+void RequestParser::raiseTypeError(const String& aName, const String& aGot, const String& aExpected)
+{
+  std::ostringstream lMsg;
+  lMsg << aGot << ": invalid type for field "
+    << aName << " (got " << aGot << ", expected " << aExpected << ")";
+  theThrower->raiseException("HC005", lMsg.str());
+}
+
+void RequestParser::raiseMissingError(const String& aName)
+{
+  std::ostringstream lMsg;
+  lMsg << "required field " << aName << " has not been specified";
+  theThrower->raiseException("HC005", lMsg.str());
+}
+
+void RequestParser::parseHeaders(const Item& aItem)
+{
+  Item lKey;
+  String lName;
+  String lValue;
+
+  zorba::Iterator_t lIterator = aItem.getObjectKeys();
+  lIterator->open();
+
+  while (lIterator->next(lKey))
+  {
+    lName = lKey.getStringValue();
+    getString(aItem,lName,true,lValue);
+    theHandler->header(lName, lValue);
+  }
+
+  lIterator->close();
+}
+
+void RequestParser::parseOptions(const Item& aItem, bool& aStatusOnly, String& aOverrideContentType,bool& aFollowRedirect, bool& aUserDefinedFollowRedirect, String& aUserAgent, int& aTimeout)
+{
+  getBoolean(aItem,"status-only",false,aStatusOnly);
+  getString(aItem,"override-media-type", false,aOverrideContentType);
+  aUserDefinedFollowRedirect = getBoolean(aItem,"follow-redirect", false,aFollowRedirect);
+  getInteger(aItem,"timeout",false,aTimeout);
+  getString(aItem,"user-agent",false,aUserAgent);
+}
+
+void RequestParser::parseBody(const Item& aItem)
+{
+  String lMediaType;
+  String lSrc;
+
+  getString(aItem,"media-type",true,lMediaType);
+  std::string charset;
+  getCharset(lMediaType, charset);
+  getString(aItem,"src",false,lSrc);
+
+  std::vector<Item> lItems;
+  std::auto_ptr<VectorItemSequence> lSequence(new VectorItemSequence(lItems));
+  theHandler->beginBody(lMediaType, lSrc, lSequence.get());
+
+  Item lContentI;
+  getItem(aItem,"content",true,lContentI);
+  theHandler->any(lContentI,charset);
+  theHandler->endBody();
+}
+
+void RequestParser::parsePart(const Item& aItem)
+{
+  Item lHeaders;
+  Item lBody;
+
+  bool lHaveHeaders = getObject(aItem,"headers",false,lHeaders);
+  if (lHaveHeaders)
+    parseHeaders(lHeaders);
+
+  getObject(aItem,"body",true,lBody);
+  parseBody(lBody);
+}
+
+void RequestParser::parseMultipart(const Item& aItem)
+{
+  String lMediaType;
+  String lBoundary;
+
+  std::string charset;
+  getString(aItem,"media-type",true,lMediaType);
+  getCharset(lMediaType,charset);
+  getString(aItem,"boundary",false,lBoundary);
+
+  theHandler->beginMultipart(lMediaType, lBoundary);
+  Item lParts = aItem.getObjectValue("parts");
+  if (!lParts.isNull())
+  {
+    if (lParts.isAtomic() || !lParts.isJSONItem() || lParts.getJSONItemKind() != store::StoreConsts::jsonArray)
+      raiseTypeError("parts", store::StoreConsts::toString(lParts.getJSONItemKind()), store::StoreConsts::toString(store::StoreConsts::jsonArray));
+    else
+    {
+      uint64_t lSize = lParts.getArraySize();
+      for(uint64_t i = 1; i <= lSize; ++i)
+      {
+        Item lMember = lParts.getArrayValue(i);
+        if (lMember.isAtomic() || !lMember.isJSONItem() || lMember.getJSONItemKind() != store::StoreConsts::jsonObject)
+          raiseTypeError("part",store::StoreConsts::toString(lMember.getJSONItemKind()),store::StoreConsts::toString(store::StoreConsts::jsonObject));
+        parsePart(lMember);
+      }
+    }
+  }
+  theHandler->endMultipart();
+}
+
+void RequestParser::parseAuthentication(const Item& aItem, String& aUserName, String& aPassword, String& aAuthMethod)
+{
+  getString(aItem,"username",true,aUserName);
+  getString(aItem,"password",true,aPassword);
+  getString(aItem,"auth-method",true,aAuthMethod);
+}
+
+void RequestParser::parseRequest(const Item& aItem)
+{
+  theHandler->begin();
+  String lMethod;
+  String lHref;
+  bool lStatusOnly = false;
+  String lUsername;
+  String lPassword;
+  String lAuthMethod;
+  bool lSendAuthentication = false;
+  String lOverrideContentType;
+  bool lFollowRedirect = false;
+  bool lUserDefinedFollowRedirect = false;
+  int lTimeout = -1;
+  String lUserAgent;
+
+  if(!getString(aItem,"method",false,lMethod))
+    lMethod ="GET";
+  getString(aItem,"href",true,lHref);
+
+  Item lAuthentication;
+  if ((lSendAuthentication = getObject(aItem,"authentication",false,lAuthentication)))
+    parseAuthentication(lAuthentication,lUsername,lPassword,lAuthMethod);
+
+  Item lOptions;
+  if (getObject(aItem,"options",false,lOptions))
+    parseOptions(lOptions,lStatusOnly,lOverrideContentType,lFollowRedirect,lUserDefinedFollowRedirect,lUserAgent,lTimeout);
+
+  lMethod = fn::upper_case(lMethod);
+
+  // follow-redirect: take care of the default (if the user didn't provide one)
+  if (lMethod == "GET" || lMethod == "HEAD" || lMethod == "OPTIONS")
+  {
+    if (!lUserDefinedFollowRedirect)
+      lFollowRedirect = "true";
+  }
+  else
+  {
+    if (lFollowRedirect)
+    {
+      std::ostringstream lMsg;
+      lMsg << lMethod << ": cannot follow redirect";
+      theThrower->raiseException("HCV02", lMsg.str());
+    }
+  }
+
+  theHandler->beginRequest(lMethod, lHref, lStatusOnly, lUsername, lPassword,
+      lAuthMethod, lSendAuthentication, lOverrideContentType, lFollowRedirect,
+      lUserAgent, lTimeout);
+
+  Item lHeaders;
+  bool haveHeaders = getObject(aItem,"headers",false,lHeaders);
+  if (haveHeaders)
+    parseHeaders(lHeaders);
+
+  Item lBody;
+  Item lMultipart;
+  bool haveBody = getObject(aItem,"body",false,lBody);
+  bool haveMultipart = getObject(aItem,"multipart",false,lMultipart);
+  if (haveBody && haveMultipart)
+    theThrower->raiseException("HC005","HTTP request cannot contain both body and multipart");
+
+  if (haveBody)
+    parseBody(lBody);
+
+  if (haveMultipart)
+    parseMultipart(lMultipart);
+
+  theHandler->endRequest();
+  theHandler->end();
+}
+
+void RequestParser::getCharset(const String& aMediaType, std::string& charset)
+{
+  std::string mime_type;
+  parse_content_type(aMediaType.c_str(),&mime_type,&charset);
+  if (!charset.empty() && transcode::is_necessary(charset.c_str()) && !transcode::is_supported(charset.c_str()))
+  {
+    std::ostringstream lMsg;
+    lMsg << charset << ": unsupported encoding charset";
+    theThrower->raiseException("HCV03", lMsg.str());
+  }
+}
+
+}
+}

=== added file 'modules/io/zorba/modules/http-client.xq.src/request_parser.h'
--- modules/io/zorba/modules/http-client.xq.src/request_parser.h	1970-01-01 00:00:00 +0000
+++ modules/io/zorba/modules/http-client.xq.src/request_parser.h	2013-06-15 00:58:33 +0000
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2006-2013 The FLWOR Foundation.
+ * 
+ * Licensed 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.
+ */
+#ifndef REQUEST_PARSER_H
+#define REQUEST_PARSER_H
+
+#include <string>
+
+namespace zorba {
+class Item;
+class String;
+class ItemFactory;
+
+namespace http_client {
+class RequestHandler;
+class ErrorThrower;
+
+class RequestParser {
+protected:
+  RequestHandler* theHandler;
+  ErrorThrower*   theThrower;
+  ItemFactory* theFactory;
+
+public:
+  RequestParser(RequestHandler* aHandler, ErrorThrower& aThrower, ItemFactory* aFactory) : theHandler(aHandler), theThrower(&aThrower), theFactory(aFactory) {}
+  void parseRequest(const Item& aItem);
+
+private:
+  void parseHeaders(const Item& aItem);
+  void parseOptions(const Item& aItem, bool& aStatusOnly, String& aOverrideContentType,bool& aFollowRedirect, bool& aUserDefinedFollowRedirect, String& aUserAgent, int& aTimeout);
+  void parseBody(const Item& aItem);
+  void parsePart(const Item& aItem);
+  void parseMultipart(const Item& aItem);
+  void parseAuthentication(const Item& aItem, String& aUserName, String& aPassword, String& aAuthMethod);
+
+  bool getString(const Item& aItem, const String& aName, const bool aMandatory, String& aResult);
+  bool getInteger(const Item& aItem, const String& aName, const bool aMandatory, int& aResult);
+  bool getBoolean(const Item& aItem, const String& aName, const bool aMandatory, bool& aResult);
+  bool getObject(const Item& aItem, const String& aName, const bool aMandatory, Item& aResult);
+  bool getItem(const Item& aItem, const String& aName, const bool aMandatory, Item& aResult);
+  bool getArray(const Item& aItem, const String& aName, const bool aMandatory, Item& aResult);
+
+  void getCharset(const String& aMediaType, std::string& charset);
+
+  void raiseTypeError(const String& aName, const String& aGot, const String& aExpected);
+  void raiseMissingError(const String& aName);
+};
+} //namespace zorba
+} //namespace http_request
+
+#endif // REQUEST_PARSER_H

=== added directory 'test/rbkt/ExpQueryResults/zorba/json-http-client'
=== added directory 'test/rbkt/ExpQueryResults/zorba/json-http-client/delete'
=== added file 'test/rbkt/ExpQueryResults/zorba/json-http-client/delete/delete.xml.res'
--- test/rbkt/ExpQueryResults/zorba/json-http-client/delete/delete.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/json-http-client/delete/delete.xml.res	2013-06-15 00:58:33 +0000
@@ -0,0 +1,3 @@
+Method: DELETE
+Query: 
+Post: 

=== added directory 'test/rbkt/ExpQueryResults/zorba/json-http-client/get'
=== added directory 'test/rbkt/ExpQueryResults/zorba/json-http-client/get-binary'
=== added file 'test/rbkt/ExpQueryResults/zorba/json-http-client/get-binary/get-binary_binary.xml.res'
--- test/rbkt/ExpQueryResults/zorba/json-http-client/get-binary/get-binary_binary.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/json-http-client/get-binary/get-binary_binary.xml.res	2013-06-15 00:58:33 +0000
@@ -0,0 +1,1 @@
+VW5jaGFuZ2luZyBiaW5hcnkgZGF0YQo=

=== added file 'test/rbkt/ExpQueryResults/zorba/json-http-client/get-binary/get-binary_text.xml.res'
--- test/rbkt/ExpQueryResults/zorba/json-http-client/get-binary/get-binary_text.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/json-http-client/get-binary/get-binary_text.xml.res	2013-06-15 00:58:33 +0000
@@ -0,0 +1,1 @@
+TWV0aG9kOiBHRVQKUXVlcnk6IApQb3N0OiAK

=== added file 'test/rbkt/ExpQueryResults/zorba/json-http-client/get-binary/get-binary_text_query.xml.res'
--- test/rbkt/ExpQueryResults/zorba/json-http-client/get-binary/get-binary_text_query.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/json-http-client/get-binary/get-binary_text_query.xml.res	2013-06-15 00:58:33 +0000
@@ -0,0 +1,1 @@
+TWV0aG9kOiBHRVQKUXVlcnk6IHF1ZXJ5c3RyaW5nClBvc3Q6IAo=

=== added file 'test/rbkt/ExpQueryResults/zorba/json-http-client/get-binary/get-binary_xml.xml.res'
--- test/rbkt/ExpQueryResults/zorba/json-http-client/get-binary/get-binary_xml.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/json-http-client/get-binary/get-binary_xml.xml.res	2013-06-15 00:58:33 +0000
@@ -0,0 +1,1 @@
+PGJvZHk+CjxtZXRob2Q+R0VUPC9tZXRob2Q+CjxxdWVyeT48L3F1ZXJ5Pgo8cG9zdD4KPC9wb3N0PjwvYm9keT4K

=== added file 'test/rbkt/ExpQueryResults/zorba/json-http-client/get-binary/get-binary_xml_query.xml.res'
--- test/rbkt/ExpQueryResults/zorba/json-http-client/get-binary/get-binary_xml_query.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/json-http-client/get-binary/get-binary_xml_query.xml.res	2013-06-15 00:58:33 +0000
@@ -0,0 +1,1 @@
+PGJvZHk+CjxtZXRob2Q+R0VUPC9tZXRob2Q+CjxxdWVyeT5xdWVyeXN0cmluZzwvcXVlcnk+Cjxwb3N0Pgo8L3Bvc3Q+PC9ib2R5Pgo=
\ No newline at end of file

=== added directory 'test/rbkt/ExpQueryResults/zorba/json-http-client/get-node'
=== added file 'test/rbkt/ExpQueryResults/zorba/json-http-client/get-node/get-node_binary.xml.res'
--- test/rbkt/ExpQueryResults/zorba/json-http-client/get-node/get-node_binary.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/json-http-client/get-node/get-node_binary.xml.res	2013-06-15 00:58:33 +0000
@@ -0,0 +1,1 @@
+VW5jaGFuZ2luZyBiaW5hcnkgZGF0YQo=

=== added file 'test/rbkt/ExpQueryResults/zorba/json-http-client/get-node/get-node_text.xml.res'
--- test/rbkt/ExpQueryResults/zorba/json-http-client/get-node/get-node_text.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/json-http-client/get-node/get-node_text.xml.res	2013-06-15 00:58:33 +0000
@@ -0,0 +1,3 @@
+Method: GET
+Query: 
+Post: 

=== added file 'test/rbkt/ExpQueryResults/zorba/json-http-client/get-node/get-node_text_query.xml.res'
--- test/rbkt/ExpQueryResults/zorba/json-http-client/get-node/get-node_text_query.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/json-http-client/get-node/get-node_text_query.xml.res	2013-06-15 00:58:33 +0000
@@ -0,0 +1,3 @@
+Method: GET
+Query: querystring
+Post: 

=== added file 'test/rbkt/ExpQueryResults/zorba/json-http-client/get-node/get-node_xml.xml.res'
--- test/rbkt/ExpQueryResults/zorba/json-http-client/get-node/get-node_xml.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/json-http-client/get-node/get-node_xml.xml.res	2013-06-15 00:58:33 +0000
@@ -0,0 +1,5 @@
+<body>
+<method>GET</method>
+<query/>
+<post>
+</post></body>

=== added file 'test/rbkt/ExpQueryResults/zorba/json-http-client/get-node/get-node_xml_query.xml.res'
--- test/rbkt/ExpQueryResults/zorba/json-http-client/get-node/get-node_xml_query.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/json-http-client/get-node/get-node_xml_query.xml.res	2013-06-15 00:58:33 +0000
@@ -0,0 +1,1 @@
+querystring

=== added directory 'test/rbkt/ExpQueryResults/zorba/json-http-client/get-text'
=== added file 'test/rbkt/ExpQueryResults/zorba/json-http-client/get-text/get-text_binary.xml.res'
--- test/rbkt/ExpQueryResults/zorba/json-http-client/get-text/get-text_binary.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/json-http-client/get-text/get-text_binary.xml.res	2013-06-15 00:58:33 +0000
@@ -0,0 +1,1 @@
+Unchanging binary data

=== added file 'test/rbkt/ExpQueryResults/zorba/json-http-client/get-text/get-text_text.xml.res'
--- test/rbkt/ExpQueryResults/zorba/json-http-client/get-text/get-text_text.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/json-http-client/get-text/get-text_text.xml.res	2013-06-15 00:58:33 +0000
@@ -0,0 +1,3 @@
+Method: GET
+Query: 
+Post: 

=== added file 'test/rbkt/ExpQueryResults/zorba/json-http-client/get-text/get-text_text_query.xml.res'
--- test/rbkt/ExpQueryResults/zorba/json-http-client/get-text/get-text_text_query.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/json-http-client/get-text/get-text_text_query.xml.res	2013-06-15 00:58:33 +0000
@@ -0,0 +1,3 @@
+Method: GET
+Query: querystring
+Post: 

=== added file 'test/rbkt/ExpQueryResults/zorba/json-http-client/get-text/get-text_xml.xml.res'
--- test/rbkt/ExpQueryResults/zorba/json-http-client/get-text/get-text_xml.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/json-http-client/get-text/get-text_xml.xml.res	2013-06-15 00:58:33 +0000
@@ -0,0 +1,5 @@
+&lt;body&gt;
+&lt;method&gt;GET&lt;/method&gt;
+&lt;query&gt;&lt;/query&gt;
+&lt;post&gt;
+&lt;/post&gt;&lt;/body&gt;

=== added file 'test/rbkt/ExpQueryResults/zorba/json-http-client/get-text/get-text_xml_query.xml.res'
--- test/rbkt/ExpQueryResults/zorba/json-http-client/get-text/get-text_xml_query.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/json-http-client/get-text/get-text_xml_query.xml.res	2013-06-15 00:58:33 +0000
@@ -0,0 +1,5 @@
+&lt;body&gt;
+&lt;method&gt;GET&lt;/method&gt;
+&lt;query&gt;querystring&lt;/query&gt;
+&lt;post&gt;
+&lt;/post&gt;&lt;/body&gt;

=== added file 'test/rbkt/ExpQueryResults/zorba/json-http-client/get/get_binary.xml.res'
--- test/rbkt/ExpQueryResults/zorba/json-http-client/get/get_binary.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/json-http-client/get/get_binary.xml.res	2013-06-15 00:58:33 +0000
@@ -0,0 +1,1 @@
+VW5jaGFuZ2luZyBiaW5hcnkgZGF0YQo=

=== added file 'test/rbkt/ExpQueryResults/zorba/json-http-client/get/get_text.xml.res'
--- test/rbkt/ExpQueryResults/zorba/json-http-client/get/get_text.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/json-http-client/get/get_text.xml.res	2013-06-15 00:58:33 +0000
@@ -0,0 +1,3 @@
+Method: GET
+Query: 
+Post: 

=== added file 'test/rbkt/ExpQueryResults/zorba/json-http-client/get/get_text_query.xml.res'
--- test/rbkt/ExpQueryResults/zorba/json-http-client/get/get_text_query.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/json-http-client/get/get_text_query.xml.res	2013-06-15 00:58:33 +0000
@@ -0,0 +1,3 @@
+Method: GET
+Query: querystring
+Post: 

=== added file 'test/rbkt/ExpQueryResults/zorba/json-http-client/get/get_xml.xml.res'
--- test/rbkt/ExpQueryResults/zorba/json-http-client/get/get_xml.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/json-http-client/get/get_xml.xml.res	2013-06-15 00:58:33 +0000
@@ -0,0 +1,5 @@
+<body>
+<method>GET</method>
+<query/>
+<post>
+</post></body>

=== added file 'test/rbkt/ExpQueryResults/zorba/json-http-client/get/get_xml_query.xml.res'
--- test/rbkt/ExpQueryResults/zorba/json-http-client/get/get_xml_query.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/json-http-client/get/get_xml_query.xml.res	2013-06-15 00:58:33 +0000
@@ -0,0 +1,1 @@
+querystring

=== added directory 'test/rbkt/ExpQueryResults/zorba/json-http-client/head'
=== added file 'test/rbkt/ExpQueryResults/zorba/json-http-client/head/head_content-type_binary.xml.res'
--- test/rbkt/ExpQueryResults/zorba/json-http-client/head/head_content-type_binary.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/json-http-client/head/head_content-type_binary.xml.res	2013-06-15 00:58:33 +0000
@@ -0,0 +1,1 @@
+application/octet-stream

=== added file 'test/rbkt/ExpQueryResults/zorba/json-http-client/head/head_content-type_text.xml.res'
--- test/rbkt/ExpQueryResults/zorba/json-http-client/head/head_content-type_text.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/json-http-client/head/head_content-type_text.xml.res	2013-06-15 00:58:33 +0000
@@ -0,0 +1,1 @@
+text/plain; charset=UTF-8

=== added file 'test/rbkt/ExpQueryResults/zorba/json-http-client/head/head_content-type_xml.xml.res'
--- test/rbkt/ExpQueryResults/zorba/json-http-client/head/head_content-type_xml.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/json-http-client/head/head_content-type_xml.xml.res	2013-06-15 00:58:33 +0000
@@ -0,0 +1,1 @@
+text/xml

=== added file 'test/rbkt/ExpQueryResults/zorba/json-http-client/head/head_status.xml.res'
--- test/rbkt/ExpQueryResults/zorba/json-http-client/head/head_status.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/json-http-client/head/head_status.xml.res	2013-06-15 00:58:33 +0000
@@ -0,0 +1,1 @@
+200

=== added directory 'test/rbkt/ExpQueryResults/zorba/json-http-client/options'
=== added file 'test/rbkt/ExpQueryResults/zorba/json-http-client/options/options.xml.res'
--- test/rbkt/ExpQueryResults/zorba/json-http-client/options/options.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/json-http-client/options/options.xml.res	2013-06-15 00:58:33 +0000
@@ -0,0 +1,1 @@
+GET HEAD POST OPTIONS TRACE
\ No newline at end of file

=== added directory 'test/rbkt/ExpQueryResults/zorba/json-http-client/post'
=== added file 'test/rbkt/ExpQueryResults/zorba/json-http-client/post/post2_binary.xml.res'
--- test/rbkt/ExpQueryResults/zorba/json-http-client/post/post2_binary.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/json-http-client/post/post2_binary.xml.res	2013-06-15 00:58:33 +0000
@@ -0,0 +1,4 @@
+Method: POST
+Query: 
+Post: 
+hello there

=== added file 'test/rbkt/ExpQueryResults/zorba/json-http-client/post/post2_string.xml.res'
--- test/rbkt/ExpQueryResults/zorba/json-http-client/post/post2_string.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/json-http-client/post/post2_string.xml.res	2013-06-15 00:58:33 +0000
@@ -0,0 +1,4 @@
+Method: POST
+Query: 
+Post: 
+poststring

=== added file 'test/rbkt/ExpQueryResults/zorba/json-http-client/post/post3_binary.xml.res'
--- test/rbkt/ExpQueryResults/zorba/json-http-client/post/post3_binary.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/json-http-client/post/post3_binary.xml.res	2013-06-15 00:58:33 +0000
@@ -0,0 +1,4 @@
+Method: POST
+Query: 
+Post: 
+hello there

=== added file 'test/rbkt/ExpQueryResults/zorba/json-http-client/post/post3_string.xml.res'
--- test/rbkt/ExpQueryResults/zorba/json-http-client/post/post3_string.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/json-http-client/post/post3_string.xml.res	2013-06-15 00:58:33 +0000
@@ -0,0 +1,4 @@
+Method: POST
+Query: 
+Post: 
+poststring

=== added directory 'test/rbkt/ExpQueryResults/zorba/json-http-client/put'
=== added file 'test/rbkt/ExpQueryResults/zorba/json-http-client/put/put2_binary.xml.res'
--- test/rbkt/ExpQueryResults/zorba/json-http-client/put/put2_binary.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/json-http-client/put/put2_binary.xml.res	2013-06-15 00:58:33 +0000
@@ -0,0 +1,4 @@
+Method: PUT
+Query: 
+Post: 
+hello there

=== added file 'test/rbkt/ExpQueryResults/zorba/json-http-client/put/put2_string.xml.res'
--- test/rbkt/ExpQueryResults/zorba/json-http-client/put/put2_string.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/json-http-client/put/put2_string.xml.res	2013-06-15 00:58:33 +0000
@@ -0,0 +1,4 @@
+Method: PUT
+Query: 
+Post: 
+putstring

=== added file 'test/rbkt/ExpQueryResults/zorba/json-http-client/put/put3_binary.xml.res'
--- test/rbkt/ExpQueryResults/zorba/json-http-client/put/put3_binary.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/json-http-client/put/put3_binary.xml.res	2013-06-15 00:58:33 +0000
@@ -0,0 +1,4 @@
+Method: PUT
+Query: 
+Post: 
+hello there

=== added file 'test/rbkt/ExpQueryResults/zorba/json-http-client/put/put3_string.xml.res'
--- test/rbkt/ExpQueryResults/zorba/json-http-client/put/put3_string.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/json-http-client/put/put3_string.xml.res	2013-06-15 00:58:33 +0000
@@ -0,0 +1,4 @@
+Method: PUT
+Query: 
+Post: 
+putstring
\ No newline at end of file

=== added directory 'test/rbkt/ExpQueryResults/zorba/json-http-client/send-request'
=== added file 'test/rbkt/ExpQueryResults/zorba/json-http-client/send-request/http1-redirect.xml.res'
--- test/rbkt/ExpQueryResults/zorba/json-http-client/send-request/http1-redirect.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/json-http-client/send-request/http1-redirect.xml.res	2013-06-15 00:58:33 +0000
@@ -0,0 +1,1 @@
+200

=== added file 'test/rbkt/ExpQueryResults/zorba/json-http-client/send-request/http1-useragent.xml.res'
--- test/rbkt/ExpQueryResults/zorba/json-http-client/send-request/http1-useragent.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/json-http-client/send-request/http1-useragent.xml.res	2013-06-15 00:58:33 +0000
@@ -0,0 +1,1 @@
+28.io
\ No newline at end of file

=== added file 'test/rbkt/ExpQueryResults/zorba/json-http-client/send-request/http2-read-svg.xml.res'
--- test/rbkt/ExpQueryResults/zorba/json-http-client/send-request/http2-read-svg.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/json-http-client/send-request/http2-read-svg.xml.res	2013-06-15 00:58:33 +0000
@@ -0,0 +1,11 @@
+<svg xmlns="http://www.w3.org/2000/svg"; xmlns:xlink="http://www.w3.org/1999/xlink"; xmlns:ev="http://www.w3.org/2001/xml-events"; version="1.1" baseProfile="full" width="700px" height="400px" viewBox="0 0 700 400">
+ 
+ <!-- Anschlüsse links und rechts -->
+ <line x1="0" y1="200" x2="700" y2="200" stroke="black" stroke-width="20px"/>
+ <!-- Das Rechteck -->
+ <rect x="100" y="100" width="500" height="200" fill="white" stroke="black" stroke-width="20px"/>
+ <!-- Der Schleifer -->
+ <line x1="180" y1="370" x2="500" y2="50" stroke="black" stroke-width="15px"/>
+ <!-- Die Pfeilspitze -->
+  <polygon points="585 0 525 25 585 50" transform="rotate(135 525 25)"/>
+</svg>

=== added file 'test/rbkt/ExpQueryResults/zorba/json-http-client/send-request/http3-multipart.xml.res'
--- test/rbkt/ExpQueryResults/zorba/json-http-client/send-request/http3-multipart.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/json-http-client/send-request/http3-multipart.xml.res	2013-06-15 00:58:33 +0000
@@ -0,0 +1,1 @@
+<result><number-of-bodies>3</number-of-bodies><headers><http:header xmlns:http="http://expath.org/ns/http-client"; name="User-Agent" value="libcurl-agent/1.0"/><http:header xmlns:http="http://expath.org/ns/http-client"; name="Host" value="zorbatest.lambda.nu:8080"/><http:header xmlns:http="http://expath.org/ns/http-client"; name="Accept" value="*/*"/><http:header xmlns:http="http://expath.org/ns/http-client"; name="foo" value="bar"/><http:header xmlns:http="http://expath.org/ns/http-client"; name="Expect" value="100-continue"/><http:header xmlns:http="http://expath.org/ns/http-client"; name="Content-Disposition" value="form-data; name=&quot;zorba-default&quot;"/><http:header xmlns:http="http://expath.org/ns/http-client"; name="insidemutlipart" value="blubb"/><http:header xmlns:http="http://expath.org/ns/http-client"; name="Content-Type" value="text/plain"/><http:header xmlns:http="http://expath.org/ns/http-client"; name="Content-Disposition" value="form-data; name=&quot;zorba-default&quot;"/><http:header xmlns:http="http://expath.org/ns/http-client"; name="Content-Type" value="text/plain"/><http:header xmlns:http="http://expath.org/ns/http-client"; name="Content-Disposition" value="form-data; name=&quot;zorba-default&quot;"/><http:header xmlns:http="http://expath.org/ns/http-client"; name="Content-Type" value="img/png"/></headers></result>

=== added file 'test/rbkt/ExpQueryResults/zorba/json-http-client/send-request/http3-post.xml.res'
--- test/rbkt/ExpQueryResults/zorba/json-http-client/send-request/http3-post.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/json-http-client/send-request/http3-post.xml.res	2013-06-15 00:58:33 +0000
@@ -0,0 +1,12 @@
+<http:request xmlns:http="http://expath.org/ns/http-client"; method="POST" href="zorbatest.lambda.nu:8080/http-test-data/request.php">
+  <http:header name="User-Agent" value="libcurl-agent/1.0"/>
+  <http:header name="Host" value="zorbatest.lambda.nu:8080"/>
+  <http:header name="Accept" value="*/*"/>
+  <http:header name="foo" value="bar"/>
+  <http:header name="Content-Type" value="text/plain"/>
+  <http:header name="Content-Length" value="37"/>
+  <http:body content-type="text/plain">
+
+      Dies ist ein kleiner Test
+      </http:body>
+</http:request>

=== added file 'test/rbkt/ExpQueryResults/zorba/json-http-client/send-request/http_error_hc002.xml.res'
--- test/rbkt/ExpQueryResults/zorba/json-http-client/send-request/http_error_hc002.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/json-http-client/send-request/http_error_hc002.xml.res	2013-06-15 00:58:33 +0000
@@ -0,0 +1,1 @@
+ok

=== added file 'test/rbkt/ExpQueryResults/zorba/json-http-client/send-request/http_error_hc004.xml.res'
--- test/rbkt/ExpQueryResults/zorba/json-http-client/send-request/http_error_hc004.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/json-http-client/send-request/http_error_hc004.xml.res	2013-06-15 00:58:33 +0000
@@ -0,0 +1,1 @@
+ok

=== added file 'test/rbkt/ExpQueryResults/zorba/json-http-client/send-request/http_error_hc005.xml.res'
--- test/rbkt/ExpQueryResults/zorba/json-http-client/send-request/http_error_hc005.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/json-http-client/send-request/http_error_hc005.xml.res	2013-06-15 00:58:33 +0000
@@ -0,0 +1,1 @@
+ok ok ok ok ok ok ok

=== added file 'test/rbkt/ExpQueryResults/zorba/json-http-client/send-request/send-request_get_binary.xml.res'
--- test/rbkt/ExpQueryResults/zorba/json-http-client/send-request/send-request_get_binary.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/json-http-client/send-request/send-request_get_binary.xml.res	2013-06-15 00:58:33 +0000
@@ -0,0 +1,1 @@
+true true true

=== added file 'test/rbkt/ExpQueryResults/zorba/json-http-client/send-request/send-request_href.xml.res'
--- test/rbkt/ExpQueryResults/zorba/json-http-client/send-request/send-request_href.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/json-http-client/send-request/send-request_href.xml.res	2013-06-15 00:58:33 +0000
@@ -0,0 +1,5 @@
+<body>
+<method>GET</method>
+<query>querystring</query>
+<post>
+</post></body>

=== added directory 'test/rbkt/Queries/zorba/json-http-client'
=== added directory 'test/rbkt/Queries/zorba/json-http-client/delete'
=== added file 'test/rbkt/Queries/zorba/json-http-client/delete/delete.xq'
--- test/rbkt/Queries/zorba/json-http-client/delete/delete.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/delete/delete.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,7 @@
+jsoniq version "1.0";
+import module namespace http="http://zorba.io/modules/http-client";;
+
+variable $result :=
+  http:delete("http://zorbatest.lambda.nu:8080/cgi-bin/test-text";);
+
+$result.body.content

=== added file 'test/rbkt/Queries/zorba/json-http-client/delete/delete_error_http.spec'
--- test/rbkt/Queries/zorba/json-http-client/delete/delete_error_http.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/delete/delete_error_http.spec	2013-06-15 00:58:33 +0000
@@ -0,0 +1,1 @@
+Error: http://zorba.io/modules/http-client:HC001

=== added file 'test/rbkt/Queries/zorba/json-http-client/delete/delete_error_http.xq'
--- test/rbkt/Queries/zorba/json-http-client/delete/delete_error_http.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/delete/delete_error_http.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,6 @@
+import module namespace http="http://zorba.io/modules/http-client";;
+
+variable $result :=
+  http:delete("http://localhost:99558/cgi-bin/test-text";);
+
+$result[2]

=== added directory 'test/rbkt/Queries/zorba/json-http-client/get'
=== added directory 'test/rbkt/Queries/zorba/json-http-client/get-binary'
=== added file 'test/rbkt/Queries/zorba/json-http-client/get-binary/get-binary_binary.xq'
--- test/rbkt/Queries/zorba/json-http-client/get-binary/get-binary_binary.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/get-binary/get-binary_binary.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,5 @@
+jsoniq version "1.0";
+import module namespace http="http://zorba.io/modules/http-client";;
+
+http:get-binary("http://zorbatest.lambda.nu:8080/cgi-bin/test-binary";).body.content
+

=== added file 'test/rbkt/Queries/zorba/json-http-client/get-binary/get-binary_error_http.spec'
--- test/rbkt/Queries/zorba/json-http-client/get-binary/get-binary_error_http.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/get-binary/get-binary_error_http.spec	2013-06-15 00:58:33 +0000
@@ -0,0 +1,1 @@
+Error: http://zorba.io/modules/http-client:HC001

=== added file 'test/rbkt/Queries/zorba/json-http-client/get-binary/get-binary_error_http.xq'
--- test/rbkt/Queries/zorba/json-http-client/get-binary/get-binary_error_http.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/get-binary/get-binary_error_http.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,5 @@
+import module namespace http="http://zorba.io/modules/http-client";;
+
+(: Connect to an invalid server :)
+http:get-binary("http://localhost:9998/cgi-bin/test-xml?foo&amp;";)[2]
+

=== added file 'test/rbkt/Queries/zorba/json-http-client/get-binary/get-binary_text.xq'
--- test/rbkt/Queries/zorba/json-http-client/get-binary/get-binary_text.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/get-binary/get-binary_text.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,5 @@
+jsoniq version "1.0";
+import module namespace http="http://zorba.io/modules/http-client";;
+
+http:get-binary("http://zorbatest.lambda.nu:8080/cgi-bin/test-text";).body.content
+

=== added file 'test/rbkt/Queries/zorba/json-http-client/get-binary/get-binary_text_query.xq'
--- test/rbkt/Queries/zorba/json-http-client/get-binary/get-binary_text_query.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/get-binary/get-binary_text_query.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,5 @@
+jsoniq version "1.0";
+import module namespace http="http://zorba.io/modules/http-client";;
+
+http:get-binary("http://zorbatest.lambda.nu:8080/cgi-bin/test-text?querystring";).body.content
+

=== added file 'test/rbkt/Queries/zorba/json-http-client/get-binary/get-binary_xml.xq'
--- test/rbkt/Queries/zorba/json-http-client/get-binary/get-binary_xml.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/get-binary/get-binary_xml.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,5 @@
+jsoniq version "1.0";
+import module namespace http="http://zorba.io/modules/http-client";;
+
+http:get-binary("http://zorbatest.lambda.nu:8080/cgi-bin/test-xml";).body.content
+

=== added file 'test/rbkt/Queries/zorba/json-http-client/get-binary/get-binary_xml_query.xq'
--- test/rbkt/Queries/zorba/json-http-client/get-binary/get-binary_xml_query.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/get-binary/get-binary_xml_query.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,5 @@
+jsoniq version "1.0";
+import module namespace http="http://zorba.io/modules/http-client";;
+
+http:get-binary("http://zorbatest.lambda.nu:8080/cgi-bin/test-xml?querystring";).body.content
+

=== added directory 'test/rbkt/Queries/zorba/json-http-client/get-node'
=== added file 'test/rbkt/Queries/zorba/json-http-client/get-node/get-node_error_http.spec'
--- test/rbkt/Queries/zorba/json-http-client/get-node/get-node_error_http.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/get-node/get-node_error_http.spec	2013-06-15 00:58:33 +0000
@@ -0,0 +1,1 @@
+Error: http://zorba.io/modules/http-client:HC001

=== added file 'test/rbkt/Queries/zorba/json-http-client/get-node/get-node_error_http.xq'
--- test/rbkt/Queries/zorba/json-http-client/get-node/get-node_error_http.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/get-node/get-node_error_http.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,6 @@
+jsoniq version "1.0";
+import module namespace http="http://zorba.io/modules/http-client";;
+
+(: Connect to an invalid server :)
+http:get("http://localhost:9998/cgi-bin/test-xml?foo&amp;";).body.content
+

=== added file 'test/rbkt/Queries/zorba/json-http-client/get-node/get-node_xml.xq'
--- test/rbkt/Queries/zorba/json-http-client/get-node/get-node_xml.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/get-node/get-node_xml.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,3 @@
+import module namespace http="http://zorba.io/modules/http-client";;
+
+parse-xml(http:get("http://zorbatest.lambda.nu:8080/cgi-bin/test-xml";)("body")("content"))
\ No newline at end of file

=== added file 'test/rbkt/Queries/zorba/json-http-client/get-node/get-node_xml_query.xq'
--- test/rbkt/Queries/zorba/json-http-client/get-node/get-node_xml_query.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/get-node/get-node_xml_query.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,4 @@
+import module namespace http="http://zorba.io/modules/http-client";;
+
+parse-xml(http:get("http://zorbatest.lambda.nu:8080/cgi-bin/test-xml?querystring";)("body")("content"))/body/query/text()
+

=== added directory 'test/rbkt/Queries/zorba/json-http-client/get-text'
=== added file 'test/rbkt/Queries/zorba/json-http-client/get-text/get-text_binary.xq'
--- test/rbkt/Queries/zorba/json-http-client/get-text/get-text_binary.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/get-text/get-text_binary.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,4 @@
+jsoniq version "1.0";
+import module namespace http="http://zorba.io/modules/http-client";;
+
+http:get-text("http://zorbatest.lambda.nu:8080/cgi-bin/test-binary";).body.content
\ No newline at end of file

=== added file 'test/rbkt/Queries/zorba/json-http-client/get-text/get-text_error_http.spec'
--- test/rbkt/Queries/zorba/json-http-client/get-text/get-text_error_http.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/get-text/get-text_error_http.spec	2013-06-15 00:58:33 +0000
@@ -0,0 +1,1 @@
+Error: http://zorba.io/modules/http-client:HC001

=== added file 'test/rbkt/Queries/zorba/json-http-client/get-text/get-text_error_http.xq'
--- test/rbkt/Queries/zorba/json-http-client/get-text/get-text_error_http.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/get-text/get-text_error_http.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,5 @@
+import module namespace http="http://zorba.io/modules/http-client";;
+
+(: Connect to an invalid server :)
+http:get-text("http://localhost:9998/cgi-bin/test-xml?foo&amp;";)[2]
+

=== added file 'test/rbkt/Queries/zorba/json-http-client/get-text/get-text_text.xq'
--- test/rbkt/Queries/zorba/json-http-client/get-text/get-text_text.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/get-text/get-text_text.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,5 @@
+jsoniq version "1.0";
+import module namespace http="http://zorba.io/modules/http-client";;
+
+http:get-text("http://zorbatest.lambda.nu:8080/cgi-bin/test-text";).body.content
+

=== added file 'test/rbkt/Queries/zorba/json-http-client/get-text/get-text_text_query.xq'
--- test/rbkt/Queries/zorba/json-http-client/get-text/get-text_text_query.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/get-text/get-text_text_query.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,5 @@
+jsoniq version "1.0";
+import module namespace http="http://zorba.io/modules/http-client";;
+
+http:get-text("http://zorbatest.lambda.nu:8080/cgi-bin/test-text?querystring";).body.content
+

=== added file 'test/rbkt/Queries/zorba/json-http-client/get-text/get-text_xml.xq'
--- test/rbkt/Queries/zorba/json-http-client/get-text/get-text_xml.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/get-text/get-text_xml.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,5 @@
+jsoniq version "1.0";
+import module namespace http="http://zorba.io/modules/http-client";;
+
+http:get-text("http://zorbatest.lambda.nu:8080/cgi-bin/test-xml";).body.content
+

=== added file 'test/rbkt/Queries/zorba/json-http-client/get-text/get-text_xml_query.xq'
--- test/rbkt/Queries/zorba/json-http-client/get-text/get-text_xml_query.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/get-text/get-text_xml_query.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,5 @@
+jsoniq version "1.0";
+import module namespace http="http://zorba.io/modules/http-client";;
+
+http:get-text("http://zorbatest.lambda.nu:8080/cgi-bin/test-xml?querystring";).body.content
+

=== added file 'test/rbkt/Queries/zorba/json-http-client/get/get_binary.xq'
--- test/rbkt/Queries/zorba/json-http-client/get/get_binary.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/get/get_binary.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,5 @@
+jsoniq version "1.0";
+import module namespace http="http://zorba.io/modules/http-client";;
+
+http:get("http://zorbatest.lambda.nu:8080/cgi-bin/test-binary";).body.content
+

=== added file 'test/rbkt/Queries/zorba/json-http-client/get/get_error_http.spec'
--- test/rbkt/Queries/zorba/json-http-client/get/get_error_http.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/get/get_error_http.spec	2013-06-15 00:58:33 +0000
@@ -0,0 +1,1 @@
+Error: http://zorba.io/modules/http-client:HC001

=== added file 'test/rbkt/Queries/zorba/json-http-client/get/get_error_http.xq'
--- test/rbkt/Queries/zorba/json-http-client/get/get_error_http.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/get/get_error_http.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,5 @@
+import module namespace http="http://zorba.io/modules/http-client";;
+
+(: Connect to an invalid server :)
+http:get("http://localhost:9998/cgi-bin/test-xml?foo&amp;";)[2]
+

=== added file 'test/rbkt/Queries/zorba/json-http-client/get/get_text.xq'
--- test/rbkt/Queries/zorba/json-http-client/get/get_text.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/get/get_text.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,5 @@
+jsoniq version "1.0";
+import module namespace http="http://zorba.io/modules/http-client";;
+
+http:get("http://zorbatest.lambda.nu:8080/cgi-bin/test-text";).body.content
+

=== added file 'test/rbkt/Queries/zorba/json-http-client/get/get_text_query.xq'
--- test/rbkt/Queries/zorba/json-http-client/get/get_text_query.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/get/get_text_query.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,5 @@
+jsoniq version "1.0";
+import module namespace http="http://zorba.io/modules/http-client";;
+
+http:get("http://zorbatest.lambda.nu:8080/cgi-bin/test-text?querystring";).body.content
+

=== added file 'test/rbkt/Queries/zorba/json-http-client/get/get_xml.xq'
--- test/rbkt/Queries/zorba/json-http-client/get/get_xml.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/get/get_xml.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,4 @@
+jsoniq version "1.0";
+import module namespace http="http://zorba.io/modules/http-client";;
+
+parse-xml(http:get("http://zorbatest.lambda.nu:8080/cgi-bin/test-xml";).body.content)
\ No newline at end of file

=== added file 'test/rbkt/Queries/zorba/json-http-client/get/get_xml_query.xq'
--- test/rbkt/Queries/zorba/json-http-client/get/get_xml_query.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/get/get_xml_query.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,3 @@
+import module namespace http="http://zorba.io/modules/http-client";;
+
+parse-xml(http:get("http://zorbatest.lambda.nu:8080/cgi-bin/test-xml?querystring";)("body")("content"))/body/query/text()

=== added directory 'test/rbkt/Queries/zorba/json-http-client/head'
=== added file 'test/rbkt/Queries/zorba/json-http-client/head/head_content-type_binary.xq'
--- test/rbkt/Queries/zorba/json-http-client/head/head_content-type_binary.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/head/head_content-type_binary.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,6 @@
+jsoniq version "1.0";
+import module namespace http="http://zorba.io/modules/http-client";;
+
+declare namespace exp="http://expath.org/ns/http-client";;
+
+http:head("http://zorbatest.lambda.nu:8080/cgi-bin/test-binary";).headers.("Content-Type")
\ No newline at end of file

=== added file 'test/rbkt/Queries/zorba/json-http-client/head/head_content-type_text.xq'
--- test/rbkt/Queries/zorba/json-http-client/head/head_content-type_text.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/head/head_content-type_text.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,6 @@
+jsoniq version "1.0";
+import module namespace http="http://zorba.io/modules/http-client";;
+
+declare namespace exp="http://expath.org/ns/http-client";;
+
+http:head("http://zorbatest.lambda.nu:8080/cgi-bin/test-text";).headers("Content-Type")
\ No newline at end of file

=== added file 'test/rbkt/Queries/zorba/json-http-client/head/head_content-type_xml.xq'
--- test/rbkt/Queries/zorba/json-http-client/head/head_content-type_xml.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/head/head_content-type_xml.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,6 @@
+jsoniq version "1.0";
+import module namespace http="http://zorba.io/modules/http-client";;
+
+declare namespace exp="http://expath.org/ns/http-client";;
+
+http:head("http://zorbatest.lambda.nu:8080/cgi-bin/test-xml";).headers("Content-Type")
\ No newline at end of file

=== added file 'test/rbkt/Queries/zorba/json-http-client/head/head_error_http.spec'
--- test/rbkt/Queries/zorba/json-http-client/head/head_error_http.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/head/head_error_http.spec	2013-06-15 00:58:33 +0000
@@ -0,0 +1,1 @@
+Error: http://zorba.io/modules/http-client:HC001

=== added file 'test/rbkt/Queries/zorba/json-http-client/head/head_error_http.xq'
--- test/rbkt/Queries/zorba/json-http-client/head/head_error_http.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/head/head_error_http.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,9 @@
+import module namespace http="http://zorba.io/modules/http-client";;
+
+declare namespace exp="http://expath.org/ns/http-client";;
+
+data(
+  http:head("http://localhost:99955/cgi-bin/test-xml";)/@status
+)
+
+

=== added file 'test/rbkt/Queries/zorba/json-http-client/head/head_status.xq'
--- test/rbkt/Queries/zorba/json-http-client/head/head_status.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/head/head_status.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,6 @@
+jsoniq version "1.0";
+import module namespace http="http://zorba.io/modules/http-client";;
+
+declare namespace exp="http://expath.org/ns/http-client";;
+
+http:head("http://zorbatest.lambda.nu:8080/cgi-bin/test-xml";).status
\ No newline at end of file

=== added directory 'test/rbkt/Queries/zorba/json-http-client/options'
=== added file 'test/rbkt/Queries/zorba/json-http-client/options/options.xq'
--- test/rbkt/Queries/zorba/json-http-client/options/options.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/options/options.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,3 @@
+import module namespace http = "http://zorba.io/modules/http-client";;
+http:options("http://zorbatest.lambda.nu:8080/http-test-data/http1.xml";)
+

=== added file 'test/rbkt/Queries/zorba/json-http-client/options/options_error_http.spec'
--- test/rbkt/Queries/zorba/json-http-client/options/options_error_http.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/options/options_error_http.spec	2013-06-15 00:58:33 +0000
@@ -0,0 +1,1 @@
+Error: http://zorba.io/modules/http-client:HC001

=== added file 'test/rbkt/Queries/zorba/json-http-client/options/options_error_http.xq'
--- test/rbkt/Queries/zorba/json-http-client/options/options_error_http.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/options/options_error_http.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,3 @@
+import module namespace http = "http://zorba.io/modules/http-client";;
+http:options("http://localhost:99558/rest-tests/http1.xml";)
+

=== added directory 'test/rbkt/Queries/zorba/json-http-client/post'
=== added file 'test/rbkt/Queries/zorba/json-http-client/post/post2_binary.xq'
--- test/rbkt/Queries/zorba/json-http-client/post/post2_binary.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/post/post2_binary.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,10 @@
+jsoniq version "1.0";
+import module namespace http="http://zorba.io/modules/http-client";;
+
+(: value is "hello there" in base64 :)
+variable $arg as xs:base64Binary := "aGVsbG8gdGhlcmUK" cast as xs:base64Binary;
+variable $result :=
+  http:post("http://zorbatest.lambda.nu:8080/cgi-bin/test-text";, $arg);
+
+$result.body.content
+

=== added file 'test/rbkt/Queries/zorba/json-http-client/post/post2_error_http.spec'
--- test/rbkt/Queries/zorba/json-http-client/post/post2_error_http.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/post/post2_error_http.spec	2013-06-15 00:58:33 +0000
@@ -0,0 +1,1 @@
+Error: http://zorba.io/modules/http-client:HC001

=== added file 'test/rbkt/Queries/zorba/json-http-client/post/post2_error_http.xq'
--- test/rbkt/Queries/zorba/json-http-client/post/post2_error_http.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/post/post2_error_http.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,8 @@
+import module namespace http="http://zorba.io/modules/http-client";;
+
+variable $arg := "hello";
+variable $result :=
+  http:post("http://localhost:99558/cgi-bin/test-text";, $arg);
+
+$result[2]
+

=== added file 'test/rbkt/Queries/zorba/json-http-client/post/post2_string.xq'
--- test/rbkt/Queries/zorba/json-http-client/post/post2_string.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/post/post2_string.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,6 @@
+jsoniq version "1.0";
+import module namespace http="http://zorba.io/modules/http-client";;
+
+variable $result := http:post("http://zorbatest.lambda.nu:8080/cgi-bin/test-text";, "poststring");
+
+$result.body.content
\ No newline at end of file

=== added file 'test/rbkt/Queries/zorba/json-http-client/post/post3_binary.xq'
--- test/rbkt/Queries/zorba/json-http-client/post/post3_binary.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/post/post3_binary.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,9 @@
+jsoniq version "1.0";
+import module namespace http="http://zorba.io/modules/http-client";;
+
+(: value is "hello there" in base64 :)
+variable $arg as xs:base64Binary := "aGVsbG8gdGhlcmUK" cast as xs:base64Binary;
+variable $result :=  http:post("http://zorbatest.lambda.nu:8080/cgi-bin/test-text";, $arg, "application/octet-stream");
+
+$result.body.content
+

=== added file 'test/rbkt/Queries/zorba/json-http-client/post/post3_encoding_error.spec'
--- test/rbkt/Queries/zorba/json-http-client/post/post3_encoding_error.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/post/post3_encoding_error.spec	2013-06-15 00:58:33 +0000
@@ -0,0 +1,1 @@
+Error: http://zorba.io/modules/http-client:HCV03

=== added file 'test/rbkt/Queries/zorba/json-http-client/post/post3_encoding_error.xq'
--- test/rbkt/Queries/zorba/json-http-client/post/post3_encoding_error.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/post/post3_encoding_error.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,7 @@
+import module namespace http="http://zorba.io/modules/http-client";;
+
+variable $arg := "hello";
+variable $result := http:post("http://localhost:99558/cgi-bin/test-text";, $arg, "text plain; charset=mycharset");
+
+$result[2]
+

=== added file 'test/rbkt/Queries/zorba/json-http-client/post/post3_error_http.spec'
--- test/rbkt/Queries/zorba/json-http-client/post/post3_error_http.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/post/post3_error_http.spec	2013-06-15 00:58:33 +0000
@@ -0,0 +1,1 @@
+Error: http://zorba.io/modules/http-client:HC001

=== added file 'test/rbkt/Queries/zorba/json-http-client/post/post3_error_http.xq'
--- test/rbkt/Queries/zorba/json-http-client/post/post3_error_http.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/post/post3_error_http.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,9 @@
+import module namespace http="http://zorba.io/modules/http-client";;
+
+variable $arg := "hello";
+variable $result :=
+  http:post("http://localhost:99558/cgi-bin/test-text";, $arg,
+           "application/octet-stream");
+
+$result[2]
+

=== added file 'test/rbkt/Queries/zorba/json-http-client/post/post3_string.xq'
--- test/rbkt/Queries/zorba/json-http-client/post/post3_string.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/post/post3_string.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,6 @@
+jsoniq version "1.0";
+import module namespace http="http://zorba.io/modules/http-client";;
+
+variable $result := http:post("http://zorbatest.lambda.nu:8080/cgi-bin/test-text";, "poststring","text/plain");
+$result.body.content
+

=== added directory 'test/rbkt/Queries/zorba/json-http-client/put'
=== added file 'test/rbkt/Queries/zorba/json-http-client/put/put2_binary.xq'
--- test/rbkt/Queries/zorba/json-http-client/put/put2_binary.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/put/put2_binary.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,10 @@
+jsoniq version "1.0";
+import module namespace http="http://zorba.io/modules/http-client";;
+
+(: value is "hello there" in base64 :)
+variable $arg as xs:base64Binary := "aGVsbG8gdGhlcmUK" cast as xs:base64Binary;
+variable $result :=
+  http:put("http://zorbatest.lambda.nu:8080/cgi-bin/test-text";, $arg);
+
+$result.body.content
+

=== added file 'test/rbkt/Queries/zorba/json-http-client/put/put2_error_http.spec'
--- test/rbkt/Queries/zorba/json-http-client/put/put2_error_http.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/put/put2_error_http.spec	2013-06-15 00:58:33 +0000
@@ -0,0 +1,1 @@
+Error: http://zorba.io/modules/http-client:HC001

=== added file 'test/rbkt/Queries/zorba/json-http-client/put/put2_error_http.xq'
--- test/rbkt/Queries/zorba/json-http-client/put/put2_error_http.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/put/put2_error_http.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,8 @@
+import module namespace http="http://zorba.io/modules/http-client";;
+
+variable $arg := "hello";
+variable $result :=
+  http:put("http://localhost:99558/cgi-bin/test-text";, $arg);
+
+$result[2]
+

=== added file 'test/rbkt/Queries/zorba/json-http-client/put/put2_string.xq'
--- test/rbkt/Queries/zorba/json-http-client/put/put2_string.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/put/put2_string.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,8 @@
+jsoniq version "1.0";
+import module namespace http="http://zorba.io/modules/http-client";;
+
+variable $result :=
+  http:put("http://zorbatest.lambda.nu:8080/cgi-bin/test-text";, "putstring");
+
+$result.body.content
+

=== added file 'test/rbkt/Queries/zorba/json-http-client/put/put3_binary.xq'
--- test/rbkt/Queries/zorba/json-http-client/put/put3_binary.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/put/put3_binary.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,9 @@
+jsoniq version "1.0";
+import module namespace http="http://zorba.io/modules/http-client";;
+
+(: value is "hello there" in base64 :)
+variable $arg as xs:base64Binary := "aGVsbG8gdGhlcmUK" cast as xs:base64Binary;
+variable $result := http:put("http://zorbatest.lambda.nu:8080/cgi-bin/test-text";, $arg, "application/octet-stream");
+
+$result.body.content
+

=== added file 'test/rbkt/Queries/zorba/json-http-client/put/put3_error_http.spec'
--- test/rbkt/Queries/zorba/json-http-client/put/put3_error_http.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/put/put3_error_http.spec	2013-06-15 00:58:33 +0000
@@ -0,0 +1,1 @@
+Error: http://zorba.io/modules/http-client:HC001

=== added file 'test/rbkt/Queries/zorba/json-http-client/put/put3_error_http.xq'
--- test/rbkt/Queries/zorba/json-http-client/put/put3_error_http.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/put/put3_error_http.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,9 @@
+import module namespace http="http://zorba.io/modules/http-client";;
+
+variable $arg := "hello";
+variable $result :=
+  http:put("http://localhost:99558/cgi-bin/test-text";, $arg,
+           "application/octet-stream");
+
+$result[2]
+

=== added file 'test/rbkt/Queries/zorba/json-http-client/put/put3_string.xq'
--- test/rbkt/Queries/zorba/json-http-client/put/put3_string.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/put/put3_string.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,7 @@
+jsoniq version "1.0";
+import module namespace http="http://zorba.io/modules/http-client";;
+
+variable $result :=
+  http:put("http://zorbatest.lambda.nu:8080/cgi-bin/test-text";, "putstring","text/plain");
+
+$result.body.content
\ No newline at end of file

=== added directory 'test/rbkt/Queries/zorba/json-http-client/send-request'
=== added file 'test/rbkt/Queries/zorba/json-http-client/send-request/http1-redirect.xq'
--- test/rbkt/Queries/zorba/json-http-client/send-request/http1-redirect.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/send-request/http1-redirect.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,32 @@
+jsoniq version "1.0";
+import module namespace http="http://zorba.io/modules/http-client";;
+
+declare namespace h = "http://expath.org/ns/http-client";;
+
+variable $http-res-with := 
+http:send-request(
+{
+  "href": "http://zorbatest.lambda.nu:8080/remotequeue";,
+  "method": "HEAD",
+  "options": {
+    "follow-redirect": true
+  }  
+});
+
+variable $http-res-without := 
+http:send-request(
+{
+  "href": "http://zorbatest.lambda.nu:8080/remotequeue";,
+  "method": "HEAD",
+  "options": {
+    "follow-redirect": false
+  }  
+});
+
+let $status-with := $http-res-with.status
+let $status-without := $http-res-without.status
+return
+  if ($status-without eq 301) then
+    $status-with
+  else "failed" 
+  
\ No newline at end of file

=== added file 'test/rbkt/Queries/zorba/json-http-client/send-request/http1-useragent.xq'
--- test/rbkt/Queries/zorba/json-http-client/send-request/http1-useragent.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/send-request/http1-useragent.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,18 @@
+import module namespace http="http://zorba.io/modules/http-client";;
+
+variable $req :=
+{
+  "method": "POST",
+  "href": "http://zorbatest.lambda.nu:8080/http-test-data/request.php";,  
+  "body": {
+    "media-type": "text/plain",
+    "content": "
+      Dies ist ein kleiner Test
+    "
+  },
+  "options": {
+    "user-agent": "28.io"
+  }
+};
+
+parse-xml(http:send-request($req)("body")("content"))//*:header[@*:name="User-Agent"]/@value/string(.)
\ No newline at end of file

=== added file 'test/rbkt/Queries/zorba/json-http-client/send-request/http2-read-svg.xq'
--- test/rbkt/Queries/zorba/json-http-client/send-request/http2-read-svg.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/send-request/http2-read-svg.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,20 @@
+jsoniq version "1.0";
+(: test content having a content type ending with +xml, i.e. image/svg+xml :)
+import module namespace http = "http://zorba.io/modules/http-client";;
+declare namespace h = "http://expath.org/ns/http-client";;
+
+variable $req := 
+{
+  "method": "GET",
+  "href": "http://zorbatest.lambda.nu:8080/http-test-data/basic-auth/example.svg";,
+  "authentication": {
+    "auth-method": "Basic",    
+    "username": "zorba",
+    "password": "blub"
+  },
+  "options": {
+    "override-media-type": "application/xml; charset=utf-8"
+  }
+};
+
+parse-xml(http:send-request($req).body.content)
\ No newline at end of file

=== added file 'test/rbkt/Queries/zorba/json-http-client/send-request/http3-multipart.xq'
--- test/rbkt/Queries/zorba/json-http-client/send-request/http3-multipart.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/send-request/http3-multipart.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,52 @@
+xquery version "3.0";
+import module namespace httpc = "http://zorba.io/modules/http-client";;
+import module namespace libjn = "http://jsoniq.org/function-library";;
+
+declare namespace http = "http://expath.org/ns/http-client";;
+
+variable $req :=
+{
+  "method": "POST", 
+  "href": "http://zorbatest.lambda.nu:8080/http-test-data/request.php";,
+  "headers": {"foo": "bar"},
+  "multipart": {
+    "media-type": "multipart/mixed",    
+    "parts" : [
+      {
+        "headers": {"insidemutlipart": "blubb"},        
+        "body": {
+          "media-type": "text/plain",
+          "content": "
+        A small text test
+      "
+        }
+      },
+      {        
+        "body": {
+          "media-type": "text/plain",
+          "content": " 
+        Another small text body
+      "
+        }
+      },
+      {
+        "body": {
+          "media-type": "img/png",
+          "content": "lqenw"
+        }
+      }      
+    ]
+  }
+};
+
+variable $res := parse-xml(httpc:send-request($req)("body")("content"));
+<result>
+      <number-of-bodies>{fn:count($res//http:body)}</number-of-bodies>
+      <headers>{
+        $res//http:header[fn:not(
+          fn:contains(data(@value), "boundary")
+            or
+          fn:contains(data(@name), "------")
+            or
+          fn:contains(data(@name), "Content-Length"))]}</headers>
+</result>
\ No newline at end of file

=== added file 'test/rbkt/Queries/zorba/json-http-client/send-request/http3-post.xq'
--- test/rbkt/Queries/zorba/json-http-client/send-request/http3-post.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/send-request/http3-post.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,19 @@
+jsoniq version "1.0";
+import module namespace http = "http://zorba.io/modules/http-client";;
+
+declare default element namespace "http://expath.org/ns/http-client";;
+
+variable $req :=
+{
+  "method": "POST",
+  "href": "http://zorbatest.lambda.nu:8080/http-test-data/request.php";,
+  "headers": {"foo":"bar"},
+  "body": {
+    "media-type": "text/plain",
+    "content": "
+      Dies ist ein kleiner Test
+    "
+  }
+};
+
+parse-xml(http:send-request($req).body.content)
\ No newline at end of file

=== added file 'test/rbkt/Queries/zorba/json-http-client/send-request/http4-post-redirect.spec'
--- test/rbkt/Queries/zorba/json-http-client/send-request/http4-post-redirect.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/send-request/http4-post-redirect.spec	2013-06-15 00:58:33 +0000
@@ -0,0 +1,1 @@
+Error: http://zorba.io/modules/http-client:HCV02

=== added file 'test/rbkt/Queries/zorba/json-http-client/send-request/http4-post-redirect.xq'
--- test/rbkt/Queries/zorba/json-http-client/send-request/http4-post-redirect.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/send-request/http4-post-redirect.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,13 @@
+jsoniq version "1.0";
+import module namespace http="http://zorba.io/modules/http-client";;
+
+declare namespace h = "http://expath.org/ns/http-client";;
+
+http:send-request(
+{
+  "href": "http://zorbatest.lambda.nu:8080/remotequeue";, 
+  "method": "POST",
+  "options": { 
+    "follow-redirect": true
+  }
+});

=== added file 'test/rbkt/Queries/zorba/json-http-client/send-request/http_error_hc005.spec'
--- test/rbkt/Queries/zorba/json-http-client/send-request/http_error_hc005.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/send-request/http_error_hc005.spec	2013-06-15 00:58:33 +0000
@@ -0,0 +1,1 @@
+ Error: http://www.zorba.io/modules/http-client:HC005
\ No newline at end of file

=== added file 'test/rbkt/Queries/zorba/json-http-client/send-request/http_error_hc005.xq'
--- test/rbkt/Queries/zorba/json-http-client/send-request/http_error_hc005.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/send-request/http_error_hc005.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,65 @@
+import module namespace http = "http://zorba.io/modules/http-client";;
+declare namespace h = "http://expath.org/ns/http-client";;
+
+try {
+  http:send-request({"hi":"hello"})
+} catch http:HC005 {
+  "ok"
+},
+try {
+  http:send-request({"method": 3})
+} catch http:HC005 {
+  "ok"
+},
+try {
+  http:send-request({
+  "mistypedhref": "http://zorbatest.lambda.nu:8080/remotequeue";,
+  "method": "GET",
+  "options": {
+    "follow-redirect": false
+  }  
+})
+} catch http:HC005 {
+  "ok"
+},
+try {
+  http:send-request({
+  "href": "http://zorbatest.lambda.nu:8080/remotequeue";,
+  "method": 3,
+  "options": {
+    "follow-redirect": false
+  }  
+})
+} catch http:HC005 {
+  "ok"
+},
+try {
+  http:send-request({
+  "href": "http://zorbatest.lambda.nu:8080/remotequeue";,
+  "method": "GET",
+  "headers": "three",
+  "options": {
+    "follow-redirect": false
+  }  
+})
+} catch http:HC005 {
+  "ok"
+},
+try {
+  http:post("http://zorbatest.lambda.nu:8080/cgi-bin/test-text";, 3,"text/plain")  
+} catch http:HCV04 {
+  "ok"
+},
+try {
+  http:send-request(
+  {
+    "method": "POST",
+    "href": "www.ggg.ggg",
+    "body": {
+      "media-type": "text/plain",
+      "content": [2,3]
+    }
+  })
+} catch http:HCV04 {
+  "ok"
+}

=== added file 'test/rbkt/Queries/zorba/json-http-client/send-request/send-request_get_binary.xq'
--- test/rbkt/Queries/zorba/json-http-client/send-request/send-request_get_binary.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/send-request/send-request_get_binary.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,22 @@
+jsoniq version "1.0";
+import module namespace http = "http://zorba.io/modules/http-client";;
+declare namespace h = "http://expath.org/ns/http-client";;
+
+variable $req := 
+{
+  "method": "GET",
+  "href": "http://zorbatest.lambda.nu:8080/http-test-data/basic-auth/download.png";,
+  "authentication": {
+    "auth-method": "Basic",               
+    "username": "zorba",
+    "password": "blub"
+  }
+};
+
+let $res := http:send-request($req)
+return
+(
+   $res.headers.("Content-Type") eq "image/png",
+   $res.body.("media-type") eq "image/png",
+   $res.headers.("Content-Length") eq "5577"
+)

=== added file 'test/rbkt/Queries/zorba/json-http-client/send-request/send-request_href.xq'
--- test/rbkt/Queries/zorba/json-http-client/send-request/send-request_href.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/json-http-client/send-request/send-request_href.xq	2013-06-15 00:58:33 +0000
@@ -0,0 +1,10 @@
+jsoniq version "1.0";
+import module namespace http = "http://zorba.io/modules/http-client";;
+
+variable $req := 
+{
+  "method" : "GET",
+  "href" : "http://zorbatest.lambda.nu:8080/cgi-bin/test-xml?querystring";
+};
+
+parse-xml(http:send-request($req).body.content)
\ No newline at end of file


Follow ups