Search in sources :

Example 1 with ServiceClientHolderInputStream

use of com.amazonaws.util.ServiceClientHolderInputStream in project aws-sdk-android by aws-amplify.

the class AmazonS3Client method getObject.

/*
     * (non-Javadoc)
     * @see
     * com.amazonaws.services.s3.AmazonS3#getObject(com.amazonaws.services.s3
     * .model.GetObjectRequest)
     */
@Override
public S3Object getObject(GetObjectRequest getObjectRequest) throws AmazonClientException, AmazonServiceException {
    assertParameterNotNull(getObjectRequest, "The GetObjectRequest parameter must be specified when requesting an object");
    assertParameterNotNull(getObjectRequest.getBucketName(), "The bucket name parameter must be specified when requesting an object");
    assertParameterNotNull(getObjectRequest.getKey(), "The key parameter must be specified when requesting an object");
    final Request<GetObjectRequest> request = createRequest(getObjectRequest.getBucketName(), getObjectRequest.getKey(), getObjectRequest, HttpMethodName.GET);
    if (getObjectRequest.getVersionId() != null) {
        request.addParameter("versionId", getObjectRequest.getVersionId());
    }
    // Range
    final long[] range = getObjectRequest.getRange();
    if (range != null) {
        String rangeHeader = "bytes=" + Long.toString(range[0]) + "-";
        if (range[1] >= 0) {
            /*
                 * Negative value is invalid per S3 range get and will result in
                 * downloading the entire object. Leaving last byte empty so as
                 * to resume download from range[0].
                 */
            rangeHeader += Long.toString(range[1]);
        }
        request.addHeader(Headers.RANGE, rangeHeader);
    }
    populateRequesterPaysHeader(request, getObjectRequest.isRequesterPays());
    addResponseHeaderParameters(request, getObjectRequest.getResponseHeaders());
    addDateHeader(request, Headers.GET_OBJECT_IF_MODIFIED_SINCE, getObjectRequest.getModifiedSinceConstraint());
    addDateHeader(request, Headers.GET_OBJECT_IF_UNMODIFIED_SINCE, getObjectRequest.getUnmodifiedSinceConstraint());
    addStringListHeader(request, Headers.GET_OBJECT_IF_MATCH, getObjectRequest.getMatchingETagConstraints());
    addStringListHeader(request, Headers.GET_OBJECT_IF_NONE_MATCH, getObjectRequest.getNonmatchingETagConstraints());
    // Populate the SSE-CPK parameters to the request header
    populateSSE_C(request, getObjectRequest.getSSECustomerKey());
    /*
         * This is compatible with progress listener set by either the legacy
         * method GetObjectRequest#setProgressListener or the new method
         * GetObjectRequest#setGeneralProgressListener.
         */
    final ProgressListener progressListener = getObjectRequest.getGeneralProgressListener();
    final ProgressListenerCallbackExecutor progressListenerCallbackExecutor = ProgressListenerCallbackExecutor.wrapListener(progressListener);
    try {
        final S3Object s3Object = invoke(request, new S3ObjectResponseHandler(), getObjectRequest.getBucketName(), getObjectRequest.getKey());
        /*
             * TODO: For now, it's easiest to set there here in the client, but
             * we could push this back into the response handler with a little
             * more work.
             */
        s3Object.setBucketName(getObjectRequest.getBucketName());
        s3Object.setKey(getObjectRequest.getKey());
        InputStream input = s3Object.getObjectContent();
        // Hold a reference to this client while the InputStream is still
        // around - otherwise a finalizer in the HttpClient may reset the
        // underlying TCP connection out from under us.
        input = new ServiceClientHolderInputStream(input, this);
        // stream in a filter that will trigger progress reports.
        if (progressListenerCallbackExecutor != null) {
            @SuppressWarnings("resource") final ProgressReportingInputStream progressReportingInputStream = new ProgressReportingInputStream(input, progressListenerCallbackExecutor);
            progressReportingInputStream.setFireCompletedEvent(true);
            progressReportingInputStream.setNotificationThreshold(this.notificationThreshold);
            input = progressReportingInputStream;
            fireProgressEvent(progressListenerCallbackExecutor, ProgressEvent.STARTED_EVENT_CODE);
        }
        // Ensures the data received from S3 has the same length as the
        // expected content-length
        input = new LengthCheckInputStream(input, // expected length
        s3Object.getObjectMetadata().getContentLength(), // bytes received from S3 are all included even if skipped
        INCLUDE_SKIPPED_BYTES);
        // Re-wrap within an S3ObjectInputStream. Explicitly do not collect
        // metrics here because we know we're ultimately wrapping another
        // S3ObjectInputStream which will take care of that.
        s3Object.setObjectContent(new S3ObjectInputStream(input));
        return s3Object;
    } catch (final AmazonS3Exception ase) {
        /*
             * If the request failed because one of the specified constraints
             * was not met (ex: matching ETag, modified since date, etc.), then
             * return null, so that users don't have to wrap their code in
             * try/catch blocks and check for this status code if they want to
             * use constraints.
             */
        if (ase.getStatusCode() == 412 || ase.getStatusCode() == 304) {
            fireProgressEvent(progressListenerCallbackExecutor, ProgressEvent.CANCELED_EVENT_CODE);
            return null;
        }
        fireProgressEvent(progressListenerCallbackExecutor, ProgressEvent.FAILED_EVENT_CODE);
        throw ase;
    }
}
Also used : LengthCheckInputStream(com.amazonaws.util.LengthCheckInputStream) ServiceClientHolderInputStream(com.amazonaws.util.ServiceClientHolderInputStream) LengthCheckInputStream(com.amazonaws.util.LengthCheckInputStream) ByteArrayInputStream(java.io.ByteArrayInputStream) ProgressReportingInputStream(com.amazonaws.event.ProgressReportingInputStream) RepeatableFileInputStream(com.amazonaws.services.s3.internal.RepeatableFileInputStream) InputStream(java.io.InputStream) ProgressListenerCallbackExecutor(com.amazonaws.event.ProgressListenerCallbackExecutor) ProgressListener(com.amazonaws.event.ProgressListener) S3ObjectResponseHandler(com.amazonaws.services.s3.internal.S3ObjectResponseHandler) ProgressReportingInputStream(com.amazonaws.event.ProgressReportingInputStream) ServiceClientHolderInputStream(com.amazonaws.util.ServiceClientHolderInputStream)

Aggregations

ProgressListener (com.amazonaws.event.ProgressListener)1 ProgressListenerCallbackExecutor (com.amazonaws.event.ProgressListenerCallbackExecutor)1 ProgressReportingInputStream (com.amazonaws.event.ProgressReportingInputStream)1 RepeatableFileInputStream (com.amazonaws.services.s3.internal.RepeatableFileInputStream)1 S3ObjectResponseHandler (com.amazonaws.services.s3.internal.S3ObjectResponseHandler)1 LengthCheckInputStream (com.amazonaws.util.LengthCheckInputStream)1 ServiceClientHolderInputStream (com.amazonaws.util.ServiceClientHolderInputStream)1 ByteArrayInputStream (java.io.ByteArrayInputStream)1 InputStream (java.io.InputStream)1