MikeF
MikeF

Reputation: 1008

Azure storage REST Api call - Invalid Header x-ms-version

Following the advice from this question, and the API documentation (e.g., Blob service REST API), I have an x-ms-version specified in the header. My code works against Azurite, and is authenticated by Azure, but returns a

HTTP/1.1 400 The value for one of the HTTP headers is not in the correct format.

The xml body has more details:

<Error>
    <Code>InvalidHeaderValue</Code>
    <Message>The value for one of the HTTP headers is not in the correct format.
RequestId:d39d2cad-301e-009e-1546-3940de000000
Time:2018-08-21T11:58:14.2369850Z</Message>
   <HeaderName>x-ms-version</HeaderName>
   <HeaderValue>2017-01-19</HeaderValue>
</Error>

My guess is it is not the format, but the value. How do I find the right value, or even a list of all possible values that I can try running one at a time, or does someone know that this is a misleading error, and I need to be looking somewhere else?

While playing with this a little more a x-ms-version=2015-02-21 generates.

HTTP/1.1 400 One of the request inputs is out of range.

Here is the request:

 -> GET /mike-ecu-test?restype=container&comp=list HTTP/1.1
 -> Host: mikeecutest.blob.core.windows.net
 -> User-Agent: libcurl/7.54.0 r-curl/3.1 httr/1.3.1
 -> Accept-Encoding: gzip, deflate
 -> Accept: application/json, text/xml, application/xml, */*
 -> Authorization: SharedKey mikeecutest/mike-ecu-test:9j5XodD9OIslzMnzHXiU7c76EpOXFi5jeQITbHk/Y8g=
 -> x-ms-date: Wed, 22 Aug 2018 01:35:06 GMT
 -> x-ms-version: 2018-03-28

Here is the r code that generates it, credit for the code is answer 4 to this question

library("httr")
azureout <- function(){
    url <- "http://mikeecutest.blob.core.windows.net/mike-ecu-test?restype=container&comp=list"
    sak <- "dfgwhsfhsfg.....hjdkfgs==" 

    requestdate<-format(Sys.time(),"%a, %d %b %Y %H:%M:%S %Z", tz="GMT")
    msapiversion<- "2018-03-28"
    signaturestring<-paste0("GET",paste(rep("\n",12),collapse=""),
                            "x-ms-date:",requestdate,
                            "x-ms-version:",msapiversion,"\n",
                            "mikeecutest", "\n",
                            "comp:list","\n",
                            "restype:container")

    headerstuff<-add_headers(Authorization=paste0("SharedKey mikeecutest/mike-ecu-test:",
                                                  RCurl::base64(digest::hmac(key=RCurl::base64Decode(sak, mode="raw"),
                                                                             object=enc2utf8(signaturestring),
                                                                             algo= "sha256", raw=TRUE))),
                             `x-ms-date`=requestdate,
                             `x-ms-version`=msapiversion)

    content(GET(url,config = headerstuff, verbose() ))

}

Storage API version 2018-03-28 generates a:

 <- HTTP/1.1 400 One of the request inputs is out of range.

Storage API version 2018-02-01 generates a:

 <- HTTP/1.1 400 The value for one of the HTTP headers is not in the correct format.

Upvotes: 3

Views: 13402

Answers (2)

Jerry Liu
Jerry Liu

Reputation: 17790

You are right, 2017-01-19 is not a valid Storage service version, see all versions here. The documentation article Versioning for the Azure Storage services also suggests the latest API version at the top.

Recommend you to use the latest if there is no specific requirement.

Update

See three points to fix:

signaturestring<-paste0("GET",paste(rep("\n",12),collapse=""),
                            "x-ms-date:",requestdate,"\n",   # miss "\n"
                            "x-ms-version:",msapiversion,"\n",
                            "/mikeecutest/mike-ecu-test", "\n", # should be /accountname/containername
                            "comp:list","\n",
                            "restype:container")

headerstuff<-add_headers(Authorization=paste0("SharedKey mikeecutest:", # only need accountname here
                                                  RCurl::base64(digest::hmac(key=RCurl::base64Decode(sak, mode="raw"),
                                                                             object=enc2utf8(signaturestring),
                                                                             algo= "sha256", raw=TRUE))),
                             `x-ms-date`=requestdate,
                             `x-ms-version`=msapiversion)

Package of REST API is always preferred, you can have a try at that provided by @Hong.

Upvotes: 4

Hong Ooi
Hong Ooi

Reputation: 57686

Consider using my AzureStor package which is an interface to file and blob storage on Azure. It handles authentication, including both access key and SAS, and admin details like getting the API version right.

install.packages("AzureStor")
library(AzureStor)

bl <- blob_endpoint("http://mikeecutest.blob.core.windows.net",
                    key="your_key")

cont <- blob_container(bl, "mike-ecu-test")
list_blobs(cont)
upload_blob(cont, "srcfile", "destblob") # blocked upload is supported for blob storage
download_blob(cont, "srcblob", "destfile")

newcontainer <- create_blob_container(bl, "newcontainer")
delete_blob_container(newcontainer)

Upvotes: 3

Related Questions