GetObjectRequest.cs 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  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.Globalization;
  10. using System.Text;
  11. using Aliyun.OSS.Util;
  12. namespace Aliyun.OSS
  13. {
  14. /// <summary>
  15. /// 指定从OSS下载Object的请求参数。
  16. /// </summary>
  17. public class GetObjectRequest
  18. {
  19. private readonly IList<string> _matchingETagConstraints = new List<string>();
  20. private readonly IList<string> _nonmatchingEtagConstraints = new List<string>();
  21. private readonly ResponseHeaderOverrides _responseHeaders = new ResponseHeaderOverrides();
  22. /// <summary>
  23. /// 获取或设置<see cref="Bucket" />的名称。
  24. /// </summary>
  25. public string BucketName { get; private set; }
  26. /// <summary>
  27. /// 获取或设置要下载<see cref="OssObject" />的Key。
  28. /// </summary>
  29. public string Key { get; private set; }
  30. /// <summary>
  31. /// 获取表示请求应当返回<see cref="OssObject" />内容的字节范围。
  32. /// </summary>
  33. /// <remarks>
  34. /// 调用<see cref="SetRange" />方法进行设置,如果没有设置,则返回null。
  35. /// </remarks>
  36. public long[] Range { get; private set; }
  37. /// <summary>
  38. /// 获取或设置“If-Unmodified-Since”参数。
  39. /// </summary>
  40. /// <remarks>
  41. /// 该参数表示:如果传入参数中的时间等于或者晚于文件实际修改时间,则传送文件;
  42. /// 如果早于实际修改时间,则返回错误。
  43. /// </remarks>
  44. public DateTime? UnmodifiedSinceConstraint { get; set; }
  45. /// <summary>
  46. /// 获取或设置“If-Modified-Since”参数。
  47. /// </summary>
  48. /// <remarks>
  49. /// 该参数表示:如果指定的时间早于实际修改时间,则正常传送文件,并返回 200 OK;
  50. /// 如果参数中的时间和实际修改时间一样或者更晚,会返回错误。
  51. /// </remarks>
  52. public DateTime? ModifiedSinceConstraint { get; set; }
  53. /// <summary>
  54. /// 获取一个列表表示:如果传入期望的ETag和<see cref="OssObject" />的ETag匹配,则正常的发送文件。
  55. /// 如果不符合,返回错误。
  56. /// 对应“If-Match”参数,
  57. /// </summary>
  58. public IList<string> MatchingETagConstraints
  59. {
  60. get { return _matchingETagConstraints; }
  61. }
  62. /// <summary>
  63. /// 获取一个列表表示:如果传入期望的ETag和<see cref="OssObject" />的ETag不匹配,则正常的发送文件。
  64. /// 如果符合,返回错误。
  65. /// 对应“If-None-Match”参数,
  66. /// </summary>
  67. public IList<string> NonmatchingETagConstraints
  68. {
  69. get { return _nonmatchingEtagConstraints; }
  70. }
  71. /// <summary>
  72. /// 获取的返回请求头重载<see cref="ResponseHeaderOverrides" />实例。
  73. /// </summary>
  74. public ResponseHeaderOverrides ResponseHeaders
  75. {
  76. get { return _responseHeaders; }
  77. }
  78. /// <summary>
  79. /// 构造一个新的<see cref="GetObjectRequest" />实例。
  80. /// </summary>
  81. /// <param name="bucketName"><see cref="OssObject" />所在<see cref="Bucket" />的名称。</param>
  82. /// <param name="key"><see cref="OssObject" />的<see cref="P:OssObject.Key" />。</param>
  83. public GetObjectRequest(string bucketName, string key)
  84. {
  85. BucketName = bucketName;
  86. Key = key;
  87. }
  88. /// <summary>
  89. /// 设置一个值表示请求应当返回Object内容的字节范围(可选)。
  90. /// </summary>
  91. /// <param name="start">
  92. /// 范围的起始值。
  93. /// <para>
  94. /// 当值大于或等于0时,表示起始的字节位置。
  95. /// 当值为-1时,表示不设置起始的字节位置,此时end参数不能-1,
  96. /// 例如end为100,Range请求头的值为bytes=-100,表示获取最后100个字节。
  97. /// </para>
  98. /// </param>
  99. /// <param name="end">
  100. /// 范围的结束值,应当小于内容的字节数。(最大为内容的字节数-1)
  101. /// <para>
  102. /// 当值小于或等于0时,表示结束的字节位或最后的字节数。
  103. /// 当值为-1时,表示不设置结束的字节位置,此时start参数不能为-1,
  104. /// 例如start为99,Range请求头的值为bytes=99-,表示获取第100个字节及
  105. /// 以后的所有内容。
  106. /// </para>
  107. /// </param>
  108. public void SetRange(long start, long end)
  109. {
  110. Range = new[] { start, end };
  111. }
  112. /// <summary>
  113. /// 添加Header值
  114. /// </summary>
  115. /// <param name="headers">添加完Header之后的最终Header</param>
  116. internal void Populate(IDictionary<string, string> headers)
  117. {
  118. if (Range != null && (Range[0] >= 0 || Range[1] >= 0))
  119. {
  120. var rangeHeaderValue = new StringBuilder();
  121. rangeHeaderValue.Append("bytes=");
  122. if (Range[0] >= 0)
  123. rangeHeaderValue.Append(Range[0].ToString(CultureInfo.InvariantCulture));
  124. rangeHeaderValue.Append("-");
  125. if (Range[1] >= 0)
  126. rangeHeaderValue.Append(Range[1].ToString(CultureInfo.InvariantCulture));
  127. headers.Add(HttpHeaders.Range, rangeHeaderValue.ToString());
  128. }
  129. if (ModifiedSinceConstraint != null)
  130. {
  131. headers.Add(OssHeaders.GetObjectIfModifiedSince,
  132. DateUtils.FormatRfc822Date(ModifiedSinceConstraint.Value));
  133. }
  134. if (UnmodifiedSinceConstraint != null)
  135. {
  136. headers.Add(OssHeaders.GetObjectIfUnmodifiedSince,
  137. DateUtils.FormatRfc822Date(UnmodifiedSinceConstraint.Value));
  138. }
  139. if (_matchingETagConstraints.Count > 0)
  140. {
  141. headers.Add(OssHeaders.GetObjectIfMatch,
  142. OssUtils.JoinETag(_matchingETagConstraints));
  143. }
  144. if (_nonmatchingEtagConstraints.Count > 0)
  145. {
  146. headers.Add(OssHeaders.GetObjectIfNoneMatch,
  147. OssUtils.JoinETag(_nonmatchingEtagConstraints));
  148. }
  149. }
  150. }
  151. }