public Metadata ToHeaders() { Metadata headers = new Metadata(); headers.Add("filename", FileName); headers.Add("compression", Compression.ToString()); headers.Add("offset", Offset.ToString()); if (FileSize > 0) { headers.Add("filesize", FileSize.ToString()); } if (ChunkSize > 0) { headers.Add("chunksize", ChunkSize.ToString()); } if (ErrorType != null) { headers.Add("errortype", ErrorType); } if (ErrorMessage != null) { headers.Add("errormessage", ErrorMessage); } return(headers); }
public Metadata GetHeaders() { Metadata headers = new Metadata(); headers.Add("fileName", FileName); headers.Add("offset", Offset.ToString()); if (FileSize >= 0) { headers.Add("fileSize", FileSize.ToString()); } if (ChunkSize >= 0) { headers.Add("chunkSize", ChunkSize.ToString()); } if (Compression == CopyCompression.Gzip) { headers.Add("compression", Compression.ToString()); } if (Error is null) { headers.Add("success", "true"); } else { headers.Add("success", "false"); headers.Add("exception", Error.GetType().Name); headers.Add("message", Error.Message); } return(headers); }
public Metadata ToMetadata() { Metadata headers = new Metadata(); headers.Add("compression", Compression.ToString()); headers.Add("filename", FileName); return(headers); }
/// <summary> /// Implements a copy file request. /// </summary> private async Task CopyFileAsync(CopyFileRequest request, IServerStreamWriter <CopyFileResponse> responseStream, ServerCallContext context) { try { LogRequestHandling(); // Get the content stream. Context cacheContext = new Context(new Guid(request.TraceId), _logger); HashType type = (HashType)request.HashType; ContentHash hash = request.ContentHash.ToContentHash((HashType)request.HashType); OpenStreamResult result = await GetFileStreamAsync(cacheContext, hash); using (result.Stream) { // Figure out response headers. CopyCompression compression = CopyCompression.None; Metadata headers = new Metadata(); switch (result.Code) { case OpenStreamResult.ResultCode.ContentNotFound: headers.Add("Exception", "ContentNotFound"); headers.Add("Message", $"Requested content at {hash} not found."); break; case OpenStreamResult.ResultCode.Error: Debug.Assert(result.Exception != null); headers.Add("Exception", result.Exception.GetType().Name); headers.Add("Message", result.Exception.Message); break; case OpenStreamResult.ResultCode.Success: Debug.Assert(result.Stream != null); long size = result.Stream.Length; headers.Add("FileSize", size.ToString()); if ((request.Compression == CopyCompression.Gzip) && (size > _bufferSize)) { compression = CopyCompression.Gzip; } headers.Add("Compression", compression.ToString()); headers.Add("ChunkSize", _bufferSize.ToString()); break; default: throw new NotImplementedException(); } // Send the response headers. await context.WriteResponseHeadersAsync(headers); // Send the content. if (result.Succeeded) { _logger.Debug($"Streaming file through GRPC with GZip {(compression == CopyCompression.Gzip ? "on" : "off")}"); byte[] buffer = new byte[_bufferSize]; switch (compression) { case CopyCompression.None: await StreamContentAsync(result.Stream, buffer, responseStream, context.CancellationToken); break; case CopyCompression.Gzip: await StreamContentWithCompressionAsync(result.Stream, buffer, responseStream, context.CancellationToken); break; } } } } catch (Exception) { throw; } }
/// <summary> /// Implements a copy file request. /// </summary> private async Task CopyFileAsync(CopyFileRequest request, IServerStreamWriter <CopyFileResponse> responseStream, ServerCallContext context) { OperationStarted(); // Get the content stream. Context cacheContext = new Context(new Guid(request.TraceId), Logger); ContentHash hash = request.GetContentHash(); OpenStreamResult result = await GetFileStreamAsync(cacheContext, hash); // If result is unsuccessful, then result.Stream is null, but using(null) is just a no op. using (result.Stream) { // Figure out response headers. CopyCompression compression = CopyCompression.None; Metadata headers = new Metadata(); switch (result.Code) { case OpenStreamResult.ResultCode.ContentNotFound: headers.Add("Exception", "ContentNotFound"); headers.Add("Message", $"Requested content at {hash} not found."); break; case OpenStreamResult.ResultCode.Error: Contract.Assert(result.Exception != null); headers.Add("Exception", result.Exception.GetType().Name); headers.Add("Message", result.Exception.Message); break; case OpenStreamResult.ResultCode.Success: Contract.Assert(result.Stream != null); long size = result.Stream.Length; headers.Add("FileSize", size.ToString()); if ((request.Compression == CopyCompression.Gzip) && (size > _gzipSizeBarrier)) { compression = CopyCompression.Gzip; } headers.Add("Compression", compression.ToString()); headers.Add("ChunkSize", _bufferSize.ToString()); break; default: throw new NotImplementedException($"Unknown result.Code '{result.Code}'."); } // Send the response headers. await context.WriteResponseHeadersAsync(headers); // Send the content. if (result.Succeeded) { var operationContext = new OperationContext(cacheContext, context.CancellationToken); using (var arrayHandle = _pool.Get()) { StreamContentDelegate streamContent = compression == CopyCompression.None ? (StreamContentDelegate)StreamContentAsync : StreamContentWithCompressionAsync; byte[] buffer = arrayHandle.Value; await operationContext.PerformOperationAsync( _tracer, () => streamContent(result.Stream, buffer, responseStream, context.CancellationToken), traceOperationStarted : false, // Tracing only stop messages extraEndMessage : r => $"Hash={hash.ToShortString()}, GZip={(compression == CopyCompression.Gzip ? "on" : "off")}.") .IgnoreFailure(); // The error was already logged. } } } }