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.

siphiuel
  • 3,480
  • 4
  • 31
  • 34

3 Answers3

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();
siphiuel
  • 3,480
  • 4
  • 31
  • 34
4

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.

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).
riroo
  • 134
  • 3
  • 15