Git Product home page Git Product logo

thorium / owin.compression Goto Github PK

View Code? Open in Web Editor NEW
22.0 8.0 11.0 551 KB

Compression (Deflate / GZip) module for Microsoft OWIN filesystem pipeline. Works with Selfhost and also on AspNetCore.

Home Page: https://Thorium.github.io/Owin.Compression/

License: The Unlicense

Batchfile 0.37% F# 97.38% Shell 2.25%
owin compression webserver speedup gzip deflate etag aspnet-core aspnetcore kestrel

owin.compression's Introduction

Owin.Compression

Compression (Deflate / GZip) module for Microsoft OWIN Selfhost filesystem pipeline. Can be used also with AspNetCore e.g. with .NET8.0 and Kestrel.

With this module you can compress, deflate / gzip large files (like concatenated *.js or *.css files) to reduce amount of web traffic. Supports eTag caching: If client sent hashcode match, sends 302 instead of re-sending the same content.

This project works on C# and F# and should work on all .NET platforms, also on Windows, and even Mono as well.

Here is a demo in action from Fiddler net traffic monitor:

compressed

Read the Getting started tutorial to learn more.

Documentation: https://thorium.github.io/Owin.Compression

owin.compression's People

Contributors

forki avatar nipa-msft avatar thorium avatar tom-sloboda avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

owin.compression's Issues

ETAG is always the same

I have a simple OWIN application. On GET it returns a big chunk of JSON.

When compression enabled, it computes an ETAG and the ETAG remains the same even if the data changes.

After playing a bit with sources it turns out if I change the following line

                    if usecompress && checkNoValidETag(context.Response.Body) then

to

                    if usecompress && checkNoValidETag(buffer) then

and add this

        let getMd5Hash (item:Stream) =
            item.Position <- 0L

it starts to work and properly computes ETAG.

But it doesn't feel like it's a correct fix.

Missing FSharp.Core dependency

Upon downloading the nuget package into a brand new C# project and adding the appropriate app.UseCompressionModule() code, I start my self hosted server and get the following error:

System.TypeInitializationException was unhandled by user code
  HResult=-2146233036
  Message=The type initializer for '<StartupCode$Owin-Compression>.$CompressionModule' threw an exception.
  Source=Owin.Compression
  TypeName=<StartupCode$Owin-Compression>.$CompressionModule
  StackTrace:
       at Owin.OwinCompression.get_DefaultCompressionSettings()
       at Owin.CompressionExtensions.UseCompressionModule(IAppBuilder app)
       at AspNetSelfHostDemo.Startup.Configuration(IAppBuilder app) in {{path-to-project-hidden}}\Startup.cs:line 52
  InnerException: 
       FileName=FSharp.Core, Version=4.4.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
       FusionLog==== Pre-bind state information ===
LOG: DisplayName = FSharp.Core, Version=4.4.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
 (Fully-specified)
LOG: Appbase = file:///{{path-to-project-hidden}}/bin/Debug/
LOG: Initial PrivatePath = NULL
Calling assembly : Owin.Compression, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null.
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: {{path-to-project-hidden}}\bin\Debug\AspNetSelfHostDemo.vshost.exe.Config
LOG: Using host configuration file: 
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
LOG: Post-policy reference: FSharp.Core, Version=4.4.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
LOG: Attempting download of new URL file:///{{path-to-project-hidden}}/bin/Debug/FSharp.Core.DLL.
LOG: Attempting download of new URL file:///{{path-to-project-hidden}}/bin/Debug/FSharp.Core/FSharp.Core.DLL.
LOG: Attempting download of new URL file:///{{path-to-project-hidden}}/bin/Debug/FSharp.Core.EXE.
LOG: Attempting download of new URL file:///{{path-to-project-hidden}}/bin/Debug/FSharp.Core/FSharp.Core.EXE.

       HResult=-2147024894
       Message=Could not load file or assembly 'FSharp.Core, Version=4.4.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.
       Source=Owin.Compression
       StackTrace:
            at <StartupCode$Owin-Compression>.$CompressionModule..cctor()
       InnerException: 

Downloading the FSharp.Core nuget package fixes the error. Are you assuming your user has FSharp installed on their machine? Seems like a poor assumption or one that should be mentioned in your documentation somewhere.

Also begs the question why should I have a dependency on FSharp.Core in my C# project....

Compression Based on Mime Type of Response

Hello,
I notice that you may be assuming that anything without an extension is inherently compressable. This is not the case for us, virtually nothing has an extension.
e.g.
GET /swagger/ui/images/logo_small-png

We would really like to be able to define what responses are compressed based on the response mime-type.
At the moment everything and anything without an extension is compressed.


let compressableExtension =
match context.Request.Path.ToString() with
| null -> true
| x when x.Contains(".") ->
let typemap = settings.AllowedExtensionAndMimeTypes |> Map.ofSeq
typemap.ContainsKey(x.Substring(x.LastIndexOf "."))
| _ -> true

If the request is being forwarded from one cluster to another. The compression fails probably because it is not checking if response is already compressed

I was using this library for compression of a response which is for a stateful request. We have a project scenario in our app such that if the project is already open in a cluster(we have multiple clusters in different regions like - East US , South east asia etc) the request gets forwarded to that cluster. What happened was if you just hit one cluster compression was working fine but when the request was being forwarded and as the library is part of middle ware , the library is trying to compress the already compressed response. Library should check if the response is already compressed it should do nothing and just return. It could use response header to add a simple check in usecompress function.

Build errors due to wrong dependency in Owin.Compression?

Severity Code Description Project File Line Suppression State
Error NU1603 Owin.Compression 1.0.16 depends on Owin (>= 1.0.0-prerelease && <= 1.0.0) but Owin 1.0.0-prerelease was not found. An approximate best match of Owin 1.0.0 was resolved

Integration to OWIN pipeline with Microsoft.Owin.StaticFiles

Currently this module is serving static files from the file system. Instead it could use just compress HTTP-response, so that it could be plugged with other modules, e.g. Microsoft.Owin.StaticFiles NuGet package to do the actual file loading.

The problem seems to be that Microsoft.Owin.StaticFiles won't actually integrate to OWIN-pipeline but it will send the file directly. So there might not be a way to interrupt the HTTP-response. There are very few events (Microsoft.Owin.StaticFiles.FileServerOptions().StaticFileOptions.OnPrepareResponse) and it seems that those can't also be to interrupt the actual response.

Assuming files are always UTF-8 encoded text

Reading file contents in getFile() function of OwinCompression module implemented as StreamReader.ReadToEndAsync() + System.Text.Encoding.UTF8.GetBytes:
https://github.com/Thorium/Owin.Compression/blob/master/src/Owin.Compression/CompressionModule.fs#L156

How it will proceed with arbitrary encoded text files or binary files (for example, images and fonts) - the file contents will be corrupted in response. This applies when using .MapCompressionModule(...) and respectively ResponseMode.File.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.