diff --git a/SharpGs/Cors/Cors.cs b/SharpGs/Cors/Cors.cs
new file mode 100644
index 0000000..34b11f7
--- /dev/null
+++ b/SharpGs/Cors/Cors.cs
@@ -0,0 +1,61 @@
+using System;
+using System.Linq;
+using System.Text;
+using System.Xml.Linq;
+using SharpGs.Cors.Internal;
+
+namespace SharpGs.Cors
+{
+ public class Cors : ICors
+ {
+ private IOrigin Origins = new Origin();
+ private IHttpMethods Methods = new HttpMethods();
+ private IResponseHeader ResponseHeaders = new ResponseHeader();
+ public int MaxAge { get; set; }
+ public Cors()
+ {
+ MaxAge = 1800;
+ }
+
+ public Cors(XDocument document)
+ {
+ foreach (var origin in document.Descendants("Origin"))
+ Origins.AddOrigin(origin.Value);
+ foreach (var method in document.Descendants("Method"))
+ Methods.AddMethod(method.Value.ToUpper());
+ foreach (var response in document.Descendants("ResponseHeader"))
+ ResponseHeaders.AddResponseHeader(response.Value);
+ var firstOrDefault = document.Descendants("MaxAgeSec").FirstOrDefault();
+ if (firstOrDefault != null)
+ MaxAge = Convert.ToInt16(firstOrDefault.Value);
+ }
+ public void AddOrigin(string origin)
+ {
+ Origins.AddOrigin(origin);
+ }
+
+ public void AddMethod(string method)
+ {
+ Methods.AddMethod(method);
+ }
+
+ public void AddHeader(string responseHeader)
+ {
+ ResponseHeaders.AddResponseHeader(responseHeader);
+ }
+
+ public string ToXmlString()
+ {
+ var sb = new StringBuilder("").AppendLine();
+ sb.AppendLine("");
+ sb.AppendLine("\t");
+ sb.Append(Origins.ToXmlString());
+ sb.Append(Methods.ToXmlString());
+ sb.Append(ResponseHeaders.ToXmlString());
+ sb.AppendLine("\t\t" + MaxAge + "");
+ sb.AppendLine("\t");
+ sb.AppendLine("");
+ return sb.ToString();
+ }
+ }
+}
diff --git a/SharpGs/Cors/ICors.cs b/SharpGs/Cors/ICors.cs
new file mode 100644
index 0000000..6c88b8f
--- /dev/null
+++ b/SharpGs/Cors/ICors.cs
@@ -0,0 +1,45 @@
+using SharpGs.RestApi;
+
+namespace SharpGs.Cors
+{
+ ///
+ /// Setup Cross Origin
+ ///
+ public interface ICors
+ {
+
+ ///
+ /// Adds an origin to the origin collection.
+ ///
+ /// An Origin permitted for cross origin resource sharing with this Google Cloud Storage bucket.
+ /// For example, http://origin1.example.com. You can use wildcards ("*"). However, if the host part of the Origin begins with a *,
+ /// then any origin that ends with the same suffix will be considered a match. If you supply a value that consists of only
+ /// the wildcard (*), this gives access to ALL origins.
+ ///
+ /// The origin to add
+ void AddOrigin(string origin);
+
+ ///
+ /// Adds a request method to the collection of methods supported in this configuration. Valid values are GET, HEAD, PUT, POST, and DELETE.
+ ///
+ ///
+ ///
+ void AddMethod(string method);
+
+ ///
+ /// Adds a response header/s that the user agent is permitted to share across origins.
+ ///
+ void AddHeader(string responseHeader);
+
+ ///
+ /// This value is used to respond to preflight requests, indicating the number of seconds that the client (browser) is allowed to make
+ /// requests before the client must repeat the preflight request. (Indicates cache expiry time.) Preflight requests are required if
+ /// the request method contains non-simple headers or if the request method is not POST, GET, or HEAD. The value is returned in the
+ /// Access-Control-Max-Age header in responses to preflight requests.
+ ///
+ int MaxAge { get; set; }
+
+
+ string ToXmlString();
+ }
+}
diff --git a/SharpGs/Cors/IHttpMethods.cs b/SharpGs/Cors/IHttpMethods.cs
new file mode 100644
index 0000000..7b21dba
--- /dev/null
+++ b/SharpGs/Cors/IHttpMethods.cs
@@ -0,0 +1,8 @@
+namespace SharpGs.Cors
+{
+ public interface IHttpMethods
+ {
+ void AddMethod(string method);
+ string ToXmlString();
+ }
+}
diff --git a/SharpGs/Cors/IOrigin.cs b/SharpGs/Cors/IOrigin.cs
new file mode 100644
index 0000000..cce75de
--- /dev/null
+++ b/SharpGs/Cors/IOrigin.cs
@@ -0,0 +1,8 @@
+namespace SharpGs.Cors
+{
+ public interface IOrigin
+ {
+ void AddOrigin(string origin);
+ string ToXmlString();
+ }
+}
diff --git a/SharpGs/Cors/IResponseHeader.cs b/SharpGs/Cors/IResponseHeader.cs
new file mode 100644
index 0000000..4d0281c
--- /dev/null
+++ b/SharpGs/Cors/IResponseHeader.cs
@@ -0,0 +1,8 @@
+namespace SharpGs.Cors
+{
+ public interface IResponseHeader
+ {
+ void AddResponseHeader(string responseHeader);
+ string ToXmlString();
+ }
+}
diff --git a/SharpGs/Cors/Internal/HttpMethods.cs b/SharpGs/Cors/Internal/HttpMethods.cs
new file mode 100644
index 0000000..8d81e35
--- /dev/null
+++ b/SharpGs/Cors/Internal/HttpMethods.cs
@@ -0,0 +1,31 @@
+using System.Collections.Generic;
+using System.Text;
+
+namespace SharpGs.Cors.Internal
+{
+ internal class HttpMethods : IHttpMethods
+ {
+ public List RequestMethods;
+
+ public HttpMethods()
+ {
+ RequestMethods = new List();
+ }
+
+ public void AddMethod(string method)
+ {
+ RequestMethods.Add(method);
+ }
+
+ public string ToXmlString()
+ {
+ var sb = new StringBuilder();
+ sb.AppendLine("\t\t");
+ foreach (var requestMethod in RequestMethods)
+ {
+ sb.AppendLine(string.Format("\t\t\t{0}", requestMethod));
+ }
+ return sb.AppendLine("\t\t").ToString();
+ }
+ }
+}
diff --git a/SharpGs/Cors/Internal/Origin.cs b/SharpGs/Cors/Internal/Origin.cs
new file mode 100644
index 0000000..5beca84
--- /dev/null
+++ b/SharpGs/Cors/Internal/Origin.cs
@@ -0,0 +1,32 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace SharpGs.Cors.Internal
+{
+ internal class Origin : IOrigin
+ {
+ public List Origins;
+ public Origin()
+ {
+ Origins = new List();
+ }
+
+ public void AddOrigin(string origin)
+ {
+ Origins.Add(origin);
+ }
+
+ public string ToXmlString()
+ {
+ var sb = new StringBuilder();
+ sb.AppendLine("\t\t");
+ foreach (var origin in Origins)
+ {
+ sb.AppendLine(String.Format("\t\t\t{0}", origin));
+ }
+ return sb.AppendLine("\t\t").ToString();
+ }
+
+ }
+}
diff --git a/SharpGs/Cors/Internal/ResponseHeader.cs b/SharpGs/Cors/Internal/ResponseHeader.cs
new file mode 100644
index 0000000..95c5ac7
--- /dev/null
+++ b/SharpGs/Cors/Internal/ResponseHeader.cs
@@ -0,0 +1,27 @@
+using System.Collections.Generic;
+using System.Text;
+
+namespace SharpGs.Cors.Internal
+{
+ internal class ResponseHeader: IResponseHeader
+ {
+ public List ResponseHeaders = new List();
+ public void AddResponseHeader(string responseHeader)
+ {
+ ResponseHeaders.Add(responseHeader);
+ }
+
+ public string ToXmlString()
+ {
+ if (ResponseHeaders.Count == 0)
+ return null;
+ var sb = new StringBuilder();
+ sb.AppendLine("\t\t");
+ foreach (var responseHeader in ResponseHeaders)
+ {
+ sb.AppendLine(string.Format("\t\t\t{0}", responseHeader));
+ }
+ return sb.AppendLine("\t\t").ToString();
+ }
+ }
+}
diff --git a/SharpGs/IBucket.cs b/SharpGs/IBucket.cs
index 88406f4..f940d00 100644
--- a/SharpGs/IBucket.cs
+++ b/SharpGs/IBucket.cs
@@ -1,5 +1,6 @@
using System;
using System.IO;
+using SharpGs.Cors;
namespace SharpGs
{
@@ -51,5 +52,17 @@ public interface IBucket : IAclSetup
/// Delete current bucket
///
void Delete();
+
+ ///
+ /// Retrieve Cross origin resource sharing object for the bucket
+ ///
+ ICors Cors { get; }
+
+ ///
+ /// Save a new resource sharing object for the bucket
+ ///
+ ///
+ void CorsSave(ICors cors);
+
}
}
diff --git a/SharpGs/ISharpGs.cs b/SharpGs/ISharpGs.cs
index 70ce065..2bfa5dd 100644
--- a/SharpGs/ISharpGs.cs
+++ b/SharpGs/ISharpGs.cs
@@ -1,52 +1,52 @@
-using System;
-using System.Collections.Generic;
-using System.Net;
-
-namespace SharpGs
-{
- ///
- /// Google Storage service connector
- ///
- public interface ISharpGs : IDisposable
- {
- ///
- /// Get the AuthKey of GoogleStorage account
- ///
- string AuthKey { get; }
-
- ///
- /// Get the AuthSecret of GoogleStorage account
- ///
- string AuthSecret { get; }
-
- ///
- /// If true, uses https secured protocol. True by default
- ///
- bool SecuredConnection { get; set; }
-
- ///
- /// If is not null, connection will be done through proxy
- ///
- IWebProxy WebProxy { get; set; }
-
- ///
- /// Request server for list of buckets
- /// https://code.google.com/apis/storage/docs/reference-methods.html#getservice
- ///
- IEnumerable Buckets { get; }
-
- ///
- /// Create new bucket. If bucket with same name already exists in GS, exception will be thrown.
- /// https://code.google.com/apis/storage/docs/reference-methods.html#putbucket
- ///
- /// unique name of the bucket
- void CreateBucket(string name);
-
- ///
- /// Get the bucket info
- ///
- /// name of the bucket
- /// bucket information
- IBucket GetBucket(string name);
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Net;
+
+namespace SharpGs
+{
+ ///
+ /// Google Storage service connector
+ ///
+ public interface ISharpGs : IDisposable
+ {
+ ///
+ /// Get the AuthKey of GoogleStorage account
+ ///
+ string AuthKey { get; }
+
+ ///
+ /// Get the AuthSecret of GoogleStorage account
+ ///
+ string AuthSecret { get; }
+
+ ///
+ /// If true, uses https secured protocol. True by default
+ ///
+ bool SecuredConnection { get; set; }
+
+ ///
+ /// If is not null, connection will be done through proxy
+ ///
+ IWebProxy WebProxy { get; set; }
+
+ ///
+ /// Request server for list of buckets
+ /// https://code.google.com/apis/storage/docs/reference-methods.html#getservice
+ ///
+ IEnumerable Buckets { get; }
+
+ ///
+ /// Create new bucket. If bucket with same name already exists in GS, exception will be thrown.
+ /// https://code.google.com/apis/storage/docs/reference-methods.html#putbucket
+ ///
+ /// unique name of the bucket
+ void CreateBucket(string name);
+
+ ///
+ /// Get the bucket info
+ ///
+ /// name of the bucket
+ /// bucket information
+ IBucket GetBucket(string name);
+ }
+}
diff --git a/SharpGs/Internal/Bucket.cs b/SharpGs/Internal/Bucket.cs
index 7b55d2d..396440d 100644
--- a/SharpGs/Internal/Bucket.cs
+++ b/SharpGs/Internal/Bucket.cs
@@ -5,6 +5,7 @@
using System.Xml.Linq;
using SharpGs.Acl;
using SharpGs.Acl.Internal;
+using SharpGs.Cors;
using SharpGs.RestApi;
namespace SharpGs.Internal
@@ -82,6 +83,27 @@ public void Delete()
_connector.Request(RequestMethod.DELETE, Name);
}
+ ///
+ /// Retrieve Cross origin resource sharing object for the bucket
+ ///
+ public ICors Cors
+ {
+ get
+ {
+ var result = _connector.Request(RequestMethod.CORS_GET, Name);
+ return new Cors.Cors(result);
+ }
+ }
+
+ ///
+ /// Save a new resource sharing object for the bucket
+ ///
+ ///
+ public void CorsSave(ICors cors)
+ {
+ _connector.Request(RequestMethod.CORS_SET, Name, null, Encoding.UTF8.GetBytes(cors.ToXmlString()), "application/xml");
+ }
+
public IAccessControlList Acl
{
get
diff --git a/SharpGs/Internal/SharpGsClient.cs b/SharpGs/Internal/SharpGsClient.cs
index d9123d7..94d5012 100644
--- a/SharpGs/Internal/SharpGsClient.cs
+++ b/SharpGs/Internal/SharpGsClient.cs
@@ -1,183 +1,187 @@
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.IO;
-using System.Linq;
-using System.Security.Cryptography;
-using System.Text;
-using System.Xml.Linq;
-using SharpGs.RestApi;
-using System.Net;
-
-namespace SharpGs.Internal
-{
- internal class SharpGsClient : ISharpGs
- {
- private const string DefaultGoogleHost = @"commondatastorage.googleapis.com";
-
- protected string GoogleStorageHost
- {
- get; set;
- }
-
- public string AuthKey
- {
- get; private set;
- }
-
- public string AuthSecret
- {
- get; private set;
- }
-
- public bool SecuredConnection
- {
- get; set;
- }
-
- public IWebProxy WebProxy
- {
- get; set;
- }
-
- private Uri ConnectionUrl(RequestMethod requestMethod, string bucketName = null, string path = null, string parameters = null)
- {
- var bucket = bucketName == null ? String.Empty : bucketName + '.';
- return
- new Uri(String.Format("{0}://{1}{2}/{3}{4}", SecuredConnection ? Uri.UriSchemeHttps : Uri.UriSchemeHttp,
- bucket, GoogleStorageHost, path, GetAdditionalParameters(requestMethod, parameters)));
- }
-
- private static string GetAdditionalParameters(RequestMethod requestMethod, string parameters)
- {
- if (requestMethod == RequestMethod.ACL_GET || requestMethod == RequestMethod.ACL_SET)
- return "?acl";
- if (parameters != null)
- return "?" + parameters;
- return String.Empty;
- }
-
- public SharpGsClient(string key, string secret)
- {
- AuthKey = key;
- AuthSecret = secret;
- SecuredConnection = true;
- GoogleStorageHost = DefaultGoogleHost;
- }
-
- #region Request Generation
-
- private static string SyndicateCanonicalHeaders(RequestMethod requestMethod, string contentMd5, string contentType, string date)
- {
- return String.Format("{0}\n{1}\n{2}\n{3}\n", RestApiClient.PureRequestMethod(requestMethod), contentMd5, contentType, date);
- }
-
- private static string SyndicateCanonicalResource(RequestMethod requestMethod, string bucket, string path)
- {
- var sb = new StringBuilder("/");
- if (bucket != null)
- {
- sb.Append(bucket);
- sb.Append("/");
- if (path != null)
- sb.Append(path);
- if (requestMethod == RequestMethod.ACL_GET || requestMethod == RequestMethod.ACL_SET)
- sb.Append("?acl");
- }
- return sb.ToString();
- }
-
- private static string SyndicateAuthValue(string key, string signature)
- {
- return String.Format(@"GOOG1 {0}:{1}", key, signature);
- }
-
- internal XDocument Request(RequestMethod requestMethod = RequestMethod.GET, string bucket = null, string path = null, byte[] content = null, string contentType = null, Bucket.ObjectHead objectHead = null, bool withData = false, string parameters = null)
- {
- var stream = content == null ? null : new MemoryStream(content);
- try
- {
- return RequestStream(requestMethod, bucket, path, stream, contentType, objectHead, withData, parameters);
- }
- finally
- {
- if (stream != null)
- stream.Close();
- }
- }
-
- internal XDocument RequestStream(RequestMethod requestMethod = RequestMethod.GET, string bucket = null, string path = null, Stream content = null, string contentType = null, Bucket.ObjectHead objectHead = null, bool withData = false, string parameters = null)
- {
- var contentTypeFixed = contentType ?? @"application/xml";
- var dateO = DateTime.UtcNow;
- var date = dateO.ToString(@"ddd, dd MMM yyyy HH':'mm':'ss 'GMT'", CultureInfo.GetCultureInfo("EN-US"));
-
- var canonicalHeaders = SyndicateCanonicalHeaders(requestMethod,
- content == null
- ? null
- : Convert.ToBase64String(
- MD5.Create().ComputeHash(content)),
- contentTypeFixed,
- date);
- var canonicalResource = SyndicateCanonicalResource(requestMethod, bucket, path);
-
- var signatureOrigin = String.Format("{0}{1}", canonicalHeaders, canonicalResource);
- var signature =
- Convert.ToBase64String(
- new HMACSHA1(Encoding.UTF8.GetBytes(AuthSecret)).ComputeHash(Encoding.UTF8.GetBytes(signatureOrigin)));
-
- var api = new RestApiClient(ConnectionUrl(requestMethod, bucket, path, parameters), requestMethod, WebProxy);
- if (objectHead != null)
- objectHead.Key = path;
- var result = api.Request(SyndicateAuthValue(AuthKey, signature), dateO, content, contentTypeFixed,
- objectHead, withData);
- if (String.IsNullOrEmpty(result))
- return null;
- var responce = XDocument.Parse(FilterResponse(result));
- var error = responce.Descendants(@"Error").FirstOrDefault();
- if (error == null)
- return responce;
- throw error.FindException();
- }
-
- private static string FilterResponse(string response)
- {
- var p = response;
- while (true)
- {
- var ptr = p.IndexOf(" xmlns=");
- if (ptr < 0)
- break;
- var ptrE = p.IndexOf(p[ptr + 7], ptr + 8);
- if (ptrE <= ptr)
- break;
- p = p.Substring(0, ptr) + p.Substring(ptrE + 1);
- }
- return p;
- }
-
- #endregion Request Generation
-
- public IEnumerable Buckets
- {
- get
- {
- return Request().Descendants(@"Bucket").Select(bucket => Bucket.FromXml(bucket, this));
- }
- }
-
- public IBucket GetBucket(string name)
- {
- return Buckets.FirstOrDefault(b => b.Name.Equals(name));
- }
-
- public void CreateBucket(string name)
- {
- Request(RequestMethod.PUT, name);
- }
-
- public void Dispose()
- {
- }
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Security.Cryptography;
+using System.Text;
+using System.Xml.Linq;
+using SharpGs.RestApi;
+using System.Net;
+
+namespace SharpGs.Internal
+{
+ internal class SharpGsClient : ISharpGs
+ {
+ private const string DefaultGoogleHost = @"commondatastorage.googleapis.com";
+
+ protected string GoogleStorageHost
+ {
+ get; set;
+ }
+
+ public string AuthKey
+ {
+ get; private set;
+ }
+
+ public string AuthSecret
+ {
+ get; private set;
+ }
+
+ public bool SecuredConnection
+ {
+ get; set;
+ }
+
+ public IWebProxy WebProxy
+ {
+ get; set;
+ }
+
+ private Uri ConnectionUrl(RequestMethod requestMethod, string bucketName = null, string path = null, string parameters = null)
+ {
+ var bucket = bucketName == null ? String.Empty : bucketName + '.';
+ return
+ new Uri(String.Format("{0}://{1}{2}/{3}{4}", SecuredConnection ? Uri.UriSchemeHttps : Uri.UriSchemeHttp,
+ bucket, GoogleStorageHost, path, GetAdditionalParameters(requestMethod, parameters)));
+ }
+
+ private static string GetAdditionalParameters(RequestMethod requestMethod, string parameters)
+ {
+ if (requestMethod == RequestMethod.ACL_GET || requestMethod == RequestMethod.ACL_SET)
+ return "?acl";
+ if (requestMethod == RequestMethod.CORS_GET || requestMethod == RequestMethod.CORS_SET)
+ return "?cors";
+ if (parameters != null)
+ return "?" + parameters;
+ return String.Empty;
+ }
+
+ public SharpGsClient(string key, string secret)
+ {
+ AuthKey = key;
+ AuthSecret = secret;
+ SecuredConnection = true;
+ GoogleStorageHost = DefaultGoogleHost;
+ }
+
+ #region Request Generation
+
+ private static string SyndicateCanonicalHeaders(RequestMethod requestMethod, string contentMd5, string contentType, string date)
+ {
+ return String.Format("{0}\n{1}\n{2}\n{3}\n", RestApiClient.PureRequestMethod(requestMethod), contentMd5, contentType, date);
+ }
+
+ private static string SyndicateCanonicalResource(RequestMethod requestMethod, string bucket, string path)
+ {
+ var sb = new StringBuilder("/");
+ if (bucket != null)
+ {
+ sb.Append(bucket);
+ sb.Append("/");
+ if (path != null)
+ sb.Append(path);
+ if (requestMethod == RequestMethod.ACL_GET || requestMethod == RequestMethod.ACL_SET)
+ sb.Append("?acl");
+ if (requestMethod == RequestMethod.CORS_GET || requestMethod == RequestMethod.CORS_SET)
+ sb.Append("?cors");
+ }
+ return sb.ToString();
+ }
+
+ private static string SyndicateAuthValue(string key, string signature)
+ {
+ return String.Format(@"GOOG1 {0}:{1}", key, signature);
+ }
+
+ internal XDocument Request(RequestMethod requestMethod = RequestMethod.GET, string bucket = null, string path = null, byte[] content = null, string contentType = null, Bucket.ObjectHead objectHead = null, bool withData = false, string parameters = null)
+ {
+ var stream = content == null ? null : new MemoryStream(content);
+ try
+ {
+ return RequestStream(requestMethod, bucket, path, stream, contentType, objectHead, withData, parameters);
+ }
+ finally
+ {
+ if (stream != null)
+ stream.Close();
+ }
+ }
+
+ internal XDocument RequestStream(RequestMethod requestMethod = RequestMethod.GET, string bucket = null, string path = null, Stream content = null, string contentType = null, Bucket.ObjectHead objectHead = null, bool withData = false, string parameters = null)
+ {
+ var contentTypeFixed = contentType ?? @"application/xml";
+ var dateO = DateTime.UtcNow;
+ var date = dateO.ToString(@"ddd, dd MMM yyyy HH':'mm':'ss 'GMT'", CultureInfo.GetCultureInfo("EN-US"));
+
+ var canonicalHeaders = SyndicateCanonicalHeaders(requestMethod,
+ content == null
+ ? null
+ : Convert.ToBase64String(
+ MD5.Create().ComputeHash(content)),
+ contentTypeFixed,
+ date);
+ var canonicalResource = SyndicateCanonicalResource(requestMethod, bucket, path);
+
+ var signatureOrigin = String.Format("{0}{1}", canonicalHeaders, canonicalResource);
+ var signature =
+ Convert.ToBase64String(
+ new HMACSHA1(Encoding.UTF8.GetBytes(AuthSecret)).ComputeHash(Encoding.UTF8.GetBytes(signatureOrigin)));
+
+ var api = new RestApiClient(ConnectionUrl(requestMethod, bucket, path, parameters), requestMethod, WebProxy);
+ if (objectHead != null)
+ objectHead.Key = path;
+ var result = api.Request(SyndicateAuthValue(AuthKey, signature), dateO, content, contentTypeFixed,
+ objectHead, withData);
+ if (String.IsNullOrEmpty(result))
+ return null;
+ var responce = XDocument.Parse(FilterResponse(result));
+ var error = responce.Descendants(@"Error").FirstOrDefault();
+ if (error == null)
+ return responce;
+ throw error.FindException();
+ }
+
+ private static string FilterResponse(string response)
+ {
+ var p = response;
+ while (true)
+ {
+ var ptr = p.IndexOf(" xmlns=");
+ if (ptr < 0)
+ break;
+ var ptrE = p.IndexOf(p[ptr + 7], ptr + 8);
+ if (ptrE <= ptr)
+ break;
+ p = p.Substring(0, ptr) + p.Substring(ptrE + 1);
+ }
+ return p;
+ }
+
+ #endregion Request Generation
+
+ public IEnumerable Buckets
+ {
+ get
+ {
+ return Request().Descendants(@"Bucket").Select(bucket => Bucket.FromXml(bucket, this));
+ }
+ }
+
+ public IBucket GetBucket(string name)
+ {
+ return Buckets.FirstOrDefault(b => b.Name.Equals(name));
+ }
+
+ public void CreateBucket(string name)
+ {
+ Request(RequestMethod.PUT, name);
+ }
+
+ public void Dispose()
+ {
+ }
+ }
+}
diff --git a/SharpGs/RestApi/RequestMethod.cs b/SharpGs/RestApi/RequestMethod.cs
index 2e14883..5680166 100644
--- a/SharpGs/RestApi/RequestMethod.cs
+++ b/SharpGs/RestApi/RequestMethod.cs
@@ -8,6 +8,8 @@ internal enum RequestMethod
DELETE,
HEAD,
ACL_GET,
- ACL_SET
+ ACL_SET,
+ CORS_GET,
+ CORS_SET
}
}
diff --git a/SharpGs/RestApi/RestApiClient.cs b/SharpGs/RestApi/RestApiClient.cs
index 15cf5d7..4642d1e 100644
--- a/SharpGs/RestApi/RestApiClient.cs
+++ b/SharpGs/RestApi/RestApiClient.cs
@@ -1,136 +1,140 @@
-using System;
-using System.IO;
-using System.Net;
-using System.Security.Cryptography;
-using SharpGs.Internal;
-
-namespace SharpGs.RestApi
-{
- internal class RestApiClient
- {
- private readonly Uri _uri;
- private readonly RequestMethod _method;
- private readonly IWebProxy _webProxy;
-
- public RestApiClient(Uri uri, RequestMethod method, IWebProxy proxy = null)
- {
- _uri = uri;
- _method = method;
- _webProxy = proxy;
- }
-
- internal static RequestMethod PureRequestMethod(RequestMethod method)
- {
- switch (method)
- {
- case RequestMethod.ACL_GET:
- return RequestMethod.GET;
- case RequestMethod.ACL_SET:
- return RequestMethod.PUT;
- default:
- return method;
- }
- }
-
- public static void CopyStream(Stream input, Stream output)
- {
- var buffer = new byte[32768];
- int read;
- while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
- {
- output.Write(buffer, 0, read);
- }
- }
-
- private HttpWebRequest CreateRequest(string authValue, DateTime date, Stream content, string contentType)
- {
- var request = (HttpWebRequest)WebRequest.Create(_uri);
- request.Method = PureRequestMethod(_method).ToString();
-
- if (_webProxy != null)
- request.Proxy = _webProxy;
-
- request.Headers.Add(@"Authorization", authValue);
- if (content != null)
- {
- content.Seek(0, SeekOrigin.Begin);
- request.Headers.Add(@"Content-MD5", Convert.ToBase64String(MD5.Create().ComputeHash(content)));
- }
- request.Date = date;
- request.ContentLength = content == null ? 0 : content.Length;
- request.ContentType = contentType;
- request.KeepAlive = false;
- if (content != null)
- {
- var resultedStream = request.GetRequestStream();
- content.Seek(0, SeekOrigin.Begin);
- CopyStream(content, resultedStream);
- }
- return request;
- }
-
- private static bool FetchDataFromResponse(HttpWebResponse response, Bucket.ObjectHead objectHead, bool withData)
- {
- if (objectHead == null)
- return false;
- objectHead.Size = response.ContentLength;
- objectHead.ContentType = response.ContentType;
- objectHead.ETag = response.Headers["ETag"];
- objectHead.LastModified = response.LastModified;
- if (withData)
- {
- var stream = response.GetResponseStream();
- if (objectHead.TargetStream == null)
- {
- objectHead.Content = new byte[objectHead.Size];
- var read = (long) 0;
- if (stream != null)
- {
- while (read < objectHead.Size)
- {
- var toread = (int) ((objectHead.Size - read)%4048);
- read += stream.Read(objectHead.Content, 0, toread);
- }
- return true;
- }
- }
- else
- {
- if (stream != null)
- {
- CopyStream(stream, objectHead.TargetStream);
- return true;
- }
- }
- }
- return false;
- }
-
- private static string StreamToString(Stream stream)
- {
- using (var reader = new StreamReader(stream))
- {
- return reader.ReadToEnd();
- }
- }
-
- public string Request(string authValue, DateTime date, Stream content, string contentType, Bucket.ObjectHead objectHead, bool withData)
- {
- try
- {
- var request = CreateRequest(authValue, date, content, contentType);
-
- using (var response = (HttpWebResponse)request.GetResponse())
- {
- if (response.StatusCode == HttpStatusCode.OK && FetchDataFromResponse(response, objectHead, withData))
- return String.Empty;
- return StreamToString(response.GetResponseStream());
- }
- }
- catch (WebException exception)
- {
- return StreamToString(exception.Response.GetResponseStream());
- }
- }
- }
-}
+using System;
+using System.IO;
+using System.Net;
+using System.Security.Cryptography;
+using SharpGs.Internal;
+
+namespace SharpGs.RestApi
+{
+ internal class RestApiClient
+ {
+ private readonly Uri _uri;
+ private readonly RequestMethod _method;
+ private readonly IWebProxy _webProxy;
+
+ public RestApiClient(Uri uri, RequestMethod method, IWebProxy proxy = null)
+ {
+ _uri = uri;
+ _method = method;
+ _webProxy = proxy;
+ }
+
+ internal static RequestMethod PureRequestMethod(RequestMethod method)
+ {
+ switch (method)
+ {
+ case RequestMethod.ACL_GET:
+ return RequestMethod.GET;
+ case RequestMethod.ACL_SET:
+ return RequestMethod.PUT;
+ case RequestMethod.CORS_GET:
+ return RequestMethod.GET;
+ case RequestMethod.CORS_SET:
+ return RequestMethod.PUT;
+ default:
+ return method;
+ }
+ }
+
+ public static void CopyStream(Stream input, Stream output)
+ {
+ var buffer = new byte[32768];
+ int read;
+ while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
+ {
+ output.Write(buffer, 0, read);
+ }
+ }
+
+ private HttpWebRequest CreateRequest(string authValue, DateTime date, Stream content, string contentType)
+ {
+ var request = (HttpWebRequest)WebRequest.Create(_uri);
+ request.Method = PureRequestMethod(_method).ToString();
+
+ if (_webProxy != null)
+ request.Proxy = _webProxy;
+
+ request.Headers.Add(@"Authorization", authValue);
+ if (content != null)
+ {
+ content.Seek(0, SeekOrigin.Begin);
+ request.Headers.Add(@"Content-MD5", Convert.ToBase64String(MD5.Create().ComputeHash(content)));
+ }
+ request.Date = date;
+ request.ContentLength = content == null ? 0 : content.Length;
+ request.ContentType = contentType;
+ request.KeepAlive = false;
+ if (content != null)
+ {
+ var resultedStream = request.GetRequestStream();
+ content.Seek(0, SeekOrigin.Begin);
+ CopyStream(content, resultedStream);
+ }
+ return request;
+ }
+
+ private static bool FetchDataFromResponse(HttpWebResponse response, Bucket.ObjectHead objectHead, bool withData)
+ {
+ if (objectHead == null)
+ return false;
+ objectHead.Size = response.ContentLength;
+ objectHead.ContentType = response.ContentType;
+ objectHead.ETag = response.Headers["ETag"];
+ objectHead.LastModified = response.LastModified;
+ if (withData)
+ {
+ var stream = response.GetResponseStream();
+ if (objectHead.TargetStream == null)
+ {
+ objectHead.Content = new byte[objectHead.Size];
+ var read = (long) 0;
+ if (stream != null)
+ {
+ while (read < objectHead.Size)
+ {
+ var toread = (int) ((objectHead.Size - read)%4048);
+ read += stream.Read(objectHead.Content, 0, toread);
+ }
+ return true;
+ }
+ }
+ else
+ {
+ if (stream != null)
+ {
+ CopyStream(stream, objectHead.TargetStream);
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ private static string StreamToString(Stream stream)
+ {
+ using (var reader = new StreamReader(stream))
+ {
+ return reader.ReadToEnd();
+ }
+ }
+
+ public string Request(string authValue, DateTime date, Stream content, string contentType, Bucket.ObjectHead objectHead, bool withData)
+ {
+ try
+ {
+ var request = CreateRequest(authValue, date, content, contentType);
+
+ using (var response = (HttpWebResponse)request.GetResponse())
+ {
+ if (response.StatusCode == HttpStatusCode.OK && FetchDataFromResponse(response, objectHead, withData))
+ return String.Empty;
+ return StreamToString(response.GetResponseStream());
+ }
+ }
+ catch (WebException exception)
+ {
+ return StreamToString(exception.Response.GetResponseStream());
+ }
+ }
+ }
+}
diff --git a/SharpGs/SharpGs.csproj b/SharpGs/SharpGs.csproj
index 5731b2c..b747526 100644
--- a/SharpGs/SharpGs.csproj
+++ b/SharpGs/SharpGs.csproj
@@ -53,6 +53,14 @@
+
+
+
+
+
+
+
+
diff --git a/SharpGsDemo/Program.cs b/SharpGsDemo/Program.cs
index d044b40..3b6dc49 100644
--- a/SharpGsDemo/Program.cs
+++ b/SharpGsDemo/Program.cs
@@ -1,78 +1,78 @@
-using System;
-using System.IO;
-using System.Text;
-using SharpGs;
-
-namespace SharpGsDemo
-{
- class Program
- {
- // Google keys pair - key & secret
- private const string AuthKey = @"put yours here";
- private const string AuthSecret = @"put yours here";
-
- static void Main()
- {
- var client = GoogleStorageFactory.Create(AuthKey, AuthSecret);
-
- //--- Proxy usage (implemented by community user Fabrizio)
- //IWebProxy proxy = HttpWebRequest.DefaultWebProxy;
- //proxy.Credentials = CredentialCache.DefaultCredentials;
- //client.WebProxy = proxy;
-
- for (var i = 0; i < 2; i++)
- {
- // Create a bucket
- var name = "temp-bucket-" + new Random().Next();
- client.CreateBucket(name);
- }
-
- // Fetching all buckets of user
- foreach (var bucket in client.Buckets)
- {
- Console.WriteLine("{0} - {1}", bucket.Name, bucket.CreationDate);
-
- // Simple buffer content
- bucket.AddObject("someobj/on" + new Random().Next(), Encoding.UTF8.GetBytes("Simple text"), "text/plain");
- // Streamed content (stream will be closed at the end)
- bucket.AddObject("someobj/stream-on" + new Random().Next(), GetStreamedString("Stream me!!!"), "text/plain", true);
-
- foreach (var o in bucket.Objects)
- {
- Console.WriteLine(" {0} - {1}", o.Key, o.Size);
- if (o.Key.StartsWith("someobj/stream-on"))
- {
- // Get streamed content
- using (var ms = new MemoryStream())
- {
- o.Retrieve(ms);
- ms.Seek(0, SeekOrigin.Begin);
- using (var reader = new StreamReader(ms))
- {
- Console.WriteLine(" {0}", reader.ReadToEnd());
- }
- }
- }
- else
- {
- // Get simple content
- Console.WriteLine(" {0}", Encoding.UTF8.GetString(o.Retrieve().Content));
- }
- o.Delete();
- }
-
- // Delete bucket
- if (bucket.Name.StartsWith("temp-bucket-"))
- bucket.Delete();
- }
-
- Console.WriteLine("Finished");
- Console.ReadKey();
- }
-
- static Stream GetStreamedString(string data)
- {
- return new MemoryStream(Encoding.UTF8.GetBytes(data));
- }
- }
-}
+using System;
+using System.IO;
+using System.Text;
+using SharpGs;
+
+namespace SharpGsDemo
+{
+ class Program
+ {
+ // Google keys pair - key & secret
+ private const string AuthKey = @"put yours here";
+ private const string AuthSecret = @"put yours here";
+
+ static void Main()
+ {
+ var client = GoogleStorageFactory.Create(AuthKey, AuthSecret);
+
+ //--- Proxy usage (implemented by community user Fabrizio)
+ //IWebProxy proxy = HttpWebRequest.DefaultWebProxy;
+ //proxy.Credentials = CredentialCache.DefaultCredentials;
+ //client.WebProxy = proxy;
+
+ for (var i = 0; i < 2; i++)
+ {
+ // Create a bucket
+ var name = "temp-bucket-" + new Random().Next();
+ client.CreateBucket(name);
+ }
+
+ // Fetching all buckets of user
+ foreach (var bucket in client.Buckets)
+ {
+ Console.WriteLine("{0} - {1}", bucket.Name, bucket.CreationDate);
+
+ // Simple buffer content
+ bucket.AddObject("someobj/on" + new Random().Next(), Encoding.UTF8.GetBytes("Simple text"), "text/plain");
+ // Streamed content (stream will be closed at the end)
+ bucket.AddObject("someobj/stream-on" + new Random().Next(), GetStreamedString("Stream me!!!"), "text/plain", true);
+
+ foreach (var o in bucket.Objects)
+ {
+ Console.WriteLine(" {0} - {1}", o.Key, o.Size);
+ if (o.Key.StartsWith("someobj/stream-on"))
+ {
+ // Get streamed content
+ using (var ms = new MemoryStream())
+ {
+ o.Retrieve(ms);
+ ms.Seek(0, SeekOrigin.Begin);
+ using (var reader = new StreamReader(ms))
+ {
+ Console.WriteLine(" {0}", reader.ReadToEnd());
+ }
+ }
+ }
+ else
+ {
+ // Get simple content
+ Console.WriteLine(" {0}", Encoding.UTF8.GetString(o.Retrieve().Content));
+ }
+ o.Delete();
+ }
+
+ // Delete bucket
+ if (bucket.Name.StartsWith("temp-bucket-"))
+ bucket.Delete();
+ }
+
+ Console.WriteLine("Finished");
+ Console.ReadKey();
+ }
+
+ static Stream GetStreamedString(string data)
+ {
+ return new MemoryStream(Encoding.UTF8.GetBytes(data));
+ }
+ }
+}