[cors] Redirects and preflights

Hi WebApps fans! (woot)

So a few issues I've run into playing around with redirects and
preflighted requests. Below are some scenarios, questions and proposed
answers.

First of all, what should happen in the following case:

1. A page on site A makes a DELETE request to a uri on site A (no
preflight requested since it's same-site)
2. The server responds with a 303 and points to a uri on site B.

since this is a 303 redirect, that means that the request to site B is
a GET request. Does this mean that no preflight is needed in the
request to site B?

I think the redirect should be followed and no preflight be made.


What about the following scenario:
1. A page on site A initiates a DELETE request to a uri on site B
2. The UA makes a preflight OPTIONS request to the uri on site B
3. The site responds and says the original DELETE request is ok
4. The UA makes the DELETE request to site B
5. The site responds with a 303 that redirects to a different uri on site B.

Should this redirect not be followed even though it technically does
not require a preflight?

I think it's fairly important that we do follow the redirect since a
common way to deal with state changing requests is to redirect to a
URI that contains the response. This avoids ugly "you have to refresh
to display this page" pages in browsers. So I think the redirect
should be followed.


What should be done in the following scenario:
1. A page on site A initiates a DELETE request to a uri on site B
2. The UA makes a preflight OPTIONS request to the uri on site B
3. The site responds with a 303 to a different uri on site B.

Does this mean that the UA should make a GET request to the new URI on
site B? I believe the HTTP spec says the UA should, however it seems
somewhat strange to me to not use OPTIONS. Or is the answer here that
the site shouldn't use a 303 redirect but rather a 307? Should perhaps
a 303 redirect mean that the DELETE request should be made to the
initial uri on site B, assuming that the preflight after redirects
ended up returning a response with the appropriate headers?

I don't have strong opinions on this one. But a gut feeling is that
only a 307 should cause the DELETE to go somewhere else as that is the
only time when that would have happened if the DELETE would have been
done directly to the first uri on site B.

And here's another:
1. A page on site A initiates a POST request to a uri on site B. The request is
   a entity body and a Content-Type of "text/plain"
2. Since no preflight is needed The UA makes the request to the uri on site B
3. Before the server has responded, the page adds a event listener for the
   progress event on the upload object. (This listener won't be
notified according
   to spec)
4. The server responds with a 307 redirect to another URI on site B.

Should the request to the new URI on site be now be done with a
preflight? Or should the algorithm abort because a preflight is now
required but there is a redirect. Or should the redirect be followed
but the event listener not be notified? In other words, should the
fact that there is upload event listeners be measured on just the
initial request, or on each redirect.

I think the fact that there is upload event listeners should be
measured just on the initial request. So in the example above the
redirect should be followed but no events would be fired on the upload
object.


The following scenario might be gecko-specific:
1. A page on site A initiates a POST request to a uri on site B. The request is
   not given a body, but is given a Content-Type of "text/plain"
2. Since no preflight is needed The UA makes the request to the uri on site B
3. The server responds with a 307 redirect to another URI on site B.

In this case Gecko creates a new request that doesn't have a
Content-Type header since there is no body. I suspect this is Gecko
specific behavior though and so nothing that needs to be addressed
specifically. Would be interesting to hear if other browsers have the
same behavior though.


So to sum things up. I suggest the following behavior:
* When the actual request (i.e. not a preflight request) is done, only
abort with a network error if the newly created request would require
a preflight. So don't abort in the case when the redirect changes the
request from one that requires a preflight into one that doesn't.
(This means that in the gecko-specific case above, abort with a
network error since the newly createde request does require
preflight).
* Measure the fact that there are upload event listeners only when the
initial request is done.
* When making the OPTIONS preflight request, only change the
destination uri of the actual request if the response is a 307.

/ Jonas

Received on Thursday, 5 March 2009 02:03:45 UTC