public void Get(string remotename, System.IO.Stream stream) { AsyncHttpRequest req; if (m_filecache == null || !m_filecache.ContainsKey(remotename)) List(); if (m_filecache != null && m_filecache.ContainsKey(remotename)) req = new AsyncHttpRequest(m_helper.CreateRequest(string.Format("{0}/b2api/v1/b2_download_file_by_id?fileId={1}", m_helper.DownloadUrl, Library.Utility.Uri.UrlEncode(GetFileID(remotename))))); else req = new AsyncHttpRequest(m_helper.CreateRequest(string.Format("{0}/{1}{2}", m_helper.DownloadUrl, m_urlencodedprefix, Library.Utility.Uri.UrlPathEncode(remotename)))); try { using(var resp = req.GetResponse()) using(var rs = req.GetResponseStream()) Library.Utility.Utility.CopyStream(rs, stream); } catch (Exception ex) { if (B2AuthHelper.GetExceptionStatusCode(ex) == HttpStatusCode.NotFound) throw new FileMissingException(); B2AuthHelper.AttemptParseAndThrowException(ex); throw; } }
public void Put(string remotename, System.IO.Stream stream) { TempFile tmp = null; // A bit dirty, but we need the underlying stream to compute the hash without any interference var measure = stream; while (measure is OverrideableStream) { measure = typeof(OverrideableStream).GetField("m_basestream", System.Reflection.BindingFlags.DeclaredOnly | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).GetValue(measure) as System.IO.Stream; } if (measure == null) { throw new Exception(string.Format("Unable to unwrap stream from: {0}", stream.GetType())); } string sha1; if (measure.CanSeek) { // Record the stream position var p = measure.Position; // Compute the hash using (var hashalg = Duplicati.Library.Utility.HashAlgorithmHelper.Create("sha1")) sha1 = Library.Utility.Utility.ByteArrayAsHexString(hashalg.ComputeHash(measure)); // Reset the stream position measure.Position = p; } else { // No seeking possible, use a temp file tmp = new TempFile(); using (var sr = System.IO.File.OpenWrite(tmp)) using (var hc = new HashCalculatingStream(measure, "sha1")) { Library.Utility.Utility.CopyStream(hc, sr); sha1 = hc.GetFinalHashString(); } stream = System.IO.File.OpenRead(tmp); } if (m_filecache == null) { List(); } try { var fileinfo = m_helper.GetJSONData <UploadFileResponse>( UploadUrlData.UploadUrl, req => { req.Method = "POST"; req.Headers["Authorization"] = UploadUrlData.AuthorizationToken; req.Headers["X-Bz-Content-Sha1"] = sha1; req.Headers["X-Bz-File-Name"] = m_urlencodedprefix + Utility.Uri.UrlPathEncode(remotename); req.ContentType = "application/octet-stream"; req.ContentLength = stream.Length; }, req => { using (var rs = req.GetRequestStream()) Utility.Utility.CopyStream(stream, rs); } ); // Delete old versions if (m_filecache.ContainsKey(remotename)) { Delete(remotename); } m_filecache[remotename] = new List <FileEntity>(); m_filecache[remotename].Add(new FileEntity() { FileID = fileinfo.FileID, FileName = fileinfo.FileName, Action = "upload", Size = fileinfo.ContentLength, UploadTimestamp = (long)(DateTime.UtcNow - Utility.Utility.EPOCH).TotalMilliseconds }); } catch (Exception ex) { m_filecache = null; var code = (int)B2AuthHelper.GetExceptionStatusCode(ex); if (code >= 500 && code <= 599) { m_uploadUrl = null; } throw; } finally { try { if (tmp != null) { tmp.Dispose(); } } catch { } } }