public async Task <bool> ServeAsync( IHttpRequest request, IHttpResponse response) { // Early exit for non GET/HEAD request if (request.Header.Method != HttpRequestMethod.GET && request.Header.Method != HttpRequestMethod.HEAD) { return(false); } // Early exit if the request is not for a file if (false == _fileServer.TryResolve(request, out string resolvedPathToFile)) { return(false); } // Now write the header and contents response.Header[HttpKeys.ContentType] = _fileServer.GetContentTypeHeader(resolvedPathToFile); using (var fs = _fileServer.OpenRead(resolvedPathToFile)) { response.Header[HttpKeys.ContentLength] = fs.Length.ToString(CultureInfo.InvariantCulture); // Write body (only for GET request) if (request.Header.Method == HttpRequestMethod.GET) { await fs.CopyToAsync(response.Body, _tcpSettings.ReadWriteBufferSize); } // For HEAD request, we are not sending the body, // Immediatly flush the header to prevent Content-length // validation on body upon completion of this request. else { await response.SendHeaderAsync(); } } // Return true, as we have served the content return(true); }
public static async Task WriteAsync( this IStaticFileServer inst, IHttpRequest request, StaticRangeRequest rangeRequest, IHttpResponse response, string pathToContentFile, int writeBufferSize) { Validation.RequireValidBufferSize(writeBufferSize); // Set headers response.Header[HttpKeys.ContentType] = inst.GetContentTypeHeader(pathToContentFile); // Open the file using (var fs = inst.OpenRead(pathToContentFile)) { // The requested range may contains relative values, // Convert them to absolute values here, as we knew the // content length rangeRequest = rangeRequest.ToAbsolute(fs.Length); // Set headers (cont) var contentLength = rangeRequest.To - rangeRequest.From + 1L; response.Header[HttpKeys.ContentLength] = contentLength.Str(); response.Header[HttpKeys.ContentRange] = rangeRequest.GenerateRangeHeaderValue(fs.Length); // Write body (for GET method only) if (request.Header.Method == HttpRequestMethod.GET) { fs.Position = rangeRequest.From; await fs.CopyToAsync( response.Body, count : contentLength, bufferSize : writeBufferSize); } } }
public static async Task WriteAsync( this IStaticFileServer staticFileServer, IHttpRequest request, StaticRangeRequest[] ranges, IHttpResponse response, string pathToContentFile, int writeBufferSize) { var contentType = staticFileServer.GetContentTypeHeader(pathToContentFile); using (var fs = staticFileServer.OpenRead(pathToContentFile)) { for (var i = 0; i < ranges.Length; i++) { ranges[i] = ranges[i].ToAbsolute(fs.Length); } // Write header var chunks = GenerateChunks(ranges, fs.Length, contentType); response.Header[HttpKeys.ContentType] = $"multipart/byteranges; boundary={MultiRangeBoundaryString}"; response.Header[HttpKeys.ContentLength] = CalculateContentLength(chunks).Str(); // Write body and footer (GET method only) if (request.Header.Method == HttpRequestMethod.GET) { for (var i = 0; i < chunks.Count; i++) { await WriteChunkBody(response, writeBufferSize, fs, chunks[i]); } await response.Body.WriteAsync( MultiRangeBoundaryFooterString, writeBufferSize ); } } }