Laravel redirect with no cache header - php

I'm using Laravel 3 and it's not obvious how to set headers in any way other than through Response::make().
I am doing a redirect like this:
return Redirect::to('admin/check');
I'd like to set an additional no-cache header for the redirect like so:
"Cache-Control: no-store, no-cache, must-revalidate"
I realize I could just do this directly in PHP, but is there any way to set response headers via Laravel?

When you call Redirect::to() Laravel instantiates a Response object with 302 status and a Location header. That Response object is then returned by the controller and rendered as a proper HTTP response, so, at controller time, you can still change its headers.
To be even more precise class Redirect extends Response. Take a look here
You can achieve that by simply using:
return Redirect::to('admin/check')
->header('Cache-Control', 'no-store, no-cache, must-revalidate');

I'm afraid, the accepted answer is wrong and misleading!
It's impossible to redirect to a page with custom headers set, no matter what language or framework you use. In other words, there's no way to trigger an HTTP redirect and cause the client (browser) to add a custom header.
You might be thinking that this code should work just fine:
return Redirect::to('admin/check')
->header('Cache-Control', 'no-store, no-cache, must-revalidate');
But it won't. You're setting the custom headers for the response which is instructing the browser to redirect, not for the redirect itself.
The only way for a site to instruct a browser to issue an HTTP request with a custom header is to use Javascript and the XMLHttpRequest object. And it needs CORS implemented on the target server to allow such ajax requests.
Please note that a page can not set HTTP request headers unless it's making an async request using XMLHttpRequest. Meaning that you can't do such redirection with the custom header on the client-side as well.
That's not how the web works.

Related

Angular $http executed twice when using headers

I'm developing an ionic project and I'm using header parameters in each POST and GET Request. How ever When I test the project on Android Phone and monitor all requests that come into my server through my android device there are no issues. But when I deploying my ionic project and testing it in my web browser ( Chrome Web Browser ) I see that each request has been executed twice,( one without headers params and without inputs when I use POST method, and the second one is with all params ).
I've solved it in my server if there are no header parameters to ignore the request each time. How can I prevent the duplicated execution for the $http (POST and GET)?
These parameters I've set in the angular.config js file.
$httpProvider.defaults.headers.common['Accept'] = 'application/json; q=0.01';
$httpProvider.defaults.headers.common['Authorization-Token'] = value;
and my PHP service starts with
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: Content-Type, Authorization-Token");
header('Access-Control-Max-Age: 60');
header('Access-Control-Allow-Methods: ["GET","POST"]');
header("Content-Type: application/json; charset=UTF-8");
Sounds like an OPTION call indeed.
It should be done, and not carry any payload, it is just to check with the server what actions are allowed on the resource before performing the actual call (post/get/whatever).
Check the answer to this similar question : Angular 2 HTTP POST does an OPTIONS call
The first request is the preflight.
This is part of the browser mechanism.
You cannot avoid it.
It all comes down to how browsers manage CORS. When making a cross-domain request in JavaScript that is not "simple" (i.e. a GET request), the browser will automatically make a HTTP OPTIONS request to the specified URL/URI, called a "pre-flight" request or "promise". As long as the remote source returns a HTTP status code of 200 and relevant details about what it will accept in the response headers, then the browser will go ahead with the original JavaScript call
Please look here and here

Can I add a custom header to simplexml_load_file

I'd like to download a remote page only when it differs from a version I have already. There's no "Last-Modified" or "Expires" (the server sends Cache-Control: max-age=0, private, must-revalidate) but there's the ETag: field.
So, I can send If-None-Match: header with last ETag value and on any error (including 304 Not Modified) retry after a delay.
Currently I'm using simplexml_load_file to grab the URL, and I wonder if I can just call it in some way adding the extra header, or do I need to roll out more heavyweight solutions (curl, file_get_contents etc)?
You can use cURL with adding custom header, then use simplexml_load_string (with return content from cURL request) to get SimpleXMLElementobject.
curl_setopt($ch, CURLOPT_HTTPHEADER, array('If-None-Match:: XXX'));

PHP cookie handling

A centain web client that I need to support, is sending back the Cookies header to my application twice in the HTTP headers, this in turn is making PHP unable to read the correct value for the cookie thus ignoring the session.
Here is the relevant part of the request I am seeing:
GET / HTTP/1.1
Cache-Control: max-age=0
Accept-Language: en-US
Cookie: PHPSESSID=49af82ddf12740e6a35b15985e93d91a
Connection: Keep-Alive
Cookie: PHPSESSID=49af82ddf12740e6a35b15985e93d91a
[...] Other irrelevant headers
I have two questions:
Is that a PHP bug? or is the behavior undefined when the client sends that same header twice?
Is there a quick workaround to make things work without having to manually parse the HTTP headers so I can read the right value of the cookie (and session) in my application? Or should I manually parse the HTTP header to set the session to its correct value?
According to the HTTP spec, a double header simply concatenates the values together with a comma, making it:
Cookie: PHPSESSID=49af82ddf12740e6a35b15985e93d91a, PHPSESSID=49af82ddf12740e6a35b15985e93d91a
PHP should be able to parse the cookies, but the behavior of sessions is undefined when there are two session IDs.
I strongly recommend fixing the client. If that's not an option, you'll have to parse the headers manually.

How do you set a cookie from within an ESI:include script?

I have a basic PHP page being loaded through Varnish with a single ESI include that calls back to the server to set a cookie. The cookie is set with domain access and the like, but when called through ESI the cookie is never set. If you access the ESI include path directly, the cookie is set with no issue. I have even set my Varnish configuration to never cache anything, thinking the VCL could be killing the cookie.
This...
<esi:include src="/init.php?<?=http_build_query($_GET); ?>"></esi:include>
...includes this...
<?php
header("Cache-Control: no-cache, must-revalidate");
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");
setcookie('superman', 'clark kent', 0, '/', '.whatever.com');
?>
I'm new with Varnish and ESI, so I'm starting to wonder if this is a known limitation (either with ESI or with Varnish's ESI implementation), but I can't find any discussion of my problem online.
An interesting question which has been asked -but not answered- before ( Setting Cookies via ESI:include, how? ). I don't think you can do it this way. With ESI-include, the ESI processor makes a separate request and replaces a part from the body, not the header. In order to make your preferred set-cookie behavior work correctly, the ESI specification should specify how to 'merge' all set-cookie headers.
See chapter six of the ESI spec: http://www.w3.org/TR/esi-lang
When an ESI template is processed, a
separate request will need to be made
for each include encountered.
Implementations may use the original
request's headers (e.g., Cookie,
User-Agent, etc.) when doing so.
Additionally, response headers from
fragments (e.g., Set-Cookie, Server,
Cache-Control, Last-Modified) may be
ignored, and should not influence the
assembled page.
Could you try to convert your set-cookie header in a javascript set-cookie script? This could be included in the body...

Send HTTP headers before or after a cookie header?

I was wondering if there are any problems or difference between sending normal headers before or after sending cookie headers. Do some browsers prefer a certain order to headers? If the cookie header is to large would subsequent headers never be parsed?
setcookie("TestCookie", $value);
header("Content-type: text/javascript");
or
header('Location: http://www.example.com/');
setcookie("TestCookie", $value);
or
setcookie("SuperLargeCookie", $massive_value);
setcookie("TinyCookie", $small_value);
header("Status: 404 Not Found");
There is no difference. The Http protocol does not specify that headers are to be in a certain order. Browsers do not differentiate based on the order of headers either.
The total length of Http headers does have a limit. This limit is imposed by the server and not the browser. Typically between 8K and 16K. However this is configurable.
It really doesn't matter as long as the other HTTP headers have not been sent. setcookie() actually writes a header itself:
Set-Cookie: SuperLargeCookie=whatever; Max-Age=3600; Version=1
similar to a header() call:
Location: http://www.example.com/redirect
HTTP messages span packets all the time, so you'd be hard-pressed to overfill one unless you're jamming tons of kilobytes in there. If you need to do that, consider a better design. Browsers don't care about the order of headers since different servers (and applications) append headers all the time. Cookies are implemented as HTTP headers, so they should appear like so in the HTTP request:
Cookie: TestCookie=value\r\n
Content-type: text/javascript\r\n
\r\n
I'm not sure what the Status header is supposed to do in your example, but I don't think it's right since the webserver will set a 200 OK response code if the code executes correctly... The header function page has this examaple:
<?php
header("HTTP/1.0 404 Not Found");
?>
With the PHP header function, just make sure you're not writing any text out before issuing it. Otherwise, you could mess everything up.

Categories