diff options
Diffstat (limited to 'testing/web-platform/tests/docs/writing-tests/server-pipes.md')
-rw-r--r-- | testing/web-platform/tests/docs/writing-tests/server-pipes.md | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/testing/web-platform/tests/docs/writing-tests/server-pipes.md b/testing/web-platform/tests/docs/writing-tests/server-pipes.md new file mode 100644 index 0000000000..dc376ddacf --- /dev/null +++ b/testing/web-platform/tests/docs/writing-tests/server-pipes.md @@ -0,0 +1,155 @@ +# wptserve Pipes + +Pipes are designed to allow simple manipulation of the way that +static files are sent without requiring any custom code. They are also +useful for cross-origin tests because they can be used to activate a +substitution mechanism which can fill in details of ports and server +names in the setup on which the tests are being run. + +## Enabling + +Pipes are functions that may be used when serving files to alter parts +of the response. These are invoked by adding a pipe= query parameter +taking a | separated list of pipe functions and parameters. The pipe +functions are applied to the response from left to right. For example: + + GET /sample.txt?pipe=slice(1,200)|status(404). + +This would serve bytes 1 to 199, inclusive, of foo.txt with the HTTP status +code 404. + +Note: If you write directly to the response socket using ResponseWriter, or +when using the asis handler, only the trickle pipe will affect the response. + +There are several built-in pipe functions, and it is possible to add +more using the `@pipe` decorator on a function, if required. + +Note: Because of the way pipes compose, using some pipe functions prevents the +content-length of the response from being known in advance. In these cases the +server will close the connection to indicate the end of the response, +preventing the use of HTTP 1.1 keepalive. + +## Built-In Pipes + +### `sub` + +Used to substitute variables from the server environment, or from the +request into the response. A typical use case is for testing +cross-domain since the exact domain name and ports of the servers are +generally unknown. + +Substitutions are marked in a file using a block delimited by `{{` +and `}}`. Inside the block the following variables are available: + +- `{{host}}` - The host name of the server excluding any subdomain part. +- `{{domains[]}}` - The domain name of a particular subdomain e.g. + `{{domains[www]}}` for the `www` subdomain. +- `{{hosts[][]}}` - The domain name of a particular subdomain for a particular + host. The first key may be empty (designating the "default" host) or the + value `alt`; i.e., `{{hosts[alt][]}}` (designating the alternate host). +- `{{ports[][]}}` - The port number of servers, by protocol e.g. + `{{ports[http][0]}}` for the first (and, depending on setup, possibly only) + http server +- `{{headers[]}}` The HTTP headers in the request e.g. `{{headers[X-Test]}}` + for a hypothetical `X-Test` header. +- `{{header_or_default(header, default)}}` The value of an HTTP header, or a + default value if it is absent. e.g. `{{header_or_default(X-Test, + test-header-absent)}}` +- `{{GET[]}}` The query parameters for the request e.g. `{{GET[id]}}` for an id + parameter sent with the request. + +So, for example, to write a JavaScript file called `xhr.js` that +depends on the host name of the server, without hardcoding, one might +write: + + var server_url = http://{{host}}:{{ports[http][0]}}/path/to/resource; + //Create the actual XHR and so on + +The file would then be included as: + + <script src="xhr.js?pipe=sub"></script> + +This pipe can also be enabled by using a filename `*.sub.ext`, e.g. the file above could be called `xhr.sub.js`. + +### `status` + +Used to set the HTTP status of the response, for example: + + example.js?pipe=status(410) + +### `headers` + +Used to add or replace http headers in the response. Takes two or +three arguments; the header name, the header value and whether to +append the header rather than replace an existing header (default: +False). So, for example, a request for: + + example.html?pipe=header(Content-Type,text/plain) + +causes example.html to be returned with a text/plain content type +whereas: + + example.html?pipe=header(Content-Type,text/plain,True) + +Will cause example.html to be returned with both text/html and +text/plain content-type headers. + +If the comma (`,`) or closing parenthesis (`)`) characters appear in the header +value, those characters must be escaped with a backslash (`\`): + + example?pipe=header(Expires,Thu\,%2014%20Aug%201986%2018:00:00%20GMT) + +(Note that the programming environment from which the request is issued may +require that the backslash character itself be escaped.) + +### `slice` + +Used to send only part of a response body. Takes the start and, +optionally, end bytes as arguments, although either can be null to +indicate the start or end of the file, respectively. So for example: + + example.txt?pipe=slice(10,20) + +Would result in a response with a body containing 10 bytes of +example.txt including byte 10 but excluding byte 20. + + example.txt?pipe=slice(10) + +Would cause all bytes from byte 10 of example.txt to be sent, but: + + example.txt?pipe=slice(null,20) + +Would send the first 20 bytes of example.txt. + +### `trickle` + +Note: Using this function will force a connection close. + +Used to send the body of a response in chunks with delays. Takes a +single argument that is a microsyntax consisting of colon-separated +commands. There are three types of commands: + +* Bare numbers represent a number of bytes to send + +* Numbers prefixed `d` indicate a delay in seconds + +* Numbers prefixed `r` must only appear at the end of the command, and + indicate that the preceding N items must be repeated until there is + no more content to send. The number of items to repeat must be even. + +In the absence of a repetition command, the entire remainder of the content is +sent at once when the command list is exhausted. So for example: + + example.txt?pipe=trickle(d1) + +causes a 1s delay before sending the entirety of example.txt. + + example.txt?pipe=trickle(100:d1) + +causes 100 bytes of example.txt to be sent, followed by a 1s delay, +and then the remainder of the file to be sent. On the other hand: + + example.txt?pipe=trickle(100:d1:r2) + +Will cause the file to be sent in 100 byte chunks separated by a 1s +delay until the whole content has been sent. |