While working on the MrFlick sample code above, and to get it working, I had to change a few things.
The date string must be set in English, for example:
lct <- Sys.getlocale("LC_TIME") Sys.setlocale("LC_TIME", "us") requestdate <- format(Sys.time(),"%a, %d %b %Y %H:%M:%S %Z", tz="GMT") Sys.setlocale("LC_TIME", lct)
"signaturestring" must be formed with \ n between the parameters:
signaturestring <- paste0("GET", paste(rep("\n", 12), collapse=""), "x-ms-date:", requestdate, "\nx-ms-version:2009-09-19\n/preconstuff/pings\ncomp:list\nrestype:container")
EDIT: The following procedure works for me. Based on the example of Stef Locke.
library(httr) library(RCurl) azureBlobCall <- function(url, verb, key, requestBody=NULL, headers=NULL, ifMatch="", md5="") { urlcomponents <- httr::parse_url(url) account <- gsub(".blob.core.windows.net", "", urlcomponents$hostname, fixed = TRUE) container <- urlcomponents$path # get timestamp in us locale lct <- Sys.getlocale("LC_TIME"); Sys.setlocale("LC_TIME", "us") `x-ms-date` <- format(Sys.time(),"%a, %d %b %Y %H:%M:%S %Z", tz="GMT") Sys.setlocale("LC_TIME", lct) # if requestBody exist get content length in bytes and content type `Content-Length` <- ""; `Content-Type` <- "" if(!is.null(requestBody)) { if(class(requestBody) == "form_file") { `Content-Length` <- (file.info(requestBody$path))$size `Content-Type` <- requestBody$type } else { requestBody <- enc2utf8(as.character(requestBody)) `Content-Length` <- nchar(requestBody, "bytes") `Content-Type` <- "text/plain; charset=UTF-8" } } # combine timestamp and version headers with any input headers, order and create the CanonicalizedHeaders headers <- setNames(c(`x-ms-date`, "2015-04-05", unlist(headers)), c("x-ms-date", "x-ms-version", unclass(names(unlist(headers))))) headers <- headers[order(names(headers))] CanonicalizedHeaders <- paste(names(headers), headers, sep=":", collapse = "\n") # create CanonicalizedResource headers and add any queries to it if(!is.null(urlcomponents$query)) { components <- setNames(unlist(urlcomponents$query), unclass(names(unlist(urlcomponents$query)))) componentstring <- paste0("\n", paste(names(components[order(names(components))]), components[order(names(components))], sep=":", collapse = "\n")) } else componentstring <- "" CanonicalizedResource <- paste0("/",account,"/",container, componentstring) # create the authorizationtoken signaturestring <- paste0(verb, "\n\n\n", `Content-Length`, "\n", md5, "\n", `Content-Type`, "\n\n\n", ifMatch, "\n\n\n\n", CanonicalizedHeaders, "\n", CanonicalizedResource) requestspecificencodedkey <- RCurl::base64( digest::hmac(key=RCurl::base64Decode(key, mode="raw"), object=enc2utf8(signaturestring), algo= "sha256", raw=TRUE) ) authorizationtoken <- paste0("SharedKey ", account, ":", requestspecificencodedkey) # make the call headers_final <- add_headers(Authorization=authorizationtoken, headers, `Content-Type` = `Content-Type`) call <- httr::VERB(verb=verb, url=url, config=headers_final, body=requestBody, verbose()) print("signaturestring");print(signaturestring); print(headers_final); print(call) return(content(call)) } ## Tests. Replace 'key' and 'accountName' with yours key <- "YowThr***********RDw==" # Creates a container named 'test' azureBlobCall("https://accountName.blob.core.windows.net/test?restype=container", "PUT", key) # Creates a blob named 'blob' under container 'test' with the content of "Hej världen!" azureBlobCall("https://accountName.blob.core.windows.net/test/blob", "PUT", key, headers = c("x-ms-blob-type"="BlockBlob"), requestBody = "Hej världen!") #upload_file("blob.txt")) # List all blob in the container 'test' azureBlobCall("https://accountName.blob.core.windows.net/test?comp=list&restype=container", "GET", key) # deletes the blobl named 'blob' azureBlobCall("https://accountName.blob.core.windows.net/test/blob", "DELETE", key) # Creates a blob named 'blob' under container 'test' with and upload the file 'blob.txt' azureBlobCall("https://accountName.blob.core.windows.net/test/blob", "PUT", key, headers = c("x-ms-blob-type"="BlockBlob"), requestBody = upload_file("blob.txt")) # deletes the container named 'test' azureBlobCall("https://accountName.blob.core.windows.net/test?restype=container", "DELETE", key)