private void HandleRangeRequest(IRequest request) { var rangeHeader = request.Headers["Range"]; var response = request.CreateResponse(HttpStatusCode.PartialContent, "Welcome"); response.ContentType = "application/octet-stream"; response.AddHeader("Accept-Ranges", "bytes"); response.AddHeader("Content-Disposition", @"attachment;filename=""ReallyBigFile.Txt"""); //var fileStream = new FileStream(Environment.CurrentDirectory + @"\Ranges\ReallyBigFile.Txt", FileMode.Open, // FileAccess.Read, FileShare.ReadWrite); var fileStream = new FileStream(@"C:\Users\jgauffin\Downloads\AspNetMVC3ToolsUpdateSetup.exe", FileMode.Open, FileAccess.Read, FileShare.ReadWrite); var ranges = new RangeCollection(); ranges.Parse(rangeHeader.Value, (int)fileStream.Length); response.AddHeader("Content-Range", ranges.ToHtmlHeaderValue((int)fileStream.Length)); response.Body = new ByteRangeStream(ranges, fileStream); Send(response); }
/// <summary> /// Handle the request. /// </summary> /// <param name="context">HTTP context</param> /// <returns><see cref="ModuleResult.Stop"/> will stop all processing except <see cref="IHttpModule.EndRequest"/>.</returns> /// <remarks>Invoked in turn for all modules unless you return <see cref="ModuleResult.Stop"/>.</remarks> public ModuleResult HandleRequest(IHttpContext context) { // only handle GET and HEAD if (!context.Request.Method.Equals("GET", StringComparison.OrdinalIgnoreCase) && !context.Request.Method.Equals("HEAD", StringComparison.OrdinalIgnoreCase)) { return(ModuleResult.Continue); } // serve a directory if (ListFiles) { if (TryGenerateDirectoryPage(context)) { return(ModuleResult.Stop); } } var header = context.Request.Headers["If-Modified-Since"]; var time = header != null ? DateTime.ParseExact(header.Value, "R", CultureInfo.InvariantCulture) : DateTime.MinValue; var fileContext = new FileContext(context.Request, time); _fileService.GetFile(fileContext); if (!fileContext.IsFound) { return(ModuleResult.Continue); } if (!fileContext.IsModified) { context.Response.StatusCode = (int)HttpStatusCode.NotModified; context.Response.StatusDescription = "Was last modified " + fileContext.LastModifiedAtUtc.ToString("R"); return(ModuleResult.Stop); } var mimeType = MimeTypeProvider.Instance.Get(fileContext.Filename); if (mimeType == null) { context.Response.StatusCode = (int)HttpStatusCode.UnsupportedMediaType; context.Response.StatusDescription = string.Format("File type '{0}' is not supported.", Path.GetExtension(fileContext.Filename)); return(ModuleResult.Stop); } context.Response.AddHeader("Last-Modified", fileContext.LastModifiedAtUtc.ToString("R")); context.Response.AddHeader("Accept-Ranges", "bytes"); context.Response.AddHeader("Content-Disposition", "inline;filename=\"" + Path.GetFileName(fileContext.Filename) + "\""); context.Response.ContentType = mimeType; context.Response.ContentLength = (int)fileContext.FileStream.Length; // ranged/partial transfers var rangeHeader = context.Request.Headers["Range"]; if (rangeHeader != null && !string.IsNullOrEmpty(rangeHeader.Value)) { var ranges = new RangeCollection(); ranges.Parse(rangeHeader.Value, (int)fileContext.FileStream.Length); context.Response.AddHeader("Content-Range", ranges.ToHtmlHeaderValue((int)fileContext.FileStream.Length)); context.Response.Body = new ByteRangeStream(ranges, fileContext.FileStream); context.Response.ContentLength = ranges.TotalLength; context.Response.StatusCode = 206; } else { context.Response.Body = fileContext.FileStream; } // do not include a body when the client only want's to get content information. if (context.Request.Method.Equals("HEAD", StringComparison.OrdinalIgnoreCase)) { context.Response.Body.Dispose(); context.Response.Body = null; } return(ModuleResult.Stop); }
/// <summary> /// Handle the request. /// </summary> /// <param name="context">HTTP context</param> /// <returns><see cref="ModuleResult.Stop"/> will stop all processing except <see cref="IHttpModule.EndRequest"/>.</returns> /// <remarks>Invoked in turn for all modules unless you return <see cref="ModuleResult.Stop"/>.</remarks> public ModuleResult HandleRequest(IHttpContext context) { // only handle GET and HEAD if (!context.Request.HttpMethod.Equals("GET", StringComparison.OrdinalIgnoreCase) && !context.Request.HttpMethod.Equals("HEAD", StringComparison.OrdinalIgnoreCase)) return ModuleResult.Continue; // serve a directory if (AllowFileListing) { if (TryGenerateDirectoryPage(context)) return ModuleResult.Stop; } var header = context.Request.Headers["If-Modified-Since"]; var time = header != null ? DateTime.ParseExact(header, "R", CultureInfo.InvariantCulture) : DateTime.MinValue; var fileContext = new FileContext(context.Request, time); _fileService.GetFile(fileContext); if (!fileContext.IsFound) return ModuleResult.Continue; if (!fileContext.IsModified) { context.Response.StatusCode = (int)HttpStatusCode.NotModified; context.Response.ReasonPhrase = "Was last modified " + fileContext.LastModifiedAtUtc.ToString("R"); return ModuleResult.Stop; } if (fileContext.IsGzipSubstitute) { context.Response.AddHeader("Content-Encoding", "gzip"); } var mimeType = MimeTypeProvider.Instance.Get(fileContext.Filename); if (mimeType == null) { context.Response.StatusCode = (int)HttpStatusCode.UnsupportedMediaType; context.Response.ReasonPhrase = string.Format("File type '{0}' is not supported.", Path.GetExtension(fileContext.Filename)); return ModuleResult.Stop; } context.Response.AddHeader("Last-Modified", fileContext.LastModifiedAtUtc.ToString("R")); context.Response.AddHeader("Accept-Ranges", "bytes"); context.Response.AddHeader("Content-Disposition", "inline;filename=\"" + Path.GetFileName(fileContext.Filename) + "\""); context.Response.ContentType = mimeType; context.Response.ContentLength = (int)fileContext.FileStream.Length; // ranged/partial transfers var rangeStr = context.Request.Headers["Range"]; if (!string.IsNullOrEmpty(rangeStr)) { var ranges = new RangeCollection(); ranges.Parse(rangeStr, (int)fileContext.FileStream.Length); context.Response.AddHeader("Content-Range", ranges.ToHtmlHeaderValue((int)fileContext.FileStream.Length)); context.Response.Body = new ByteRangeStream(ranges, fileContext.FileStream); context.Response.ContentLength = ranges.TotalLength; context.Response.StatusCode = 206; } else context.Response.Body = fileContext.FileStream; // do not include a body when the client only want's to get content information. if (context.Request.HttpMethod.Equals("HEAD", StringComparison.OrdinalIgnoreCase) && context.Response.Body != null) { context.Response.Body.Dispose(); context.Response.Body = null; } return ModuleResult.Stop; }