From 55e230ff49566e293ed62bc486b9e879731c9c14 Mon Sep 17 00:00:00 2001 From: Kenneth Skovhede Date: Wed, 17 May 2017 10:59:07 +0200 Subject: [PATCH] Reworked the way the `AllowWriteBuffering` flag is set to fix errors caused by `ContentLength` not being set. --- Duplicati/Library/Backend/CloudFiles/CloudFiles.cs | 7 ++++++- Duplicati/Library/Backend/FTP/FTPBackend.cs | 2 +- Duplicati/Library/Utility/AsyncHttpRequest.cs | 12 ++++++++---- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/Duplicati/Library/Backend/CloudFiles/CloudFiles.cs b/Duplicati/Library/Backend/CloudFiles/CloudFiles.cs index 597d17c69..1b33756d3 100644 --- a/Duplicati/Library/Backend/CloudFiles/CloudFiles.cs +++ b/Duplicati/Library/Backend/CloudFiles/CloudFiles.cs @@ -346,8 +346,13 @@ namespace Duplicati.Library.Backend { string fileHash = null; + long streamLen = -1; + try { streamLen = stream.Length; } + catch {} + + Utility.AsyncHttpRequest areq = new Utility.AsyncHttpRequest(req); - using (System.IO.Stream s = areq.GetRequestStream()) + using (System.IO.Stream s = areq.GetRequestStream(streamLen)) using (var mds = new Utility.MD5CalculatingStream(s)) { Utility.Utility.CopyStream(stream, mds, true, m_copybuffer); diff --git a/Duplicati/Library/Backend/FTP/FTPBackend.cs b/Duplicati/Library/Backend/FTP/FTPBackend.cs index c39fa96db..1aea8537d 100644 --- a/Duplicati/Library/Backend/FTP/FTPBackend.cs +++ b/Duplicati/Library/Backend/FTP/FTPBackend.cs @@ -222,7 +222,7 @@ namespace Duplicati.Library.Backend catch {} Utility.AsyncHttpRequest areq = new Utility.AsyncHttpRequest(req); - using (System.IO.Stream rs = areq.GetRequestStream()) + using (System.IO.Stream rs = areq.GetRequestStream(streamLen)) Utility.Utility.CopyStream(input, rs, true, m_copybuffer); if (m_listVerify) diff --git a/Duplicati/Library/Utility/AsyncHttpRequest.cs b/Duplicati/Library/Utility/AsyncHttpRequest.cs index adbfa7853..1592cfbf5 100644 --- a/Duplicati/Library/Utility/AsyncHttpRequest.cs +++ b/Duplicati/Library/Utility/AsyncHttpRequest.cs @@ -95,8 +95,7 @@ namespace Duplicati.Library.Utility ((HttpWebRequest)m_request).ReadWriteTimeout = System.Threading.Timeout.Infinite; // Prevent in-memory buffering causing out-of-memory issues - ((HttpWebRequest)m_request).AllowReadStreamBuffering = false; - ((HttpWebRequest)m_request).AllowWriteStreamBuffering = false; + ((HttpWebRequest)m_request).AllowReadStreamBuffering = false; } } @@ -106,7 +105,7 @@ namespace Duplicati.Library.Utility public WebRequest Request { get { return m_request; } } /// - /// Gets or sets the timeout used to guard the and calls + /// Gets or sets the timeout used to guard the and calls /// public int Timeout { get { return m_timeout; } set { m_timeout = value; } } @@ -114,8 +113,13 @@ namespace Duplicati.Library.Utility /// Gets the request stream /// /// The request stream - public Stream GetRequestStream() + /// The content length to use + public Stream GetRequestStream(long contentlength = -1) { + // Prevent in-memory buffering causing out-of-memory issues + if (contentlength >= 0 || m_request.ContentLength >= 0) + ((HttpWebRequest)m_request).AllowWriteStreamBuffering = false; + if (m_state == RequestStates.GetRequest) return (Stream)m_asyncRequest.GetResponseOrStream();