views:

205

answers:

2

Hi everyone

I am not sure how to send a request using ASP.Net to Amazon CloudFront to invalidate an object.

The details are here http://docs.amazonwebservices.com/AmazonCloudFront/latest/DeveloperGuide/index.html?Invalidation.html but I am not sure how to implement this in ASP.Net... can someone please help?

A: 

Got it working, here it is if anyone else finds it useful.

    public static void InvalidateContent(string distributionId, string fileName)
    {
        string httpDate = Helpers.GetHttpDate();

        ASCIIEncoding encoding = new ASCIIEncoding();
        string postData = @"<InvalidationBatch>" +
                            "   <Path>/" + fileName + "</Path>" +
                            "   <CallerReference>" + httpDate + "</CallerReference>" +
                            "</InvalidationBatch>";
        byte[] data = encoding.GetBytes(postData);

        // Prepare web request...
        HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create("https://cloudfront.amazonaws.com/2010-08-01/distribution/" + distributionId + "/invalidation");
        webRequest.Method = "POST";
        webRequest.ContentType = "text/xml";
        webRequest.Headers.Add("x-amz-date", httpDate);

        Encoding ae = new UTF8Encoding();
        HMACSHA1 signature = new HMACSHA1(ae.GetBytes(GlobalSettings.AWSSecretAccessKey.ToCharArray()));
        string b64 = Convert.ToBase64String(signature.ComputeHash(ae.GetBytes(webRequest.Headers["x-amz-date"].ToCharArray())));
        webRequest.Headers.Add(HttpRequestHeader.Authorization, "AWS" + " " + GlobalSettings.AWSAccessKeyId + ":" + b64);

        webRequest.ContentLength = data.Length;

        Stream newStream = webRequest.GetRequestStream();
        // Send the data.
        newStream.Write(data, 0, data.Length);
        newStream.Close();
    }

    /// <summary>
    /// Gets a proper HTTP date
    /// </summary>
    public static string GetHttpDate()
    {
        // Setting the Culture will ensure we get a proper HTTP Date.
        string date = System.DateTime.UtcNow.ToString("ddd, dd MMM yyyy HH:mm:ss ", System.Globalization.CultureInfo.InvariantCulture) + "GMT";
        return date;
    }
dimos
+1  A: 

Here's a python version of the above, if anyone finds it useful

from datetime import datetime
import urllib2, base64, hmac, hashlib

def getHTTPDate():
    return datetime.utcnow().strftime("%a, %d %b %Y %H:%M:%S UTC")

def submitInvalidationRequest(fileName,distributionId):
    url = "https://cloudfront.amazonaws.com/2010-08-01/distribution/" + distributionId + "/invalidation"
    httpDate = getHTTPDate();
    postData = "<InvalidationBatch>" +"<Path>/" + fileName + "</Path>" +"<CallerReference>" + httpDate + "</CallerReference>" +"</InvalidationBatch>";
    sig = hmac.new(AWSSecretAccessKey, unicode(httpDate), hashlib.sha1)

    headers = {"ContentType": "text/xml",
           "x-amz-date": httpDate,
           "Authorization":"AWS " + AWSAccessKeyId + ":" +  base64.b64encode( sig.digest() )}

    req = urllib2.Request(url,postData,headers)
    return urllib2.urlopen(req).read()
Alex Hofsteede
Thanks for that - good of you to put that up.