1
0
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:
Michael Dowling 2013-11-02 18:18:30 -07:00
parent 7228451b67
commit 3a421c9c64
4 changed files with 82 additions and 28 deletions

View File

@ -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()
));
);
}
}
}

View File

@ -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);
}
}
}

View File

@ -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;

View File

@ -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)