From 20621b76fb48333ca17efb4f0ad17bb8441b93a4 Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Fri, 7 Feb 2020 21:32:43 +1100 Subject: [PATCH 1/3] Issue #4537 - fix potential spin when discarding in WebSocketConnection Signed-off-by: Lachlan Roberts --- .../jetty/websocket/common/io/AbstractWebSocketConnection.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/io/AbstractWebSocketConnection.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/io/AbstractWebSocketConnection.java index c93330d7d56..a9535a9d932 100644 --- a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/io/AbstractWebSocketConnection.java +++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/io/AbstractWebSocketConnection.java @@ -497,7 +497,7 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp case DISCARD: if (LOG.isDebugEnabled()) LOG.debug("Discarded buffer - {}", BufferUtil.toDetailString(buffer)); - buffer.clear(); + BufferUtil.clear(buffer); break; case SUSPEND: From ab5005b9f746cfdc9fd223c098d9582c6d36f852 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Sun, 16 Feb 2020 09:43:31 +0100 Subject: [PATCH 2/3] Fixes #4575 Stopping Reserved Thread Fixes #4575 Stopping Reserved Thread by removing the `isRunning` check from `reservedWait`. The main run loop is also simplified to improve `isRunning` checks before the thread is put on the stack. Javadoc improved to explain each step. Signed-off-by: Greg Wilkins --- .../util/thread/ReservedThreadExecutor.java | 37 ++++++++++--------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/ReservedThreadExecutor.java b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/ReservedThreadExecutor.java index 0bc982c266c..ef59ff2a6f8 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/ReservedThreadExecutor.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/ReservedThreadExecutor.java @@ -299,9 +299,6 @@ public class ReservedThreadExecutor extends AbstractLifeCycle implements TryExec while (true) { - if (!isRunning()) - return STOP; - try { Runnable task = _idleTime <= 0 ? _task.take() : _task.poll(_idleTime, _idleTimeUnit); @@ -333,23 +330,26 @@ public class ReservedThreadExecutor extends AbstractLifeCycle implements TryExec { // test and increment size BEFORE decrementing pending, // so that we don't have a race starting new pending. - while (true) + int size = _size.get(); + + // Are we stopped? + if (size < 0) + return; + + // Are we surplus to capacity? + if (size >= _capacity) { - int size = _size.get(); - if (size < 0) - return; - if (size >= _capacity) - { - if (LOG.isDebugEnabled()) - LOG.debug("{} size {} > capacity", this, size, _capacity); - if (_starting) - _pending.decrementAndGet(); - return; - } - if (_size.compareAndSet(size, size + 1)) - break; + if (LOG.isDebugEnabled()) + LOG.debug("{} size {} > capacity", this, size, _capacity); + if (_starting) + _pending.decrementAndGet(); + return; } + // If we cannot update size then recalculate + if (!_size.compareAndSet(size, size + 1)) + continue; + if (_starting) { if (LOG.isDebugEnabled()) @@ -362,7 +362,8 @@ public class ReservedThreadExecutor extends AbstractLifeCycle implements TryExec // that only effects the decision to keep other threads reserved. _stack.offerFirst(this); - // Wait for a task + // Once added to the stack, we must always wait for a job on the _task Queue + // and never return early, else we may leave a thread blocked offering a _task. Runnable task = reservedWait(); if (task == STOP) From 652428ad7040444d46888f652fb4a0b1a28c7832 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Sun, 16 Feb 2020 11:04:34 +0100 Subject: [PATCH 3/3] Tests #4573 X-Forwarded ordering Added tests for header ordering fixed cut-and-paste error of _for to _host Signed-off-by: Greg Wilkins --- .../server/ForwardedRequestCustomizer.java | 3 +- .../ForwardedRequestCustomizerTest.java | 56 +++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ForwardedRequestCustomizer.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ForwardedRequestCustomizer.java index 93a69857792..4d224dfe3cb 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/ForwardedRequestCustomizer.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ForwardedRequestCustomizer.java @@ -589,13 +589,14 @@ public class ForwardedRequestCustomizer implements Customizer } } + @SuppressWarnings("unused") public void handleHost(HttpField field) { if (getForwardedPortAsAuthority() && !StringUtil.isEmpty(getForwardedPortHeader())) { if (_host == null) _host = new PossiblyPartialHostPort(getLeftMost(field.getValue())); - else if (_for instanceof PortSetHostPort) + else if (_host instanceof PortSetHostPort) _host = new HostPort(HostPort.normalizeHost(getLeftMost(field.getValue())), _host.getPort()); } else if (_host == null) diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ForwardedRequestCustomizerTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ForwardedRequestCustomizerTest.java index 9a60e7f20d6..a6dfa9f58a2 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/ForwardedRequestCustomizerTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ForwardedRequestCustomizerTest.java @@ -397,6 +397,34 @@ public class ForwardedRequestCustomizerTest .requestURL("http://myhost:4444/") .remoteAddr("192.168.1.200").remotePort(0) ), + Arguments.of(new Request("X-Forwarded-* (all headers except server)") + .headers( + "GET / HTTP/1.1", + "Host: myhost", + "X-Forwarded-Proto: https", + "X-Forwarded-Host: www.example.com", + "X-Forwarded-Port: 4333", + "X-Forwarded-For: 8.5.4.3:2222" + ), + new Expectations() + .scheme("https").serverName("www.example.com").serverPort(4333) + .requestURL("https://www.example.com:4333/") + .remoteAddr("8.5.4.3").remotePort(2222) + ), + Arguments.of(new Request("X-Forwarded-* (all headers except server, port first)") + .headers( + "GET / HTTP/1.1", + "Host: myhost", + "X-Forwarded-Proto: https", + "X-Forwarded-Port: 4333", + "X-Forwarded-Host: www.example.com", + "X-Forwarded-For: 8.5.4.3:2222" + ), + new Expectations() + .scheme("https").serverName("www.example.com").serverPort(4333) + .requestURL("https://www.example.com:4333/") + .remoteAddr("8.5.4.3").remotePort(2222) + ), Arguments.of(new Request("X-Forwarded-* (all headers)") .headers( "GET / HTTP/1.1", @@ -427,6 +455,21 @@ public class ForwardedRequestCustomizerTest .requestURL("https://www.example.com:4333/") .remoteAddr("8.5.4.3").remotePort(2222) ), + Arguments.of(new Request("X-Forwarded-* (all headers reversed)") + .headers( + "GET / HTTP/1.1", + "Host: myhost", + "X-Forwarded-Server: fw.example.com", + "X-Forwarded-For: 8.5.4.3:2222", + "X-Forwarded-Port: 4333", + "X-Forwarded-Host: www.example.com", + "X-Forwarded-Proto: https" + ), + new Expectations() + .scheme("https").serverName("www.example.com").serverPort(4333) + .requestURL("https://www.example.com:4333/") + .remoteAddr("8.5.4.3").remotePort(2222) + ), Arguments.of(new Request("X-Forwarded-* (Server and Port)") .headers( "GET / HTTP/1.1", @@ -440,6 +483,19 @@ public class ForwardedRequestCustomizerTest .requestURL("http://fw.example.com:4333/") .remoteAddr("8.5.4.3").remotePort(2222) ), + Arguments.of(new Request("X-Forwarded-* (Port and Server)") + .headers( + "GET / HTTP/1.1", + "Host: myhost", + "X-Forwarded-Port: 4333", + "X-Forwarded-For: 8.5.4.3:2222", + "X-Forwarded-Server: fw.example.com" + ), + new Expectations() + .scheme("http").serverName("fw.example.com").serverPort(4333) + .requestURL("http://fw.example.com:4333/") + .remoteAddr("8.5.4.3").remotePort(2222) + ), // ================================================================= // Mixed Behavior