$contentLengthCutoff
$contentLengthCutoff : integer
Ensures that an the MD5 hash of an entity body matches the Content-MD5 header (if set) of an HTTP response. An exception is thrown if the calculated MD5 does not match the expected MD5.
__construct(boolean $contentEncoded = true, boolean|integer $contentLengthCutoff = false)
boolean | $contentEncoded | Calculating the MD5 hash of an entity body where a Content-Encoding was applied is a more expensive comparison because the entity body will need to be compressed in order to get the correct hash. Set to FALSE to not validate the MD5 hash of an entity body with an applied Content-Encoding. |
boolean|integer | $contentLengthCutoff | Maximum Content-Length (bytes) in which a MD5 hash will be validated. Any response with a Content-Length greater than this value will not be validated because it will be deemed too memory intensive. |
getSubscribedEvents() : array
Returns an array of event names this subscriber wants to listen to.
The array keys are event names and the value can be:
For instance:
The event names to listen to
onRequestComplete(\Guzzle\Common\Event $event)
{@inheritdoc}
\Guzzle\Common\Event | $event |
<?php
namespace Guzzle\Plugin\Md5;
use Guzzle\Common\Event;
use Guzzle\Common\Exception\UnexpectedValueException;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* Ensures that an the MD5 hash of an entity body matches the Content-MD5
* header (if set) of an HTTP response. An exception is thrown if the
* calculated MD5 does not match the expected MD5.
*/
class Md5ValidatorPlugin implements EventSubscriberInterface
{
/** @var int Maximum Content-Length in bytes to validate */
protected $contentLengthCutoff;
/** @var bool Whether or not to compare when a Content-Encoding is present */
protected $contentEncoded;
/**
* @param bool $contentEncoded Calculating the MD5 hash of an entity body where a Content-Encoding was
* applied is a more expensive comparison because the entity body will need to
* be compressed in order to get the correct hash. Set to FALSE to not
* validate the MD5 hash of an entity body with an applied Content-Encoding.
* @param bool|int $contentLengthCutoff Maximum Content-Length (bytes) in which a MD5 hash will be validated. Any
* response with a Content-Length greater than this value will not be validated
* because it will be deemed too memory intensive.
*/
public function __construct($contentEncoded = true, $contentLengthCutoff = false)
{
$this->contentLengthCutoff = $contentLengthCutoff;
$this->contentEncoded = $contentEncoded;
}
public static function getSubscribedEvents()
{
return array('request.complete' => array('onRequestComplete', 255));
}
/**
* {@inheritdoc}
* @throws UnexpectedValueException
*/
public function onRequestComplete(Event $event)
{
$response = $event['response'];
if (!$contentMd5 = $response->getContentMd5()) {
return;
}
$contentEncoding = $response->getContentEncoding();
if ($contentEncoding && !$this->contentEncoded) {
return false;
}
// Make sure that the size of the request is under the cutoff size
if ($this->contentLengthCutoff) {
$size = $response->getContentLength() ?: $response->getBody()->getSize();
if (!$size || $size > $this->contentLengthCutoff) {
return;
}
}
if (!$contentEncoding) {
$hash = $response->getBody()->getContentMd5();
} elseif ($contentEncoding == 'gzip') {
$response->getBody()->compress('zlib.deflate');
$hash = $response->getBody()->getContentMd5();
$response->getBody()->uncompress();
} elseif ($contentEncoding == 'compress') {
$response->getBody()->compress('bzip2.compress');
$hash = $response->getBody()->getContentMd5();
$response->getBody()->uncompress();
} else {
return;
}
if ($contentMd5 !== $hash) {
throw new UnexpectedValueException(
"The response entity body may have been modified over the wire. The Content-MD5 "
. "received ({$contentMd5}) did not match the calculated MD5 hash ({$hash})."
);
}
}
}