Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make PHP generate Chunked response

I googled for this problem but there is no answer for it.

I want my PHP script to generate HTTP response in chunked( http://en.wikipedia.org/wiki/Chunked_transfer_encoding). How to do it?

Update: I figured it out. I have to specify Transfer-encoding header and flush it.

header("Transfer-encoding: chunked"); flush();  

The flush is necessary. Otherwise, Content-Length header will be generated.

And, I have to make chunks by myself. With a helper function, it is not hard.

function dump_chunk($chunk) {     echo sprintf("%x\r\n", strlen($chunk));     echo $chunk;     echo "\r\n"; } 
like image 553
Morgan Cheng Avatar asked Mar 20 '10 03:03

Morgan Cheng


People also ask

How do I enable chunked transfer encoding?

To enable chunked transfer encoding, you need to set the value of AspEnableChunkedEncoding to "True" in the metabase of the site, server, or virtual directory for which chunked transfer encoding is enabled. By default this value is set to "True", you can try to change the value to "False" to disable it.

What is a chunked HTTP response?

Chunking is a technique that HTTP servers use to improve responsiveness. Chunking can help you avoid situations where the server needs to obtain dynamic content from an external source and delays sending the response to the client until receiving all of the content so the server can calculate a Content-Length header.

What means transfer encoding chunked?

Chunked transfer encoding is a streaming data transfer mechanism available in version 1.1 of the Hypertext Transfer Protocol (HTTP). In chunked transfer encoding, the data stream is divided into a series of non-overlapping "chunks". The chunks are sent out and received independently of one another.

How do you stop transfer encoding chunked?

Try adding "&headers=false" to your request. That should shorten it up and cause the response to be less likely to be chunked. Also, are you sending a HTTP/1.1 or HTTP/1.0 request? Try sending a HTTP/1.0 if your device cannot handle a HTTP/1.1 request.


2 Answers

A PHP response will always be chunked if you don't specify a content-length header, and a flush occurs. (which will happen automatically after x bytes, just don't know exactly how much).

This is a weird thing to care about. Is this some kind of academic/learning exercise or is there a real world problem you're trying to solve?

like image 50
Evert Avatar answered Sep 26 '22 05:09

Evert


This has gotten a little vauge... if you don't mind big assed chunks, (0x1000 octets or so), then yes, PHP will make them.

<?php  while (true) {     # output data     flush()     usleep(pow(2,18)); } ?> 

PHP will generated the numbered sections, etc.

If you want to send tiny little chunks, as you might do with an AJAX client... well, I've combined the OPs question, with some research on PHP.NET, and it does look like he was on to a good thing.

$ echo -en "GET /chunked/ HTTP/1.1\r\nHost: ec\r\n\r\n" | nc localhost 80

HTTP/1.1 200 OK Date: Wed, 23 May 2012 13:03:01 GMT Server: Apache/2.2.9 (Debian) PHP/5.3.5-1 with Suhosin-Patch mod_ssl/2.2.9 OpenSSL/0.9.8o X-Powered-By: PHP/5.3.5-1 Transfer-encoding: chunked Content-Type: text/html  14 Teachers have class. 50 We secure our friends not by accepting favors but by doing them.             -- Thucydides 48 Vulcans never bluff.             -- Spock, "The Doomsday Machine", stardate 4202.1 31 All kings is mostly rapscallions.             -- Mark Twain 41 Reappraisal, n.:     An abrupt change of mind after being found out. 49 He who knows, does not speak.  He who speaks, does not know.             -- Lao Tsu 

Whether or not it will eventually squeeze out it out's own (incorrect) chunk count, remains to be seen... but I saw no sign of it.

<?php header("Transfer-encoding: chunked"); @apache_setenv('no-gzip', 1); @ini_set('zlib.output_compression', 0); @ini_set('implicit_flush', 1); for ($i = 0; $i < ob_get_level(); $i++)  ob_end_flush(); ob_implicit_flush(1); flush();  function dump_chunk($chunk) {   printf("%x\r\n%s\r\n", strlen($chunk), $chunk);   flush(); }  for (;;) {   $output = array();   exec("/usr/games/fortune", $output);   dump_chunk(implode("\n", $output));   usleep(pow(2,18)); } ?> 
like image 43
Orwellophile Avatar answered Sep 26 '22 05:09

Orwellophile