request
The request
action carries out a HTTP or HTTPS request to load content from remote sources.
content="..."
to set the id for a request (optional, default is main
)url="..."
to set the request URL (required)method="GET|POST|..."
to set the request method (optional, default is GET
)The request
element may contain any request options.
Examples:
<request content="main" url="http://example.com">
<timeout request="1" connect="2" />
<header name="X-A" value="A" />
<query name="y" value="b" />
<post name="x" value="a" />
<upload name="fieldName" filename="path_to_file.txt" size="123" type="text/plain" src="fit://request/uploads/myFile" />
</request>
<request content="weather" url="http://example.com/weather" />
The response body will be written into fit://request/content/<ID>
. Additional information about the response, such as headers and status code can be found in fit://request/content/<ID>/response
.
The main request (with content="main"
) receives a special treatment. See default-request
action for more information. Usually you should use default-request
to obtain the main content.
If you want to request more than one content, you should use the requests
action that is able to execute requests in parallel. The syntax is the same. Thus wrapping a <request>
with a <requests>
parent element is equivalent.
All request options set in conf/sources.xml
file that match the requested domain and path will also be applied to your request. However, options in the action have precedence over those from conf/sources.xml
.
Be careful with selection values for the name
attributes in input
elements (<input name="" ... />
) in your HTML documents. PHP automatically replaces many signs to underscores (_
), so it can lead to unexpected field names in your backend systems. In some cases PHP removes even the fields completely from request.
Examples:
<input name="test.abc" /> <!-- Result: "test_abc" -->
<input name="test.abc[]" /> <!-- Result: "test_abc[]" -->
<input name="test[abc].xyz" type="input" /> <!-- Result: "test[abc]" -->
<input name="test[abc].xyz" type="file" /> <!-- Result: this field will be completely removed -->
Simple POST requests can be created as follows. Here we send a POST
request to the httpbin Request & Response Service:
<flow>
<request url="https://httpbin.org/post" method="post" />
<dump/>
</flow>
To get a working example, we also have to allow the origin in the ACLs:
<allow url="https://httpbin.org:443/" />
For convenience, our example flow simply dumps the supplied JSON response wherein https://httpbin.org/
just reflects the request we’ve just sent:
{
"args": {},
"data": "",
"files": {},
"form": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "deflate, gzip",
"Connection": "close",
"Content-Length": "0",
"Host": "httpbin.org",
"User-Agent": "Sevenval FIT"
},
"json": null,
"origin": "94.216.65.254",
"url": "https://httpbin.org/post"
}
Let’s now send some data in the body
field. Since the HTTP method will be automatically set to POST
, we can omit method="post"
here:
<request url="https://httpbin.org/post">
<body>foo=42&qux</body>
</request>
The response shows that FIT sends the data as (application/x-www-form-urlencoded
), i.e. as URL-encoded form data foo=42&qux
:
{
…
"form": {
"foo": "42"
"qux": "",
},
"headers": {
…
"Content-Length": "10",
"Content-Type": "application/x-www-form-urlencoded",
…
},
…
}
By the way, have you noticed how we XML-encoded the ampersand as &
in the request? Not only do we have to consider the XML context we’re in, but we also need to URL-encode the data ourselves, as the body
field contains the raw POST data as they will be sent to the origin.
The post
field to the rescue! We can achieve the same result with the following, much simpler request, automatic URL-encoding included:
<request url="https://httpbin.org/post">
<post name="foo" value="42" />
<post name="qux" />
</request>
Thus, for submitting URL-encoded form data, the post
field is the way to go.
Let’s go back to the body
field. As we’ve seen before FIT automatically sends the data as application/x-www-form-urlencoded
. We can change that by adding a different Content-Type
header
field:
<request url="https://httpbin.org/post">
<header name="Content-Type" value="text/plain" />
<body>foo</body>
</request>
{
"args": {},
"data": "foo",
"files": {},
"form": {},
"headers": {
…
"Content-Length": "3",
"Content-Type": "text/plain",
…
},
…
}
Next, we will send an XML body. First, we set the MIME type in the header
field to text/xml
and supply the XML payload as text (!) in the body
field:
<request url="https://httpbin.org/post">
<header name="Content-Type" value="text/xml" />
<body><![CDATA[<foo/>]]></body>
</request>
Instead of using <![CDATA[…]]>
we could have written <body><foo/></body>
. In contrast, <body><foo/></body>
will not produce the desired result! (cf. the mode=xml
documented below).
{
…
"data": "<foo/>",
…
"headers": {
…
"Content-Length": "6",
"Content-Type": "text/xml",
…
},
…
}
The body does not have to be placed inline. We can also make use of the body
field’s src
attribute to specify a location where the body content should be read from:
<request url="https://httpbin.org/post">
<header name="Content-Type" value="text/plain" />
<body src="fit://site/conf/foo" />
</request>
This way is binary safe, so we could also send an image or any other content:
<request url="https://httpbin.org/post">
<header name="Content-Type" value="image/jpeg" />
<body src="fit://site/public/foo.jpg" />
</request>
{
…
"data": "data:application/octet-stream;base64,/9j/4AAQSkZJR…
…
"headers": {
…
"Content-Length": "15198",
"Content-Type": "image/jpeg",
…
},
…
}
The referenced content may be created dynamically with XSLT:
<xslt src="body.xsl" out="fit://request/dynamic-body" />
<request url="https://httpbin.org/post">
<header name="Content-Type" value="text/xml" />
<body src="fit://request/dynamic-body" />
</request>
There is a special mode for JSON request bodies. You may you use the JSON XML notation inside the <body>
element:
<request url="https://httpbin.org/post">
<body mode="json">
<json-document>
<cool type="boolean" value="true" />
</json-document>
</body>
</request>
With mode=json
, the body will be converted into a JSON document:
{"cool":true}
This mode also works with body content sourced from a fit://
location.
<request url="https://httpbin.org/post">
<body mode="json" src="fit://request/some-json-xml-body" />
</request>
If no Content-Type
header was set explicitly, application/json
will be used. As usual, the Content-Length
is calculated automatically. For all requests with body
, the default HTTP method is POST
. You may override that, e.g. with PUT
.
Sending an XML request body is a common task, too. The xml
mode let’s you write inline XML inside your request definition:
<request url="https://httpbin.org/post">
<body mode="xml">
<message>foo bar</message>
</body>
</request>
In contrast to the raw POSTs (mode=text
) that we have seen above, in XML mode the POSTed body is
<message>foo bar</message>
If not set explicitly, a Content-Type: text/xml
header will be added.
Note, that <body>
may only contain one child element. That child will be XML serialized with all its children. This includes XML comments, too.
When you are working with XML namespaces, you have to repeat the namespace definition inside the request’s <body>
element.