none
Error 400 The value for one of the HTTP headers is not in the correct format

    Question

  • I've been trying to use the rest-based API to list the containers in my Azure storage account.

    But I get this error

    ------------------------------------------------------------------------------

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

    Content-Length: 328

    Content-Type: application/xml

    Server: Microsoft-HTTPAPI/2.0

    x-ms-request-id: c66d53c7-0001-0068-2b8e-14f711000000

    Date: Thu, 22 Sep 2016 05:00:45 GMT

     

    <?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:c66d53c7-0001-0068-2b8e-14f711000000

    Time:2016-09-22T05:00:46.5806561Z</Message><HeaderName>x-ms-version</HeaderName><HeaderValue>2009-09-19</HeaderValue></Error>

    ------------------------------------------------------------------------------

    I have tried a number of different versions for x-ms-version with the same result. Any hints would be much appreciated,

    using System;
    using System.Collections.Generic;
    using System.Collections;
    using System.Collections.Specialized;
    using System.Linq;
    using System.Text;
    using System.IO;
    using System.Net;
    using System.Web;
    using System.Xml;
    using System.Xml.Linq;
    using System.Globalization;
    using System.Security.Cryptography;
    
    namespace StorageSampleREST
    {
        public class Program
        {
            // Specify your storage project credentials here.
            // NOTE: Best practice is not to embed credentials in code or leave in the clear.
            const string StorageAccount = "brunoblog";
            const string StorageKey = "2wTvOtN5ZLZI83DrywcLEbvl43Agt1aaG73IE5Df5WEi/dqZQU0PsJ0TP1bB8nRcUYUXT573ACs0Dl6h4qrwvg==";
            const string BlobEndPoint = "http://brunoblog.blob.core.windows.net/";
    
            static void Main(string[] args)
            {
                 GetBlobs();
    
                 Console.WriteLine("\nPress <Enter> to end");
                 Console.Read();
            }
    
            // Perform blob storage operations.
            private static void GetBlobs()
            {
                string requestMethod = "GET";
                String urlPath = "comp=list";
                String urlPathResource = "comp:list";
                //String msVersion = "2012-02-12";
                String msVersion = "2009-09-19";
                //String msVersion = "2015-11-12";
                String dateInRfc1123Format = DateTime.UtcNow.ToString("R", CultureInfo.InvariantCulture);
                String canonicalizedHeaders = String.Format("x-ms-date:{0}\nx-ms-version:{1}", dateInRfc1123Format, msVersion);
                String canonicalizedResource = String.Format("/{0}/\n{1}", StorageAccount, urlPathResource);
                String stringToSign = String.Format("{0}\n\n\n\n\n\n\n\n\n\n\n\n{1}\n{2}", requestMethod, canonicalizedHeaders, canonicalizedResource);
                String authorizationHeader = CreateAuthorizationHeader(stringToSign);
    
                //Uri uri = new Uri(AzureStorageConstants.BlobEndPoint + "?" + urlPath);
                Uri uri = new Uri(BlobEndPoint + "?" + urlPath);
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
                request.Method = requestMethod;
                request.Headers.Add("x-ms-date", dateInRfc1123Format);
                request.Headers.Add("x-ms-version", msVersion);
                request.Headers.Add("Authorization", authorizationHeader);
                request.Headers.Add("Accept-Charset", "UTF-8");
                request.Accept = "application/atom+xml,application/xml";
    
                using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                {
                    Stream dataStream = response.GetResponseStream();
                    using (StreamReader reader = new StreamReader(dataStream))
                    {
                        String responseFromServer = reader.ReadToEnd();
                    }
                }
            }
            private static String CreateAuthorizationHeader(String canonicalizedString)
            {
                if (String.IsNullOrEmpty(canonicalizedString))
                {
                    throw new ArgumentNullException("canonicalizedString");
                }
                //byte[] Key = System.Text.Encoding.UTF8.GetBytes(StorageKey);
                byte[] Key = Convert.FromBase64String(StorageKey);
    
                String signature = CreateHmacSignature(canonicalizedString, Key);
                String authorizationHeader = String.Format(CultureInfo.InvariantCulture, "{0} {1}:{2}", "SharedKey", StorageAccount, signature);
    
                return authorizationHeader;
            }
            private static String CreateHmacSignature(String unsignedString, Byte[] key)
            {
                if (String.IsNullOrEmpty(unsignedString))
                {
                    throw new ArgumentNullException("unsignedString");
                }
    
                if (key == null)
                {
                    throw new ArgumentNullException("key");
                }
    
                Byte[] dataToHmac = System.Text.Encoding.UTF8.GetBytes(unsignedString);
                //Byte[] dataToHmac = Convert.FromBase64String(unsignedString); 
                using (HMACSHA256 hmacSha256 = new HMACSHA256(key))
                {
                    return Convert.ToBase64String(hmacSha256.ComputeHash(dataToHmac));
                }
            }
        }
    }
    
    


    Bruno Terkaly

    Thursday, September 22, 2016 5:12 AM

All replies

  • With some help from my friend Neil MacKenzie, the following code works, which may be of help to others.

            public static String CreateAuthorizationHeader2(String canonicalizedString)
            {
                String signature = String.Empty;
                using (HMACSHA256 hmacSha256 = new HMACSHA256(Convert.FromBase64String(StorageKey)))
                {
                    Byte[] dataToHmac = System.Text.Encoding.UTF8.GetBytes(canonicalizedString);
    
                    signature = Convert.ToBase64String(hmacSha256.ComputeHash(dataToHmac));
                }
    
                String authorizationHeader = String.Format(
                    CultureInfo.InvariantCulture,
                    "{0} {1}:{2}",
                    "SharedKey",
                     "brunoblog", 
                    signature);
                return authorizationHeader;
            }
            public static void PutBlob(String containerName, String blobName) 
            { 
                String requestMethod = "PUT"; 
     
                String urlPath = String.Format("{0}/{1}", containerName, blobName); 
     
                String storageServiceVersion = "2015-12-11"; 
     
                String dateInRfc1123Format = DateTime.UtcNow.ToString("R", CultureInfo.InvariantCulture); 
     
                String content = "Andrew Carnegie was born in Dunfermline"; 
                UTF8Encoding utf8Encoding = new UTF8Encoding(); 
                Byte[] blobContent = utf8Encoding.GetBytes(content); 
                Int32 blobLength = blobContent.Length; 
     
                const String blobType = "BlockBlob"; 
     
                String canonicalizedHeaders = String.Format( 
                        "x-ms-blob-type:{0}\nx-ms-date:{1}\nx-ms-version:{2}", 
                        blobType, 
                        dateInRfc1123Format, 
                        storageServiceVersion); 
                String canonicalizedResource = String.Format("/{0}/{1}", StorageAccount, urlPath); 
                String stringToSign = String.Format( 
                        "{0}\n\n\n{1}\n\n\n\n\n\n\n\n\n{2}\n{3}", 
                        requestMethod, 
                        blobLength, 
                        canonicalizedHeaders, 
                        canonicalizedResource); 
                String authorizationHeader = CreateAuthorizationHeader2(stringToSign);
    
                String blobEndPoint = String.Format("http://{0}.{1}/", StorageAccount, blobServiceEndpoint);
                Uri uri = new Uri(blobEndPoint + urlPath); 
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri); 
                request.Method = requestMethod; 
                request.Headers.Add("x-ms-blob-type", blobType); 
                request.Headers.Add("x-ms-date", dateInRfc1123Format); 
                request.Headers.Add("x-ms-version", storageServiceVersion); 
                request.Headers.Add("Authorization", authorizationHeader); 
                request.ContentLength = blobLength; 
     
                using (Stream requestStream = request.GetRequestStream()) 
                { 
                    requestStream.Write(blobContent, 0, blobLength); 
                } 
     
                using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) 
                { 
                    String ETag = response.Headers["ETag"]; 
                } 
            }
    


    Bruno Terkaly

    Thursday, September 22, 2016 5:28 AM
  • Just tried running source code above as is for one of my storage account (ARM) containing multiple containers and it worked as expected, returned list of containers in the storage account. Make sure if you are using correct storage account name and access key.

    Bhushan | Blog | LinkedIn | Twitter


    Thursday, September 22, 2016 5:48 AM