W3C home > Mailing lists > Public > public-webapps@w3.org > January to March 2015

Re: CORS performance

From: Brian Smith <brian@briansmith.org>
Date: Thu, 19 Feb 2015 05:21:30 -0800
Message-ID: <CAFewVt5vg34QFR8+LYM65H2eu_KOXTBafBB25io9bLhNb3fgDA@mail.gmail.com>
To: Dale Harvey <dale@arandomurl.com>
Cc: Anne van Kesteren <annevk@annevk.nl>, WebAppSec WG <public-webappsec@w3.org>, WebApps WG <public-webapps@w3.org>, Monsur Hossain <monsur@gmail.com>, Jonas Sicking <jonas@sicking.cc>
On Thu, Feb 19, 2015 at 4:49 AM, Dale Harvey <dale@arandomurl.com> wrote:
>> so presumably it is OK to set the Content-Type to text/plain
>
> Thats not ok, but may explain my confusion, is Content-Type considered a
> Custom Header that will always trigger a preflight?

To be clear, my comment was about POST requests to the bulk document
API, not about other requests.

I ran your demo and observed the network traffic using Wireshark.
Indeed, OPTIONS requests are being sent for every GET. But, that is
because you are setting the Content-Type header field on your GET
requests. Since GET requests don't have a request body, you shouldn't
set the Content-Type header field on them. And, if you do, then
browsers will treat it as a custom header field. That is what forces
the preflight for those requests.

Compare the network traffic for these two scripts:

  <script>
    xhr=new XMLHttpRequest();
    xhr.open("GET",
"http://skimdb.iriscouch.com/registry/_changes?timeout=25000&style=all_docs&since=209&limit=100&_nonce=xhGtdb3XqOaYCWh4",
true);
    xhr.setRequestHeader("Accept","application/json");
    xhr.setRequestHeader("Content-Type","application/json");
    xhr.send();
  </script>

  <script>
    xhr=new XMLHttpRequest();
    xhr.open("GET",
"http://skimdb.iriscouch.com/registry/_changes?timeout=25000&style=all_docs&since=209&limit=100&_nonce=xhGtdb3XqOaYCWh4",
true);
    xhr.setRequestHeader("Accept","application/json");
    xhr.send();
  </script>

They are the same, except the second one doesn't set the Content-Type
header, and thus it doesn't cause the preflight to be sent.

> if so then none of the
> caching will apply, CouchDB requires sending the appropriate content-type

CouchDB may require sending "Accept: application/json", but that isn't
considered a custom header field, so it doesn't trigger preflight.

> The /_changes requests are only part of the problem, once we receive the
> changes information we then have to request information about individual
> documents which all have a unique id
>
>   GET /registry/mypackagename
>
> We do one of those per document (70,000 npm docs), all trigger a preflight
> (whether or not custom headers are involved)

I believe none of these require preflight unless a mistake is being
made (probably setting Content-Type on GET requests).

Also, regardless, you can use the CouchDB bulk document API to fetch
all these documents in one request, instead of 70,000 requests.

> Also performance details aside every week somebody has a library or proxy
> that sends some custom header or they just missed a step when configuring
> CORS, its a constant source of confusion for our users. We try to get around
> it by providing helper scripts but Anne's proposal mirroring flashes cross
> domain.xml sounds vastly superior to the current implementation from the
> developers perspective.

I agree that things can be improved here. I think the solution may be
better developer tools. In particular, devtools should tell you
exactly why a request triggered preflight.

Cheers,
Brian
Received on Thursday, 19 February 2015 13:22:02 UTC

This archive was generated by hypermail 2.3.1 : Friday, 27 October 2017 07:27:25 UTC