Initial commit

This commit is contained in:
2019-12-07 15:03:02 +01:00
commit e02e43217c
9 changed files with 375 additions and 0 deletions

117
src/Http2.php Normal file
View 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
View 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
View 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
View File

@@ -0,0 +1,16 @@
<?php
namespace JoopSchilder\Http2;
/**
* Interface ResponseHandler
*/
interface ResponseHandler
{
/**
* @param Response $response
* @return mixed
*/
function __invoke(Response $response): void;
}