locked
DeleteMessage Storage API REST returning 403 RRS feed

  • Question

  • Hi,

    I just code 4 methods for API REST, but the last I need is not working. This is deleting the message queue. I have this code:

    public static string DeleteMessage(String queueName, string account, byte[] key, string endpoint, string popreceipt,string messageid)
            {
                string requestMethod = "DELETE";
    
                String urlPath = String.Format("{0}/messages/{1}?popreceipt={2}", queueName,Uri.EscapeDataString(messageid),Uri.EscapeDataString(popreceipt));
    
                String storageServiceVersion = "2009-09-19";
                String dateInRfc1123Format = DateTime.UtcNow.ToString("R", CultureInfo.InvariantCulture);
                String canonicalizedHeaders = String.Format(
                      "x-ms-date:{0}\nx-ms-version:{1}",
                      dateInRfc1123Format,
                      storageServiceVersion);
                String canonicalizedResource = String.Format("/{0}/{1}", account, urlPath);
                //String canonicalizedResource = String.Format("/{0}/{1}\npopreceipt:{2}", account, urlPath, popreceipt);
                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, account, key);
    
                Uri uri = new Uri(endpoint + urlPath);
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
                request.Method = requestMethod;
                request.Headers.Add("x-ms-date", dateInRfc1123Format);
                request.Headers.Add("x-ms-version", storageServiceVersion);
                request.Headers.Add("Authorization", authorizationHeader);
                
                using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                {
                    Stream dataStream = response.GetResponseStream();
    
                    return response.StatusCode.ToString();
                    
                }
            }
    
            public static string GetMessage(String queueName,string account, byte[] key,string endpoint)
            {
                string requestMethod = "GET";
    
                String urlPath = String.Format("{0}/messages", queueName);
    
                String storageServiceVersion = "2009-09-19";
                String dateInRfc1123Format = DateTime.UtcNow.ToString("R", CultureInfo.InvariantCulture);
                String canonicalizedHeaders = String.Format(
                      "x-ms-date:{0}\nx-ms-version:{1}",
                      dateInRfc1123Format,
                      storageServiceVersion );
                String canonicalizedResource = String.Format("/{0}/{1}", account, urlPath);
                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,account,key);
    
                Uri uri = new Uri(endpoint + urlPath);
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
                request.Method = requestMethod;
                request.Headers.Add("x-ms-date", dateInRfc1123Format);
                request.Headers.Add("x-ms-version", storageServiceVersion );
                request.Headers.Add("Authorization", authorizationHeader);
                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();
    
                        return responseFromServer;
                    }
                }
            }

    GetMessage is just working and DeleteMessage is not working, the CreateAuthorithation Headers Code is :

            private static String CreateAuthorizationHeader(String canonicalizedString, string account, byte[] key)
            {
                String signature = string.Empty;
                using (HMACSHA256 hmacSha256 = new HMACSHA256(key))
                {
                    Byte[] dataToHmac = System.Text.Encoding.UTF8.GetBytes(canonicalizedString);
                    signature = Convert.ToBase64String(hmacSha256.ComputeHash(dataToHmac));
                }
    
                String authorizationHeader = String.Format(
                      CultureInfo.InvariantCulture,
                      "{0} {1}:{2}",
                      "SharedKey",
                      account,
                      signature);
    
                return authorizationHeader;
            }

    I pass the KEY using "Convert.FromBase64String(AccountSharedKey)", that works for GetMessage (and also another method for put message), but this is not working for DELETING THE MESSAGE.

    I see the API in MSDN and DELETE and GET message use the same parameters, except the parameters passed by the query string.

    Any idea?

    I´m really blocked, I don´t know what more I can do.

    Wednesday, November 21, 2012 11:17 PM

Answers

  • Hi,

    I post my test project with a test storage account, for if someone want to try:

    https://dl.dropbox.com/u/38063432/C%23.zip

    Thursday, November 22, 2012 4:16 AM

All replies

  • I see that the problem is in the Canonical Resource of my method:

    I read: http://msdn.microsoft.com/en-us/library/windowsazure/dd179428.aspx and I think that for my calling to delete:

    http://myaccount.queue.core.windows.net/myqueue/messages/messageid?popreceipt=string-value

    I must use the next cannonical resource:

    string.Format("/{0}/{1}/messages/messageid\npopreceipt:{2}", account, queueName, popreceipt);

    Thursday, November 22, 2012 2:58 AM
  • Hi,

    I post my test project with a test storage account, for if someone want to try:

    https://dl.dropbox.com/u/38063432/C%23.zip

    Thursday, November 22, 2012 4:16 AM
  • Finally I solved it with this canonicalizedResource: string canonicalizedResource = string.Format("/{0}/{1}/messages/{2}\npopreceipt:{3}", account, queueName, messageid, popreceipt);

    The upload project is working, maybe it would be usefull for anyone.

    Thursday, November 22, 2012 4:50 AM
  • Hi,

    Happy to hear that you have solved the issue. For any Azure issue, welcome to post in the forum. Thanks for sharing the solution.

    Thanks,


    Please mark the replies as answers if they help or unmark if not. If you have any feedback about my replies, please contact msdnmg@microsoft.com Microsoft One Code Framework

    Thursday, November 22, 2012 4:53 AM