Search Unity

Resolved [Blazor Server App] Can't get brotli compressed webgl build running

Discussion in 'Web' started by MaskedMouse, Feb 13, 2023.

  1. MaskedMouse

    MaskedMouse

    Joined:
    Jul 8, 2014
    Posts:
    1,092
    I'm trying to get a brotli compressed WebGL build running in a Blazor Server App.
    I have very little knowledge of web development. Hence I am trying to start something to broaden my knowledge.

    A normal uncompressed build seems to work fine. But as soon as I try to use brotli, it just won't run.

    The request returns a 404.
    I have built webGL builds before for my daily job that works fine for an old asp.net project.
    But they get accompanied by a web.config. In this blazor project it doesn't seem to apply.

    Which after some searching I stumbled upon the following that works for the uncompressed builds.
    But it doesn't seem to work for the brotli compressed builds.

    Program.cs
    Code (CSharp):
    1. var uncompressedProvider = new FileExtensionContentTypeProvider
    2. {
    3.     Mappings =
    4.     {
    5.         [".data"] = "application/octet-stream",
    6.         [".wasm"] = "application/wasm",
    7.         [".js"] = "application/javascript",
    8.         [".symbols.json"] = "application/octet-stream"
    9.     }
    10. };
    11.  
    12. app.MapWhen(ctx => ctx.Request.Path.StartsWithSegments("/Unity/WebGL/Build"),
    13.     subApp => subApp.UseStaticFiles(new StaticFileOptions { ContentTypeProvider = uncompressedProvider }));
    14.  
    Code (CSharp):
    1. var brotliCompressedProvider = new FileExtensionContentTypeProvider
    2. {
    3.     Mappings =
    4.     {
    5.         [".data.br"] = "application/octet-stream",
    6.         [".wasm.br"] = "application/wasm",
    7.         [".js.br"] = "application/javascript",
    8.         [".symbols.json.br"] = "application/octet-stream",
    9.     }
    10. };
    11.  
    12. app.MapWhen(ctx => ctx.Request.Path.StartsWithSegments("/Unity/WebGLBrotli/Build"),
    13.     subApp => subApp.UseStaticFiles(new StaticFileOptions { ContentTypeProvider = brotliCompressedProvider }));
    14.  
    upload_2023-2-13_16-58-52.png

    Edit:
    I got it working by changing it to:
    Code (CSharp):
    1.         var provider = new FileExtensionContentTypeProvider
    2.         {
    3.             Mappings =
    4.             {
    5.                 [".js.br"] = "application/javascript",
    6.                 [".data.br"] = "application/octet-stream",
    7.                 [".wasm.br"] = "application/wasm",
    8.                 [".symbols.json.br"] = "application/octet-stream",
    9.             }
    10.         };
    11.  
    12.         webApplication.MapWhen(ctx => ctx.Request.Path.StartsWithSegments("/Unity/WebGLBrotli/Build"),
    13.             subApp => subApp.UseStaticFiles(new StaticFileOptions
    14.             {
    15.                 ServeUnknownFileTypes = true,
    16.                 ContentTypeProvider = provider,
    17.                 OnPrepareResponse = context =>
    18.                 {
    19.                     if (context.File.Name.EndsWith("loader.js")) return;
    20.  
    21.                     context.Context.Response.Headers["Content-Encoding"] = "br";
    22.                     if (context.File.Name.EndsWith("js.br"))
    23.                         context.Context.Response.Headers["content-type"] = "application/javascript";
    24.                     if (context.File.Name.EndsWith("data.br"))
    25.                         context.Context.Response.Headers["content-type"] = "application/octet-stream";
    26.                     if (context.File.Name.EndsWith("wasm.br"))
    27.                         context.Context.Response.Headers["content-type"] = "application/wasm";
    28.                 }
    29.             }));
    Though I required the
    ServeUnknownFileTypes
    to
    true

    And I also needed to set the content-type & content-encoding headers manually.
    Even though I specified it with the
    FileExtensionContentTypeProvider
    it doesn't seem to apply it at all.

    So what would be the proper way to make this work?
    I'm running it locally with Rider and have set the run config to IIS Express.
    It is a default Blazor Server App with .NET 7.0
     
    Last edited: Feb 14, 2023
  2. MaskedMouse

    MaskedMouse

    Joined:
    Jul 8, 2014
    Posts:
    1,092
    I have now removed the
    ServeUnknownFileTypes
    .
    Apparently it doesn't like it when you add multiple file extension types.
    i.e.
    .js.br

    When I changed it to
    .br
    only, it got served just fine.
    Though since there are multiple types brotli compressed, I still have to change the response to set the proper
    content-type
    header based on the file name.

    Code (CSharp):
    1. var contentTypeProvider = new FileExtensionContentTypeProvider();
    2.  
    3. contentTypeProvider.Mappings.Remove(".js");
    4. contentTypeProvider.Mappings.Add(".js", "application/javascript");
    5. contentTypeProvider.Mappings.Add(".br", "plain");
    6.  
    7. webApplication.MapWhen(ctx => ctx.Request.Path.StartsWithSegments("/Unity/WebGLBrotli/Build"),
    8.     subApp => subApp.UseStaticFiles(new StaticFileOptions
    9.     {
    10.         ContentTypeProvider = contentTypeProvider,
    11.         OnPrepareResponse = fileResponseContext =>
    12.         {
    13.             var headers = fileResponseContext.Context.Response.Headers;
    14.             var fileName = fileResponseContext.File.Name;
    15.            
    16.             if (fileName.EndsWith(".loader.js"))
    17.             {
    18.                 headers["content-type"] = "application/javascript";
    19.                 return;
    20.             }
    21.        
    22.             if(fileName.EndsWith(".br"))
    23.                 headers["Content-Encoding"] = "br";
    24.                
    25.             if (fileName.EndsWith("js.br"))
    26.                 headers["content-type"] = "application/javascript";
    27.             else if (fileName.EndsWith("data.br"))
    28.                 headers["content-type"] = "application/octet-stream";
    29.             else if (fileName.EndsWith("wasm.br"))
    30.                 headers["content-type"] = "application/wasm";
    31.         }
    32.     }));
     
    Last edited: Feb 15, 2023
    radiantboy likes this.