Initial commit
This commit is contained in:
117
src/Http2.php
Normal file
117
src/Http2.php
Normal file
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
|
||||
namespace JoopSchilder\Http2;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* Class Http2
|
||||
*/
|
||||
class Http2
|
||||
{
|
||||
/** @var resource */
|
||||
private $multihandle;
|
||||
|
||||
/** @var callable */
|
||||
private $responseHandler;
|
||||
|
||||
|
||||
/**
|
||||
* Http2 constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->multihandle = curl_multi_init();
|
||||
curl_multi_setopt($this->multihandle, CURLMOPT_PIPELINING, CURLPIPE_MULTIPLEX);
|
||||
curl_multi_setopt($this->multihandle, CURLMOPT_MAX_HOST_CONNECTIONS, 1);
|
||||
curl_multi_setopt($this->multihandle, CURLMOPT_MAX_TOTAL_CONNECTIONS, 1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Http2 destructor.
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
if (is_resource($this->multihandle)) {
|
||||
curl_multi_close($this->multihandle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @param bool $priorKnowledge
|
||||
* @return Request
|
||||
*/
|
||||
public function createRequest(string $url, bool $priorKnowledge = true): Request
|
||||
{
|
||||
return (new Request($url))->setOptions([
|
||||
CURLOPT_AUTOREFERER => 1,
|
||||
CURLOPT_FOLLOWLOCATION => 1,
|
||||
CURLOPT_HEADER => 1,
|
||||
CURLOPT_HTTP_VERSION => ($priorKnowledge ? CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE : CURL_HTTP_VERSION_2),
|
||||
CURLOPT_MAXREDIRS => 5,
|
||||
CURLOPT_PIPEWAIT => 1,
|
||||
CURLOPT_RETURNTRANSFER => 1,
|
||||
CURLOPT_SSL_VERIFYPEER => 0,
|
||||
CURLOPT_TIMEOUT => 10,
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
*/
|
||||
public function addRequest(Request $request): void
|
||||
{
|
||||
$handle = curl_init($request->getUri());
|
||||
curl_setopt_array($handle, $request->getOptions());
|
||||
curl_multi_add_handle($this->multihandle, $handle);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param callable $responseHandler
|
||||
*/
|
||||
public function onResponse(callable $responseHandler): void
|
||||
{
|
||||
$this->responseHandler = $responseHandler;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function execute(): void
|
||||
{
|
||||
$this->guardNoResponseHandler();
|
||||
do {
|
||||
curl_multi_exec($this->multihandle, $stillRunning);
|
||||
while (false !== ($message = curl_multi_info_read($this->multihandle))) {
|
||||
$handle = $message['handle'];
|
||||
$content = curl_multi_getcontent($handle);
|
||||
|
||||
$header = substr($content, 0, curl_getinfo($handle, CURLINFO_HEADER_SIZE));
|
||||
$content = str_replace($header, '', $content);
|
||||
$url = curl_getinfo($handle, CURLINFO_EFFECTIVE_URL);
|
||||
call_user_func($this->responseHandler, new Response($url, $header, $content));
|
||||
curl_multi_remove_handle($this->multihandle, $handle);
|
||||
curl_close($handle);
|
||||
}
|
||||
usleep(5);
|
||||
} while ($stillRunning > 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function guardNoResponseHandler(): void
|
||||
{
|
||||
if (!is_callable($this->responseHandler)) {
|
||||
throw new RuntimeException('No valid response handler found');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
57
src/Request.php
Normal file
57
src/Request.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace JoopSchilder\Http2;
|
||||
|
||||
/**
|
||||
* Class Request
|
||||
*/
|
||||
class Request
|
||||
{
|
||||
/** @var string */
|
||||
private $uri;
|
||||
|
||||
/** @var array */
|
||||
private $options;
|
||||
|
||||
|
||||
/**
|
||||
* Request constructor.
|
||||
* @param string $uri
|
||||
*/
|
||||
public function __construct(string $uri)
|
||||
{
|
||||
$this->uri = $uri;
|
||||
$this->options = [];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getUri(): string
|
||||
{
|
||||
return $this->uri;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getOptions(): array
|
||||
{
|
||||
return $this->options;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param array $options
|
||||
* @return Request
|
||||
*/
|
||||
public function setOptions(array $options)
|
||||
{
|
||||
$this->options = array_replace($this->options, $options);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
}
|
||||
60
src/Response.php
Normal file
60
src/Response.php
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
namespace JoopSchilder\Http2;
|
||||
|
||||
/**
|
||||
* Class Response
|
||||
*/
|
||||
class Response
|
||||
{
|
||||
/** @var string */
|
||||
private $originalUrl;
|
||||
|
||||
/** @var string */
|
||||
private $header;
|
||||
|
||||
/** @var string */
|
||||
private $content;
|
||||
|
||||
|
||||
/**
|
||||
* Response constructor.
|
||||
* @param string $originalUrl
|
||||
* @param string $header
|
||||
* @param string $content
|
||||
*/
|
||||
public function __construct(string $originalUrl, string $header, string $content)
|
||||
{
|
||||
$this->originalUrl = trim($originalUrl);
|
||||
$this->header = trim($header);
|
||||
$this->content = trim($content);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getOriginalUrl(): string
|
||||
{
|
||||
return $this->originalUrl;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getHeader(): string
|
||||
{
|
||||
return $this->header;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getContent(): string
|
||||
{
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
}
|
||||
16
src/ResponseHandler.php
Normal file
16
src/ResponseHandler.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace JoopSchilder\Http2;
|
||||
|
||||
/**
|
||||
* Interface ResponseHandler
|
||||
*/
|
||||
interface ResponseHandler
|
||||
{
|
||||
/**
|
||||
* @param Response $response
|
||||
* @return mixed
|
||||
*/
|
||||
function __invoke(Response $response): void;
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user