On Thu, Jun 11, 2015 at 1:04 PM, Yoav Weiss <
yo...@yoav.ws> wrote:
> On Thu, Jun 11, 2015 at 9:59 PM, Matt Menke <
mme...@chromium.org> wrote:
>>
>> I assume it still doesn't work for "privacy mode" connections?
>
>
> It would before shipping, using the `crossorigin` attribute.
Right, this is what the hold-up was about, but is hopefully resolved.
TL;DR:
crossorigin="anonymous" == PRIVACY_MODE_ENABLED (but indirectly,
through multiple layers)
crossorigin="use-credentials" == PRIVACY_MODE_DISABLED
Fetch RequestCredentials == "omit" == PRIVACY_MODE_ENABLED
Fetch RequestCredentials == "same-origin" == PRIVACY_MODE_ENABLED ||
PRIVACY_MODE_DISABLED [depending on origin]
Fetch RequestCredentials == "include" == PRIVACY_MODE_DISABLED
Fetch CORS Preflight == PRIVACY_MODE_ENABLED [yes, this means that
CORS preflights and the HTTP requests that follow use *different*
socket pools)
Explanation: We effectively maintain two distinct socket pools that
correspond to Fetch specs notion of a requests' credentials flag (see
https://fetch.spec.whatwg.org/#http-network-fetch )
When the credentials flag is not set (aka omit), that corresponds
roughly to (LOAD_DO_NOT_SEND_COOKIES | LOAD_DO_NOT_STORE_COOKIES |
LOAD_DO_NOT_SEND_AUTH_DATA) [plus an additional load flag we don't
express, which is don't send client certs; that's a bug].
When the credentials flag is set, then you can send/store cookies and
include auth data (HTTP, client auth)
The above is done for security (that is, the credentials flag is about
preserving CORS security as well as stripping ambient auth on
cross-origin requests)
What isn't specified by Fetch (AFAIK) is we also make a distinction
between First-Party and Third-Party requests (like other browsers). A
third-party request is one which omits cookies, if the user has
third-party cookie blocking enabled. This is done for
privacy/tracking.
Ideally, a 'third-party request' is simply one that would be done with
the credentials flag not set - that is, omit cookies and ambient auth.
Unfortunately, we've implemented a concept called privacy_mode to
reflect that separation, separate-to/in addition-to the load flags (I
say unfortunately, but it was the right decision at the time, it just
makes things weird now in terms of naming).
As code evolved, we've mapped Blink's notion of the credentials flag
to the load flag LOAD_DO_NOT_SEND_COOKIES |
LOAD_DO_NOT_SEND_AUTH_DATA, and then we eventually ended up mapping
LOAD_DO_NOT_[SEND/SAVE]_COOKIES to PRIVACY_MODE_ENABLED (in the
UrlRequestHttpJob -
https://code.google.com/p/chromium/codesearch#chromium/src/net/url_request/url_request_http_job.cc&l=243
)
PRIVACY_MODE_ENABLED is what distinguishes the two socket pools, and
though it's named PRIVACY_MODE, it really maps into fetch's notion of
the "credentials flag"
I mention all of this because I've had to explain it repeatedly the
past few weeks as we've tried to work through all these issues, so
it's good to document the concepts somewhere, since the
rel="preconnect" case is the first time we're really going whole-hog
into exposing the separation of pools to the Web Platform, even though
it's spec'd (Fetch + credentials flag; which was spec'd in part
because of what we did), and because I'm always confused on what
'privacy mode' is meant to guarantee w/r/t privacy (it's weird and I
won't get into the original motivations, but suffice to say, it serves
a purpose now, so OK)
For conceptual mapping, whenever you see the Fetch spec talk about
"credentials flag", just substitute "privacy mode". Eventually, it may
make sense to rename privacy_mode to better express this concept, but
we're still working through all the implications (as you can see on
the CL).
The performance implications of this are probably pretty wide-ranging,
and a consequence of the distinction between "First party" and "Third
party" cookies as a privacy gate, "TLS client certs" being a form of
ambient authority (which CORS tries to prevent leaking), and the HTTP
NEGOTIATE auth method being connection oriented (violating the
HTTP/1.1 semantics). If none of these were true, we could use a common
socket pool and just rely on per-request semantics for distinguishing
ambient auth. But, alas, we cannot. So bring on MORE CONNECTIONS.
In case it's also not obvious, this also means two SPDY/QUIC/HTTP/2
connections as well (one for w/ credentials, one for w/o). Even though
they don't suffer the ambient auth problem (TLS client certs are
unicorns that don't work in practice with those methods, nor does the
HTTP Negotiate work - both use HTTP_1_1_REQUIRED, effectively),
because the first-party/third-party cookie split for privacy, we need
distinct connections.