HTTP Client

Machine

This module defines a set of functions to send HTTP & HTTPS requests and handle responses. This is a quite low-level functionality, allowing one to deal with most aspects of the HTTP protocol (redirections, headers, body contents, multipart...), while integrating smoothly within the XPath Data Model.

This module was written initially for EXSLT 2.0, but it is really an XPath extension, that makes sense to be used in XQuery as well, for instance. It is being moved to EXPath, but the legacy page is still available. As this is the first EXPath module so far, any thought about how it should be released and about packaging would be much appreciated on the mailing list.

Introduction

Besides the specification, here is an informal introduction to this module. See also the samples page for more elaborate samples. This module defines a single function, http:send-request() (with several arities for the sake of ease of use.) The function takes a description of the request in parameter, and returns a representation of the response.

The request is represented by an http:request element, giving the URI, the HTTP method, the headers and the body content (for POST and PUT methods.) The response is returned as a sequence of one or more items. The first one is an http:response element with quite the same structure as an http:request, but without the content itself. The content is returned as the second item (or several items in case of a multipart response) as a string, a document node or a binary item, depending on the Content-Type returned by the server. Here is a simple example of call in XQuery, which sends a text content by POST:

http:send-request(
   <http:request href="..." method="post">
      <http:body content-type="text/plain">
         Hello, world!
      </http:body>
   </http:request>
)

The response element can look like the following:

<http:response status="200" message="Ok">
   <http:header name="Content-Type" value="text/html"/>
   <http:header name="Server" value="Apache ..."/>
   ...
   <http:body content-type="text/html"/>
</http:response>

It is important to understand that the result of the function, in the example of the above call, is a sequence of 2 items: the http:response element, and a document node representing the HTML document. Here is an example of query that illustrate that fact; it checks the status of the response within the http:response element, then use the title element in the HTML document:

<!-- The request element to get Google page. -->
<xsl:variable name="req" as="element()">
   <http:request href="http://www.google.com/" method="get"/>
</xsl:variable>

<!-- The response sequence (http:response + HTML doc.) -->
<xsl:variable name="resp" select="http:send-request($req)"/>

<!-- If status code is not 200, throw an error. -->
<xsl:if test="$resp[1]/xs:integer(@status) ne 200">
   <xsl:sequence select="error((), 'Status is not 200.')"/>
</xsl:if>

<!-- Use the title element in the HTML document. -->
<xsl:value-of select="$resp[2]/h:html/h:head/h:title"/>

You can find other examples on the samples page.