Search code examples
azureazure-storageazure-blob-storageblobstorage

Azure blob storage: Unable to upload the blob with size 0


Our applicaiton has a requirement to upload the blob with size 0. We are using cURL to invoke Azure storage REST API. While uploading with size it failing with HTTP error code [400]

Following error message it returned


<?xml version="1.0" encoding="utf-8"?>
    <Error>  
           <Code>InvalidHeaderValue</Code>
           <Message>
                  The value for one of the HTTP headers 
                  is not in the correct format.
                  RequestId:2b1ec18b-0001-007d-7811-e40725000000
                  Time:2016-07-22T12:07:28.5435467Z
          </Message>
          <HeaderName>Content-Length</HeaderName>
          <HeaderValue>-1</HeaderValue>
          </Error>

Through wireshark, we ensured that, the value of content length header is sent appropriatly.

Following are the captured headers from wireshark


PUT /test/DC70439C-5004-11E6-B4B2-91D87435845D HTTP/1.1
Host: mytest.blob.core.windows.net
Accept: */*
Transfer-Encoding: chunked
x-ms-blob-type:BlockBlob
x-ms-version:2015-02-21
Content-Length:0
x-ms-date:Fri, 22 Jul 2016 12:07:28 GMT
Authorization:SharedKey   kanchan:HQQ7a47TPQtEhL0ek6rim64ZKC8NRubgKuq+4Os+Aoo=
Expect: 100-continue

Can you plese help to figure out why content-length header value has been set as -1?

Thanks and regards, Rahul Naik


Solution

  • I didn't reproduce your issue. The following is my tested code using cURL to upload file to Azure blob storage. It works on my side, and I can upload a file of size 0(set file content as ""). Hope this could give you some tips.

    storage_account="<account name>"
    container_name="<container name>"
    access_key="<account key>"
    content="<file content>"
    len=${#content}
    blobname="<blob name>"
    blob_store_url="blob.core.windows.net"
    authorization="SharedKey"
    request_method="PUT"
    request_date=$(TZ=GMT date "+%a, %d %h %Y %H:%M:%S %Z")
    storage_service_version="2011-08-18"
    # HTTP Request headers
    x_ms_date_h="x-ms-date:$request_date"
    x_ms_version_h="x-ms-version:$storage_service_version"
    # Build the signature string
    canonicalized_headers="x-ms-blob-type:BlockBlob\n${x_ms_date_h}\n${x_ms_version_h}"
    canonicalized_resource="/${storage_account}/${container_name}/${blobname}"
    string_to_sign="${request_method}\n\n\n${len}\n\napplication/x-www-form-urlencoded\n\n\n\n\n\n\n${canonicalized_headers}\n${canonicalized_resource}"
    # Decode the Base64 encoded access key, convert to Hex.
    decoded_hex_key="$(echo -n $access_key | base64 -d -w0 | xxd -p -c256)"
    signature=$(printf "$string_to_sign" | openssl dgst -sha256 -mac HMAC -macopt "hexkey:$decoded_hex_key" -binary |  base64 -w0)
    authorization_header="Authorization: $authorization $storage_account:$signature"
    
    
    curl \
      -X PUT \
      -H "$x_ms_date_h" \
      -H "$x_ms_version_h" \
      -H "Content-Type: application/x-www-form-urlencoded" \
      -H "$authorization_header" \
      -H "x-ms-blob-type:BlockBlob" \
      -d ${content} "https://${storage_account}.${blob_store_url}/${container_name}/${blobname}"