summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/docs/writing-tests/server-pipes.md
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--testing/web-platform/tests/docs/writing-tests/server-pipes.md155
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.