using System;
using System.Collections.Generic;
namespace Aliyun.OSS
{
///
/// 表示一条CORS规则。
///
public class CORSRule
{
private IList _allowedOrigins = new List();
private IList _allowedMethods = new List();
private IList _allowedHeaders = new List();
private IList _exposeHeaders = new List();
private Int32 _maxAgeSeconds;
///
/// 指定允许的跨域请求的来源,允许使用多个元素来指定多个允许的来源。
/// 允许使用最多一个*通配符。如果指定为“ *”则表示允许所有的来源的跨域请求。
///
public IList AllowedOrigins
{
get { return ((List) _allowedOrigins).AsReadOnly(); }
set
{
if (CountOfAsterisk(value) > 1)
throw new ArgumentException("At most one asterisk wildcard allowed.");
_allowedOrigins = value;
}
}
///
/// 指定允许的跨域请求方法(GET,PUT,DELETE,POST,HEAD)。
///
public IList AllowedMethods
{
get { return ((List)_allowedMethods).AsReadOnly(); }
set { _allowedMethods = value; }
}
///
/// 控制在 OPTIONS 预取指令中 Access-Control-Request-Headers 头中指定的 header
/// 是否允许。在 Access-Control-Request-Headers 中指定的每个 header 都必须在
/// AllowedHeader 中有一条对应的项。允许使用最多一个*通配符。
///
public IList AllowedHeaders
{
get { return ((List)_allowedHeaders).AsReadOnly(); }
set
{
if (CountOfAsterisk(value) > 1)
throw new ArgumentException("At most one asterisk wildcard allowed.");
_allowedHeaders = value;
}
}
///
/// 指定允许用户从应用程序中访问的响应头(例如一个 Javascript 的
/// XMLHttpRequest 对象。不允许使用 *通配符。
///
public IList ExposeHeaders
{
get { return ((List)_exposeHeaders).AsReadOnly(); }
set
{
if (CountOfAsterisk(value) > 0)
throw new ArgumentException("Asterisk wildcard not allowed.");
_exposeHeaders = value;
}
}
///
/// 指定浏览器对特定资源的预取( OPTIONS)请求返回结果的缓存时间,单位为秒,
/// 最大值不超过999999999,且一个 CORSRule 里面最多允许出现一个。
///
public Int32 MaxAgeSeconds
{
get { return _maxAgeSeconds; }
set
{
if (value < 0 || value > 999999999)
throw new ArgumentException("MaxAge should not less than 0 or greater than 999999999");
_maxAgeSeconds = value;
}
}
///
/// 添加一条AllowedOrigin。
///
/// 指定允许的跨域请求的来源,允许使用最多一个“*”通配符。
public void AddAllowedOrigin(String allowedOrigin)
{
if (allowedOrigin == null)
throw new ArgumentNullException("allowedOrigin");
var hasAsterisk = allowedOrigin.Contains("*");
if (hasAsterisk && CountOfAsterisk(_allowedOrigins) > 0)
throw new ArgumentException("At most one asterisk wildcard allowed.");
_allowedOrigins.Add(allowedOrigin);
}
///
/// 添加一条AllowedMethod。
///
/// 指定允许的跨域请求方法。 类型:GET,PUT,DELETE,POST,HEAD
public void AddAllowedMethod(String allowedMethod)
{
if (!InAllowedMethods(allowedMethod))
throw new ArgumentException("allowedMethod not in allowed methods(GET/PUT/DELETED/POST/HEAD)");
_allowedMethods.Add(allowedMethod);
}
///
/// 添加一条AllowedHeader。
///
/// 控制在OPTIONS预取指令中Access-Control-Request-Headers头中指定的header是否允许
public void AddAllowedHeader(String allowedHeader)
{
if (allowedHeader == null)
throw new ArgumentNullException("allowedHeader");
var hasAsterisk = allowedHeader.Contains("*");
if (hasAsterisk && CountOfAsterisk(AllowedHeaders) > 0)
throw new ArgumentException("At most one asterisk wildcard allowed.");
_allowedHeaders.Add(allowedHeader);
}
///
/// 添加一条ExposeHeader。
///
/// 指定允许用户从应用程序中访问的响应头(例如一个Javascript的XMLHttpRequest对象)
public void AddExposeHeader(String exposedHeader)
{
if (exposedHeader == null)
throw new ArgumentNullException("exposedHeader");
var hasAsterisk = exposedHeader.Contains("*");
if (hasAsterisk)
throw new ArgumentException("Asterisk wildcard not allowed.");
_exposeHeaders.Add(exposedHeader);
}
///
/// 获取*通配符的个数。
///
/// 获取这些数据里的通配符个数
/// 通配符的个数
private static int CountOfAsterisk(IEnumerable items)
{
int count = 0;
foreach (var item in items)
{
if (!string.IsNullOrEmpty(item) && item.Trim() == "*")
{
count++;
}
}
return count;
}
///
/// 判断某个method是否被允许
///
/// 需要判断的method
/// 是否被允许
private static bool InAllowedMethods(string allowedMethod)
{
if (string.IsNullOrEmpty(allowedMethod))
throw new ArgumentException("allowedMethod should not be null or empty");
var tmp = allowedMethod.Trim();
if (tmp == "GET" || tmp == "PUT" || tmp == "DELETED" ||
tmp == "POST" || tmp == "HEAD")
{
return true;
}
return false;
}
}
}