protected HttpRequest sign()

in apis/s3/src/main/java/org/jclouds/s3/filters/Aws4SignerForAuthorizationHeader.java [70:168]


   protected HttpRequest sign(HttpRequest request) throws HttpException {
      checkNotNull(request, "request is not ready to sign");
      checkNotNull(request.getEndpoint(), "request is not ready to sign, request.endpoint not present.");

      Payload payload = request.getPayload();

      // get host & port from request endpoint.
      String host = request.getEndpoint().getHost();

      Date date = timestampProvider.get();
      String timestamp = timestampFormat.format(date);
      String datestamp = dateFormat.format(date);

      String service = serviceAndRegion.service();
      String region = serviceAndRegion.region(host);
      String credentialScope = Joiner.on('/').join(datestamp, region, service, "aws4_request");

      HttpRequest.Builder<?> requestBuilder = request.toBuilder() //
            .removeHeader(AUTHORIZATION) // remove Authorization
            .removeHeader(DATE); // remove date

      ImmutableMap.Builder<String, String> signedHeadersBuilder = ImmutableSortedMap.<String, String>naturalOrder();

      // Content Type
      // content-type is not a required signing param. However, examples use this, so we include it to ease testing.
      String contentType = getContentType(request);
      if (!Strings.isNullOrEmpty(contentType)) {
         requestBuilder.replaceHeader(HttpHeaders.CONTENT_TYPE, contentType);
         signedHeadersBuilder.put(HttpHeaders.CONTENT_TYPE.toLowerCase(), contentType);
      }

      // Content-Length for PUT or POST request http method
      String contentLength = getContentLength(request);
      if (!Strings.isNullOrEmpty(contentLength)) {
         requestBuilder.replaceHeader(HttpHeaders.CONTENT_LENGTH, contentLength);
         signedHeadersBuilder.put(HttpHeaders.CONTENT_LENGTH.toLowerCase(), contentLength);
      }

      // Content MD5
      String contentMD5 = request.getFirstHeaderOrNull(CONTENT_MD5);
      if (payload != null) {
         HashCode md5 = payload.getContentMetadata().getContentMD5AsHashCode();
         if (md5 != null) {
            contentMD5 = BaseEncoding.base64().encode(md5.asBytes());
         }
      }
      if (contentMD5 != null) {
         requestBuilder.replaceHeader(CONTENT_MD5, contentMD5);
         signedHeadersBuilder.put(CONTENT_MD5.toLowerCase(), contentMD5);
      }

      // host
      host = hostHeaderFor(request.getEndpoint());
      requestBuilder.replaceHeader(HttpHeaders.HOST, host);
      signedHeadersBuilder.put(HttpHeaders.HOST.toLowerCase(), host);

      // user-agent
      String userAgent = request.getFirstHeaderOrNull(HttpHeaders.USER_AGENT);
      if (userAgent != null) {
         signedHeadersBuilder.put(HttpHeaders.USER_AGENT.toLowerCase(), userAgent);
      }

      // all x-amz-* headers
      appendAmzHeaders(request, signedHeadersBuilder);

      // x-amz-security-token
      Credentials credentials = creds.get();
      if (credentials instanceof SessionCredentials) {
         String token = SessionCredentials.class.cast(credentials).getSessionToken();
         requestBuilder.replaceHeader(AMZ_SECURITY_TOKEN_HEADER, token);
         signedHeadersBuilder.put(AMZ_SECURITY_TOKEN_HEADER.toLowerCase(), token);
      }

      // x-amz-content-sha256
      String contentSha256 = getPayloadHash(request);
      requestBuilder.replaceHeader(AMZ_CONTENT_SHA256_HEADER, contentSha256);
      signedHeadersBuilder.put(AMZ_CONTENT_SHA256_HEADER.toLowerCase(), contentSha256);

      // put x-amz-date
      requestBuilder.replaceHeader(AMZ_DATE_HEADER, timestamp);
      signedHeadersBuilder.put(AMZ_DATE_HEADER.toLowerCase(), timestamp);

      ImmutableMap<String, String> signedHeaders = signedHeadersBuilder.build();

      String stringToSign = createStringToSign(request.getMethod(), request.getEndpoint(), signedHeaders, timestamp,
            credentialScope, contentSha256);
      signatureWire.getWireLog().debug("<< " + stringToSign);

      byte[] signatureKey = signatureKey(credentials.credential, datestamp, region, service);
      String signature = base16().lowerCase().encode(hmacSHA256(stringToSign, signatureKey));

      StringBuilder authorization = new StringBuilder(AMZ_ALGORITHM_HMAC_SHA256).append(" ");
      authorization.append("Credential=").append(Joiner.on("/").join(credentials.identity, credentialScope))
            .append(", ");
      authorization.append("SignedHeaders=").append(Joiner.on(";").join(signedHeaders.keySet()))
            .append(", ");
      authorization.append("Signature=").append(signature);
      return requestBuilder.replaceHeader(HttpHeaders.AUTHORIZATION, authorization.toString()).build();
   }