This file is indexed.

/usr/share/php/Aws/S3/ResumableDownload.php is in php-aws-sdk 2.7.2-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
<?php
/**
 * Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License").
 * You may not use this file except in compliance with the License.
 * A copy of the License is located at
 *
 * http://aws.amazon.com/apache2.0
 *
 * or in the "license" file accompanying this file. This file is distributed
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */

namespace Aws\S3;

use Aws\Common\Exception\RuntimeException;
use Aws\Common\Exception\UnexpectedValueException;
use Guzzle\Http\EntityBody;
use Guzzle\Http\ReadLimitEntityBody;
use Guzzle\Http\EntityBodyInterface;
use Guzzle\Service\Resource\Model;

/**
 * Allows you to resume the download of a partially downloaded object.
 *
 * Downloads objects from Amazon S3 in using "Range" downloads. This allows a partially downloaded object to be resumed
 * so that only the remaining portion of the object is downloaded.
 */
class ResumableDownload
{
    /** @var S3Client The S3 client to use to download objects and issue HEAD requests */
    protected $client;

    /** @var \Guzzle\Service\Resource\Model Model object returned when the initial HeadObject operation was called */
    protected $meta;

    /** @var array Array of parameters to pass to a GetObject operation */
    protected $params;

    /** @var \Guzzle\Http\EntityBody Where the object will be downloaded */
    protected $target;

    /**
     * @param S3Client                            $client Client to use when executing requests
     * @param string                              $bucket Bucket that holds the object
     * @param string                              $key    Key of the object
     * @param string|resource|EntityBodyInterface $target Where the object should be downloaded to. Pass a string to
     *                                                    save the object to a file, pass a resource returned by
     *                                                    fopen() to save the object to a stream resource, or pass a
     *                                                    Guzzle EntityBody object to save the contents to an
     *                                                    EntityBody.
     * @param array                               $params Any additional GetObject or HeadObject parameters to use
     *                                                    with each command issued by the client. (e.g. pass "Version"
     *                                                    to download a specific version of an object)
     * @throws RuntimeException if the target variable points to a file that cannot be opened
     */
    public function __construct(S3Client $client, $bucket, $key, $target, array $params = array())
    {
        $this->params = $params;
        $this->client = $client;
        $this->params['Bucket'] = $bucket;
        $this->params['Key'] = $key;

        // If a string is passed, then assume that the download should stream to a file on disk
        if (is_string($target)) {
            if (!($target = fopen($target, 'a+'))) {
                throw new RuntimeException("Unable to open {$target} for writing");
            }
            // Always append to the file
            fseek($target, 0, SEEK_END);
        }

        // Get the metadata and Content-MD5 of the object
        $this->target = EntityBody::factory($target);
    }

    /**
     * Get the bucket of the download
     *
     * @return string
     */
    public function getBucket()
    {
        return $this->params['Bucket'];
    }

    /**
     * Get the key of the download
     *
     * @return string
     */
    public function getKey()
    {
        return $this->params['Key'];
    }

    /**
     * Get the file to which the contents are downloaded
     *
     * @return string
     */
    public function getFilename()
    {
        return $this->target->getUri();
    }

    /**
     * Download the remainder of the object from Amazon S3
     *
     * Performs a message integrity check if possible
     *
     * @return Model
     */
    public function __invoke()
    {
        $command = $this->client->getCommand('HeadObject', $this->params);
        $this->meta = $command->execute();

        if ($this->target->ftell() >= $this->meta['ContentLength']) {
            return false;
        }

        $this->meta['ContentMD5'] = (string) $command->getResponse()->getHeader('Content-MD5');

        // Use a ReadLimitEntityBody so that rewinding the stream after an error does not cause the file pointer
        // to enter an inconsistent state with the data being downloaded
        $this->params['SaveAs'] = new ReadLimitEntityBody(
            $this->target,
            $this->meta['ContentLength'],
            $this->target->ftell()
        );

        $result = $this->getRemaining();
        $this->checkIntegrity();

        return $result;
    }

    /**
     * Send the command to get the remainder of the object
     *
     * @return Model
     */
    protected function getRemaining()
    {
        $current = $this->target->ftell();
        $targetByte = $this->meta['ContentLength'] - 1;
        $this->params['Range'] = "bytes={$current}-{$targetByte}";

        // Set the starting offset so that the body is never seeked to before this point in the event of a retry
        $this->params['SaveAs']->setOffset($current);
        $command = $this->client->getCommand('GetObject', $this->params);

        return $command->execute();
    }

    /**
     * Performs an MD5 message integrity check if possible
     *
     * @throws UnexpectedValueException if the message does not validate
     */
    protected function checkIntegrity()
    {
        if ($this->target->isReadable() && $expected = $this->meta['ContentMD5']) {
            $actual = $this->target->getContentMd5();
            if ($actual != $expected) {
                throw new UnexpectedValueException(
                    "Message integrity check failed. Expected {$expected} but got {$actual}."
                );
            }
        }
    }
}