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
Related
I have a client application that sends the data to a php file (hosted on Apache). Usually this works without any problem. On a client site I get 206 partial content every time the client app sends data.
The data size is 10 - 30 kB so it is not huge.
If you have any suggestion - like changing Apache settings .. or something similar I would appreciate it.
Thanks.
Its not an issue. Any 2xx code means "Success". You can view details # Why does Firebug show a "206 Partial Content" response on a video loading request?
I am having an hybrib application in that in that a simple php page will open which contents some link of files, and from my android wrapper i have implemented the download functionality of file.
So for user convenience i am showing the length and progress of download while the file is downloading for that my application server has set a content-length header to pass the size on device, but the problem I am facing is surprising.
The file length is working fine in Android 2.2. I am getting the content header correctlt but in Android 2.3 above I am getting the content length for smaller files but for the larger file I am not even getting the Header Field.
con.getHeaderField("content-length");
returning me null in case of Android 2.3 above.
So is there any limitation of size for the User Agent above 2.3 because if it is working fine in 2.2 means there is no problem at server end it is the problem only on device user agent.
Update
I have tried it with different size of files and it is working fine till 60KB in Android 2.3 above as well.
It sounds like the client may be chunking the file. Check for the presence of the following header:
Transfer-Encoding: chunked
If that exists, the request is chunked and you will not get a Content-Length header.
See http://en.wikipedia.org/wiki/Chunked_transfer_encoding for more details.
I think my question seems pretty casual but bear with me as it gets interesting (at least for me :)).
Consider a PHP page that its purpose is to read a requested file from filesystem and echo it as the response. Now the question is how to enable cache for this page? The thing to point out is that the files can be pretty huge and enabling the cache is to save the client from downloading the same content again and again.
The ideal strategy would be using the "If-None-Match" request header and "ETag" response header in order to implement a reverse proxy cache system. Even though I know this far, I'm not sure if this is possible or what should I return as response in order to implement this technique!
Serving huge or many auxiliary files with PHP is not exactly what it's made for.
Instead, look at X-accel for nginx, X-Sendfile for Lighttpd or mod_xsendfile for Apache.
The initial request gets handled by PHP, but once the download file has been determined it sets a few headers to indicate that the server should handle the file sending, after which the PHP process is freed up to serve something else.
You can then use the web server to configure the caching for you.
Static generated content
If your content is generated from PHP and particularly expensive to create, you could write the output to a local file and apply the above method again.
If you can't write to a local file or don't want to, you can use HTTP response headers to control caching:
Expires: <absolute date in the future>
Cache-Control: public, max-age=<relative time in seconds since request>
This will cause clients to cache the page contents until it expires or when a user forces a page reload (e.g. press F5).
Dynamic generated content
For dynamic content you want the browser to ping you every time, but only send the page contents if there's something new. You can accomplish this by setting a few other response headers:
ETag: <hash of the contents>
Last-Modified: <absolute date of last contents change>
When the browser pings your script again, they will add the following request headers respectively:
If-None-Match: <hash of the contents that you sent last time>
If-Modified-Since: <absolute date of last contents change>
The ETag is mostly used to reduce network traffic as in some cases, to know the contents hash, you first have to calculate it.
The Last-Modified is the easiest to apply if you have local file caches (files have a modification date). A simple condition makes it work:
if (!file_exists('cache.txt') ||
filemtime('cache.txt') > strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
// update cache file and send back contents as usual (+ cache headers)
} else {
header('HTTP/1.0 304 Not modified');
}
If you can't do file caches, you can still use ETag to determine whether the contents have changed meanwhile.
I know that there are php functions that allow a user to download or you to download file using PHP BUT I have not seen a single one that allows your php file to navigate and download a file and store it in a specific directory..
So here is what I want to do. I have a web host which runs php applications. Then I have a website with a calendar. The calendar has options on the side...
Tools--->export as doc
I want to write a PHP code that EVERYDAY automatically goes to calendar's Tool options, then downloads the calendar called Team Calendar into the webhost where the script can use it.
For experimental purposes lets assume the calendar URL is at http://webdesign.about.com/od/php/ht
How do I go about this?
Thanks a bunch
EDIT: I TRIED WGET THIS IS WHAT I GOT, HOW CAN I MAKE IT DOWNLOAD THE FILE IN DOC FROM TOOLS?
[/cygdrive/c/documents and settings/omar.khawaja]$ wget http://confluence.com/display/prodsupport/Team+Calendar
--2011-06-02 16:33:43-- http://confluence.rogersdigitalmedia.com/display/prodsupport/Team+Calendar
Resolving confluence.com... 204.225.248.160
Connecting to confluence.com|204.225.248.160|:80... connected.
HTTP request sent, awaiting response... 302 Moved Temporarily
Location: http://confluence.com/login.action;jsessionid=2F13926CF763FE4F3862FAFC24AB81D7?os_destinati
on=%2Fdisplay%2Fprodsupport%2FTeam%2BCalendar [following]
--2011-06-02 16:33:43-- http://confluence.com/login.action;jsessionid=2F13926CF763FE4F3862FAFC24AB81
D7?os_destination=%2Fdisplay%2Fprodsupport%2FTeam%2BCalendar
Connecting to confluence.com|204.225.248.160|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 7865 (7.7K) [text/html]
Saving to: `login.action;jsessionid=2F13926CF763FE4F3862FAFC24AB81D7#os_destination=%2Fdisplay%2Fprodsupport%2FTeam+Cale
ndar'
100%[==============================================================================>] 7,865 --.-K/s in 0.04s
2011-06-02 16:33:43 (207 KB/s) - `login.action;jsessionid=2F13926CF763FE4F3862FAFC24AB81D7#os_destination=%2Fdisplay%2Fp
rodsupport%2FTeam+Calendar' saved [7865/7865]
You need to use a cron job on the server to do this. Have that cron job call a PHP script that simply saves the doc to a directory on the web server.
In a PHP shutdown function, I want to know the size of the HTTP response that's been received by the client.
I'd like to register a shutdown function and verify the size of the HTTP response received by the client with the size of the file which was read. This would let me flag cases where the response was incomplete.
Background: We're seeing reports of damaged (incomplete) file downloads using Ubercart uc_file.
http://api.ubercart.org/api/function/_uc_file_download_transfer/2 is the function serving the file. It already checks that the complete file has been read before logging the download, but it doesn't check if the client was still connected when the file is fully served.
I don't know how to obtain the size of generated content, but the reason why your clients are experiencing incomplete downloads could be that you don't specify the correct Content-Length header before sending the file. Standards-compliant browsers will not save the file if it's size turns out to be less than the Content-Length declared in HTTP response.