C#调用阿里云CDN API刷新缓存
使用CDN必须要解决CDN缓存的问题,要么在每次更新文件时生成不同的URL,要么在每次更新文件时刷新CDN缓存。我们在一个实际应用场景中用到了后者,所以需要调用阿里云CDN的API进行缓存刷新的操作。
刷新缓存本身的接口很简单,只需要给Action与ObjectPath这2个参数传值,比如:Action=RefreshObjectCaches&ObjectPath=test.com/test.jpg 。但是实际除了这2参数之外,还需要传递8个公共请求参数:Format, Version, Signature,SignatureMethod, SignatureNonce, SignatureVersion, AccessKeyId, Timestamp,其中的Signature(签名结果串)的值计算很复杂,而阿里云官网帮助文档中只有python的示例代码,而我们用的是C#,于是只能参考帮助文档与python示例自己动手(用的是C# 6.0)。
针对这8个公共请求参数,定义了一个CdnRequest类,这个类有8个属性对应这8个公共请求参数,并且根据文档中的要求进行赋值。
public class CdnRequest
{
public CdnResponseFormat Format { get; set; } = CdnResponseFormat.Json;
public string Version { get; } = "2014-11-11";
public string AccessKeyId { get; set; } = ConfigurationManager.AppSettings["AliyunAccessKeyId"];
public string Signature { get; set; }
public string SignatureMethod { get; } = "HMAC-SHA1";
public string TimeStamp { get; set; } = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ");
public string SignatureVersion { get; } = "1.0";
public string SignatureNonce { get; } = Guid.NewGuid().ToString();
}
接下来进行最复杂的工作,计算签名(Signature)。
由于签名时用到Http Method与AccessKeySecret,所以给CdnRequest增加2个属性。
private HttpMethod _httpMethod;
private string AccessKeySecret { get; set; } = ConfigurationManager.AppSettings["AccessKeySecret"];
签名是基于请求的URL中所有参数的名称与值,而且还要基于参数名对参数进行排序,所以我们需要增加一个Dictionary,并且将除Signature之外的7个公共参数添加到字典中。
private Dictionary<string, string> _parameters;
private void BuildParameters()
{
_parameters.Add(nameof(Format), Format.ToString().ToUpper());
_parameters.Add(nameof(Version), Version);
_parameters.Add(nameof(AccessKeyId), AccessKeyId);
_parameters.Add(nameof(SignatureVersion), SignatureVersion);
_parameters.Add(nameof(SignatureMethod), SignatureMethod);
_parameters.Add(nameof(SignatureNonce), SignatureNonce);
_parameters.Add(nameof(TimeStamp), TimeStamp);
}
接下来实现计算签名的方法,代码如下:
public void ComputeSignature()
{
BuildParameters();
var canonicalizedQueryString = string.Join("&",
_parameters.OrderBy(x => x.Key)
.Select(x => PercentEncode(x.Key) + "=" + PercentEncode(x.Value)));
var stringToSign = _httpMethod.ToString().ToUpper() + "&%2F&" + PercentEncode(canonicalizedQueryString);
var keyBytes = Encoding.UTF8.GetBytes(AccessKeySecret + "&");
var hmac = new HMACSHA1(keyBytes);
var hashBytes = hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign));
Signature = Convert.ToBase64String(hashBytes);
_parameters.Add(nameof(Signature), Signature);
}
在实现这部分代码时,遇到了一个坑,坑在PercentEncode()方法的实现中:
private string PercentEncode(string value)
{
return UpperCaseUrlEncode(value)
.Replace("+", "%20")
.Replace("*", "%2A")
.Replace("%7E", "~");
}
一开始用的不是UpperCaseUrlEncode,而是.NET类库中的HttpUtility.UrlEncode,结果调用API时总是报”IncompleteSignature“的错误。
后来才知道在Java中进行Url Encode时用于编码的字符是大写,而C#中是小写;阿里云CDN API服务端用的是Java,于是我们用C#编出的码,API服务端就不认。
再后来,在stackoverflow上找到了解决方法:
private static string UpperCaseUrlEncode(string s)
{
char[] temp = HttpUtility.UrlEncode(s).ToCharArray();
for (int i = 0; i < temp.Length - 2; i++)
{
if (temp[i] == '%')
{
temp[i + 1] = char.ToUpper(temp[i + 1]);
temp[i + 2] = char.ToUpper(temp[i + 2]);
}
}
return new string(temp);
}
到这里就万事俱备,只剩下生成完整的请求URL:
public string GetUrl()
{
ComputeSignature();
return CDN_SERVICE_BASE_ADDRESS + "?" +
string.Join("&", _parameters.Select(x => x.Key + "=" + HttpUtility.UrlEncode(x.Value)));
}
忘了一个地方,CdnRequest的构造函数:
public CdnRequest(HttpMethod httpMethod, Dictionary<string, string> parameters)
{
_httpMethod = httpMethod;
_parameters = parameters;
}
最后,测试CdnRequest是否可以正常工作,测试代码如下:
public async Task RefreshObjectCaches()
{
var parameters = new Dictionary<string, string>()
{
{ "Action", "RefreshObjectCaches" },
{ "ObjectPath", "http://images.cnblogs.com/logo.gif" }
};
var request = new CdnRequest(HttpMethod.Get, parameters);
var url = request.GetUrl();
using (var httpClient = new HttpClient())
{
var response = await httpClient.GetAsync(url);
response.EnsureSuccessStatusCode();
var content = await response.Content.ReadAsStringAsync();
Console.WriteLine(content);
}
}
运行后,控制台输出:
{"RefreshTaskId":"206155358","RequestId":"10F650BD-3527-4241-BB6D-D4D238AC88C7"}
这样的输出说明成功调用了阿里云CDN API刷新了缓存。
搞定!
C#调用阿里云CDN API刷新缓存的更多相关文章
- 通过AccessKey调用阿里云CDN接口刷新CDN资源案例
通过AccessKey远程调用阿里云CDN接口,快速实现自动化集成部署. CdnService.java package com.nfky.cdn; import com.aliyuncs.Defau ...
- python 调用阿里云服务器api创建服务器
首先安装阿里云SDK pip install aliyun-python-sdk-core pip install aliyun-python-sdk-ecs 可以配合jenkins传递参数 #!/u ...
- 突破!阿里云CDN实现毫秒级全网刷新
通常在某网站使用了CDN节点来实现内容分发加速后,当源站内容更新的时候,CDN刷新系统会通过提交刷新请求将CDN节点上的指定缓存内容强制过期.当用户访问的时候,CDN节点将回源获取最新内容返回给用户, ...
- Python 调用阿里云 API 收集 ECS 数据
#!/usr/bin/env python # coding: utf-8 # author: Wang XiaoQiang ''' 功能介绍: 1.调用阿里云API,收集所有区域 ECS 信息 2. ...
- 云计算之路-阿里云上:访问阿里云CDN上的图片,自动跳转到百度首页
昨天有用户向我们反馈一篇博文(一条语句导致CPU持续100%)中的部分图片不能显示,我们的图片访问用的是阿里云CDN,原以为是某个CDN节点不稳定的问题,但在排查时发现这些图片不能显示竟然是因为请求时 ...
- 阿里云CDN+OSS完成图片加速
我们使用React Native开发APP,在列表中显示图片时,列表框经常出现长时间的空白.经过稍微研究和参考其他人的经验,我们知道React Native的ListView以及后来改进版的FlatL ...
- 阿里云 CDN 业务基于边缘容器的云原生转型实践
导读:本文基于边缘容器的阿里云 CDN 云原生实践, 涵盖了边缘容器的背景和趋势,边缘托管集群 ACK Managed Edge K8s(文中简称“Edge@ACK”) 的能力.架构,以及基于边缘容器 ...
- 什么是阿里云CDN
阿里云内容分发网络(Content Delivery Network,简称CDN)是建立并覆盖在承载网之上,由分布在不同区域的边缘节点服务器群组成的分布式网络.阿里云CDN分担源站压力,避免网络拥塞, ...
- 使用Node.js调用阿里云短信的发送以及接收
为了使用Node.js调用阿里云短信服务,我自己写了个npm包, 目前实现了: 使用Node.js调用阿里云短信服务,发送短信: 使用Node.js调用阿里云短信服务以及MNS服务,接收用户上行短信 ...
随机推荐
- 生产者消费者模式--阻塞队列--LOCK,Condition--线程池
1.阻塞队列:http://www.cnblogs.com/dolphin0520/p/3932906.html 2.Condition 生产者消费者实现 :http://www.cnblogs.co ...
- Apache错误:[error] (OS 10038)在一个非套接字上尝试了一个操作
Apache错误:[error] (OS 10038)在一个非套接字上尝试了一个操作 博客分类: vb2005xu软件学习 OSApache防火墙PHPWindows 日志如下:[ ...
- iOS使用Safari调试UIWebView
1.设置Safari "Safari"->"偏好设置"->"高级",勾选"在菜单栏中显示开发菜单" 2.设置 ...
- smarty模板原理
smarty模板原理 模板主要是用来让前端和后端分离的,前台页面只是一个前台页面,后台页面用php代码写逻辑,写完逻辑拿到前台显示. 一.写法 一般需要以下:写3个页面: 1.显示页面aa.htm ...
- UNIX环境高级编程--10. 信号
第十章 信号 信号是软中断,提供了一种处理异步事件的方法.例如,终端用户键入终端键,会通过信号机制停止一个进程,或及早终止管道中的下一个程序. 每个信号都有一个名字,SIG开 ...
- 在Linux终端命令行下播放音乐的命令(Ubuntu)
现在的 Linux 桌面已经发展的很好了,在桌面下播放音乐操作起来也很简单.那么我们还记得在桌面不是那么好的时候我们是怎么播放音乐的么?哎,我是想不起来了,实在是太难了. 不过现在我们可以先安装一个小 ...
- 开发板通过UART向主机发送数据
/********************************* 代码功能:开发板通过UART向主机发送数据 使用函数: Serial.begin(数据传输的波特率); Serial.printl ...
- centos 下添加epel源
来源于http://www.centoscn.com/CentOS/config/2014/0920/3793.html,收录备用 0.安装yum优先级插件 yum install yum-prior ...
- Selenium2+python自动化14-iframe
前言 有很多小伙伴在拿163作为登录案例的时候,发现不管怎么定位都无法定位到,到底是什么鬼呢,本篇详细介绍iframe相关的切换 以http://mail.163.com/登录页面10为案例,详细介绍 ...
- python-->基础-->004-->迭代器
http://blog.chinaunix.net/uid-23500957-id-3990473.html http://www.cnblogs.com/vamei/archive/2012/07/ ...