Beispiel #1
0
        public async Task CreateContainer(string containerName, bool isPublic, int retries, int millisecondsBetweenRetries)
        {
            HttpStatusCode statusCode;
            StorageExtendedErrorInformation error;

            while (true)
            {
                HttpRequestMessage request = BlobTests.CreateContainerRequest(BlobContext, containerName);
                Assert.IsTrue(request != null, "Failed to create HttpRequestMessage");
                if (isPublic)
                {
                    request.Headers.Add("x-ms-blob-public-access", "container");
                }

                using (HttpResponseMessage response = await BlobTestUtils.GetResponse(request, BlobContext))
                {
                    statusCode = response.StatusCode;
                    string statusDescription = response.ReasonPhrase;
                    error = await StorageExtendedErrorInformation.ReadFromStreamAsync(
                        HttpResponseParsers.GetResponseStream(response));
                }

                // if the container is being deleted, retry up to the specified times.
                if (statusCode == HttpStatusCode.Conflict && error != null && error.ErrorCode == BlobErrorCodeStrings.ContainerBeingDeleted && retries > 0)
                {
                    await Task.Delay(millisecondsBetweenRetries);

                    retries--;
                    continue;
                }

                break;
            }
        }
        internal async static Task <StorageException> PopulateStorageExceptionFromHttpResponseMessage(HttpResponseMessage response, RequestResult currentResult, CancellationToken token, Func <Stream, HttpResponseMessage, string, CancellationToken, Task <StorageExtendedErrorInformation> > parseError)
        {
            if (!response.IsSuccessStatusCode)
            {
                try
                {
                    currentResult.HttpStatusMessage = response.ReasonPhrase;
                    currentResult.HttpStatusCode    = (int)response.StatusCode;
                    currentResult.ServiceRequestID  = HttpResponseMessageUtils.GetHeaderSingleValueOrDefault(response.Headers, Constants.HeaderConstants.RequestIdHeader);

                    string tempDate = HttpResponseMessageUtils.GetHeaderSingleValueOrDefault(response.Headers, Constants.HeaderConstants.Date);
                    currentResult.RequestDate = string.IsNullOrEmpty(tempDate) ? DateTime.Now.ToString("R", CultureInfo.InvariantCulture) : tempDate;

                    if (response.Headers.ETag != null)
                    {
                        currentResult.Etag = response.Headers.ETag.ToString();
                    }

                    if (response.Content != null && response.Content.Headers.ContentMD5 != null)
                    {
                        currentResult.ContentMd5 = Convert.ToBase64String(response.Content.Headers.ContentMD5);
                    }

                    if (response.Content != null && HttpResponseParsers.GetContentCRC64(response) != null)
                    {
                        currentResult.ContentCrc64 = HttpResponseParsers.GetContentCRC64(response);
                    }

                    currentResult.ErrorCode = HttpResponseMessageUtils.GetHeaderSingleValueOrDefault(response.Headers, Constants.HeaderConstants.StorageErrorCodeHeader);
                }
                catch (Exception)
                {
                    // no op
                }

                try
                {
                    Stream errStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);

                    if (parseError != null)
                    {
                        currentResult.ExtendedErrorInformation = await parseError(errStream, response, response.Content.Headers.ContentType.ToString(), token).ConfigureAwait(false);
                    }
                    else
                    {
                        currentResult.ExtendedErrorInformation = await StorageExtendedErrorInformation.ReadFromStreamAsync(errStream, token).ConfigureAwait(false);
                    }
                }
                catch (Exception)
                {
                    // no op
                }

                return(new StorageException(currentResult, response.ReasonPhrase, null));
            }
            else
            {
                return(null);
            }
        }
Beispiel #3
0
        public async Task CreateShare(string shareName, int retries, int millisecondsBetweenRetries)
        {
            while (true)
            {
                HttpRequestMessage request = FileTests.CreateShareRequest(FileContext, shareName);
                Assert.IsTrue(request != null, "Failed to create HttpRequestMessage");

                HttpResponseMessage response = await FileTestUtils.GetResponse(request, FileContext);

                HttpStatusCode statusCode             = response.StatusCode;
                string         statusDescription      = response.ReasonPhrase;
                StorageExtendedErrorInformation error = await StorageExtendedErrorInformation.ReadFromStreamAsync(await response.Content.ReadAsStreamAsync());

                response.Dispose();

                // if the share is being deleted, retry up to the specified times.
                if (statusCode == HttpStatusCode.Conflict && error != null && error.ErrorCode == FileErrorCodeStrings.ShareBeingDeleted && retries > 0)
                {
                    Thread.Sleep(millisecondsBetweenRetries);
                    retries--;
                    continue;
                }

                Assert.AreNotEqual(HttpStatusCode.NotFound, statusCode, "Failed to create share");

                break;
            }
        }
Beispiel #4
0
        internal static async Task <IList <BlobBatchSubOperationResponse> > BatchPostProcessAsync(IList <BlobBatchSubOperationResponse> result, RESTCommand <IList <BlobBatchSubOperationResponse> > cmd, IList <HttpStatusCode> successfulStatusCodes, HttpResponseMessage response, OperationContext ctx, /*BlobRequestOptions options,*/ CancellationToken cancellationToken)
        {
            // TODO reimplement to use ASP.NET extensions to parse multipart content from content stream

            Stream       responseStream = cmd.ResponseStream;
            StreamReader streamReader   = new StreamReader(responseStream);

            List <BlobBatchSubOperationError> errors = new List <BlobBatchSubOperationError>();

            string currentLine = await streamReader.ReadLineAsync().ConfigureAwait(false);

            currentLine = await streamReader.ReadLineAsync().ConfigureAwait(false);

            while ((currentLine != null) && !(currentLine.StartsWith(@"--batchresponse") && currentLine.EndsWith("--")))
            {
                while ((currentLine != null) && !currentLine.StartsWith("Content-ID"))
                {
                    currentLine = await streamReader.ReadLineAsync().ConfigureAwait(false);
                }
                int operationIndex = int.Parse(currentLine.Split(':')[1]);

                while ((currentLine != null) && !currentLine.StartsWith("HTTP"))
                {
                    currentLine = await streamReader.ReadLineAsync().ConfigureAwait(false);
                }
                // The first line of the response looks like this:
                // HTTP/1.1 204 No Content
                // The HTTP status code is chars 9 - 11.
                var statusCode = (HttpStatusCode)int.Parse(currentLine.Substring(9, 3));

                currentLine = await streamReader.ReadLineAsync().ConfigureAwait(false);

                if (successfulStatusCodes.Contains(statusCode))
                {
                    BlobBatchSubOperationResponse subResponse = new BlobBatchSubOperationResponse
                    {
                        StatusCode     = statusCode,
                        OperationIndex = operationIndex,
                        Headers        = await ParseSubRequestHeadersAsync(currentLine, streamReader).ConfigureAwait(false)
                    };

                    // Can add logic to parse body here if necessary.

                    result.Add(subResponse);
                }
                else
                {
                    // ProcessExpectedStatusCodesNoException? How to share list of expected codes to avoid duplication? Change list type to HttpStatusCode.
                    BlobBatchSubOperationError error = new BlobBatchSubOperationError
                    {
                        OperationIndex = operationIndex,
                        StatusCode     = statusCode
                    };
                    Dictionary <string, string> headers = await ParseSubRequestHeadersAsync(currentLine, streamReader).ConfigureAwait(false);

                    error.ErrorCode = headers[Constants.HeaderConstants.StorageErrorCodeHeader];
                    int contentLength = int.Parse(headers[Constants.HeaderConstants.ContentLengthHeader]);

                    //TODO: Add check that contentLength > 0 in case we support HEAD operations.

                    char[] errorInfoBuffer = new char[contentLength];
                    var    position        = 0;

                    while (position < contentLength)
                    {
                        errorInfoBuffer[position++] = (char)streamReader.Read();
                    }

                    error.ExtendedErrorInformation = await StorageExtendedErrorInformation.ReadFromStreamAsync(new MemoryStream(Encoding.UTF8.GetBytes(errorInfoBuffer))).ConfigureAwait(false); // Is this safe/performant?

                    errors.Add(error);
                }

                currentLine = await streamReader.ReadLineAsync().ConfigureAwait(false);
            }

            if (errors.Count > 0)
            {
                BlobBatchException ex = new BlobBatchException
                {
                    ErrorResponses      = errors,
                    SuccessfulResponses = result
                };
                throw ex;
            }
            return(result);
        }