PEAR is discontinued

This is a static archive preserving historical releases and metadata. No new packages or updates will be published. For updates to existing packages, or to publish new packages, please use Composer and Packagist.

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