Search in sources :

Example 11 with Signer

use of com.amazonaws.auth.Signer in project aws-sdk-android by aws-amplify.

the class AmazonWebServiceClient method setRegion.

/**
 * An alternative to {@link AmazonWebServiceClient#setEndpoint(String)},
 * sets the regional endpoint for this client's service calls. Callers can
 * use this method to control which AWS region they want to work with.
 * <p>
 * <b>This method is not threadsafe. A region should be configured when the
 * client is created and before any service requests are made. Changing it
 * afterwards creates inevitable race conditions for any service requests in
 * transit or retrying.</b>
 * <p>
 * By default, all service endpoints in all regions use the https protocol.
 * To use http instead, specify it in the {@link ClientConfiguration}
 * supplied at construction.
 *
 * @param region The region this client will communicate with. See
 *            {@link Region#getRegion(com.amazonaws.regions.Regions)} for
 *            accessing a given region.
 * @throws java.lang.IllegalArgumentException If the given region is null,
 *             or if this service isn't available in the given region. See
 *             {@link Region#isServiceSupported(String)}
 * @see Region#getRegion(com.amazonaws.regions.Regions)
 * @see Region#createClient(Class,
 *      com.amazonaws.auth.AWSCredentialsProvider, ClientConfiguration)
 */
@SuppressWarnings("checkstyle:hiddenfield")
public void setRegion(final Region region) {
    if (region == null) {
        throw new IllegalArgumentException("No region provided");
    }
    final String serviceName = getServiceNameIntern();
    String serviceEndpoint;
    if (region.isServiceSupported(serviceName)) {
        serviceEndpoint = region.getServiceEndpoint(serviceName);
        final int protocolIdx = serviceEndpoint.indexOf("://");
        // Strip off the protocol to allow the client config to specify it
        if (protocolIdx >= 0) {
            serviceEndpoint = serviceEndpoint.substring(protocolIdx + "://".length());
        }
    } else {
        serviceEndpoint = String.format("%s.%s.%s", getEndpointPrefix(), region.getName(), region.getDomain());
    }
    final URI uri = toURI(serviceEndpoint);
    final Signer signer = computeSignerByServiceRegion(serviceName, region.getName(), signerRegionOverride, false);
    synchronized (this) {
        this.endpoint = uri;
        this.signer = signer;
    }
}
Also used : Signer(com.amazonaws.auth.Signer) RegionAwareSigner(com.amazonaws.auth.RegionAwareSigner) URI(java.net.URI)

Example 12 with Signer

use of com.amazonaws.auth.Signer in project aws-sdk-android by aws-amplify.

the class AmazonWebServiceClient method setEndpoint.

/**
 * Overrides the default endpoint for this client. Callers can use this
 * method to control which AWS region they want to work with.
 * <p>
 * <b>This method is not threadsafe. Endpoints should be configured when the
 * client is created and before any service requests are made. Changing it
 * afterwards creates inevitable race conditions for any service requests in
 * transit.</b>
 * <p>
 * Callers can pass in just the endpoint (ex: "ec2.amazonaws.com") or a full
 * URL, including the protocol (ex: "https://ec2.amazonaws.com"). If the
 * protocol is not specified here, the default protocol from this client's
 * {@link ClientConfiguration} will be used, which by default is HTTPS.
 * <p>
 * For more information on using AWS regions with the AWS SDK for Java, and
 * a complete list of all available endpoints for all AWS services, see:
 * <a href= "https://docs.aws.amazon.com/general/latest/gr/rande.html">
 * https://docs.aws.amazon.com/general/latest/gr/rande.html
 * </a>
 *
 * @param endpoint The endpoint (ex: "ec2.amazonaws.com") or a full URL,
 *            including the protocol (ex: "https://ec2.amazonaws.com") of
 *            the region specific AWS endpoint this client will communicate
 *            with.
 * @throws IllegalArgumentException If any problems are detected with the
 *             specified endpoint.
 */
public void setEndpoint(final String endpoint) {
    final URI uri = toURI(endpoint);
    @SuppressWarnings("checkstyle:hiddenfield") final Signer signer = computeSignerByURI(uri, signerRegionOverride, false);
    synchronized (this) {
        this.endpoint = uri;
        this.signer = signer;
    }
}
Also used : Signer(com.amazonaws.auth.Signer) RegionAwareSigner(com.amazonaws.auth.RegionAwareSigner) URI(java.net.URI)

Example 13 with Signer

use of com.amazonaws.auth.Signer in project aws-sdk-android by aws-amplify.

the class AmazonHttpClient method executeHelper.

/**
 * Internal method to execute the HTTP method given.
 *
 * @see AmazonHttpClient#execute(Request, HttpResponseHandler,
 *      HttpResponseHandler, ExecutionContext)
 */
@SuppressWarnings("checkstyle:methodlength")
<T> Response<T> executeHelper(Request<?> request, HttpResponseHandler<AmazonWebServiceResponse<T>> responseHandler, HttpResponseHandler<AmazonServiceException> errorResponseHandler, ExecutionContext executionContext) {
    /*
         * Depending on which response handler we end up choosing to handle the
         * HTTP response, it might require us to leave the underlying HTTP
         * connection open, depending on whether or not it reads the complete
         * HTTP response stream from the HTTP connection, or if delays reading
         * any of the content until after a response is returned to the caller.
         */
    boolean leaveHttpConnectionOpen = false;
    final AWSRequestMetrics awsRequestMetrics = executionContext.getAwsRequestMetrics();
    /*
         * add the service endpoint to the logs. You can infer service name from
         * service endpoint
         */
    awsRequestMetrics.addProperty(Field.ServiceName, request.getServiceName());
    awsRequestMetrics.addProperty(Field.ServiceEndpoint, request.getEndpoint());
    // Apply whatever request options we know how to handle, such as
    // user-agent.
    setUserAgent(request);
    request.addHeader(HEADER_SDK_TRANSACTION_ID, UUID.randomUUID().toString());
    int requestCount = 0;
    long lastBackoffDelay = 0;
    URI redirectedURI = null;
    AmazonClientException retriedException = null;
    // Make a copy of the original request params and headers so that we can
    // permute it in this loop and start over with the original every time.
    final Map<String, String> originalParameters = new LinkedHashMap<String, String>(request.getParameters());
    final Map<String, String> originalHeaders = new HashMap<String, String>(request.getHeaders());
    // mark input stream if supported
    final InputStream originalContent = request.getContent();
    if (originalContent != null && originalContent.markSupported()) {
        originalContent.mark(-1);
    }
    final AWSCredentials credentials = executionContext.getCredentials();
    Signer signer = null;
    HttpResponse httpResponse = null;
    HttpRequest httpRequest = null;
    while (true) {
        ++requestCount;
        awsRequestMetrics.setCounter(Field.RequestCount, requestCount);
        if (requestCount > 1) {
            // retry
            request.setParameters(originalParameters);
            request.setHeaders(originalHeaders);
            request.setContent(originalContent);
        }
        if (redirectedURI != null && request.getEndpoint() == null && request.getResourcePath() == null) {
            request.setEndpoint(URI.create(redirectedURI.getScheme() + "://" + redirectedURI.getAuthority()));
            request.setResourcePath(redirectedURI.getPath());
        }
        try {
            if (requestCount > 1) {
                // retry
                awsRequestMetrics.startEvent(Field.RetryPauseTime);
                try {
                    lastBackoffDelay = pauseBeforeNextRetry(request.getOriginalRequest(), retriedException, requestCount, config.getRetryPolicy());
                } finally {
                    awsRequestMetrics.endEvent(Field.RetryPauseTime);
                }
                final InputStream content = request.getContent();
                if (content != null && content.markSupported()) {
                    content.reset();
                }
            }
            request.addHeader(HEADER_SDK_RETRY_INFO, (requestCount - 1) + "/" + lastBackoffDelay);
            // Sign the request if a signer was provided
            if (signer == null) {
                signer = executionContext.getSignerByURI(request.getEndpoint());
            }
            if (signer != null && credentials != null) {
                awsRequestMetrics.startEvent(Field.RequestSigningTime);
                try {
                    signer.sign(request, credentials);
                } finally {
                    awsRequestMetrics.endEvent(Field.RequestSigningTime);
                }
            }
            if (REQUEST_LOG.isDebugEnabled()) {
                REQUEST_LOG.debug("Sending Request: " + request.toString());
            }
            httpRequest = requestFactory.createHttpRequest(request, config, executionContext);
            retriedException = null;
            awsRequestMetrics.startEvent(Field.HttpRequestTime);
            try {
                httpResponse = httpClient.execute(httpRequest);
            } finally {
                awsRequestMetrics.endEvent(Field.HttpRequestTime);
            }
            if (isRequestSuccessful(httpResponse)) {
                awsRequestMetrics.addProperty(Field.StatusCode, httpResponse.getStatusCode());
                /*
                     * If we get back any 2xx status code, then we know we
                     * should treat the service call as successful.
                     */
                leaveHttpConnectionOpen = responseHandler.needsConnectionLeftOpen();
                final T response = handleResponse(request, responseHandler, httpResponse, executionContext);
                return new Response<T>(response, httpResponse);
            } else if (isTemporaryRedirect(httpResponse)) {
                /*
                     * S3 sends 307 Temporary Redirects if you try to delete an
                     * EU bucket from the US endpoint. If we get a 307, we'll
                     * point the HTTP method to the redirected location, and let
                     * the next retry deliver the request to the right location.
                     */
                final String redirectedLocation = httpResponse.getHeaders().get("Location");
                log.debug("Redirecting to: " + redirectedLocation);
                // set redirect uri and retry
                redirectedURI = URI.create(redirectedLocation);
                request.setEndpoint(null);
                request.setResourcePath(null);
                awsRequestMetrics.addProperty(Field.StatusCode, httpResponse.getStatusCode());
                awsRequestMetrics.addProperty(Field.RedirectLocation, redirectedLocation);
                awsRequestMetrics.addProperty(Field.AWSRequestID, null);
            } else {
                leaveHttpConnectionOpen = errorResponseHandler.needsConnectionLeftOpen();
                final AmazonServiceException ase = handleErrorResponse(request, errorResponseHandler, httpResponse);
                awsRequestMetrics.addProperty(Field.AWSRequestID, ase.getRequestId());
                awsRequestMetrics.addProperty(Field.AWSErrorCode, ase.getErrorCode());
                awsRequestMetrics.addProperty(Field.StatusCode, ase.getStatusCode());
                if (!shouldRetry(request.getOriginalRequest(), httpRequest.getContent(), ase, requestCount, config.getRetryPolicy())) {
                    throw ase;
                }
                // Cache the retryable exception
                retriedException = ase;
                /*
                     * Checking for clock skew error again because we don't want
                     * to set the global time offset for every service
                     * exception.
                     */
                if (RetryUtils.isClockSkewError(ase)) {
                    final long timeOffset = parseClockSkewOffset(httpResponse, ase);
                    SDKGlobalConfiguration.setGlobalTimeOffset(timeOffset);
                }
                resetRequestAfterError(request, ase);
            }
        } catch (final IOException ioe) {
            if (log.isDebugEnabled()) {
                log.debug("Unable to execute HTTP request: " + ioe.getMessage(), ioe);
            }
            awsRequestMetrics.incrementCounter(Field.Exception);
            awsRequestMetrics.addProperty(Field.Exception, ioe);
            awsRequestMetrics.addProperty(Field.AWSRequestID, null);
            final AmazonClientException ace = new AmazonClientException("Unable to execute HTTP request: " + ioe.getMessage(), ioe);
            if (!shouldRetry(request.getOriginalRequest(), httpRequest.getContent(), ace, requestCount, config.getRetryPolicy())) {
                throw ace;
            }
            // Cache the retryable exception
            retriedException = ace;
            resetRequestAfterError(request, ioe);
        } catch (final RuntimeException e) {
            throw handleUnexpectedFailure(e, awsRequestMetrics);
        } catch (final Error e) {
            throw handleUnexpectedFailure(e, awsRequestMetrics);
        } finally {
            /*
                 * Some response handlers need to manually manage the HTTP
                 * connection and will take care of releasing the connection on
                 * their own, but if this response handler doesn't need the
                 * connection left open, we go ahead and release the it to free
                 * up resources.
                 */
            if (!leaveHttpConnectionOpen && httpResponse != null) {
                try {
                    if (httpResponse.getRawContent() != null) {
                        httpResponse.getRawContent().close();
                    }
                } catch (final IOException e) {
                    log.warn("Cannot close the response content.", e);
                }
            }
        }
    }
/* end while (true) */
}
Also used : AWSRequestMetrics(com.amazonaws.util.AWSRequestMetrics) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) InputStream(java.io.InputStream) AmazonClientException(com.amazonaws.AmazonClientException) IOException(java.io.IOException) URI(java.net.URI) AWSCredentials(com.amazonaws.auth.AWSCredentials) LinkedHashMap(java.util.LinkedHashMap) Signer(com.amazonaws.auth.Signer) AmazonWebServiceResponse(com.amazonaws.AmazonWebServiceResponse) Response(com.amazonaws.Response) AmazonServiceException(com.amazonaws.AmazonServiceException)

Example 14 with Signer

use of com.amazonaws.auth.Signer in project aws-sdk-android by aws-amplify.

the class AmazonS3Client method generatePresignedUrl.

/*
     * (non-Javadoc)
     * @see
     * com.amazonaws.services.s3.AmazonS3#generatePresignedUrl(com.amazonaws
     * .services.s3.model.GeneratePresignedUrlRequest)
     */
@Override
public URL generatePresignedUrl(GeneratePresignedUrlRequest generatePresignedUrlRequest) throws AmazonClientException {
    assertParameterNotNull(generatePresignedUrlRequest, "The request parameter must be specified when generating a pre-signed URL");
    final String bucketName = generatePresignedUrlRequest.getBucketName();
    final String key = generatePresignedUrlRequest.getKey();
    assertParameterNotNull(bucketName, "The bucket name parameter must be specified when generating a pre-signed URL");
    assertParameterNotNull(generatePresignedUrlRequest.getMethod(), "The HTTP method request parameter must be specified when generating a pre-signed URL");
    if (generatePresignedUrlRequest.getExpiration() == null) {
        generatePresignedUrlRequest.setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 15));
    }
    final HttpMethodName httpMethod = HttpMethodName.valueOf(generatePresignedUrlRequest.getMethod().toString());
    // If the key starts with a slash character itself, the following method
    // will actually add another slash before the resource path to prevent
    // the HttpClient mistakenly treating the slash as a path delimiter.
    // For presigned request, we need to remember to remove this extra slash
    // before generating the URL.
    final Request<GeneratePresignedUrlRequest> request = createRequest(bucketName, key, generatePresignedUrlRequest, httpMethod);
    addParameterIfNotNull(request, "versionId", generatePresignedUrlRequest.getVersionId());
    if (generatePresignedUrlRequest.isZeroByteContent()) {
        request.setContent(new ByteArrayInputStream(new byte[0]));
    }
    for (final Entry<String, String> entry : generatePresignedUrlRequest.getRequestParameters().entrySet()) {
        request.addParameter(entry.getKey(), entry.getValue());
    }
    if (generatePresignedUrlRequest.getContentType() != null) {
        request.addHeader(Headers.CONTENT_TYPE, generatePresignedUrlRequest.getContentType());
    }
    if (generatePresignedUrlRequest.getContentMd5() != null) {
        request.addHeader(Headers.CONTENT_MD5, generatePresignedUrlRequest.getContentMd5());
    }
    // SSE-C
    populateSSE_C(request, generatePresignedUrlRequest.getSSECustomerKey());
    // SSE
    addHeaderIfNotNull(request, Headers.SERVER_SIDE_ENCRYPTION, generatePresignedUrlRequest.getSSEAlgorithm());
    // SSE-KMS
    addHeaderIfNotNull(request, Headers.SERVER_SIDE_ENCRYPTION_KMS_KEY_ID, generatePresignedUrlRequest.getKmsCmkId());
    // Add custom query parameters
    final Map<String, String> customQueryParameters = generatePresignedUrlRequest.getCustomQueryParameters();
    if (customQueryParameters != null) {
        for (Map.Entry<String, String> e : customQueryParameters.entrySet()) {
            request.addParameter(e.getKey(), e.getValue());
        }
    }
    addResponseHeaderParameters(request, generatePresignedUrlRequest.getResponseHeaders());
    final Signer signer = createSigner(request, bucketName, key);
    if (signer instanceof Presigner) {
        // If we have a signer which knows how to presign requests,
        // delegate directly to it.
        ((Presigner) signer).presignRequest(request, awsCredentialsProvider.getCredentials(), generatePresignedUrlRequest.getExpiration());
    } else {
        // Otherwise use the default presigning method, which is hardcoded
        // to use QueryStringSigner.
        presignRequest(request, generatePresignedUrlRequest.getMethod(), bucketName, key, generatePresignedUrlRequest.getExpiration(), null);
    }
    // Remove the leading slash (if any) in the resource-path
    return ServiceUtils.convertRequestToUrl(request, true);
}
Also used : HttpMethodName(com.amazonaws.http.HttpMethodName) S3Signer(com.amazonaws.services.s3.internal.S3Signer) S3QueryStringSigner(com.amazonaws.services.s3.internal.S3QueryStringSigner) AWSS3V4Signer(com.amazonaws.services.s3.internal.AWSS3V4Signer) Signer(com.amazonaws.auth.Signer) ByteArrayInputStream(java.io.ByteArrayInputStream) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap) HashMap(java.util.HashMap) Date(java.util.Date) Presigner(com.amazonaws.auth.Presigner)

Example 15 with Signer

use of com.amazonaws.auth.Signer in project aws-sdk-android by aws-amplify.

the class AmazonS3Client method createSigner.

/**
 * Returns a "complete" S3 specific signer, taking into the S3 bucket, key,
 * and the current S3 client configuration into account.
 *
 * Signer = get a Signer based on the bucket endpoint // InternalConfig in CoreRuntime makes this decision
 * [If the region is not specified, uses SigV2 signer,
 * Else If the region is specified, and If the region only supports SigV4, then uses SigV4]
 * If Signer is not Overriden {
 *    If Signer is a V4 Signer and Region is null
 *       Get the region from AmazonS3Client or BucketRegionCache
 *       If available
 *           Use SigV4
 *       Else If PresignedUrl
 *           Use SigV2
 *   If Signer Region is overriden
 *       Use SigV4
 *   If BucketRegionCache has a region
 *       Use SigV4
 * }
 *
 * If Signer is SigV2 signer
 *      Use SigV2
 */
protected Signer createSigner(final Request<?> request, final String bucketName, final String key) {
    // Instead of using request.getEndpoint() for this parameter, we use
    // endpoint which is because
    // in accelerate mode, the endpoint in request is regionless. We need
    // the client-wide endpoint
    // to fetch the region information and pick the correct signer.
    final URI uri = clientOptions.isAccelerateModeEnabled() ? endpoint : request.getEndpoint();
    // This method retrieves the signer based on the URI. Currently
    // S3's default signer is a SigV2 signer implemented in S3Signer
    final Signer signer = getSignerByURI(uri);
    if (!isSignerOverridden()) {
        if ((signer instanceof AWSS3V4Signer) && noExplicitRegionProvided(request)) {
            final String region = clientRegion == null ? bucketRegionCache.get(bucketName) : clientRegion;
            if (region != null) {
                // If cache contains the region for the bucket, create an endpoint for the region and
                // update the request with that endpoint.
                resolveRequestEndpoint(request, bucketName, key, RuntimeHttpUtils.toUri(RegionUtils.getRegion(region).getServiceEndpoint(S3_SERVICE_NAME), clientConfiguration));
                AWSS3V4Signer sigV4Signer = (AWSS3V4Signer) signer;
                setAWSS3V4SignerWithServiceNameAndRegion((AWSS3V4Signer) signer, region);
                return sigV4Signer;
            } else if (request.getOriginalRequest() instanceof GeneratePresignedUrlRequest) {
                return createSigV2Signer(request, bucketName, key);
            }
        }
        // use the signer override if provided, else see if you can get the
        // signer from bucketreqion cache.
        final String regionOverride = getSignerRegionOverride() == null ? (clientRegion == null ? bucketRegionCache.get(bucketName) : clientRegion) : getSignerRegionOverride();
        if (regionOverride != null) {
            AWSS3V4Signer sigV4Signer = new AWSS3V4Signer();
            setAWSS3V4SignerWithServiceNameAndRegion(sigV4Signer, regionOverride);
            return sigV4Signer;
        }
    }
    if (signer instanceof S3Signer) {
        // new one with the appropriate values for this request.
        return createSigV2Signer(request, bucketName, key);
    }
    return signer;
}
Also used : S3Signer(com.amazonaws.services.s3.internal.S3Signer) S3QueryStringSigner(com.amazonaws.services.s3.internal.S3QueryStringSigner) AWSS3V4Signer(com.amazonaws.services.s3.internal.AWSS3V4Signer) Signer(com.amazonaws.auth.Signer) S3Signer(com.amazonaws.services.s3.internal.S3Signer) AWSS3V4Signer(com.amazonaws.services.s3.internal.AWSS3V4Signer) URI(java.net.URI)

Aggregations

Signer (com.amazonaws.auth.Signer)15 AWSS3V4Signer (com.amazonaws.services.s3.internal.AWSS3V4Signer)6 URI (java.net.URI)5 RegionAwareSigner (com.amazonaws.auth.RegionAwareSigner)4 AWS4Signer (com.amazonaws.auth.AWS4Signer)3 AWSCredentials (com.amazonaws.auth.AWSCredentials)3 HttpMethodName (com.amazonaws.http.HttpMethodName)3 Test (org.junit.Test)3 AmazonClientException (com.amazonaws.AmazonClientException)2 AmazonWebServiceResponse (com.amazonaws.AmazonWebServiceResponse)2 AnonymousAWSCredentials (com.amazonaws.auth.AnonymousAWSCredentials)2 Presigner (com.amazonaws.auth.Presigner)2 Regions (com.amazonaws.regions.Regions)2 S3QueryStringSigner (com.amazonaws.services.s3.internal.S3QueryStringSigner)2 S3Signer (com.amazonaws.services.s3.internal.S3Signer)2 GetObjectRequest (com.amazonaws.services.s3.model.GetObjectRequest)2 AWSRequestMetrics (com.amazonaws.util.AWSRequestMetrics)2 Date (java.util.Date)2 HashMap (java.util.HashMap)2 LinkedHashMap (java.util.LinkedHashMap)2