【问题标题】:Amazon CloudFront invalidation in ASP.NetASP.Net 中的 Amazon CloudFront 失效
【发布时间】:2011-04-07 15:53:31
【问题描述】:

我不确定如何使用 ASP.Net 向 Amazon CloudFront 发送请求以使对象无效。

详情在这里http://docs.amazonwebservices.com/AmazonCloudFront/latest/DeveloperGuide/index.html?Invalidation.html 但我不确定如何在 ASP.Net 中实现这一点...有人可以帮忙吗?

【问题讨论】:

    标签: asp.net amazon amazon-cloudfront


    【解决方案1】:

    从最新版本的适用于 .NET 的 AWS 开发工具包 (1.5.8.0) 开始,接受的答案不再有效。这应该可以解决问题:

    using Amazon;
    using Amazon.CloudFront.Model;
    

    ...

    var client = AWSClientFactory.CreateAmazonCloudFrontClient(accessKey, secretKey);
    client.CreateInvalidation(new CreateInvalidationRequest {
        DistributionId = distributionID,
        InvalidationBatch = new InvalidationBatch {
            Paths = new Paths {
                Quantity = arrayofpaths.Length,
                Items = arrayofpaths.ToList()
            },
            CallerReference = DateTime.Now.Ticks.ToString()
        }
    });
    

    【讨论】:

    • +1 可以让事情保持最新状态(很遗憾我的答案不再是了 ;-)
    【解决方案2】:

    得到它的工作,如果其他人觉得它有用,就在这里。

        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;
        }
    

    【讨论】:

    • 顺便给你同样的日期格式DateTime.UtcNow.ToString("R");
    【解决方案3】:

    这是上面的python版本,如果有人觉得有用的话

    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()
    

    【讨论】:

      【解决方案4】:

      使用AWSSDK .net api wrapper from amazon 使这项任务更加容易。

      using Amazon.CloudFront.Model;
      

      ...

      var client = Amazon.AWSClientFactory.CreateAmazonCloudFrontClient(ConfigurationManager.AppSettings["Aws.AccessKey"],
                                                                    ConfigurationManager.AppSettings["Aws.SecretKey"]);
      var request = new PostInvalidationRequest();
      request.DistributionId = ConfigurationManager.AppSettings["Cdn.DistributionId"];
      request.InvalidationBatch = new InvalidationBatch();
      request.InvalidationBatch.CallerReference = new Guid().ToString();
      request.InvalidationBatch.Paths = PathsInput.Text.Split(new[]{'\n','\r'},StringSplitOptions.RemoveEmptyEntries).ToList();
      var response = client.PostInvalidation(request);
      

      【讨论】:

      • 从适用于 .NET 的 AWS 开发工具包(版本 1.5.8.0)的最新更新开始,这似乎不再有效。我正在寻找替代品并将其发布在这里,除非有人能打败我。 :)
      【解决方案5】:

      这里是 perl:

      use warnings;
      use strict;
      use HTTP::Date;
      use Digest::SHA qw(hmac_sha1);
      use LWP::UserAgent;
      use MIME::Base64;
      use Encode qw(encode_utf8);
      
      @ARGV == 4 || die "usage: $0 url distribution_id accesskey secretkey\n";
      
      my $invalid_url = $ARGV[0];
      my $distribution_id = $ARGV[1];
      my $accesskey = $ARGV[2];
      my $secretkey = $ARGV[3];
      
      my $url = "https://cloudfront.amazonaws.com/2010-11-01/distribution/$distribution_id/invalidation";
      my $date = time2str;
      
      my $post_data = <<HERE;
      <?xml version="1.0" encoding="UTF-8"?>
      <InvalidationBatch>
        <Path>$invalid_url</Path>
        <CallerReference>$date</CallerReference>
      </InvalidationBatch>
      HERE
      
      my $sig = encode_base64(hmac_sha1(encode_utf8($date),encode_utf8($secretkey)));
      
      my $browser = LWP::UserAgent->new;
      my $res = $browser->post($url,
                               "Content" => $post_data,
                               "ContentType" => "text/xml",
                               "x-amz-date" => $date,
                               "Authorization" => "AWS $accesskey:$sig");
      
      print $res->status_line, "\n", $res->content;
      

      【讨论】:

      • 他没有要求 perl,是吗?
      • ^^ Rob:他也没有要求 Python(作者 Alex Hofsteede),是吗?
      猜你喜欢
      • 2017-09-20
      • 1970-01-01
      • 2012-09-28
      • 2016-02-08
      • 2015-05-17
      • 2018-11-17
      • 2021-01-19
      • 1970-01-01
      • 2017-01-26
      相关资源
      最近更新 更多