I would like to see if an external image is sending back the 304 not modfied header, is this able to be done on my server or will this violate the same origin policy?
The same origin policy can only make problems when using ajax. Images, javascripts etc. aren't affected by this policy, which only exists in browsers.
Simply send an curl request with the headers and then read the headers. See also: Can PHP cURL retrieve response headers AND body in a single request?
Related
I know this is a really simple question, but after searching a lot I can't find how to set headers.
Here's what I want to do:
Whenever the user goes to https://www.google.com/, then an extension should log that into a logfile. I currently am developing the extension on my own device, and using http://localhost/log.php to get POST requests and log information to files based on the information POSTed. My manifest is working and I have tested it. Below is my track.js:
function log(info){
var xhttp=new XMLHttpRequest();
xhttp.onreadystatechange=function(){
if(this.readyState===4&&this.status===200){
console.log(this.responseText);
}
}
xhttp.open("POST","http://localhost/log.php",true);
// xhttp.setRequestHeader("Access-Control-Allow-Origin","*");
// above: my first attempt to set a header (did not work)
xhttp.send("log_info="+info);
}
if(location.href==="https://www.google.com/")log("We're at google.com!");
This is my log.php:
<?php
header("Access-Control-Allow-Origin: *");
if(isset($_POST["log_item"]))
file_put_contents("log.txt", $_POST["log_item"]."\n",FILE_APPEND);
And log.txt is an empty file. I know CORS is the problem because when I open the console on https://www.google.com/, I see this:
Access to XMLHttpRequest at 'http://localhost/log.php' from origin 'https://www.google.com' has been blocked by CORS policy: Request header field access-control-allow-origin is not allowed by Access-Control-Allow-Headers in preflight response.
POST http://localhost/log.php net::ERR_FAILED
This seems really simple to me but I can't find how to set headers. Thanks for any help.
You should add "Access-Control-Allow-Origin: *" on your webserver configuration (Nginx or Apache or ...) that you are currently using on your localhost.
You can not bypass CORS from your code or your request at all.
For nginx (/etc/nginx/nginx.conf):
https://enable-cors.org/server_nginx.html
Apache:
https://enable-cors.org/server_apache.html
I'm working on a twilio project with PHP which will be playing back a frequently changing audio file.
Twilio's TwiML Voice documentation states to:
make sure your web server is sending the proper headers to inform us
that the contents of the file have changed
Which headers are these and how do I set them in PHP.
Which headers are these?
This is how caching works on Twilio
Twilio requests a .mp3 from your server using a GET request. Your
server sends back a 200 OK, and also sends back an E-Tag header.
Twilio will save the E-Tag header, as well as the mp3 file, in its
database.
The next time Twilio sends a GET request to that URL, it will send
along the E-Tag header (it should look like "If-None-Match"). If the
file has not changed since the last time Twilio accesses it, your
server will send back a 304 Not Modified header. Crucially, it will
not send the mp3 file data. Twilio will use the mp3 file it has
stored in its database. It's much faster for Twilio to read the mp3
file from its database than it is for your server to send it (and it
also saves your server bandwidth).
If you change the content of the mp3 that is being served at the URL,
and Twilio makes a GET request to the URL, then your server will send
back a 200 OK, with a new E-Tag. Twilio will download the file from
your server, and cache it.
How do I set them in PHP?
header("ETag: \"uniqueID\");
When sending a file, web server attaches ID of the file in header called ETag. When requesting file, browser checks if the file was already downloaded. If cached file is found, server sends the ID with the file request to server. Server checks if the IDs match and if they do, sends back header("HTTP/1.1 304 Not Modified"); else Server sends the file normally.
One easy way to check is by adding some fake key-value pairs to the end of the URL, like http://yoururl.com/play.mp3?key=somevalue. Your website should still serve the same mp3 as it would if you loaded example.com/test.mp3, but to Twilio it will appear to be a new URL (uncached).
Twilio uses Squid to cache MP3. You can control how long an item is cached using the cache control header.
cache-control: max-age=3600
http://wiki.squid-cache.org/SquidFaq/InnerWorkings#How_does_Squid_decide_when_to_refresh_a_cached_object.3F
I'm writing a script that will use cURL to check a number of links. I know I can use curl_getinfo() to get the http status code, but I'm not sure if that requests the entire page or just the response with the headers. Is there any curl option or setting I can use to only request the headers of the URL (i.e. 404 not found, moved, etc) ?
You can instruct cURL to not download the contents (body) of the request by setting the CURLOPT_NOBODY option to TRUE - see
Does CURLOPT_NOBODY still download the body - using bandwidth
p.s. curl_getinfo() does not make requests - it gets information from requests that have already been executed.
When I set a custom header in Apache + mod_php5, this works fine:
header('Foo: Bar');
But when I try this while also sending a 304 Not Modified response, the header appears to be removed by apache (along with X-Powered-By and other standard headers).
header('HTTP/1.1 304 No Content');
header('Foo: Bar');
Does anyone know how to solve this issue?
Does this not answer the question?
If the conditional GET used a strong cache validator (see section 13.3.3), the response SHOULD NOT include other entity-headers. Otherwise (i.e., the conditional GET used a weak validator), the response MUST NOT include other entity-headers; this prevents inconsistencies between cached entity-bodies and updated headers.
from http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.5
As of Apache 2.4.23 (the latest release as of today, as far as I know), you're not going to be able to get around that problem when you send a 304 "Not Modified" response because, indeed, Apache does explicitly remove all non-whitelisted headers:
http://svn.apache.org/viewvc/httpd/httpd/tags/2.4.23/modules/http/http_filters.c?view=markup#l1331
So, whether we like it or not (because I'm on the same boat of having my CORS headers removed by Apache from the response when I send a 304), it does seem like Apache is following the RFC recommendation and it's indeed treating everything that falls outside of that list as entity headers.
One solution is to patch-up the Apache source to extend that list and turn to deploying your home-grown package to your server(s), but that's definitely not without a long list of implications of its own. On the flip side, I hear that nginx doesn't suffer from this problem.
The content that I'm delivering will be consumed, among others, by WebGL runtimes in standard browsers, so if they do complain about the lack of CORS in my 304 responses I'm going to have to turn everything to 200 OK and forego the bandwidth savings.
I do a trick to solve this issue by :
1. put all header before 304 header
2. flush these header before send 304
header('Foo: Bar');
flush();
header('HTTP/1.1 304 No Content');
Apache will not remove any header until it found 304.
We force other header send out by flush() before send 304.
That apache can not hurt me.
Try:
header('Foo: bar', true, 304);
I'm not sure if this function in CURL just strips the response body out but still load it fully.
Is that true? I don't want to waste bandwidth, I just want the headers.
CURLOPT_NOBODY will send a HEAD request to web server. The server should respond with just the HTTP headers and no body content.
http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
The HEAD method is identical to GET except that the server MUST NOT return a message-body in the response.
It will only load the headers, it won't load the body of the requested document.
As you can see in official doc, It will not download the body if you enable it
https://curl.haxx.se/libcurl/c/CURLOPT_NOBODY.html
DESCRIPTION A long parameter set to 1 tells libcurl to not include the
body-part in the output when doing what would otherwise be a download.
For HTTP(S), this makes libcurl do a HEAD request. For most other
protocols it means just not asking to transfer the body data.
Enabling this option means asking for a download but without a body.