summaryrefslogtreecommitdiff
path: root/vendor/guzzle/guzzle/src/Guzzle/Plugin/Md5/Md5ValidatorPlugin.php
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/guzzle/guzzle/src/Guzzle/Plugin/Md5/Md5ValidatorPlugin.php')
-rw-r--r--vendor/guzzle/guzzle/src/Guzzle/Plugin/Md5/Md5ValidatorPlugin.php88
1 files changed, 88 insertions, 0 deletions
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Plugin/Md5/Md5ValidatorPlugin.php b/vendor/guzzle/guzzle/src/Guzzle/Plugin/Md5/Md5ValidatorPlugin.php
new file mode 100644
index 0000000..5d7a378
--- /dev/null
+++ b/vendor/guzzle/guzzle/src/Guzzle/Plugin/Md5/Md5ValidatorPlugin.php
@@ -0,0 +1,88 @@
+<?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})."
+ );
+ }
+ }
+}