SignUtils.cs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. /*
  2. * Copyright (C) Alibaba Cloud Computing
  3. * All rights reserved.
  4. *
  5. * 版权所有 (C)阿里云计算有限公司
  6. */
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Text;
  10. using Aliyun.OSS.Common.Communication;
  11. namespace Aliyun.OSS.Util
  12. {
  13. internal static class SignUtils
  14. {
  15. private class KeyComparer : IComparer<string>
  16. {
  17. public int Compare(string x, string y)
  18. {
  19. return String.Compare(x, y, StringComparison.Ordinal);
  20. }
  21. }
  22. private const string NewLineMarker = "\n";
  23. private static readonly IList<string> ParamtersToSign = new List<string> {
  24. "acl", "uploadId", "partNumber", "uploads", "cors", "logging",
  25. "website", "delete", "referer", "lifecycle", "security-token","append", "position",
  26. ResponseHeaderOverrides.ResponseCacheControl,
  27. ResponseHeaderOverrides.ResponseContentDisposition,
  28. ResponseHeaderOverrides.ResponseContentEncoding,
  29. ResponseHeaderOverrides.ResponseHeaderContentLanguage,
  30. ResponseHeaderOverrides.ResponseHeaderContentType,
  31. ResponseHeaderOverrides.ResponseHeaderExpires
  32. };
  33. public static string BuildCanonicalString(string method, string resourcePath,
  34. ServiceRequest request)
  35. {
  36. var canonicalString = new StringBuilder();
  37. canonicalString.Append(method).Append(NewLineMarker);
  38. var headers = request.Headers;
  39. IDictionary<string, string> headersToSign = new Dictionary<string, string>();
  40. if (headers != null)
  41. {
  42. foreach (var header in headers)
  43. {
  44. var lowerKey = header.Key.ToLowerInvariant();
  45. if (lowerKey == HttpHeaders.ContentType.ToLowerInvariant()
  46. || lowerKey == HttpHeaders.ContentMd5.ToLowerInvariant()
  47. || lowerKey == HttpHeaders.Date.ToLowerInvariant()
  48. || lowerKey.StartsWith(OssHeaders.OssPrefix))
  49. {
  50. headersToSign.Add(lowerKey, header.Value);
  51. }
  52. }
  53. }
  54. if (!headersToSign.ContainsKey(HttpHeaders.ContentType.ToLowerInvariant()))
  55. headersToSign.Add(HttpHeaders.ContentType.ToLowerInvariant(), "");
  56. if (!headersToSign.ContainsKey(HttpHeaders.ContentMd5.ToLowerInvariant()))
  57. headersToSign.Add(HttpHeaders.ContentMd5.ToLowerInvariant(), "");
  58. // Add params that start with "x-oss-"
  59. if (request.Parameters != null)
  60. {
  61. foreach (var p in request.Parameters)
  62. {
  63. if (p.Key.StartsWith(OssHeaders.OssPrefix))
  64. headersToSign.Add(p.Key.Trim(), p.Value.Trim());
  65. }
  66. }
  67. // Add all headers to sign into canonical string,
  68. // note that these headers should be ordered before adding.
  69. var sortedHeaders = new List<string>(headersToSign.Keys);
  70. sortedHeaders.Sort(new KeyComparer());
  71. foreach (var key in sortedHeaders)
  72. {
  73. var value = headersToSign[key];
  74. if (key.StartsWith(OssHeaders.OssPrefix))
  75. canonicalString.Append(key).Append(':').Append(value);
  76. else
  77. canonicalString.Append(value);
  78. canonicalString.Append(NewLineMarker);
  79. }
  80. // Add canonical resource
  81. canonicalString.Append(BuildCanonicalizedResource(resourcePath, request.Parameters));
  82. return canonicalString.ToString();
  83. }
  84. private static string BuildCanonicalizedResource(string resourcePath,
  85. IDictionary<string, string> parameters)
  86. {
  87. var canonicalizedResource = new StringBuilder();
  88. canonicalizedResource.Append(resourcePath);
  89. if (parameters != null)
  90. {
  91. var parameterNames = new List<string>(parameters.Keys);
  92. parameterNames.Sort();
  93. var separator = '?';
  94. foreach (var paramName in parameterNames)
  95. {
  96. if (!ParamtersToSign.Contains(paramName))
  97. continue;
  98. canonicalizedResource.Append(separator);
  99. canonicalizedResource.Append(paramName);
  100. var paramValue = parameters[paramName];
  101. if (!string.IsNullOrEmpty(paramValue))
  102. canonicalizedResource.Append("=").Append(paramValue);
  103. separator = '&';
  104. }
  105. }
  106. return canonicalizedResource.ToString();
  107. }
  108. }
  109. }