sdk/Domain/ObjectMetadata.cs (244 lines of code) (raw):
/*
* Copyright (C) Alibaba Cloud Computing
* All rights reserved.
*
*/
using System;
using System.Collections.Generic;
using System.Net;
using Aliyun.OSS.Util;
namespace Aliyun.OSS
{
/// <summary>
/// OSS object's metadata, which is the collection of 'key,value' pair.
/// <para>
/// It includes user's custom metadata, as well as standard HTTP headers such as Content-Length, ETag, etc.
/// </para>
/// </summary>
public class ObjectMetadata
{
private readonly IDictionary<string, string> _userMetadata =
new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
private readonly IDictionary<string, object> _metadata =
new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
/// <summary>
/// 256 bit ASE encryption algorithm.
/// </summary>
public const string Aes256ServerSideEncryption = "AES256";
/// <summary>
/// Gets the user's custom metadata.
/// </summary>
/// <remarks>
/// In OSS server side, it will add "x-oss-meta-" as the prefix for the keys of custom metadata.
/// However, here the key in UserMetadata should not include "x-oss-meta-".
/// And the key is case insensitive--in fact all the keys returned from server will be in lowercase anyway.
/// For example, for a key MyUserMeta, it will be myusermeta from the result of GetObjectMetadata().
/// </remarks>
public IDictionary<string, string> UserMetadata
{
get { return _userMetadata; }
}
/// <summary>
/// Gets HTTP standard headers and their values.
/// </summary>
public IDictionary<string, object> HttpMetadata
{
get { return _metadata; }
}
/// <summary>
/// Gets or sets the last modified timestamp of the OSS object.
/// </summary>
public DateTime LastModified
{
get
{
return _metadata.ContainsKey(HttpHeaders.LastModified)
? (DateTime)_metadata[HttpHeaders.LastModified] : DateTime.MinValue;
}
internal set
{
_metadata[HttpHeaders.LastModified] = value;
}
}
/// <summary>
/// Gets or sets the expiration time of the object.
/// </summary>
public DateTime ExpirationTime
{
get
{
return _metadata.ContainsKey(HttpHeaders.Expires)
? DateUtils.ParseRfc822Date((string)_metadata[HttpHeaders.Expires]) : DateTime.MinValue;
}
set
{
_metadata[HttpHeaders.Expires] = DateUtils.FormatRfc822Date(value);
}
}
/// <summary>
/// Gets or sets the content length of the object.
/// </summary>
public long ContentLength
{
get
{
return _metadata.ContainsKey(HttpHeaders.ContentLength)
? (long)_metadata[HttpHeaders.ContentLength] : 0;
}
set
{
_metadata[HttpHeaders.ContentLength] = value;
}
}
/// <summary>
/// Gets or sets the content type of the objeft. It's the standard MIME type.
/// </summary>
public string ContentType
{
get
{
return _metadata.ContainsKey(HttpHeaders.ContentType)
? _metadata[HttpHeaders.ContentType] as string : null;
}
set
{
if (!string.IsNullOrEmpty(value))
{
_metadata[HttpHeaders.ContentType] = value;
}
}
}
/// <summary>
/// Gets or sets the content encoding of the object.
/// </summary>
public string ContentEncoding
{
get
{
return _metadata.ContainsKey(HttpHeaders.ContentEncoding)
? _metadata[HttpHeaders.ContentEncoding] as string : null;
}
set
{
if (value != null)
{
_metadata[HttpHeaders.ContentEncoding] = value;
}
}
}
/// <summary>
/// Gets or sets the value of HTTP Cache-Control header.
/// </summary>
public string CacheControl
{
get
{
return _metadata.ContainsKey(HttpHeaders.CacheControl)
? _metadata[HttpHeaders.CacheControl] as string : null;
}
set
{
if (value != null)
{
_metadata[HttpHeaders.CacheControl] = value;
}
}
}
/// <summary>
/// Gets or sets the value of HTTP Content-Disposition header.
/// </summary>
public string ContentDisposition
{
get
{
return _metadata.ContainsKey(HttpHeaders.ContentDisposition)
? _metadata[HttpHeaders.ContentDisposition] as string : null;
}
set
{
if (value != null)
{
_metadata[HttpHeaders.ContentDisposition] = value;
}
}
}
/// <summary>
/// Gets or sets the value of HTTP ETag header. Note that this is set by OSS server.
/// To set the Content-MD5 value, use HTTP COntent-MD5 header instead.
/// </summary>
public string ETag
{
get
{
return _metadata.ContainsKey(HttpHeaders.ETag)
? _metadata[HttpHeaders.ETag] as string : null;
}
set
{
if (value != null)
{
_metadata[HttpHeaders.ETag] = value;
}
}
}
/// <summary>
/// Gets or sets the HTTP Content-MD5 header, which is the MD5 summary in Hex string of the object.
/// </summary>
public string ContentMd5
{
get
{
return _metadata.ContainsKey(HttpHeaders.ContentMd5)
? _metadata[HttpHeaders.ContentMd5] as string : null;
}
set
{
if (value != null)
{
_metadata[HttpHeaders.ContentMd5] = value;
}
}
}
/// <summary>
/// Gets or sets the crc64.
/// </summary>
/// <value>The crc64.</value>
public string Crc64
{
get{
return _metadata.ContainsKey(HttpHeaders.HashCrc64Ecma)
? _metadata[HttpHeaders.HashCrc64Ecma] as string : null;
}
set
{
if (value != null)
{
_metadata[HttpHeaders.HashCrc64Ecma] = value;
}
}
}
/// <summary>
/// Gets or sets the server side encryption algorithm. Only AES256 is support for now.
/// </summary>
public string ServerSideEncryption
{
get
{
return _metadata.ContainsKey(HttpHeaders.ServerSideEncryption)
? _metadata[HttpHeaders.ServerSideEncryption] as string : null;
}
set
{
if (Aes256ServerSideEncryption != value)
throw new ArgumentException("Unsupported server side encryption");
_metadata[HttpHeaders.ServerSideEncryption] = value;
}
}
/// <summary>
/// Gets the object type (Normal or Appendable)
/// </summary>
public string ObjectType
{
get
{
return _metadata.ContainsKey(HttpHeaders.ObjectType)
? _metadata[HttpHeaders.ObjectType] as string : null;
}
}
/// <summary>
/// Gets the object version id
/// </summary>
public string VersionId
{
get
{
return _metadata.ContainsKey(HttpHeaders.VersionId)
? _metadata[HttpHeaders.VersionId] as string : null;
}
}
/// <summary>
/// Creates a new instance of <see cref="ObjectMetadata" />.
/// </summary>
public ObjectMetadata()
{
ContentLength = -1L;
}
/// <summary>
/// Adds one HTTP header and its value.
/// </summary>
/// <param name="key">header name</param>
/// <param name="value">header value</param>
public void AddHeader(string key, object value)
{
_metadata.Add(key, value);
}
/// <summary>
/// Populates the request header dictionary with the metdata and user metadata.
/// </summary>
/// <param name="requestHeaders"></param>
internal void Populate(IDictionary<string, string> requestHeaders)
{
foreach(var entry in _metadata)
requestHeaders.Add(entry.Key, entry.Value.ToString());
if (!requestHeaders.ContainsKey(HttpHeaders.ContentType))
requestHeaders.Add(HttpHeaders.ContentType, HttpUtils.DefaultContentType);
foreach(var entry in _userMetadata)
requestHeaders.Add(OssHeaders.OssUserMetaPrefix + entry.Key, entry.Value);
}
/// <summary>
/// Populates the request header dictionary with the metdata and user metadata.
/// </summary>
/// <param name="webRequest"></param>
internal void Populate(HttpWebRequest webRequest)
{
foreach (var entry in _metadata)
{
if (entry.Key.Equals(HttpHeaders.ContentLength) )
{
if (ContentLength > 0)
{
webRequest.ContentLength = ContentLength;
}
}
else if (entry.Key.Equals(HttpHeaders.ContentType))
{
webRequest.ContentType = ContentType;
}
else
{
webRequest.Headers.Add(entry.Key, entry.Value.ToString());
}
}
foreach (var entry in _userMetadata)
{
webRequest.Headers.Add(OssHeaders.OssUserMetaPrefix + entry.Key, entry.Value);
}
}
/// <summary>
/// Get the flag which indicates if the metadata specifies the callback.
/// </summary>
/// <param name="metadata">The metadata object to check</param>
/// <returns></returns>
internal static bool HasCallbackHeader(ObjectMetadata metadata)
{
if (metadata != null && metadata.HttpMetadata.ContainsKey(HttpHeaders.Callback))
{
return true;
}
return false;
}
}
}