Example #1
0
        HttpRequestMessage Build(HttpTransferStore request)
        {
            var message = new HttpRequestMessage(new HttpMethod(request.HttpMethod), request.Uri);

            //message.Headers.ExpectContinue = false;
            message.Headers.TransferEncodingChunked = true;
            //message.Headers.Add("Keep-Alive", false);

            foreach (var header in request.Headers)
            {
                message.Headers.Add(header.Key, header.Value);
            }

            return(message);
        }
Example #2
0
        // TODO: pause due to network
        async Task <HttpTransfer> Upload(HttpTransferStore request, CancellationToken ct)
        {
            var          file             = new FileInfo(request.LocalFile);
            var          status           = HttpTransferState.Pending;
            var          bytesTransferred = 0L;
            Exception    exception        = null;
            HttpTransfer lastTransfer     = default;

            // and not cancelled or error
            while (!status.IsCompleted() && !ct.IsCancellationRequested)
            {
                try
                {
                    var content = new MultipartFormDataContent();
                    content.Add(
                        new ProgressStreamContent(
                            file.OpenRead(),
                            8192,
                            sent =>
                    {
                        status            = HttpTransferState.InProgress;
                        bytesTransferred += sent;
                        lastTransfer      = new HttpTransfer(
                            request.Id,
                            request.Uri,
                            request.LocalFile,
                            true,
                            request.UseMeteredConnection,
                            null,
                            file.Length,
                            bytesTransferred,
                            status
                            );
                        this.messageBus.Publish(lastTransfer);
                    }
                            ),
                        "blob",
                        file.Name
                        );
                    var message = this.Build(request);
                    await this.httpClient
                    .SendAsync(message, ct)
                    .ConfigureAwait(false);

                    status = HttpTransferState.Completed;
                }
                catch (TimeoutException)
                {
                    status = HttpTransferState.Retrying;
                }
                catch (IOException ex)
                {
                    if (ex.InnerException is WebException)
                    {
                        status = HttpTransferState.Retrying;
                    }
                    else
                    {
                        exception = ex;
                        status    = HttpTransferState.Error;
                    }
                }
                //Java.Net.ProtocolException
                catch (WebException ex)
                {
                    switch (ex.Status)
                    {
                    case WebExceptionStatus.ConnectFailure:
                    case WebExceptionStatus.Timeout:
                        status = HttpTransferState.Retrying;
                        break;

                    default:
                        status    = HttpTransferState.Error;
                        exception = ex;
                        break;
                    }
                }
                catch (TaskCanceledException)
                {
                    status = ct.IsCancellationRequested
                        ? HttpTransferState.Canceled
                        : HttpTransferState.Retrying;
                }
                catch (Exception ex)
                {
                    exception = ex;
                    status    = HttpTransferState.Error;
                }
                lastTransfer = new HttpTransfer(
                    request.Id,
                    request.Uri,
                    request.LocalFile,
                    true,
                    request.UseMeteredConnection,
                    exception,
                    file.Length,
                    bytesTransferred,
                    status
                    );
                this.messageBus.Publish(lastTransfer);
            }
            return(lastTransfer);
        }
Example #3
0
        async Task <HttpTransfer> Download(HttpTransferStore request, CancellationToken ct)
        {
            HttpTransfer lastTransfer     = default;
            var          status           = HttpTransferState.Pending;
            var          file             = new FileInfo(request.LocalFile);
            var          message          = this.Build(request);
            var          fileSize         = 0L;
            var          bytesTransferred = file.Exists ? file.Length : 0;
            Exception    exception        = null;
            var          fileMode         = file.Exists ? FileMode.Append : FileMode.Create;

            using (var fs = file.Open(fileMode, FileAccess.Write, FileShare.Write))
            {
                while (!status.IsCompleted() && !ct.IsCancellationRequested)
                {
                    try
                    {
                        if (fs.Length > 0)
                        {
                            var resumeOffset = fs.Length + 1;
                            message.Headers.Range = new RangeHeaderValue(resumeOffset, null);
                        }

                        var buffer   = new byte[65535];
                        var response = await this.httpClient
                                       .SendAsync(
                            message,
                            HttpCompletionOption.ResponseHeadersRead,
                            ct
                            )
                                       .ConfigureAwait(false);


                        response.EnsureSuccessStatusCode();

                        var inputStream = await response
                                          .Content
                                          .ReadAsStreamAsync()
                                          .ConfigureAwait(false);

                        var read = inputStream.Read(buffer, 0, buffer.Length);

                        // status code 206 means restart
                        if (response.Headers.AcceptRanges == null && fs.Length > 0)
                        {
                            // resume not supported, starting over
                            fs.SetLength(0);
                            fs.Flush();
                            bytesTransferred = 0;
                        }

                        var i = 0;
                        while (read > 0 && !ct.IsCancellationRequested)
                        {
                            fileSize = response.Content.Headers?.ContentRange?.Length ?? response.Content?.Headers?.ContentLength ?? 0;
                            //this.RemoteFileName = response.Content?.Headers?.ContentDisposition?.FileName ?? String.Empty;
                            ////pr.FileSize = response.Content?.Headers?.ContentLength ?? 0; // this will change on resume
                            bytesTransferred += read;

                            fs.Write(buffer, 0, read);
                            fs.Flush();

                            i++;
                            if (i % 4 == 0)
                            {
                                lastTransfer = new HttpTransfer(
                                    request.Id,
                                    request.Uri,
                                    request.LocalFile,
                                    false,
                                    request.UseMeteredConnection,
                                    null,
                                    fileSize,
                                    bytesTransferred,
                                    HttpTransferState.InProgress
                                    );
                                this.messageBus.Publish(lastTransfer);
                            }
                            read = inputStream.Read(buffer, 0, buffer.Length);
                        }
                        status = HttpTransferState.Completed;
                    }
                    catch (TaskCanceledException)
                    {
                        status = ct.IsCancellationRequested
                            ? HttpTransferState.Canceled
                            : HttpTransferState.Retrying;
                    }
                    catch (IOException ex)
                    {
                        if (ex.InnerException is WebException)
                        {
                            status = HttpTransferState.Retrying;
                        }
                        else
                        {
                            exception = ex;
                            status    = HttpTransferState.Error;
                        }
                    }
                    catch (Exception ex)
                    {
                        exception = ex;
                        status    = HttpTransferState.Error;
                    }
                    lastTransfer = new HttpTransfer(
                        request.Id,
                        request.Uri,
                        request.LocalFile,
                        true,
                        request.UseMeteredConnection,
                        exception,
                        fileSize,
                        bytesTransferred,
                        status
                        );
                    this.messageBus.Publish(lastTransfer);
                }
            }
            return(lastTransfer);
        }