RestHelpers.cs :  » Bloggers » dasBlog » Microsoft » Samples » ServiceHosting » StorageClient » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Bloggers » dasBlog 
dasBlog » Microsoft » Samples » ServiceHosting » StorageClient » RestHelpers.cs
//
// <copyright file="RestHelpers.cs" company="Microsoft">
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
using System.Diagnostics;
using System.Globalization;
using System.Collections.Specialized;
using System.Web;
using System.Xml;
using System.Text.RegularExpressions;

namespace Microsoft.Samples.ServiceHosting.StorageClient{
    namespace StorageHttpConstants
    {

        internal static class ConstChars
        {
            internal const string Linefeed = "\n";
            internal const string CarriageReturnLinefeed = "\r\n";
            internal const string Colon = ":";
            internal const string Comma = ",";
            internal const string Slash = "/";
            internal const string BackwardSlash = @"\";
            internal const string Space = " ";
            internal const string Ampersand = "&";
            internal const string QuestionMark = "?";
            internal const string Equal = "=";
            internal const string Bang = "!";
            internal const string Star = "*";
            internal const string Dot = ".";
        }

        internal static class RequestParams
        {
            internal const string NumOfMessages = "numofmessages";
            internal const string VisibilityTimeout = "visibilitytimeout";
            internal const string PeekOnly = "peekonly";
            internal const string MessageTtl = "messagettl";
            internal const string Messages = "messages";
            internal const string PopReceipt = "popreceipt";
        }

        internal static class QueryParams
        {
            internal const string SeparatorForParameterAndValue = "=";
            internal const string QueryParamTimeout = "timeout";
            internal const string QueryParamComp = "comp";

            // Other query string parameter names
            internal const string QueryParamBlockId = "blockid";
            internal const string QueryParamPrefix = "prefix";
            internal const string QueryParamMarker = "marker";
            internal const string QueryParamMaxResults = "maxresults";
            internal const string QueryParamDelimiter = "delimiter";
            internal const string QueryParamModifiedSince = "modifiedsince";
        }

        internal static class CompConstants
        {
            internal const string Metadata = "metadata";
            internal const string List = "list";
            internal const string BlobList = "bloblist";
            internal const string BlockList = "blocklist";
            internal const string Block = "block";
            internal const string Acl = "acl";
        }

        internal static class XmlElementNames
        {
            internal const string BlockList = "BlockList";
            internal const string Block = "Block";
            internal const string EnumerationResults = "EnumerationResults";
            internal const string Prefix = "Prefix";
            internal const string Marker = "Marker";
            internal const string MaxResults = "MaxResults";
            internal const string Delimiter = "Delimiter";
            internal const string NextMarker = "NextMarker";
            internal const string Containers = "Containers";
            internal const string Container = "Container";
            internal const string ContainerName = "Name";
            internal const string ContainerNameAttribute = "ContainerName";
            internal const string AccountNameAttribute = "AccountName";
            internal const string LastModified = "LastModified";
            internal const string Etag = "Etag";
            internal const string Url = "Url";
            internal const string CommonPrefixes = "CommonPrefixes";
            internal const string ContentType = "ContentType";
            internal const string ContentEncoding = "ContentEncoding";
            internal const string ContentLanguage = "ContentLanguage";
            internal const string Size = "Size";
            internal const string Blobs = "Blobs";
            internal const string Blob = "Blob";
            internal const string BlobName = "Name";
            internal const string BlobPrefix = "BlobPrefix";
            internal const string BlobPrefixName = "Name";
            internal const string Name = "Name";
            internal const string Queues = "Queues";
            internal const string Queue = "Queue";
            internal const string QueueName = "QueueName";
            internal const string QueueMessagesList = "QueueMessagesList";
            internal const string QueueMessage = "QueueMessage";
            internal const string MessageId = "MessageId";
            internal const string PopReceipt = "PopReceipt";
            internal const string InsertionTime = "InsertionTime";
            internal const string ExpirationTime = "ExpirationTime";
            internal const string TimeNextVisible = "TimeNextVisible";
            internal const string MessageText = "MessageText";

            // Error specific constants
            internal const string ErrorRootElement = "Error";
            internal const string ErrorCode = "Code";
            internal const string ErrorMessage = "Message";
            internal const string ErrorException = "ExceptionDetails";
            internal const string ErrorExceptionMessage = "ExceptionMessage";
            internal const string ErrorExceptionStackTrace = "StackTrace";
            internal const string AuthenticationErrorDetail = "AuthenticationErrorDetail";

            //The following are for table error messages
            internal const string DataWebMetadataNamespace = "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata";
            internal const string TableErrorCodeElement = "code";
            internal const string TableErrorMessageElement = "message";
        }

        internal static class HeaderNames
        {
            internal const string PrefixForStorageProperties = "x-ms-prop-";
            internal const string PrefixForMetadata = "x-ms-meta-";
            internal const string PrefixForStorageHeader = "x-ms-";
            internal const string PrefixForTableContinuation = "x-ms-continuation-";

            //
            // Standard headers...
            //
            internal const string ContentLanguage = "Content-Language";
            internal const string ContentLength = "Content-Length";
            internal const string ContentType = "Content-Type";
            internal const string ContentEncoding = "Content-Encoding";
            internal const string ContentMD5 = "Content-MD5";
            internal const string ContentRange = "Content-Range";
            internal const string LastModifiedTime = "Last-Modified";
            internal const string Server = "Server";
            internal const string Allow = "Allow";
            internal const string ETag = "ETag";
            internal const string Range = "Range";
            internal const string Date = "Date";
            internal const string Authorization = "Authorization";
            internal const string IfModifiedSince = "If-Modified-Since";
            internal const string IfUnmodifiedSince = "If-Unmodified-Since";
            internal const string IfMatch = "If-Match";
            internal const string IfNoneMatch = "If-None-Match";
            internal const string IfRange = "If-Range";
            internal const string NextPartitionKey = "NextPartitionKey";
            internal const string NextRowKey = "NextRowKey";
            internal const string NextTableName = "NextTableName";

            //
            // Storage specific custom headers...
            //
            internal const string StorageDateTime = PrefixForStorageHeader + "date";
            internal const string PublicAccess = PrefixForStorageProperties + "publicaccess";
            internal const string StorageRange = PrefixForStorageHeader + "range";

            internal const string CreationTime = PrefixForStorageProperties + "creation-time";
            internal const string ForceUpdate = PrefixForStorageHeader + "force-update";            
            internal const string ApproximateMessagesCount = PrefixForStorageHeader + "approximate-messages-count";     
        }

        internal static class HeaderValues
        {
            internal const string ContentTypeXml = "application/xml";

            /// <summary>
            /// This is the default content-type xStore uses when no content type is specified
            /// </summary>
            internal const string DefaultContentType = "application/octet-stream";

            // The Range header value is "bytes=start-end", both start and end can be empty
            internal const string RangeHeaderFormat = "bytes={0}-{1}";

        }

        internal static class AuthenticationSchemeNames
        {
            internal const string SharedKeyAuthSchemeName = "SharedKey";
            internal const string SharedKeyLiteAuthSchemeName = "SharedKeyLite";
        }

        internal static class HttpMethod
        {
            internal const string Get = "GET";
            internal const string Put = "PUT";
            internal const string Post = "POST";
            internal const string Head = "HEAD";
            internal const string Delete = "DELETE";
            internal const string Trace = "TRACE";
            internal const string Options = "OPTIONS";
            internal const string Connect = "CONNECT";
        }

        internal static class BlobBlockConstants
        {
            internal const int KB = 1024;
            internal const int MB = 1024 * KB;
            /// <summary>
            /// When transmitting a blob that is larger than this constant, this library automatically
            /// transmits the blob as individual blocks. I.e., the blob is (1) partitioned
            /// into separate parts (these parts are called blocks) and then (2) each of the blocks is 
            /// transmitted separately.
            /// The maximum size of this constant as supported by the real blob storage service is currently 
            /// 64 MB; the development storage tool currently restricts this value to 2 MB.
            /// Setting this constant can have a significant impact on the performance for uploading or
            /// downloading blobs.
            /// As a general guideline: If you run in a reliable environment increase this constant to reduce
            /// the amount of roundtrips. In an unreliable environment keep this constant low to reduce the 
            /// amount of data that needs to be retransmitted in case of connection failures.
            /// </summary>
            internal const long MaximumBlobSizeBeforeTransmittingAsBlocks = 2 * MB;
            /// <summary>
            /// The size of a single block when transmitting a blob that is larger than the 
            /// MaximumBlobSizeBeforeTransmittingAsBlocks constant (see above).
            /// The maximum size of this constant is currently 4 MB; the development storage 
            /// tool currently restricts this value to 1 MB.
            /// Setting this constant can have a significant impact on the performance for uploading or 
            /// downloading blobs.
            /// As a general guideline: If you run in a reliable environment increase this constant to reduce
            /// the amount of roundtrips. In an unreliable environment keep this constant low to reduce the 
            /// amount of data that needs to be retransmitted in case of connection failures.
            /// </summary>
            internal const long BlockSize = 1 * MB;            
        }

        internal static class ListingConstants
        {
            internal const int MaxContainerListResults = 100;
            internal const int MaxBlobListResults = 100;
            internal const int MaxQueueListResults = 50;
            internal const int MaxTableListResults = 50;
        }

        /// <summary>
        /// Contains regular expressions for checking whether container and table names conform
        /// to the rules of the storage REST protocols.
        /// </summary>
        public static class RegularExpressionStrings
        {
            /// <summary>
            /// Container or queue names that match against this regular expression are valid.
            /// </summary>
            public const string ValidContainerNameRegex = @"^([a-z]|\d){1}([a-z]|-|\d){1,61}([a-z]|\d){1}$";

            /// <summary>
            /// Table names that match against this regular expression are valid.
            /// </summary>
            public const string ValidTableNameRegex = @"^([a-z]|[A-Z]){1}([a-z]|[A-Z]|\d){2,62}$";
        }

        internal static class StandardPortalEndpoints
        {
            internal const string BlobStorage = "blob";
            internal const string QueueStorage = "queue";
            internal const string TableStorage = "table";
            internal const string StorageHostSuffix = ".core.windows.net";
            internal const string BlobStorageEndpoint = BlobStorage + StorageHostSuffix;
            internal const string QueueStorageEndpoint = QueueStorage + StorageHostSuffix;
            internal const string TableStorageEndpoint = TableStorage + StorageHostSuffix;
        }
    }

    internal static partial class Utilities
    {
        internal static HttpWebRequest CreateHttpRequest(Uri uri, string httpMethod, TimeSpan timeout)
        {
            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri);
            request.Timeout = (int)timeout.TotalMilliseconds;
            request.ReadWriteTimeout = (int)timeout.TotalMilliseconds;
            request.Method = httpMethod;
            request.ContentLength = 0;
            request.Headers.Add(StorageHttpConstants.HeaderNames.StorageDateTime,
                                Utilities.ConvertDateTimeToHttpString(DateTime.UtcNow));
            return request;
        }

        /// <summary>
        /// Converts the date time to a valid string form as per HTTP standards
        /// </summary>
        internal static string ConvertDateTimeToHttpString(DateTime dateTime)
        {
            // On the wire everything should be represented in UTC. This assert will catch invalid callers who
            // are violating this rule.
            Debug.Assert(dateTime == DateTime.MaxValue || dateTime == DateTime.MinValue || dateTime.Kind == DateTimeKind.Utc);

            // 'R' means rfc1123 date which is what our server uses for all dates...
            // It will be in the following format:
            // Sun, 28 Jan 2008 12:11:37 GMT
            return dateTime.ToString("R", CultureInfo.InvariantCulture);
        }

        /// <summary>
        /// Parse a string having the date time information in acceptable formats according to HTTP standards
        /// </summary>
        internal static bool TryGetDateTimeFromHttpString(string dateString, out DateTime? result)
        {
            DateTime dateTime;
            result = null;

            // 'R' means rfc1123 date which is the preferred format used in HTTP
            bool parsed = DateTime.TryParseExact(dateString, "R", null, DateTimeStyles.None, out dateTime);
            if (parsed)
            {
                // For some reason, format string "R" makes the DateTime.Kind as Unspecified while it's actually
                // Utc. Specifying DateTimeStyles.AssumeUniversal also doesn't make the difference. If we also
                // specify AdjustToUniversal it works as expected but we don't really want Parse to adjust 
                // things automatically.
                result = DateTime.SpecifyKind(dateTime, DateTimeKind.Utc);
                return true;
            }

            return false;
        }


        /// <summary>
        /// Copies from one stream to another
        /// </summary>
        /// <param name="sourceStream">The stream to copy from</param>
        /// <param name="destinationStream">The stream to copy to</param>
        internal static long CopyStream(Stream sourceStream, Stream destinationStream)
        {
            const int BufferSize = 0x10000;
            byte[] buffer = new byte[BufferSize];
            int n = 0;
            long totalRead = 0;
            do
            {
                n = sourceStream.Read(buffer, 0, BufferSize);
                if (n > 0)
                {
                    totalRead += n;
                    destinationStream.Write(buffer, 0, n);
                }
                
            } while (n > 0);
            return totalRead;
        }

        internal static void CopyStream(Stream sourceStream, Stream destinationStream, long length)
        {
            const int BufferSize = 0x10000;
            byte[] buffer = new byte[BufferSize];
            int n = 0;
            long amountLeft = length;           

            do
            {
                amountLeft -= n;
                n = sourceStream.Read(buffer, 0, (int)Math.Min(BufferSize, amountLeft));
                if (n > 0)
                {
                    destinationStream.Write(buffer, 0, n);
                }

            } while (n > 0);
        }

        internal static int CopyStreamToBuffer(Stream sourceStream, byte[] buffer, int bytesToRead)
        {
            int n = 0;
            int amountLeft = bytesToRead;
            do
            {
                n = sourceStream.Read(buffer, bytesToRead - amountLeft, amountLeft);
                amountLeft -= n;
            } while (n > 0);
            return bytesToRead - amountLeft;
        }

        internal static Uri CreateRequestUri(
                                Uri baseUri,
                                bool usePathStyleUris,
                                string accountName,
                                string containerName,
                                string blobName,
                                TimeSpan Timeout,
                                NameValueCollection queryParameters,
                                out ResourceUriComponents uriComponents
                                )
        {
            uriComponents = 
                new ResourceUriComponents(accountName, containerName, blobName);
            Uri uri = HttpRequestAccessor.ConstructResourceUri(baseUri, uriComponents, usePathStyleUris);

            if (queryParameters != null)
            {
                UriBuilder builder = new UriBuilder(uri);

                if (queryParameters.Get(StorageHttpConstants.QueryParams.QueryParamTimeout) == null)
                {
                    queryParameters.Add(StorageHttpConstants.QueryParams.QueryParamTimeout,
                    Timeout.TotalSeconds.ToString(CultureInfo.InvariantCulture));
                }

                StringBuilder sb = new StringBuilder();
                bool firstParam = true;
                foreach (string queryKey in queryParameters.AllKeys)
                {
                    if (!firstParam)
                        sb.Append("&");
                    sb.Append(HttpUtility.UrlEncode(queryKey));
                    sb.Append('=');
                    sb.Append(HttpUtility.UrlEncode(queryParameters[queryKey]));
                    firstParam = false;
                }

                if (sb.Length > 0)
                {
                    builder.Query = sb.ToString();
                }
                return builder.Uri;
            }
            else
            {
                return uri;
            }
        }

        internal static bool StringIsIPAddress(string address)
        {
            IPAddress outIPAddress;

            return IPAddress.TryParse(address, out outIPAddress);
        }

        internal static void AddMetadataHeaders(HttpWebRequest request, NameValueCollection metadata)
        {
            foreach (string key in metadata.Keys)
            {
                request.Headers.Add(
                    StorageHttpConstants.HeaderNames.PrefixForMetadata + key,
                    metadata[key]
                    );
            }
        }

        internal static bool IsValidTableName(string name)
        {
            if (string.IsNullOrEmpty(name))
            {
                return false;
            }
            Regex reg = new Regex(StorageHttpConstants.RegularExpressionStrings.ValidTableNameRegex);
            if (reg.IsMatch(name))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        internal static bool IsValidContainerOrQueueName(string name)
        {
            if (string.IsNullOrEmpty(name))
            {
                return false;
            }
            Regex reg = new Regex(StorageHttpConstants.RegularExpressionStrings.ValidContainerNameRegex);
            if (reg.IsMatch(name))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.