| Server IP : 14.225.204.176 / Your IP : 216.73.216.6 Web Server : nginx/1.24.0 System : Linux nodejs-ybgk 6.8.0-40-generic #40-Ubuntu SMP PREEMPT_DYNAMIC Fri Jul 5 10:34:03 UTC 2024 x86_64 User : root ( 0) PHP Version : 8.1.34 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : OFF Directory : /var/www/html/php/thanhphuong/vendor/php-http/socket-client/src/ |
Upload File : |
<?php
namespace Http\Client\Socket;
use Http\Client\Socket\Exception\StreamException;
use Http\Client\Socket\Exception\TimeoutException;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\StreamInterface;
/**
* Stream implementation for Socket Client.
*
* This implementation is used to have a Stream which react better to the Socket Client behavior.
*
* The main advantage is you can get the response of a request even if it's not finish, the response is available
* as soon as all headers are received, this stream will have the remaining socket used for the request / response
* call.
*
* It is only readable once, if you want to read the content multiple times, you can store contents of this
* stream into a variable or encapsulate it in a buffered stream.
*
* Writing and seeking is disable to avoid weird behaviors.
*
* @author Joel Wurtz <joel.wurtz@gmail.com>
*/
class Stream implements StreamInterface
{
/** @var resource Underlying socket */
private $socket;
/**
* @var bool Is stream detached
*/
private $isDetached = false;
/**
* @var int|null Size of the stream, so we know what we must read, null if not available (i.e. a chunked stream)
*/
private $size;
/**
* @var int Size of the stream readed, to avoid reading more than available and have the user blocked
*/
private $readed = 0;
/**
* @var RequestInterface request associated to this stream
*/
private $request;
/**
* Create the stream.
*
* @param resource $socket
*/
public function __construct(RequestInterface $request, $socket, ?int $size = null)
{
$this->socket = $socket;
$this->size = $size;
$this->request = $request;
}
/**
* {@inheritdoc}
*/
public function __toString()
{
try {
return $this->getContents();
} catch (\Exception $e) {
return '';
}
}
/**
* {@inheritdoc}
*/
public function close()
{
fclose($this->socket);
}
/**
* {@inheritdoc}
*/
public function detach()
{
$this->isDetached = true;
$socket = $this->socket;
$this->socket = null;
return $socket;
}
/**
* {@inheritdoc}
*/
public function getSize()
{
return $this->size;
}
/**
* {@inheritdoc}
*/
public function tell()
{
return ftell($this->socket);
}
/**
* {@inheritdoc}
*/
public function eof()
{
return feof($this->socket);
}
/**
* {@inheritdoc}
*/
public function isSeekable()
{
return false;
}
/**
* {@inheritdoc}
*/
public function seek($offset, $whence = SEEK_SET)
{
throw new StreamException('This stream is not seekable');
}
/**
* {@inheritdoc}
*/
public function rewind()
{
throw new StreamException('This stream is not seekable');
}
/**
* {@inheritdoc}
*/
public function isWritable()
{
return false;
}
/**
* {@inheritdoc}
*/
public function write($string)
{
throw new StreamException('This stream is not writable');
}
/**
* {@inheritdoc}
*/
public function isReadable()
{
return true;
}
/**
* {@inheritdoc}
*/
public function read($length)
{
if (null === $this->getSize()) {
return fread($this->socket, $length);
}
if ($this->getSize() === $this->readed) {
return '';
}
// Even if we request a length a non blocking stream can return less data than asked
$read = fread($this->socket, $length);
if ($this->getMetadata('timed_out')) {
throw new TimeoutException('Stream timed out while reading data', $this->request);
}
$this->readed += strlen($read);
return $read;
}
/**
* {@inheritdoc}
*/
public function getContents()
{
if (null === $this->getSize()) {
return stream_get_contents($this->socket);
}
$contents = '';
do {
$contents .= $this->read($this->getSize() - $this->readed);
} while ($this->readed < $this->getSize());
return $contents;
}
/**
* {@inheritdoc}
*/
public function getMetadata($key = null)
{
$meta = stream_get_meta_data($this->socket);
if (null === $key) {
return $meta;
}
return $meta[$key];
}
}