Compressing Undertow server responses
Asked Answered
E

3

6

i have a programmatic Undertow server setup. Static content is served by Undertow as well, without a reverse proxy. Java code for Undertow startup looks like this:

ResourceManager resourceManager = 
    new FileResourceManager(new File("deploymentDir"), 100);

DeploymentInfo servletBuilder = Servlets.deployment()
      .setResourceManager(resourceManager)
      .setDeploymentName("testDeployment")
      .setContextPath("/");

DeploymentManager manager = Servlets.defaultContainer()
      .addDeployment(servletBuilder);
manager.deploy();

Undertow.Builder builder = Undertow.builder();
builder.addHttpListener(8080, domainName);

PathHandler path = Handlers.path(Handlers.redirect("/"))
      .addPrefixPath("/", manager.start());

Undertow server = builder.setHandler(path).build();
server.start();

I'm wondering how does one gzip server responses in Undertow?

Thanks, Vitaliy.

Emmyemmye answered 3/2, 2015 at 9:45 Comment(0)
E
9

I had to look at GzipContentEncodingTestCase in Undertow's source to get it to work. One has to create an EncodingHandler with appropriate parameters, and then invoke setNext() so that to chain it to the PathHandler:

PathHandler path = Handlers.path(Handlers.redirect("/"))
    .addPrefixPath("/", manager.start());

final EncodingHandler handler = 
    new EncodingHandler(new ContentEncodingRepository()
      .addEncodingHandler("gzip", 
          new GzipEncodingProvider(), 50,
          Predicates.parse("max-content-size[5]")))
      .setNext(path);

// ...
Undertow server = builder.setHandler(handler).build();
Emmyemmye answered 4/2, 2015 at 19:31 Comment(0)
P
6

The answer from @siphiuel looks correct to me.

However, EncodingHandler with GZIP encoding can also be created as below:

    HttpHandler pathHandler = Handlers.path(Handlers.redirect("/"))
        .addPrefixPath("/", exchange -> exchange.getResponseSender().send("echo"));

    HttpHandler encodingHandler = new EncodingHandler.Builder().build(null)
        .wrap(pathHandler);

    Undertow server = Undertow.builder()
        .addHttpListener(8080, "localhost")
        .setHandler(encodingHandler).build();
    server.start();

EncodingHandler provides a HandlerBuilder that by default adds GzipEncodingProvider and DeflateEncodingProvider using default configuration. So your code is not coupled with the constructor and its parameters for creating an EncodingHandler.

Additionally, HandlerBuilder#build returns a HandlerWrapper for fluent HttpHandler wrapping/chaining.

Philis answered 19/10, 2017 at 18:46 Comment(0)
M
2

A very interesting link that helped me personally is : Add compression to Server-Sent events with Undertow. All the parameters used in the EncodingHandler provided by @siphiuel are explained one by one.

Here a quick summary for a gzip compression for example. the parameters of addEncodingHandler(...) would be :

  • the type (“gzip”)
  • the EncodingProvider to apply (Undertow provides implementations for deflate and gzip)
  • the priority (multiple providers can be applied, so the priority will be used to choose the provider to apply)
  • the predicate to activate the encoding (in @siphiuel's example, only responses with content size > 5 Bytes will be encoded - in the link I shared it's mentioned 5 KB but my tests have proven that it's 5 Bytes).
Millrun answered 18/1, 2017 at 15:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.