CosRequest.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using COSXML.Common;
  5. using COSXML.Network;
  6. using COSXML.Log;
  7. using COSXML.Auth;
  8. using COSXML.Utils;
  9. namespace COSXML.Model
  10. {
  11. public abstract class CosRequest
  12. {
  13. private static string TAG = typeof(CosRequest).FullName;
  14. protected Request realRequest;
  15. /// <summary>
  16. /// isHttps = true, https 请求; isHttps = false, http 请求; default isHttps = false.
  17. /// </summary>
  18. protected bool? isHttps = null;
  19. /// <summary>
  20. /// cos api 请求对应的 http method.
  21. /// </summary>
  22. protected string method = CosRequestMethod.GET;
  23. /// <summary>
  24. /// http 请求url中 path 部分.
  25. /// </summary>
  26. protected string path;
  27. /// <summary>
  28. /// http 请求url中 query 部分.
  29. /// </summary>
  30. protected Dictionary<string, string> queryParameters = new Dictionary<string, string>();
  31. /// <summary>
  32. /// http 请求 header 部分.
  33. /// </summary>
  34. protected Dictionary<string, string> headers = new Dictionary<string, string>();
  35. /// <summary>
  36. /// cos 服务的 appid.
  37. /// </summary>
  38. protected string appid;
  39. /// <summary>
  40. /// cos 服务签名的签名源部分.
  41. /// </summary>
  42. protected CosXmlSignSourceProvider cosXmlSignSourceProvider = new CosXmlSignSourceProvider();
  43. /// <summary>
  44. /// needMD5 = true, 请求中带上 Content-Md5; needMd5 = false, 请求中不带 Content-Md5; defalut needMd5 = false.
  45. /// </summary>
  46. protected bool needMD5 = true;
  47. /// <summary>
  48. /// 请求预签名URL
  49. /// </summary>
  50. protected string requestUrlWithSign = null;
  51. public CosXmlConfig serviceConfig { get; set; }
  52. /// <summary>
  53. /// http or https for cos request.
  54. /// </summary>
  55. public bool? IsHttps
  56. {
  57. get
  58. {
  59. return isHttps;
  60. }
  61. set { isHttps = value; }
  62. }
  63. /// <summary>
  64. /// http method
  65. /// </summary>
  66. public string Method
  67. {
  68. get
  69. {
  70. return method;
  71. }
  72. set { this.method = value; }
  73. }
  74. /// <summary>
  75. /// path of http url.
  76. /// </summary>
  77. public string RequestPath
  78. {
  79. get
  80. {
  81. return path;
  82. }
  83. private set { }
  84. }
  85. /// <summary>
  86. /// query of http url.
  87. /// </summary>
  88. /// <returns></returns>
  89. public virtual Dictionary<string, string> GetRequestParamters()
  90. {
  91. return queryParameters;
  92. }
  93. /// <summary>
  94. /// http request header
  95. /// </summary>
  96. /// <returns></returns>
  97. public virtual Dictionary<string, string> GetRequestHeaders()
  98. {
  99. return headers;
  100. }
  101. /// <summary>
  102. /// add query parameter for cos request, and cover the current value if it exists with the key.
  103. /// </summary>
  104. /// <param name="key"></param>
  105. /// <param name="value"></param>
  106. public void SetQueryParameter(string key, string value)
  107. {
  108. SetQueryParameter(key, value, true);
  109. }
  110. /// <summary>
  111. /// url 部分都统一 url encode
  112. /// </summary>
  113. /// <param name="key"></param>
  114. /// <param name="value"></param>
  115. /// <param name="isNeedUrlEncode"></param>
  116. public void SetQueryParameter(string key, string value, bool isNeedUrlEncode)
  117. {
  118. try
  119. {
  120. if (value == null)
  121. {
  122. value = "";
  123. }
  124. if (isNeedUrlEncode)
  125. {
  126. value = URLEncodeUtils.Encode(value);
  127. }
  128. queryParameters.Add(key, value);
  129. }
  130. catch (ArgumentException)
  131. {
  132. // cover the current value
  133. // cover the current value
  134. queryParameters[key] = value;
  135. }
  136. }
  137. /// <summary>
  138. /// add header for cos request, and cover the current value, if it exists with the key.
  139. /// </summary>
  140. /// <param name="key"> header: key </param>
  141. /// <param name="value"> header: value</param>
  142. public void SetRequestHeader(string key, string value)
  143. {
  144. SetRequestHeader(key, value, false);
  145. }
  146. /// <summary>
  147. /// add headers for cos request, and cover the current value, if it exists with the key.
  148. /// </summary>
  149. /// <param name="headers"></param>
  150. public void SetRequestHeaders(Dictionary<string, string> headers)
  151. {
  152. foreach (KeyValuePair<string, string> entry in headers)
  153. {
  154. SetRequestHeader(entry.Key, entry.Value);
  155. }
  156. }
  157. /// <summary>
  158. /// header 默认不 encode
  159. /// </summary>
  160. /// <param name="key">不能为null 即不包含空格,即 位于(\u0020, \u007F),超过这个范围,urlencode</param>
  161. /// <param name="value">可以为null,为空,且位于(\u001f,\u007F) 和 '\t',超过这个范围,urlencode</param>
  162. /// <param name="isNeedUrlEncode"></param>
  163. public void SetRequestHeader(string key, string value, bool isNeedUrlEncode)
  164. {
  165. try
  166. {
  167. if (value == null)
  168. {
  169. value = "";
  170. }
  171. if (isNeedUrlEncode)
  172. {
  173. value = URLEncodeUtils.Encode(value);
  174. }
  175. headers.Add(key, value);
  176. }
  177. catch (ArgumentException)
  178. {
  179. // cover the current value
  180. // cover the current value
  181. headers[key] = value;
  182. }
  183. }
  184. /// <summary>
  185. /// set appid for cos.
  186. /// </summary>
  187. public string APPID
  188. {
  189. get
  190. {
  191. return this.appid;
  192. }
  193. set { this.appid = value; }
  194. }
  195. /// <summary>
  196. /// 是否带上content-md5
  197. /// </summary>
  198. public bool IsNeedMD5
  199. {
  200. get
  201. {
  202. return needMD5;
  203. }
  204. set { needMD5 = value; }
  205. }
  206. /// <summary>
  207. /// return the host for cos request
  208. /// </summary>
  209. /// <returns>host(string)</returns>
  210. public abstract string GetHost();
  211. /// <summary>
  212. /// return the body for cos request. such as upload file.
  213. /// </summary>
  214. /// <returns> <see href="COSXML.Network.RequestBody"/></returns>
  215. public abstract RequestBody GetRequestBody();
  216. /// <summary>
  217. /// 返回 xml 格式的 requestBody
  218. /// </summary>
  219. /// <param name="d"></param>
  220. /// <returns></returns>
  221. protected Network.RequestBody GetXmlRequestBody(object d)
  222. {
  223. string content = Transfer.XmlBuilder.Serialize(d);
  224. byte[] data = Encoding.UTF8.GetBytes(content);
  225. ByteRequestBody body = new ByteRequestBody(data);
  226. return body;
  227. }
  228. /// <summary>
  229. /// check parameter for cos.
  230. /// </summary>
  231. /// <exception cref="COSXML.CosException.CosClientException"></exception>
  232. public abstract void CheckParameters();
  233. /// <summary>
  234. /// 设置签名的有效期: [signStartTimeSecond, signStartTimeSecond + durationSecond]
  235. /// </summary>
  236. /// <param name="signStartTimeSecond"></param>
  237. /// <param name="durationSecond"></param>
  238. public virtual void SetSign(long signStartTimeSecond, long durationSecond)
  239. {
  240. cosXmlSignSourceProvider.SetSignTime(signStartTimeSecond, durationSecond);
  241. }
  242. /// <summary>
  243. /// 计算签名时,带上头部header 和查询参数 query验证.
  244. /// 设置签名的有效期: [signStartTimeSecond, signStartTimeSecond + durationSecond]
  245. /// </summary>
  246. /// <param name="signStartTimeSecond"></param>
  247. /// <param name="durationSecond"></param>
  248. /// <param name="headerKeys"></param>
  249. /// <param name="queryParameterKeys"></param>
  250. public virtual void SetSign(long signStartTimeSecond, long durationSecond, List<string> headerKeys, List<string> queryParameterKeys)
  251. {
  252. cosXmlSignSourceProvider.SetSignTime(signStartTimeSecond, durationSecond);
  253. cosXmlSignSourceProvider.AddHeaderKeys(headerKeys);
  254. cosXmlSignSourceProvider.AddParameterKeys(queryParameterKeys);
  255. }
  256. /// <summary>
  257. /// 直接设置签名串.
  258. /// </summary>
  259. /// <param name="sign"></param>
  260. public virtual void SetSign(string sign)
  261. {
  262. SetRequestHeader(CosRequestHeaderKey.AUTHORIZAIION, sign);
  263. }
  264. /// <summary>
  265. /// 返回签名数据源
  266. /// </summary>
  267. /// <returns></returns>
  268. public virtual CosXmlSignSourceProvider GetSignSourceProvider()
  269. {
  270. // 默认签署的头部跟参数
  271. cosXmlSignSourceProvider.AddHeaderKeys(new List<string>()
  272. {
  273. "cache-control",
  274. "content-disposition",
  275. "content-encoding",
  276. "content-length",
  277. "content-md5",
  278. "content-type",
  279. "expect",
  280. "expires",
  281. "host",
  282. "if-match",
  283. "if-modified-since",
  284. "if-none-match",
  285. "if-unmodified-since",
  286. "origin",
  287. "range",
  288. "response-cache-control",
  289. "response-content-disposition",
  290. "response-content-encoding",
  291. "response-content-language",
  292. "response-content-type",
  293. "response-expires",
  294. "transfer-encoding",
  295. "versionid"
  296. });
  297. foreach (KeyValuePair<string, string> pair in headers)
  298. {
  299. if (pair.Key.StartsWith("x-cos-"))
  300. {
  301. cosXmlSignSourceProvider.AddHeaderKey(pair.Key.ToLower());
  302. }
  303. }
  304. foreach (KeyValuePair<string, string> pair in queryParameters)
  305. {
  306. cosXmlSignSourceProvider.AddParameterKey(pair.Key.ToLower());
  307. }
  308. return cosXmlSignSourceProvider;
  309. }
  310. /// <summary>
  311. /// 设置预签名URL
  312. /// </summary>
  313. public string RequestURLWithSign
  314. {
  315. get
  316. {
  317. return requestUrlWithSign;
  318. }
  319. set { requestUrlWithSign = value; }
  320. }
  321. public void BindRequest(Request request)
  322. {
  323. this.realRequest = request;
  324. }
  325. public void Cancel()
  326. {
  327. if (realRequest != null)
  328. {
  329. realRequest.Cancel();
  330. }
  331. }
  332. }
  333. }