/// <summary>
        /// Sets up the progress listeners
        /// </summary>
        /// <param name="originalStream">The content stream</param>
        /// <param name="progressUpdateInterval">The interval at which progress needs to be published</param>
        /// <param name="sender">The objects which is trigerring the progress changes</param>
        /// <param name="callback">The callback which will be invoked when the progress changed event is trigerred</param>
        /// <returns>an <see cref="EventStream"/> object, incase the progress is setup, else returns the original stream</returns>
        public Stream SetupProgressListeners(Stream originalStream, long progressUpdateInterval, object sender, EventHandler <StreamTransferProgressArgs> callback)
        {
            var eventStream = new EventStream(originalStream, true);
            var tracker     = new StreamReadTracker(sender, callback, originalStream.Length,
                                                    progressUpdateInterval);

            eventStream.OnRead += tracker.ReadProgress;
            return(eventStream);
        }
        void SetContent(HttpRequestMessage requestMessage, IRequestData state)
        {
            var request = state.Request;

            if (requestMessage.Method == HttpMethod.Get ||
                requestMessage.Method == HttpMethod.Delete ||
                requestMessage.Method == HttpMethod.Head)
            {
                return;
            }

            byte[] requestData;
            if (request.UseQueryString)
            {
                requestMessage.Content = new ByteArrayContent(new Byte[0]);
            }
            else if (request.ContentStream != null)
            {
                var eventStream = new EventStream(request.ContentStream, true);
                var tracker     = new StreamReadTracker(this, request.OriginalRequest.StreamUploadProgressCallback,
                                                        request.ContentStream.Length, this.Config.ProgressUpdateInterval);
                eventStream.OnRead += tracker.ReadProgress;

                Stream        finalStream;
                StreamContent content;
                if (state.Request.UseChunkEncoding && state.Request.AWS4SignerResult != null)
                {
                    finalStream = new ChunkedUploadWrapperStream(eventStream, Config.BufferSize, state.Request.AWS4SignerResult);
                }
                else
                {
                    finalStream = eventStream;
                }

                content = new StreamContent(finalStream, this.Config.BufferSize);
                requestMessage.Content = content;
                requestMessage.Content.Headers.ContentLength = finalStream.Length;
            }
            else if ((requestData = GetRequestData(request)) != null)
            {
                state.Metrics.AddProperty(Metric.RequestSize, requestData.Length);
                requestMessage.Content = new ByteArrayContent(requestData);
            }
            else
            {
                requestMessage.Content = new ByteArrayContent(new Byte[0]);
            }

            requestMessage.Content.Headers.ContentType = MediaTypeHeaderValue.Parse(request.Headers["Content-Type"]);

            if (requestMessage.Content != null)
            {
                if (request.Headers.ContainsKey("Content-Range"))
                {
                    requestMessage.Content.Headers.Add("Content-Range", request.Headers["Content-Range"]);
                }

                if (request.Headers.ContainsKey("Content-MD5"))
                {
                    requestMessage.Content.Headers.TryAddWithoutValidation("Content-MD5", request.Headers["Content-MD5"]);
                }

                if (request.Headers.ContainsKey("Content-Encoding"))
                {
                    requestMessage.Content.Headers.TryAddWithoutValidation("Content-Encoding", request.Headers["Content-Encoding"]);
                }

                if (request.Headers.ContainsKey("Content-Disposition"))
                {
                    requestMessage.Content.Headers.TryAddWithoutValidation("Content-Disposition", request.Headers["Content-Disposition"]);
                }

                DateTime expires;
                if (request.Headers.ContainsKey("Expires") &&
                    DateTime.TryParse(request.Headers["Expires"], CultureInfo.InvariantCulture, DateTimeStyles.None, out expires))
                {
                    requestMessage.Content.Headers.Expires = expires;
                }
            }
        }
示例#3
0
        void getRequestStreamCallback(IAsyncResult result)
        {
            AsyncResult asyncResult = result as AsyncResult;

            if (asyncResult == null)
            {
                asyncResult = result.AsyncState as AsyncResult;
            }

            asyncResult.RequestState.GetRequestStreamCallbackCalled = true;

            try
            {
                try
                {
                    AsyncResult.AsyncRequestState state = asyncResult.RequestState;
                    if (asyncResult != null &&
                        asyncResult.RequestState != null &&
                        ((asyncResult.RequestState.RequestData != null && asyncResult.RequestState.RequestData.Length > 0) || asyncResult.RequestState.RequestStream != null) &&
                        (!asyncResult.Request.UseQueryString && (asyncResult.RequestState.WebRequest.Method == "POST" || asyncResult.RequestState.WebRequest.Method == "PUT")))
                    {
                        Stream requestStream;
                        if (asyncResult.CompletedSynchronously)
                        {
                            requestStream = state.WebRequest.GetRequestStream();
                        }
                        else
                        {
                            requestStream = state.WebRequest.EndGetRequestStream(result);
                        }

                        using (requestStream)
                        {
                            if (asyncResult.RequestState.RequestStream == null)
                            {
                                byte[] requestData = asyncResult.RequestState.RequestData;
                                asyncResult.Metrics.AddProperty(Metric.RequestSize, requestData.Length);
                                requestStream.Write(requestData, 0, requestData.Length);
                            }
                            else
                            {
                                var originalStream = asyncResult.RequestState.RequestStream;
                                var callback       = asyncResult.Request.OriginalRequest.StreamUploadProgressCallback;
                                if (callback != null)
                                {
                                    var eventStream = new EventStream(originalStream, true);
                                    var tracker     = new StreamReadTracker(this, callback, originalStream.Length, this.Config.ProgressUpdateInterval);
                                    eventStream.OnRead += tracker.ReadProgress;
                                    originalStream      = eventStream;
                                }

                                var buffer      = new byte[this.Config.BufferSize];
                                var inputStream = asyncResult.Request.UseChunkEncoding && asyncResult.Request.AWS4SignerResult != null
                                    ? new ChunkedUploadWrapperStream(originalStream,
                                                                     Config.BufferSize,
                                                                     asyncResult.Request.AWS4SignerResult)
                                    : originalStream;

                                int bytesRead   = 0;
                                int bytesToRead = buffer.Length;

                                while ((bytesRead = inputStream.Read(buffer, 0, bytesToRead)) > 0)
                                {
                                    requestStream.Write(buffer, 0, bytesRead);
                                }
                            }
                        }
                    }

                    if (asyncResult.CompletedSynchronously)
                    {
                        this.getResponseCallback(asyncResult);
                    }
                    else
                    {
                        IAsyncResult httpResult = state.WebRequest.BeginGetResponse(new AsyncCallback(this.getResponseCallback), asyncResult);
                        if (httpResult.CompletedSynchronously)
                        {
                            if (!asyncResult.RequestState.GetResponseCallbackCalled)
                            {
                                getResponseCallback(httpResult);
                            }
                            asyncResult.SetCompletedSynchronously(true);
                        }
                    }
                }
                catch (WebException e)
                {
                    asyncResult.RequestState.WebRequest.Abort();
                    HandleHttpWebErrorResponse(asyncResult, e);

                    asyncResult.RetriesAttempt++;
                    InvokeHelper(asyncResult);
                }
                catch (IOException ioe)
                {
                    if (HandleIOException(asyncResult, null, ioe))
                    {
                        asyncResult.RetriesAttempt++;
                        InvokeHelper(asyncResult);
                    }
                    else
                    {
                        throw;
                    }
                }
                catch (Exception e)
                {
                    asyncResult.RequestState.WebRequest.Abort();
                    asyncResult.Metrics.AddProperty(Metric.Exception, e);

                    asyncResult.HandleException(e);
                }
            }
            catch (Exception exception)
            {
                ProcessExceptionHandlers(exception, asyncResult.Request);
                // Handle WebException/IOExceptionexceptions/AmazonServiceException
                // thrown after retry limit is reached.
                asyncResult.HandleException(exception);
            }
        }