Re: [cors] Redirects and preflights

On Thu, 05 Mar 2009 11:03:09 +0900, Jonas Sicking <jonas@sicking.cc> wrote:
> 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.

I guess I should say in XMLHttpRequest Level 2 that 303 affects "stored  
method".


> 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.

Network error steps.


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

Correct. All redirects on the actual request fail.


> 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.

Why would there be no redirect on the OPTIONS request?


> 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.

Currently the specification treats all redirects the same. I guess we  
could special case 303.


> 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.

We could treat a 303 on OPTIONS as an error.


> Or is the answer here that
> the site shouldn't use a 303 redirect but rather a 307?

That seems simplest, although it does not answer the UA question.


> 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?

No, that seems wrong.


> 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.

301 and 302 should do that too.


> 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.

I think this is already clear in the specification.


> 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.

That seems like a bug.


> 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).

This case seems so marginal that it does not seem worth the complexity to  
me. It only ever occurs in case of 303 where the preflight request is not  
redirected for whatever reason.


> * Measure the fact that there are upload event listeners only when the
> initial request is done.

This is already clear per the specification.


> * When making the OPTIONS preflight request, only change the
> destination uri of the actual request if the response is a 307.

Why not for 301 and 302?


-- 
Anne van Kesteren
<http://annevankesteren.nl/>
<http://www.opera.com/>

Received on Thursday, 5 March 2009 02:21:07 UTC