mirror of
https://github.com/guzzle/guzzle.git
synced 2025-02-25 02:22:57 +01:00
Cleaning up the message integrity plugin
This commit is contained in:
parent
7228451b67
commit
3a421c9c64
@ -4,7 +4,6 @@ namespace Guzzle\Plugin\MessageIntegrity;
|
||||
|
||||
use Guzzle\Http\Event\RequestAfterSendEvent;
|
||||
use Guzzle\Http\Message\ResponseInterface;
|
||||
use Guzzle\Stream\Stream;
|
||||
use Guzzle\Stream\StreamInterface;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
@ -68,14 +67,14 @@ class FullResponseIntegrityPlugin implements EventSubscriberInterface
|
||||
|
||||
$result = base64_encode($this->hash->complete());
|
||||
if ($hash !== $result) {
|
||||
$event->intercept(new MessageIntegrityException(
|
||||
throw new MessageIntegrityException(
|
||||
sprintf(
|
||||
'%s message integrity check failure. Expected "%s" but got "%s"',
|
||||
$this->header, $hash, $result
|
||||
),
|
||||
$event->getRequest(),
|
||||
$event->getResponse()
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace Guzzle\Plugin\MessageIntegrity;
|
||||
|
||||
use Guzzle\Http\Event\RequestBeforeSendEvent;
|
||||
use Guzzle\Http\Event\RequestEvents;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
/**
|
||||
* Verifies the message integrity of a response after all of the data has been received
|
||||
*/
|
||||
class MessageIntegrityPlugin implements EventSubscriberInterface
|
||||
{
|
||||
private $full;
|
||||
private $streaming;
|
||||
|
||||
/**
|
||||
* Creates a new plugin that validates the Content-MD5 of responses
|
||||
*
|
||||
* @return MessageIntegrityPlugin
|
||||
*/
|
||||
public static function createForContentMd5()
|
||||
{
|
||||
return new self('Content-MD5', new PhpHash('md5'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $header Header to check
|
||||
* @param HashInterface $hash Hash used to validate the header value
|
||||
* @param int $sizeCutoff Don't validate when size is greater than this number
|
||||
*/
|
||||
public function __construct($header, HashInterface $hash, $sizeCutoff = null)
|
||||
{
|
||||
$this->full = new FullResponseIntegrityPlugin($header, $hash, $sizeCutoff);
|
||||
$this->streaming = new StreamingResponseIntegrityPlugin($header, $hash);
|
||||
}
|
||||
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return [RequestEvents::BEFORE_SEND => 'onRequestBeforeSend'];
|
||||
}
|
||||
|
||||
public function onRequestBeforeSend(RequestBeforeSendEvent $event)
|
||||
{
|
||||
if ($event->getRequest()->getConfig()->get('streaming')) {
|
||||
$event->getRequest()->getEventDispatcher()->addSubscriber($this->streaming);
|
||||
} else {
|
||||
$event->getRequest()->getEventDispatcher()->addSubscriber($this->full);
|
||||
}
|
||||
}
|
||||
}
|
@ -24,8 +24,11 @@ class ReadIntegrityStream implements StreamInterface, HasDispatcherInterface
|
||||
/** @var int Last position that the hash was updated at */
|
||||
private $lastHashPos = 0;
|
||||
|
||||
public function __construct(StreamInterface $stream, HashInterface $hash, callable $validationCallback)
|
||||
{
|
||||
public function __construct(
|
||||
StreamInterface $stream,
|
||||
HashInterface $hash,
|
||||
callable $validationCallback
|
||||
) {
|
||||
$this->stream = $stream;
|
||||
$this->hash = $hash;
|
||||
$this->validationCallback = $validationCallback;
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
namespace Guzzle\Plugin\MessageIntegrity;
|
||||
|
||||
use Guzzle\Common\Event;
|
||||
use Guzzle\Http\Event\GotResponseHeadersEvent;
|
||||
use Guzzle\Http\Message\ResponseInterface;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
@ -25,30 +25,31 @@ class StreamingResponseIntegrityPlugin implements EventSubscriberInterface
|
||||
return ['request.got_headers' => ['onRequestGotHeaders', -1]];
|
||||
}
|
||||
|
||||
public function onRequestGotHeaders(Event $event)
|
||||
public function onRequestGotHeaders(GotResponseHeadersEvent $event)
|
||||
{
|
||||
if ($this->canValidate($event['response'])) {
|
||||
$response = $event['response'];
|
||||
$request = $event['request'];
|
||||
$expected = (string) $response->getHeader($this->header);
|
||||
$header = $this->header;
|
||||
$response->setBody(new ReadIntegrityStream(
|
||||
$response->getBody(),
|
||||
$this->hash,
|
||||
function ($result) use ($request, $response, $expected, $header) {
|
||||
if ($expected !== $result) {
|
||||
throw new MessageIntegrityException(
|
||||
sprintf(
|
||||
'%s message integrity check failure. Expected "%s" but got "%s"',
|
||||
$this->header, $expected, $result
|
||||
),
|
||||
$request,
|
||||
$response
|
||||
);
|
||||
}
|
||||
}
|
||||
));
|
||||
$response = $event->getResponse();
|
||||
if (!$this->canValidate($response)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$request = $event->getRequest();
|
||||
$expected = (string) $response->getHeader($this->header);
|
||||
$response->setBody(new ReadIntegrityStream(
|
||||
$response->getBody(),
|
||||
$this->hash,
|
||||
function ($result) use ($request, $response, $expected) {
|
||||
if ($expected !== $result) {
|
||||
throw new MessageIntegrityException(
|
||||
sprintf(
|
||||
'%s message integrity check failure. Expected "%s" but got "%s"',
|
||||
$this->header, $expected, $result
|
||||
),
|
||||
$request,
|
||||
$response
|
||||
);
|
||||
}
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
private function canValidate(ResponseInterface $response)
|
||||
|
Loading…
x
Reference in New Issue
Block a user