HTTP response with redirect, but without roundtrip? - http

I want the browser to reflect some other URL than the one used to create the request, but without roundtripping to the server.
I would maybe do this:
POST /form HTTP/1.1
...
...and then return:
HTTP/1.1 200 OK
Location: /hello
But that would cause a redirect, the browser will again, request URL /hello.
I would like to just tell the browser that, while the request you just sent was POST /some_url the actuall resource that I'm now returning is actually called GET /hello/1 but without preforming a roundtrip. i.e. Location: ...
Is there any way to do this with JavaScript or the base="" attribute? That will tell the browser to request /hello/1 when I hit F5 (refresh) instead of that, post submission warning?

HTTP/1.1 200 OK
Location: /hello
Actually that probably wouldn't work; it should be a 30x status rather than 200 (“303 See Other” is best for the response to a POST), and ‘Location’ should be a complete absolute URL.
(If your script just says ‘Location: /relativeurl’ without the 30x status, CGI servers will usually do an internal redirect by fetching the new URL and returning it without telling the browser anything funny happened. This may sound like what you want but it isn't really because from the browser's point of view it's no different from the original script returning a 200 and direct page.)
But that would cause a redirect, the browser will again, request URL /hello.
In practice that's probably not as bad as you think, thanks to HTTP/1.1 keep-alives. The client should be able to respond to the redirect straight away (in the next packet) as long as it's on the same server.
Is there any way [...] That will tell the browser to request /hello/1 when I hit F5 (refresh) instead of that, post submission warning?
Nope. Stick with the POST-Redirect-GET model for solving this.

No. Http is stateless, and every request has one answer. When you post, you need to redirect to a get page immediately to prevent a double post - you don't want it to sit on that post url. The redirect is what tells the browser that it is on a new page. That's just the way it works.

Related

How to find URL that a page redirects to

In my code, I have a URL to a page that redirects to another, whose URL I need. It doesn't seem to be contained within the page or headers. I'm new to Lua and StackOverflow and I don't know all the ins and outs of it, so sorry if this is a stupid question.
Read much more about the HTTP protocol (and HTTP header fields and HTTP status code, notably 301 Moved Permanently), and about HTML (e.g. <meta refresh)
Redirections can be done in both. You'll use some HTTP client library such as libcurl (see its lua curl binding) and you need to parse the entire HTTP response.

Why is the redirect url is of longer length?

I have been reading on SAML 2 binding mechanism. It says below :
HTTP REDIRECT VS. POST BINDINGS: Both SPs and IDPs can transmit and receive messages using redirect or POST bindings. Due to the limitation of URL lengths in certain scenarios, HTTP Redirect is usually used when passing short messages, and HTTP POST is used when passing longer messages.
I am unable to understand how a response with the same length can be longer in redirect than it is in post. I think I am missing something very basic. Could anyone help to clear that ?
Redirects utilize the querystring to pass data, which has a size limitation that is not present in a post.
From w3schools:
Example Get:
/test/demo_form.asp?name1=value1&name2=value2
Example Post:
POST /test/demo_form.asp HTTP/1.1
Host: w3schools.com
name1=value1&name2=value2
the parameters for a get are located within the URL itself, which has a size limitation of 2083 characters (there is some variation to this number). For a post, the information to go along with the post is in the actual body of the message, rather than the URL.
Basically you get more "room" in a post, as you're not going to hit a size restriction on URL because your information is in the body - unless your URL is already that long which would mean it'd be an issue for gets or posts.
Why is the redirect url is of longer length?
I think you might be misunderstanding, it's saying you get less room for a redirect than a post, not more/longer. Gets have a size restrictions, posts do not, or at least it's a configurable setting on the server and has a larger "higher end" than a get request would.

What is the correct behavior expected of an HTTP POST => 302 redirect to GET?

What is the correct behavior expected of a POST => 302 redirect to GET?
In chrome (and likely most every browser), after I POST (to a resource that wants me to redirect) and I receive a 302 redirect, the browser automatically issues a GET on the 302 location. This is even a well known pattern. But the way I read the spec, it seems to suggest this should not happen.
The HTTP spec says
If the 302 status code is received in response to a request other than
GET or HEAD, the user agent MUST NOT automatically redirect the
request unless it can be confirmed by the user, since this might
change the conditions under which the request was issued.
And fiddler is showing:
REQUEST 1: POST URLA
RESPONSE 1: 302 redirect to URLB
REQUEST 2: GET URLB
The section above seems to say that the browser should not make the GET request? What am I missing?
Something earlier in the spec that makes this section irrelevant
My understanding of automatically redirect is wrong (and the chrome browser that did the GET wasn't really automatically redirecting)
My understanding of confirmed this as a user
Something else?
The very next line in the spec begins:
Note: RFC 1945 and RFC 2068 specify that the client is not allowed
to change the method on the redirected request. However, most
existing user agent implementations treat 302 as if it were a 303
response, performing a GET on the Location field-value regardless
of the original request method. The status codes 303 and 307 have
been added for servers that wish to make unambiguously clear which
kind of reaction is expected of the client.
And immediately after that, it explains how a 303 should be handled, and it's exactly what you're seeing.
If you're asking why servers are still using 302 instead of 307, which all current browsers will handle correctly, it's because old browsers won't handle it. If you're wondering why browsers handle 302 as 303, it's because old servers expect it. There's really no way out of that loop, and it would probably be better for HTTP to just revert 302 to mean what it used to mean, and deprecate it (for non-GET/HEAD) in favor of 307.
abarnert was right ! I had the same issue with Google App Engine but I found a different solution.
My issue with appengine was,I did a POST with a form to a GO formHandler at backend. But it was executed as follow.
request 1: GET /formHandler -> response 1: 302 Found
request 1: POST /formHandler -> response 1: 302 Found
request 1: GET /formHandler -> response 1: 200 Ok.
Additionaly I got
No 'Access-Control-Allow-Origin' header is present on the requested resource
Which was a CORS problem.
However the solutions turns out to be to use HTTPS instead of HTTP.
Then you will have
request : POST /formHandler -> response : 200 Ok
You may want to read http://greenbytes.de/tech/webdav/draft-ietf-httpbis-p2-semantics-22.html#rfc.section.6.4.p.3, which tries to clarify the situation.
Note: In HTTP/1.0, the status codes 301 (Moved Permanently) and 302 (Found) were defined for the first type of redirect ([RFC1945], Section 9.3). Early user agents split on whether the method applied to the redirect target would be the same as the original request or would be rewritten as GET. Although HTTP originally defined the former semantics for 301 and 302 (to match its original implementation at CERN), and defined 303 (See Other) to match the latter semantics, prevailing practice gradually converged on the latter semantics for 301 and 302 as well. The first revision of HTTP/1.1 added 307 (Temporary Redirect) to indicate the former semantics without being impacted by divergent practice. Over 10 years later, most user agents still do method rewriting for 301 and 302; therefore, this specification makes that behavior conformant when the original request is POST.

What's the difference between a "GET" request and a "page refresh"?

Is there any difference between doing a "GET" request (type URL and Enter) compared to simply refreshing (CtrlR) the page?
No, it is not simply a get request, because on a page that you've POSTed to (from a separate form), the browser will confirm with you that you want to refresh the page because it is a POST request.
As for your question, you'll need to provide specifics for debugging purposes.
It is simply telling the browser to repeat the page load, which implies repeating the GET or POST request. Some browsers will inform the server that 304 (not-modified) is an acceptable response, and the server can reply with a 304 HTTP response to inform the browser that it's cached contents are valid
Most browsers ignore the Expires header if we do a "page refresh", yet respect it if we do a "url visit".
However, different browsers have their own way of differentiating "refresh" and "url visit", the only way to be sure is to manually test each one of them.

Sending info with a HTTP redirect that the browser should send to the redirected location?

Is this possible.. for example, imagine I respond to a request with a 302 (or 303), and I inform the browser to do a request to a given location.. is there a header that I can send with the HTTP 302, so that the subsequent request from the browser would include that header?
I know I could do this with the location header, as in redirect and specify the information in the url as a query string.. but I'm wondering if there is a better way.. it seems that it should be a legit scenario..
'Content has moved, go here .. oh and you'll want to take this with you to give to the redirect location'
I'm guessing a big fat no!
Thanks in advance.
Edit
The reason for this is in respect to PRG patterns, where you have a GET url and POST url, given that you post data and it isn't acceptable, the server redirects you to the GET, and does some 'magic' in order to 'send data' to that GET, using most often session state to store a variable.
However this can breakdown in scenarios where many of these PRG requests are happening, granted this isn't a common scenario and generally nobody need worry about this.. but if you do- you'll need a way to identify the requests, this can be done with query string parameters send in the 302.. so that a specific entry can be put in session state according to that request.
The question was regarding trying to remove the 'request key' from the url, and making it more implicit.. cookies 'appear' to work, but they only make the window for screw ups smaller.
It would be great to say when you go the 'location' i've specified, send these parameters.
Edit
Just to note, I'm not trying to get the browser to send arbitrary headers to the location, but if there is ANY headers designed to hint the context of the request (like the querystring parameters could).
A redirect response itself doesn't contain any data. You can redirect using a URL with query parameters, but the new "location" will need to know how to consume those parameters.
No, that’s not possible. You cannot force the client to something. You just can say “this is not the right location, but try that location instead”. But it’s not guaranteed that the client will send the same request or another request to that new location. And telling the client to add a specific header field in that subsequent request to the new location is also not possible.

Resources