This is an automated email from the ASF dual-hosted git repository.
pdallig pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/zeppelin.git
The following commit(s) were added to refs/heads/master by this push:
new d98351a551 [ZEPPELIN-6209] Rewrite Jetty Servername
d98351a551 is described below
commit d98351a55141c3edf0ac7093394a661d8c5f1cee
Author: Philipp Dallig <[email protected]>
AuthorDate: Wed Jul 2 16:08:27 2025 +0200
[ZEPPELIN-6209] Rewrite Jetty Servername
### What is this PR for?
This PR removes a hack in your Jetty configuration, which results in an
empty header.
This hack was mentioned also in this Jetty Issue
https://github.com/jetty/jetty.project/issues/6592#issuecomment-897877018
### What type of PR is it?
Bug Fix
### What is the Jira issue?
* https://issues.apache.org/jira/browse/ZEPPELIN-6209
### Screenshots (if appropriate)
Before:

After with default configuration - `zeppelin.server.send.jetty.name` = true
and `zeppelin.server.jetty.name`=` `

After with `zeppelin.server.send.jetty.name` = false

After with `zeppelin.server.send.jetty.name` = true (default) and
`zeppelin.server.jetty.name`=`ApacheZeppelin`

### Questions:
* Does the license files need to update? No
* Is there breaking changes for older versions? Yes
* Previously, we returned an empty string. In my opinion this behaviour
is very unclean, now the check is done with `StringUtils.isNotBlank()`.
* Does this needs documentation? No
Closes #4953 from Reamer/hackJettyname.
Signed-off-by: Philipp Dallig <[email protected]>
---
.../apache/zeppelin/server/JettyServername.java | 45 +++++++++++++
.../org/apache/zeppelin/server/ZeppelinServer.java | 4 +-
.../zeppelin/server/JettyServernameTest.java | 78 ++++++++++++++++++++++
3 files changed, 124 insertions(+), 3 deletions(-)
diff --git
a/zeppelin-server/src/main/java/org/apache/zeppelin/server/JettyServername.java
b/zeppelin-server/src/main/java/org/apache/zeppelin/server/JettyServername.java
new file mode 100644
index 0000000000..4c1aa83b5a
--- /dev/null
+++
b/zeppelin-server/src/main/java/org/apache/zeppelin/server/JettyServername.java
@@ -0,0 +1,45 @@
+/*
+ * 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.zeppelin.server;
+
+import org.eclipse.jetty.server.Request;
+
+import java.util.Optional;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.zeppelin.conf.ZeppelinConfiguration;
+import org.eclipse.jetty.http.HttpHeader;
+import org.eclipse.jetty.server.HttpChannel;
+
+
+public class JettyServername implements HttpChannel.Listener {
+
+ private final Optional<String> servername;
+
+ public JettyServername(final ZeppelinConfiguration zConf) {
+ if (zConf.sendJettyName() && StringUtils.isNotBlank(zConf.getJettyName()))
{
+ this.servername = Optional.of(zConf.getJettyName().strip());
+ } else {
+ this.servername = Optional.empty();
+ }
+ }
+
+ @Override
+ public void onResponseBegin(Request request) {
+ servername.ifPresent(value ->
request.getResponse().setHeader(HttpHeader.SERVER, value));
+ }
+}
diff --git
a/zeppelin-server/src/main/java/org/apache/zeppelin/server/ZeppelinServer.java
b/zeppelin-server/src/main/java/org/apache/zeppelin/server/ZeppelinServer.java
index 27f926f7ec..0df928f517 100644
---
a/zeppelin-server/src/main/java/org/apache/zeppelin/server/ZeppelinServer.java
+++
b/zeppelin-server/src/main/java/org/apache/zeppelin/server/ZeppelinServer.java
@@ -274,9 +274,6 @@ public class ZeppelinServer implements AutoCloseable {
*/
try {
jettyWebServer.start(); // Instantiates ZeppelinServer
- if (zConf.getJettyName() != null) {
-
org.eclipse.jetty.http.HttpGenerator.setJettyVersion(zConf.getJettyName());
- }
} catch (Exception e) {
LOGGER.error("Error while running jettyServer", e);
System.exit(-1);
@@ -430,6 +427,7 @@ public class ZeppelinServer implements AutoCloseable {
int timeout = 1000 * 30;
connector.setIdleTimeout(timeout);
connector.setHost(zConf.getServerAddress());
+ connector.addBean(new JettyServername(zConf));
connector.addBean(new JettyConnectionMetrics(Metrics.globalRegistry,
Tags.empty()));
server.addConnector(connector);
}
diff --git
a/zeppelin-server/src/test/java/org/apache/zeppelin/server/JettyServernameTest.java
b/zeppelin-server/src/test/java/org/apache/zeppelin/server/JettyServernameTest.java
new file mode 100644
index 0000000000..6d659870f4
--- /dev/null
+++
b/zeppelin-server/src/test/java/org/apache/zeppelin/server/JettyServernameTest.java
@@ -0,0 +1,78 @@
+/*
+ * 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.zeppelin.server;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoInteractions;
+import static org.mockito.Mockito.when;
+
+import org.apache.zeppelin.conf.ZeppelinConfiguration;
+import org.apache.zeppelin.conf.ZeppelinConfiguration.ConfVars;
+import org.eclipse.jetty.http.HttpHeader;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
+import org.junit.jupiter.api.Test;
+
+class JettyServernameTest {
+ private final String headerValue = "ZeppelinApache";
+ @Test
+ void defaultConfiguration() {
+ // given
+ Request request = mock(Request.class);
+ Response response = mock(Response.class);
+ when(request.getResponse()).thenReturn(response);
+ ZeppelinConfiguration zConf = ZeppelinConfiguration.load();
+ JettyServername httpListener = new JettyServername(zConf);
+ // when
+ httpListener.onResponseBegin(request);
+ // then
+ verifyNoInteractions(response);
+ }
+
+ @Test
+ void DoNotSendServerName() {
+ // given
+ Request request = mock(Request.class);
+ Response response = mock(Response.class);
+ when(request.getResponse()).thenReturn(response);
+ ZeppelinConfiguration zConf = ZeppelinConfiguration.load();
+ zConf.setProperty(ConfVars.ZEPPELIN_SERVER_SEND_JETTY_NAME.getVarName(),
"false");
+ zConf.setProperty(ConfVars.ZEPPELIN_SERVER_JETTY_NAME.getVarName(),
headerValue);
+ JettyServername httpListener = new JettyServername(zConf);
+ // when
+ httpListener.onResponseBegin(request);
+ // then
+ verifyNoInteractions(response);
+ }
+
+ @Test
+ void SendServerName() {
+ // given
+ Request request = mock(Request.class);
+ Response response = mock(Response.class);
+ when(request.getResponse()).thenReturn(response);
+ ZeppelinConfiguration zConf = ZeppelinConfiguration.load();
+ zConf.setProperty(ConfVars.ZEPPELIN_SERVER_SEND_JETTY_NAME.getVarName(),
"true");
+ zConf.setProperty(ConfVars.ZEPPELIN_SERVER_JETTY_NAME.getVarName(),
headerValue);
+ JettyServername httpListener = new JettyServername(zConf);
+ // when
+ httpListener.onResponseBegin(request);
+ // then
+ verify(response).setHeader(HttpHeader.SERVER, headerValue);
+ }
+}