diff options
Diffstat (limited to 'vendor/guzzle/guzzle/src/Guzzle/Plugin/Md5')
3 files changed, 172 insertions, 0 deletions
diff --git a/vendor/guzzle/guzzle/src/Guzzle/Plugin/Md5/CommandContentMd5Plugin.php b/vendor/guzzle/guzzle/src/Guzzle/Plugin/Md5/CommandContentMd5Plugin.php new file mode 100644 index 0000000..8512424 --- /dev/null +++ b/vendor/guzzle/guzzle/src/Guzzle/Plugin/Md5/CommandContentMd5Plugin.php @@ -0,0 +1,57 @@ +<?php + +namespace Guzzle\Plugin\Md5; + +use Guzzle\Common\Event; +use Guzzle\Http\Message\EntityEnclosingRequestInterface; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; + +/** + * Listener used to add a ContentMD5 header to the body of a command and adds ContentMD5 validation if the + * ValidateMD5 option is not set to false on a command + */ +class CommandContentMd5Plugin implements EventSubscriberInterface +{ + /** @var string Parameter used to check if the ContentMD5 value is being added */ + protected $contentMd5Param; + + /** @var string Parameter used to check if validation should occur on the response */ + protected $validateMd5Param; + + /** + * @param string $contentMd5Param Parameter used to check if the ContentMD5 value is being added + * @param string $validateMd5Param Parameter used to check if validation should occur on the response + */ + public function __construct($contentMd5Param = 'ContentMD5', $validateMd5Param = 'ValidateMD5') + { + $this->contentMd5Param = $contentMd5Param; + $this->validateMd5Param = $validateMd5Param; + } + + public static function getSubscribedEvents() + { + return array('command.before_send' => array('onCommandBeforeSend', -255)); + } + + public function onCommandBeforeSend(Event $event) + { + $command = $event['command']; + $request = $command->getRequest(); + + // Only add an MD5 is there is a MD5 option on the operation and it has a payload + if ($request instanceof EntityEnclosingRequestInterface && $request->getBody() + && $command->getOperation()->hasParam($this->contentMd5Param)) { + // Check if an MD5 checksum value should be passed along to the request + if ($command[$this->contentMd5Param] === true) { + if (false !== ($md5 = $request->getBody()->getContentMd5(true, true))) { + $request->setHeader('Content-MD5', $md5); + } + } + } + + // Check if MD5 validation should be used with the response + if ($command[$this->validateMd5Param] === true) { + $request->addSubscriber(new Md5ValidatorPlugin(true, false)); + } + } +} 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})." + ); + } + } +} diff --git a/vendor/guzzle/guzzle/src/Guzzle/Plugin/Md5/composer.json b/vendor/guzzle/guzzle/src/Guzzle/Plugin/Md5/composer.json new file mode 100644 index 0000000..0602d06 --- /dev/null +++ b/vendor/guzzle/guzzle/src/Guzzle/Plugin/Md5/composer.json @@ -0,0 +1,27 @@ +{ + "name": "guzzle/plugin-md5", + "description": "Guzzle MD5 plugins", + "homepage": "http://guzzlephp.org/", + "keywords": ["plugin", "guzzle"], + "license": "MIT", + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "require": { + "php": ">=5.3.2", + "guzzle/http": "self.version" + }, + "autoload": { + "psr-0": { "Guzzle\\Plugin\\Md5": "" } + }, + "target-dir": "Guzzle/Plugin/Md5", + "extra": { + "branch-alias": { + "dev-master": "3.7-dev" + } + } +} |