This is an automated email from the ASF dual-hosted git repository.

lhotari pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pulsar.git


The following commit(s) were added to refs/heads/master by this push:
     new 15ed6595af5 [improve][broker] Improve Gzip compression, allow 
excluding specific paths or disabling it (#22370)
15ed6595af5 is described below

commit 15ed6595af5489a007db82002ed3391589bad54d
Author: Lari Hotari <lhot...@users.noreply.github.com>
AuthorDate: Fri Apr 12 10:35:09 2024 -0700

    [improve][broker] Improve Gzip compression, allow excluding specific paths 
or disabling it (#22370)
---
 .../apache/pulsar/broker/ServiceConfiguration.java | 13 ++++++
 .../apache/pulsar/broker/web/GzipHandlerUtil.java  | 48 ++++++++++++++++++++++
 .../org/apache/pulsar/broker/web/WebService.java   | 10 ++---
 .../pulsar/proxy/server/AdminProxyHandler.java     |  1 +
 4 files changed, 66 insertions(+), 6 deletions(-)

diff --git 
a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/ServiceConfiguration.java
 
b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/ServiceConfiguration.java
index a7deda752fd..38a4c552f0b 100644
--- 
a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/ServiceConfiguration.java
+++ 
b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/ServiceConfiguration.java
@@ -331,6 +331,19 @@ public class ServiceConfiguration implements 
PulsarConfiguration {
             + "(0 to disable limiting)")
     private int maxHttpServerConnections = 2048;
 
+    @FieldContext(category = CATEGORY_SERVER, doc =
+            "Gzip compression is enabled by default. Specific paths can be 
excluded from compression.\n"
+                    + "There are 2 syntaxes supported, Servlet url-pattern 
based, and Regex based.\n"
+                    + "If the spec starts with '^' the spec is assumed to be a 
regex based path spec and will match "
+                    + "with normal Java regex rules.\n"
+                    + "If the spec starts with '/' then spec is assumed to be 
a Servlet url-pattern rules path spec "
+                    + "for either an exact match or prefix based match.\n"
+                    + "If the spec starts with '*.' then spec is assumed to be 
a Servlet url-pattern rules path spec "
+                    + "for a suffix based match.\n"
+                    + "All other syntaxes are unsupported.\n"
+                    + "Disable all compression with ^.* or ^.*$")
+    private List<String> httpServerGzipCompressionExcludedPaths = new 
ArrayList<>();
+
     @FieldContext(category = CATEGORY_SERVER, doc = "Whether to enable the 
delayed delivery for messages.")
     private boolean delayedDeliveryEnabled = true;
 
diff --git 
a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/web/GzipHandlerUtil.java
 
b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/web/GzipHandlerUtil.java
new file mode 100644
index 00000000000..37c9c05e5d5
--- /dev/null
+++ 
b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/web/GzipHandlerUtil.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.pulsar.broker.web;
+
+import java.util.List;
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.handler.gzip.GzipHandler;
+
+public class GzipHandlerUtil {
+    public static Handler wrapWithGzipHandler(Handler innerHandler, 
List<String> gzipCompressionExcludedPaths) {
+        Handler wrappedHandler;
+        if (isGzipCompressionCompletelyDisabled(gzipCompressionExcludedPaths)) 
{
+            // no need to add GZIP handler if it's disabled by setting the 
excluded path to "^.*" or "^.*$"
+            wrappedHandler = innerHandler;
+        } else {
+            // add GZIP handler which is active when the request contains 
"Accept-Encoding: gzip" header
+            GzipHandler gzipHandler = new GzipHandler();
+            gzipHandler.setHandler(innerHandler);
+            if (gzipCompressionExcludedPaths != null && 
gzipCompressionExcludedPaths.size() > 0) {
+                
gzipHandler.setExcludedPaths(gzipCompressionExcludedPaths.toArray(new 
String[0]));
+            }
+            wrappedHandler = gzipHandler;
+        }
+        return wrappedHandler;
+    }
+
+    public static boolean isGzipCompressionCompletelyDisabled(List<String> 
gzipCompressionExcludedPaths) {
+        return gzipCompressionExcludedPaths != null && 
gzipCompressionExcludedPaths.size() == 1
+                && (gzipCompressionExcludedPaths.get(0).equals("^.*")
+                || gzipCompressionExcludedPaths.get(0).equals("^.*$"));
+    }
+}
diff --git 
a/pulsar-broker/src/main/java/org/apache/pulsar/broker/web/WebService.java 
b/pulsar-broker/src/main/java/org/apache/pulsar/broker/web/WebService.java
index a7c42448990..8dc36e2917e 100644
--- a/pulsar-broker/src/main/java/org/apache/pulsar/broker/web/WebService.java
+++ b/pulsar-broker/src/main/java/org/apache/pulsar/broker/web/WebService.java
@@ -44,7 +44,6 @@ import org.eclipse.jetty.server.handler.HandlerCollection;
 import org.eclipse.jetty.server.handler.RequestLogHandler;
 import org.eclipse.jetty.server.handler.ResourceHandler;
 import org.eclipse.jetty.server.handler.StatisticsHandler;
-import org.eclipse.jetty.server.handler.gzip.GzipHandler;
 import org.eclipse.jetty.servlet.FilterHolder;
 import org.eclipse.jetty.servlet.ServletContextHandler;
 import org.eclipse.jetty.servlet.ServletHolder;
@@ -268,9 +267,7 @@ public class WebService implements AutoCloseable {
         }
         filterInitializer.addFilters(servletContextHandler, 
requiresAuthentication);
 
-        GzipHandler gzipHandler = new GzipHandler();
-        gzipHandler.setHandler(servletContextHandler);
-        handlers.add(gzipHandler);
+        handlers.add(servletContextHandler);
     }
 
     public void addStaticResources(String basePath, String resourcePath) {
@@ -294,8 +291,10 @@ public class WebService implements AutoCloseable {
             ContextHandlerCollection contexts = new ContextHandlerCollection();
             contexts.setHandlers(handlers.toArray(new 
Handler[handlers.size()]));
 
+            Handler handlerForContexts = 
GzipHandlerUtil.wrapWithGzipHandler(contexts,
+                    
pulsar.getConfig().getHttpServerGzipCompressionExcludedPaths());
             HandlerCollection handlerCollection = new HandlerCollection();
-            handlerCollection.setHandlers(new Handler[] { contexts, new 
DefaultHandler(), requestLogHandler });
+            handlerCollection.setHandlers(new Handler[] {handlerForContexts, 
new DefaultHandler(), requestLogHandler});
 
             // Metrics handler
             StatisticsHandler stats = new StatisticsHandler();
@@ -306,7 +305,6 @@ public class WebService implements AutoCloseable {
             } catch (IllegalArgumentException e) {
                 // Already registered. Eg: in unit tests
             }
-            handlers.add(stats);
 
             server.setHandler(stats);
             server.start();
diff --git 
a/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/AdminProxyHandler.java
 
b/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/AdminProxyHandler.java
index c528ceb2cf5..caaa99c5d40 100644
--- 
a/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/AdminProxyHandler.java
+++ 
b/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/AdminProxyHandler.java
@@ -158,6 +158,7 @@ class AdminProxyHandler extends ProxyServlet {
             client.start();
 
             // Content must not be decoded, otherwise the client gets confused.
+            // Allow encoded content, such as "Content-Encoding: gzip", to 
pass through without decoding it.
             client.getContentDecoderFactories().clear();
 
             // Pass traffic to the client, only intercept what's necessary.

Reply via email to