From 621e0adc85abaa414814569ffe7dd28334318dc3 Mon Sep 17 00:00:00 2001 From: Simon Urbanek Date: Thu, 28 May 2020 09:58:33 +1200 Subject: [PATCH] ensure x-amz-content-sha256 is part of the request (see #362) --- R/s3HTTP.R | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/R/s3HTTP.R b/R/s3HTTP.R index 6776c1d..503c64c 100644 --- a/R/s3HTTP.R +++ b/R/s3HTTP.R @@ -101,6 +101,7 @@ function(verb = "GET", # parse headers canonical_headers <- c(list(host = hostname, `x-amz-date` = d_timestamp), headers) + headers[["x-amz-date"]] <- d_timestamp # parse query arguments if (is.null(query) && !is.null(p$query)) { query <- p[["query"]] @@ -113,14 +114,24 @@ function(verb = "GET", if (isTRUE(verbose)) { message("Executing request without AWS credentials") } - headers[["x-amz-date"]] <- d_timestamp Sig <- list() - H <- do.call(httr::add_headers, headers) } else { # if authenticated, figure out the request signature - if (isTRUE(verbose)) { + if (isTRUE(verbose)) message("Executing request with AWS credentials") - } + + ## we need to augment canonical headers with + ## x-amz-content-sha256 since signature_v4_auth() doesn't do it + ## the following is what signature_v4_auth() does and it's terribly fragile! + ## We really need to convince them that using conditionals on file presence is really, really bad! + ## But for compatibility we keep it until fixed... + body_hash <- tolower(digest::digest(request_body, + file = is.character(request_body) && file.exists(request_body), + algo = "sha256", serialize = FALSE)) + + canonical_headers[["x-amz-content-sha256"]] <- + headers[["x-amz-content-sha256"]] <- body_hash + Sig <- aws.signature::signature_v4_auth( datetime = d_timestamp, region = region, @@ -135,14 +146,12 @@ function(verb = "GET", secret = secret, session_token = session_token, verbose = verbose) - headers[["x-amz-date"]] <- d_timestamp - headers[["x-amz-content-sha256"]] <- Sig$BodyHash if (!is.null(session_token) && session_token != "") { headers[["x-amz-security-token"]] <- session_token } headers[["Authorization"]] <- Sig[["SignatureHeader"]] - H <- do.call(httr::add_headers, headers) } + H <- do.call(httr::add_headers, headers) # execute request if (verb == "GET") {