Skip to content

Commit

Permalink
RFC 72: Use port-based overrides instead.
Browse files Browse the repository at this point in the history
  • Loading branch information
letitz committed May 6, 2021
1 parent 106a437 commit fbc95bd
Showing 1 changed file with 64 additions and 28 deletions.
92 changes: 64 additions & 28 deletions rfcs/address_space_overrides.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,63 +8,99 @@ More specifically, to enable tests to exercise user agent behavior in the face
of responses served from `local`, `private` and `public`
[address spaces](https://wicg.github.io/cors-rfc1918#address-space).

This is achieved by passing command-line flags to the browser under test forcing
it to artificially consider specific IP addresses `local`, `private` or
`public`.
This is achieved by passing configuration knobs to the browser under test
forcing it to artificially consider specific (IP address, port) pairs to be
`local`, `private` or `public`.

This RFC aims to fix
[web-platform-tests/wpt#26166](https://github.com/web-platform-tests/wpt/issues/26166).

## Details

### Address allocation

For the purposes of testing, declare that the following subnets are not `local`
but instead:

* 127.1.0.0/16: `private`
* 127.2.0.0/16: `public`

### Browser changes

A new configuration surface is added to each browser (it need not be uniform,
though that would certainly help with implementation) that allows overriding the
address space derived from specific IP addresses. For example, this could be a
command-line flag:
address space derived from specific (IP address, port) endpoints. For example,
this could be a command-line flag:

```sh
--test-override-address-space=127.1.0.0/16:private,127.2.0.0/16:public
--ip-address-space-overrides=127.0.0.1:8000=private,127.0.0.1:8001=public
```

Test-only code wires this command-line flag to the code in the browser under
test that determines the address space of a network endpoint.

### Test environment changes

New ports are introduced on which to serve artificially-`private` and
artificially-`public` resources. These are named after the existing protocols
with `-private` and `-public` suffixes. Concretely, the server `Config` object
sees its `ports` field extended with entries like the following:

```python
{
"http-private": [8002],
"http-public": [8003],
"https-private": [8445],
"https-public": [8446],
}
```

The `wptserve` and `wptrunner` infrastructure automatically starts new servers
on each of these ports serving the appropriate protocol.

### Test runner changes

The web platform test runner sets command-line flags on browsers such that the
browsers implement the custom address space mapping described above during
tests.
The web platform test runner sets browser-specific configuration options such
that the browsers implement the custom address space mapping described above
during tests.

Corresponding entries are added to the hosts file, as generated by
[make_hosts_file()](https://github.com/web-platform-tests/wpt/blob/master/tools/serve/serve.py#L513-L530):
This allows web platform tests to exercise browser behavior in the face of
`private` and `public` IP addresses, simply by targeting the above ports.

For example, a JS test wishing to make a request to a `public` server can
make use of the server-side substitution feature of `wptserve` to do so:

```
127.1.0.1 private.web-platform.test
127.2.0.1 public.web-platform.test
fetch("http://{{host}}:{{ports[http-public][0]}}/foo.jpg")
```

This allows web platform tests to exercise browser behavior in the face of
`private` and `public` IP addresses, simply by targeting the above domains.

## Risks

If the tests run on an IPv6-only system, the system might not know how to route
requests to the IPv4 loopback address range? This seems like an extremely remote
possibility, in which case many other assumptions made by the test framework
might have to be revisited anyway.
None identified. This approach is fed by implementation experience.

## Alternatives considered

### Override based on IP address, not port

This approach was initially submitted as PR #72, but implementation experience
pointed out its shortcomings - see issue #79. The main issue is that it assumes
the `127.0.0.0/8` IPv4 subnet is routed to loopback on all machines, but that is
not true on macOS and other BSD-derived operating systems.

Instead of overriding the IP address space based on both IP address and port,
this approach simply overrides the IP address space for certain IP addresses.
Given that `127.0.0.0/8` *should* be routed to loopback, this approach makes use
of other IP addresses than 127.0.0.1 to run `wptserve` on.

The following IP addresses see their IP address space overridden:

```
127.1.0.1: private
127.2.0.1: public
```

The configuration surface added to browsers allows overriding per address. It
is otherwise very similar to that described in the proposal above.

The WPT infrastructure is modified to run new servers on these IP addresses, by
the way of two new domains: `public-web-platform.test` and
`private-web-platform.test`. These are added to the system hosts file. All
subdomains and protocols are supported on these new domains.

See web-platform-tests/wpt#28768 for an abandoned experimental implementation.

### Override addresses themselves

This approach was suggested by @ddragana.
Expand Down

0 comments on commit fbc95bd

Please sign in to comment.