PEAR is archived and read-only

This mirror preserves historical PEAR package releases and metadata so existing references remain available.

Home » HTTP » HTTP_Request » Bug #3037

hang until socket close in an HTTP/1.1 request

Details

Submitted2004-12-27 15:52 UTC
Fromvdevaux at jetmultimedia dot fr
Assignedavb
StatusClosed
PackageHTTP_Request
PHP Version4.3.7
OSlinux
Roadmaps(Not assigned)

Comments

[2004-12-27 15:52 UTC] vdevaux at jetmultimedia dot fr

Description:
------------
in HTTP_Request version 1.2.3, in the function _readChunked;
the readAll function does not return until the socket is closed: so will the _readChuncked function too, instead of returning when a 0 length chunk part is found.

Reproduce code:
---------------
Instead of
if (0 == $this->_chunkLength) {
$this->_sock->readAll(); // make this an eof()
return '';
}

I propose
if (0 == $this->_chunkLength) {
$this->_sock->readLine();
return '';
}

It then will return as soon as possible without leaving characters to be read on the socket but without waiting for it to be closed.

[2005-01-07 15:24 UTC] vdevaux at jetmultimedia dot fr

ok, sorry for the delay i was in kind of a hurry here at work.
i check the whole package and see that i make in fact more modifications than i first thought:
here is the readChuncked function in its whole:
function _readChunked() {
if (0 == $this->_chunkLength) {
$line = $this->_sock->readLine();
if (preg_match('/^([0-9a-f]+)/i', $line, $matches)){
$this->_chunkLength = hexdec($matches[1]);
if (0 == $this->_chunkLength) {
$this->_sock->readLine();// readline instead of readAll
return '';
}
} else { // this else ...
return ''; // ... clause is new
}
}
$data = $this->_sock->read($this->_chunkLength);
$this->_chunkLength -= strlen($data);
if (0 == $this->_chunkLength) {
$this->_sock->readLine(); // Trailing CRLF
}
return $data;
}

And here is the HTTP_Response::process function with comments on the changed lines:
function process($saveBody = true) {
do {
$line = $this->_sock->readLine();
if (sscanf($line, 'HTTP/%s %s', $http_version, $returncode) != 2) {
return PEAR::raiseError('Malformed response.');
} else {
$this->_protocol = 'HTTP/' . $http_version;
$this->_code = intval($returncode);
}
while ('' !== ($header = $this->_sock->readLine())) {
$this->_processHeader($header);
}
} while (100 == $this->_code);

$this->_notify('gotHeaders', $this->_headers);
$chunked = isset($this->_headers['transfer-encoding']) && ('chunked' == $this->_headers['transfer-encoding']);
$gzipped = isset($this->_headers['content-encoding']) && ('gzip' == $this->_headers['content-encoding']);
$hasBody = false;
if((!isset($this->_headers['content-length'])) || ( 0 != $this->_headers['content-length'])) { // this is new
while (!$this->_sock->eof()) {
if ($chunked) {
$data = $this->_readChunked();
} else {
$data = $this->_sock->read(4096);
}
if ('' != $data) {
$hasBody = true;
if ($saveBody || $gzipped) {
$this->_body .= $data;
}
$this->_notify($gzipped? 'gzTick': 'tick', $data);
} else { // this break is new too
break;
}
}
}
if ($hasBody) {
// Uncompress the body if needed
if ($gzipped) {
$this->_body = gzinflate(substr($this->_body, 10));
$this->_notify('gotBody', $this->_body);
} else {
$this->_notify('gotBody');
}
}
return true;
}
I test it (i use it in production environment). It works well and correct a problem found on a server (this problem happens only on this server and is perhaps related to the presence of packet with obnly a 0 chunked length in it).

Apart from that, i would like to submit you a new feature for this package: could you set a private variable that contains the request string and a function to get it? I did it already like that: in the file Request.php
line 200: var $_request ='';
line 655:
function getRequest() {
return $this->_request;
}
line 800: $this->_request=$request;

Don't hesitate to contact me.

[2005-08-26 13:35 UTC] rouanelion at msn dot com

Hello,

I thing i have found a little problem of path in the Request.php librairie because the Request.php need three librairies:
require_once 'PEAR.php';
require_once 'Net/Socket.php';
require_once 'Net/URL.php';
and the problem is that the Socket.php need that too:
require_once 'PEAR.php';
but if you put PEAR.php into Net directory with the Socket.php, i have this problem
Fatal error: Cannot redeclare class pear in /var/www/free.fr/4/6/rouanelion/KelkooRssReaderWebApp_1-0-1/lib/Net/PEAR.php on line 103.
So i think there is an error of PATH.(maybe i was wrong)
Best regards
rouanelion