Merged branch 'jetty-9.4.x' into 'master'.
This commit is contained in:
commit
755de58ab6
|
@ -448,7 +448,7 @@ public class HttpClientTimeoutTest extends AbstractHttpClientServerTest
|
|||
start(new EmptyServerHandler());
|
||||
|
||||
long timeout = 1000;
|
||||
Request request = client.newRequest("badscheme://localhost:badport");
|
||||
Request request = client.newRequest("badscheme://localhost:" + connector.getLocalPort());
|
||||
|
||||
try
|
||||
{
|
||||
|
|
|
@ -18,23 +18,33 @@
|
|||
|
||||
package org.eclipse.jetty.deploy.providers;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assume.assumeTrue;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.FileSystemException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.eclipse.jetty.deploy.test.XmlConfiguredJetty;
|
||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||
import org.eclipse.jetty.toolchain.test.TestingDir;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
@Ignore("See issue #1200")
|
||||
public class WebAppProviderTest
|
||||
{
|
||||
@Rule
|
||||
public TestingDir testdir = new TestingDir();
|
||||
private static XmlConfiguredJetty jetty;
|
||||
|
||||
private boolean symlinkSupported = false;
|
||||
|
||||
@Before
|
||||
public void setupEnvironment() throws Exception
|
||||
{
|
||||
|
@ -45,6 +55,20 @@ public class WebAppProviderTest
|
|||
|
||||
// Setup initial context
|
||||
jetty.copyWebapp("foo-webapp-1.war","foo.war");
|
||||
|
||||
// Make symlink
|
||||
Path pathWar3 = MavenTestingUtils.getTestResourcePathFile("webapps/foo-webapp-3.war");
|
||||
Path pathBar = jetty.getJettyDir("webapps/bar.war").toPath();
|
||||
try
|
||||
{
|
||||
Files.createSymbolicLink(pathBar, pathWar3);
|
||||
symlinkSupported = true;
|
||||
} catch (UnsupportedOperationException | FileSystemException e)
|
||||
{
|
||||
// if unable to create symlink, no point testing that feature
|
||||
// this is the path that Microsoft Windows takes.
|
||||
symlinkSupported = false;
|
||||
}
|
||||
|
||||
// Should not throw an Exception
|
||||
jetty.load();
|
||||
|
@ -64,18 +88,34 @@ public class WebAppProviderTest
|
|||
public void testStartupContext()
|
||||
{
|
||||
// Check Server for Handlers
|
||||
jetty.assertWebAppContextsExists("/foo");
|
||||
jetty.assertWebAppContextsExists("/bar", "/foo");
|
||||
|
||||
File workDir = jetty.getJettyDir("workish");
|
||||
|
||||
System.err.println("workDir="+workDir);
|
||||
|
||||
// Test for regressions
|
||||
assertDirNotExists("root of work directory",workDir,"webinf");
|
||||
assertDirNotExists("root of work directory",workDir,"jsp");
|
||||
|
||||
// Test for correct behaviour
|
||||
Assert.assertTrue("Should have generated directory in work directory: " + workDir,hasJettyGeneratedPath(workDir,"foo.war"));
|
||||
assertTrue("Should have generated directory in work directory: " + workDir,hasJettyGeneratedPath(workDir,"foo.war"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStartupSymlinkContext()
|
||||
{
|
||||
assumeTrue(symlinkSupported);
|
||||
|
||||
// Check for path
|
||||
File barLink = jetty.getJettyDir("webapps/bar.war");
|
||||
assertTrue("bar.war link exists: " + barLink.toString(), barLink.exists());
|
||||
assertTrue("bar.war link isFile: " + barLink.toString(), barLink.isFile());
|
||||
|
||||
// Check Server for expected Handlers
|
||||
jetty.assertWebAppContextsExists("/bar", "/foo");
|
||||
|
||||
// Test for expected work/temp directory behaviour
|
||||
File workDir = jetty.getJettyDir("workish");
|
||||
assertTrue("Should have generated directory in work directory: " + workDir,hasJettyGeneratedPath(workDir,"bar.war"));
|
||||
}
|
||||
|
||||
private static boolean hasJettyGeneratedPath(File basedir, String expectedWarFilename)
|
||||
|
|
|
@ -75,7 +75,10 @@ server.setRequestLog(requestLog);
|
|||
This configures a request log in `{$jetty.home}/logs` with filenames including the date.
|
||||
Existing log files are appended to and the extended NCSA format is used in the GMT time zone.
|
||||
|
||||
You can customize the number of days you wish to keep request logs.
|
||||
The above configuration enables Log Latency, which is the amount of time it took the server to handle the request.
|
||||
This value is measured in milliseconds and is appended to the the log file for each request.
|
||||
|
||||
You can also customize the number of days you wish to keep request logs.
|
||||
By default, log files are kept for 90 days before being deleted.
|
||||
The value for `retainDays` (xml) or `setRetainDays` (Java) should be configured as _1 + n_ days.
|
||||
For example, if you wanted to keep the logs for the current day and the day prior you would set the `retainDays` (or `setRetainDays`) value to 2.
|
||||
|
|
|
@ -21,6 +21,8 @@ package org.eclipse.jetty.http2.client;
|
|||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
@ -42,6 +44,7 @@ import org.eclipse.jetty.http2.frames.DataFrame;
|
|||
import org.eclipse.jetty.http2.frames.HeadersFrame;
|
||||
import org.eclipse.jetty.http2.frames.PushPromiseFrame;
|
||||
import org.eclipse.jetty.http2.frames.ResetFrame;
|
||||
import org.eclipse.jetty.http2.frames.SettingsFrame;
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.servlets.PushCacheFilter;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
|
@ -885,4 +888,91 @@ public class PushCacheFilterTest extends AbstractTest
|
|||
Assert.assertTrue(primaryResponseLatch.await(5, TimeUnit.SECONDS));
|
||||
Assert.assertFalse(pushLatch.await(1, TimeUnit.SECONDS));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPushDisabled() throws Exception
|
||||
{
|
||||
final String primaryResource = "/primary.html";
|
||||
final String secondaryResource = "/secondary.png";
|
||||
final byte[] secondaryData = "SECONDARY".getBytes("UTF-8");
|
||||
start(new HttpServlet()
|
||||
{
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
|
||||
{
|
||||
String requestURI = req.getRequestURI();
|
||||
ServletOutputStream output = resp.getOutputStream();
|
||||
if (requestURI.endsWith(primaryResource))
|
||||
output.print("<html><head></head><body>PRIMARY</body></html>");
|
||||
else if (requestURI.endsWith(secondaryResource))
|
||||
output.write(secondaryData);
|
||||
}
|
||||
});
|
||||
|
||||
final Session session = newClient(new Session.Listener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public Map<Integer, Integer> onPreface(Session session)
|
||||
{
|
||||
Map<Integer, Integer> settings = new HashMap<>();
|
||||
settings.put(SettingsFrame.ENABLE_PUSH, 0);
|
||||
return settings;
|
||||
}
|
||||
});
|
||||
|
||||
// Request for the primary and secondary resource to build the cache.
|
||||
final String referrerURI = "http://localhost:" + connector.getLocalPort() + servletPath + primaryResource;
|
||||
HttpFields primaryFields = new HttpFields();
|
||||
MetaData.Request primaryRequest = newRequest("GET", primaryResource, primaryFields);
|
||||
final CountDownLatch warmupLatch = new CountDownLatch(1);
|
||||
session.newStream(new HeadersFrame(primaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onData(Stream stream, DataFrame frame, Callback callback)
|
||||
{
|
||||
callback.succeeded();
|
||||
if (frame.isEndStream())
|
||||
{
|
||||
// Request for the secondary resource.
|
||||
HttpFields secondaryFields = new HttpFields();
|
||||
secondaryFields.put(HttpHeader.REFERER, referrerURI);
|
||||
MetaData.Request secondaryRequest = newRequest("GET", secondaryResource, secondaryFields);
|
||||
session.newStream(new HeadersFrame(secondaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onData(Stream stream, DataFrame frame, Callback callback)
|
||||
{
|
||||
callback.succeeded();
|
||||
warmupLatch.countDown();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
Assert.assertTrue(warmupLatch.await(5, TimeUnit.SECONDS));
|
||||
|
||||
// Request again the primary resource, we should not get the secondary resource pushed.
|
||||
primaryRequest = newRequest("GET", primaryResource, primaryFields);
|
||||
final CountDownLatch primaryResponseLatch = new CountDownLatch(1);
|
||||
final CountDownLatch pushLatch = new CountDownLatch(1);
|
||||
session.newStream(new HeadersFrame(primaryRequest, null, true), new Promise.Adapter<>(), new Stream.Listener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public Stream.Listener onPush(Stream stream, PushPromiseFrame frame)
|
||||
{
|
||||
pushLatch.countDown();
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onData(Stream stream, DataFrame frame, Callback callback)
|
||||
{
|
||||
callback.succeeded();
|
||||
if (frame.isEndStream())
|
||||
primaryResponseLatch.countDown();
|
||||
}
|
||||
});
|
||||
Assert.assertFalse(pushLatch.await(1, TimeUnit.SECONDS));
|
||||
Assert.assertTrue(primaryResponseLatch.await(5, TimeUnit.SECONDS));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -310,7 +310,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio
|
|||
case SettingsFrame.HEADER_TABLE_SIZE:
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Update HPACK header table size to {}", value);
|
||||
LOG.debug("Update HPACK header table size to {} for {}", value, this);
|
||||
generator.setHeaderTableSize(value);
|
||||
break;
|
||||
}
|
||||
|
@ -323,26 +323,28 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio
|
|||
return;
|
||||
}
|
||||
pushEnabled = value == 1;
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("{} push for {}", pushEnabled ? "Enable" : "Disable", this);
|
||||
break;
|
||||
}
|
||||
case SettingsFrame.MAX_CONCURRENT_STREAMS:
|
||||
{
|
||||
maxLocalStreams = value;
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Update max local concurrent streams to {}", maxLocalStreams);
|
||||
LOG.debug("Update max local concurrent streams to {} for {}", maxLocalStreams, this);
|
||||
break;
|
||||
}
|
||||
case SettingsFrame.INITIAL_WINDOW_SIZE:
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Update initial window size to {}", value);
|
||||
LOG.debug("Update initial window size to {} for {}", value, this);
|
||||
flowControl.updateInitialStreamWindow(this, value, false);
|
||||
break;
|
||||
}
|
||||
case SettingsFrame.MAX_FRAME_SIZE:
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Update max frame size to {}", value);
|
||||
LOG.debug("Update max frame size to {} for {}", value, this);
|
||||
// SPEC: check the max frame size is sane.
|
||||
if (value < Frame.DEFAULT_MAX_LENGTH || value > Frame.MAX_MAX_LENGTH)
|
||||
{
|
||||
|
@ -355,14 +357,14 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements ISessio
|
|||
case SettingsFrame.MAX_HEADER_LIST_SIZE:
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Update max header list size to {}", value);
|
||||
LOG.debug("Update max header list size to {} for {}", value, this);
|
||||
generator.setMaxHeaderListSize(value);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Unknown setting {}:{}", key, value);
|
||||
LOG.debug("Unknown setting {}:{} for {}", key, value, this);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
package org.eclipse.jetty.proxy;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.URI;
|
||||
import java.net.UnknownHostException;
|
||||
|
@ -633,10 +632,13 @@ public abstract class AbstractProxyServlet extends HttpServlet
|
|||
{
|
||||
// Use Jetty specific behavior to close connection.
|
||||
proxyResponse.sendError(-1);
|
||||
AsyncContext asyncContext = clientRequest.getAsyncContext();
|
||||
asyncContext.complete();
|
||||
if (clientRequest.isAsyncStarted())
|
||||
{
|
||||
AsyncContext asyncContext = clientRequest.getAsyncContext();
|
||||
asyncContext.complete();
|
||||
}
|
||||
}
|
||||
catch (IOException x)
|
||||
catch (Throwable x)
|
||||
{
|
||||
if (_log.isDebugEnabled())
|
||||
_log.debug(getRequestId(clientRequest) + " could not close the connection", failure);
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<Set name="forwardedServerHeader"><Property name="jetty.httpConfig.forwardedServerHeader" default="X-Forwarded-Server"/></Set>
|
||||
<Set name="forwardedProtoHeader"><Property name="jetty.httpConfig.forwardedProtoHeader" default="X-Forwarded-Proto"/></Set>
|
||||
<Set name="forwardedForHeader"><Property name="jetty.httpConfig.forwardedForHeader" default="X-Forwarded-For"/></Set>
|
||||
<Set name="forwardedForHeader"><Property name="jetty.httpConfig.forwardedHttpsHeader" default="X-Proxied-Https"/></Set>
|
||||
<Set name="forwardedHttpsHeader"><Property name="jetty.httpConfig.forwardedHttpsHeader" default="X-Proxied-Https"/></Set>
|
||||
<Set name="forwardedSslSessionIdHeader"><Property name="jetty.httpConfig.forwardedSslSessionIdHeader" default="Proxy-ssl-id" /></Set>
|
||||
<Set name="forwardedCipherSuiteHeader"><Property name="jetty.httpConfig.forwardedCipherSuiteHeader" default="Proxy-auth-cert"/></Set>
|
||||
</New>
|
||||
|
|
|
@ -244,7 +244,7 @@ public class Request implements HttpServletRequest
|
|||
public PushBuilder getPushBuilder()
|
||||
{
|
||||
if (!isPushSupported())
|
||||
throw new IllegalStateException();
|
||||
throw new IllegalStateException(String.format("%s,push=%b,channel=%s", this, isPush(), getHttpChannel()));
|
||||
|
||||
HttpFields fields = new HttpFields(getHttpFields().size()+5);
|
||||
boolean conditional=false;
|
||||
|
|
|
@ -307,6 +307,7 @@ public class Session implements SessionHandler.SessionIf
|
|||
|
||||
if (_handler == null)
|
||||
throw new IllegalStateException ("No session manager for session "+ _sessionData.getId());
|
||||
|
||||
_handler.doSessionAttributeListeners(this,name,oldValue,newValue);
|
||||
}
|
||||
}
|
||||
|
@ -897,10 +898,9 @@ public class Session implements SessionHandler.SessionIf
|
|||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("invalidate {}",_sessionData.getId());
|
||||
if (isValid())
|
||||
if (_state == State.VALID || _state == State.INVALIDATING)
|
||||
{
|
||||
Set<String> keys = null;
|
||||
|
||||
do
|
||||
{
|
||||
keys = _sessionData.getKeys();
|
||||
|
|
|
@ -202,6 +202,22 @@ public class ForwardedRequestCustomizerTest
|
|||
assertEquals("0",_results.poll());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFor() throws Exception
|
||||
{
|
||||
String response=_connector.getResponse(
|
||||
"GET / HTTP/1.1\n"+
|
||||
"Host: myhost\n"+
|
||||
"X-Forwarded-For: 10.9.8.7,6.5.4.3\n"+
|
||||
"\n");
|
||||
assertThat(response, Matchers.containsString("200 OK"));
|
||||
assertEquals("http",_results.poll());
|
||||
assertEquals("myhost",_results.poll());
|
||||
assertEquals("80",_results.poll());
|
||||
assertEquals("10.9.8.7",_results.poll());
|
||||
assertEquals("0",_results.poll());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLegacyProto() throws Exception
|
||||
{
|
||||
|
|
|
@ -116,9 +116,11 @@ public class PushCacheFilter implements Filter
|
|||
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException
|
||||
{
|
||||
HttpServletRequest request = (HttpServletRequest)req;
|
||||
Request jettyRequest = Request.getBaseRequest(request);
|
||||
|
||||
if (HttpVersion.fromString(req.getProtocol()).getVersion() < 20 ||
|
||||
!HttpMethod.GET.is(request.getMethod()))
|
||||
if (HttpVersion.fromString(request.getProtocol()).getVersion() < 20 ||
|
||||
!HttpMethod.GET.is(request.getMethod()) ||
|
||||
!jettyRequest.isPushSupported())
|
||||
{
|
||||
chain.doFilter(req, resp);
|
||||
return;
|
||||
|
@ -127,7 +129,6 @@ public class PushCacheFilter implements Filter
|
|||
long now = System.nanoTime();
|
||||
|
||||
// Iterating over fields is more efficient than multiple gets
|
||||
Request jettyRequest = Request.getBaseRequest(request);
|
||||
HttpFields fields = jettyRequest.getHttpFields();
|
||||
boolean conditional = false;
|
||||
String referrer = null;
|
||||
|
@ -158,7 +159,7 @@ public class PushCacheFilter implements Filter
|
|||
}
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("{} {} referrer={} conditional={} synthetic={}", request.getMethod(), request.getRequestURI(), referrer, conditional, isPushRequest(request));
|
||||
LOG.debug("{} {} referrer={} conditional={}", request.getMethod(), request.getRequestURI(), referrer, conditional);
|
||||
|
||||
String path = URIUtil.addPaths(request.getServletPath(), request.getPathInfo());
|
||||
String query = request.getQueryString();
|
||||
|
@ -256,7 +257,7 @@ public class PushCacheFilter implements Filter
|
|||
}
|
||||
|
||||
// Push associated resources.
|
||||
if (!isPushRequest(request) && !conditional && !primaryResource._associated.isEmpty())
|
||||
if (!conditional && !primaryResource._associated.isEmpty())
|
||||
{
|
||||
PushBuilder pushBuilder = jettyRequest.getPushBuilder();
|
||||
|
||||
|
@ -282,11 +283,6 @@ public class PushCacheFilter implements Filter
|
|||
chain.doFilter(request, resp);
|
||||
}
|
||||
|
||||
private boolean isPushRequest(HttpServletRequest request)
|
||||
{
|
||||
return Boolean.TRUE.equals(request.getAttribute("org.eclipse.jetty.pushed"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy()
|
||||
{
|
||||
|
|
|
@ -546,6 +546,11 @@ public class StartArgs
|
|||
{
|
||||
CommandLineBuilder cmd = new CommandLineBuilder();
|
||||
|
||||
// Special Stop/Shutdown properties
|
||||
ensureSystemPropertySet("STOP.PORT");
|
||||
ensureSystemPropertySet("STOP.KEY");
|
||||
ensureSystemPropertySet("STOP.WAIT");
|
||||
|
||||
if (addJavaInit)
|
||||
{
|
||||
cmd.addRawArg(CommandLineBuilder.findJavaBin());
|
||||
|
@ -571,11 +576,7 @@ public class StartArgs
|
|||
cmd.addRawArg(getMainClassname());
|
||||
}
|
||||
|
||||
// Special Stop/Shutdown properties
|
||||
ensureSystemPropertySet("STOP.PORT");
|
||||
ensureSystemPropertySet("STOP.KEY");
|
||||
ensureSystemPropertySet("STOP.WAIT");
|
||||
|
||||
|
||||
// pass properties as args or as a file
|
||||
if (dryRun && exec_properties == null)
|
||||
{
|
||||
|
|
|
@ -21,7 +21,6 @@ package org.eclipse.jetty.websocket.jsr356;
|
|||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.security.Principal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
|
@ -29,6 +28,7 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.websocket.CloseReason;
|
||||
import javax.websocket.EndpointConfig;
|
||||
|
@ -42,7 +42,6 @@ import javax.websocket.WebSocketContainer;
|
|||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.websocket.api.BatchMode;
|
||||
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
|
||||
import org.eclipse.jetty.websocket.common.LogicalConnection;
|
||||
import org.eclipse.jetty.websocket.common.WebSocketSession;
|
||||
import org.eclipse.jetty.websocket.common.events.EventDriver;
|
||||
|
@ -241,13 +240,9 @@ public class JsrSession extends WebSocketSession implements javax.websocket.Sess
|
|||
@Override
|
||||
public List<Extension> getNegotiatedExtensions()
|
||||
{
|
||||
if (negotiatedExtensions == null)
|
||||
if ((negotiatedExtensions == null) && getUpgradeResponse().getExtensions() != null)
|
||||
{
|
||||
negotiatedExtensions = new ArrayList<Extension>();
|
||||
for (ExtensionConfig cfg : getUpgradeResponse().getExtensions())
|
||||
{
|
||||
negotiatedExtensions.add(new JsrExtension(cfg));
|
||||
}
|
||||
negotiatedExtensions = getUpgradeResponse().getExtensions().stream().map(JsrExtension::new).collect(Collectors.toList());
|
||||
}
|
||||
return negotiatedExtensions;
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ package org.eclipse.jetty.websocket.jsr356.server;
|
|||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
|
@ -36,6 +37,7 @@ import java.util.TimeZone;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.websocket.DecodeException;
|
||||
import javax.websocket.Decoder;
|
||||
|
@ -97,9 +99,19 @@ public class ConfiguratorTest
|
|||
public static class NoExtensionsSocket
|
||||
{
|
||||
@OnMessage
|
||||
public String echo(String message)
|
||||
public String echo(Session session, String message)
|
||||
{
|
||||
return message;
|
||||
List<Extension> negotiatedExtensions = session.getNegotiatedExtensions();
|
||||
if (negotiatedExtensions == null)
|
||||
{
|
||||
return "negotiatedExtensions=null";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "negotiatedExtensions=" + negotiatedExtensions.stream()
|
||||
.map((ext) -> ext.getName())
|
||||
.collect(Collectors.joining(",", "[", "]"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -420,8 +432,13 @@ public class ConfiguratorTest
|
|||
client.addExtensions("identity");
|
||||
client.connect();
|
||||
client.sendStandardRequest();
|
||||
HttpResponse response = client.readResponseHeader();
|
||||
Assert.assertThat("response.extensions", response.getExtensionsHeader(), nullValue());
|
||||
HttpResponse response = client.expectUpgradeResponse();
|
||||
assertThat("response.extensions", response.getExtensionsHeader(), nullValue());
|
||||
|
||||
client.write(new TextFrame().setPayload("NegoExts"));
|
||||
EventQueue<WebSocketFrame> frames = client.readFrames(1, 1, TimeUnit.SECONDS);
|
||||
WebSocketFrame frame = frames.poll();
|
||||
assertThat("Frame Response", frame.getPayloadAsUTF8(), is("negotiatedExtensions=[]"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -53,7 +53,6 @@ import org.eclipse.jetty.io.EndPoint;
|
|||
import org.eclipse.jetty.util.B64Code;
|
||||
import org.eclipse.jetty.util.MultiMap;
|
||||
import org.eclipse.jetty.util.QuotedStringTokenizer;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.UrlEncoded;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
@ -91,10 +90,11 @@ public class WebSocketUpgradeRequest extends HttpRequest implements CompleteList
|
|||
{
|
||||
this.extensions = new ArrayList<>(request.getExtensions());
|
||||
this.subProtocols = new ArrayList<>(request.getSubProtocols());
|
||||
|
||||
request.getHeaders().forEach((name, values) ->
|
||||
values.forEach((value) -> header(name, value))
|
||||
);
|
||||
|
||||
// Copy values from ClientUpgradeRequest into place
|
||||
if (StringUtil.isNotBlank(request.getOrigin()))
|
||||
header(HttpHeader.ORIGIN,request.getOrigin());
|
||||
for (HttpCookie cookie : request.getCookies())
|
||||
{
|
||||
cookie(cookie);
|
||||
|
|
|
@ -53,6 +53,7 @@ import org.junit.Test;
|
|||
/**
|
||||
* Various connect condition testing
|
||||
*/
|
||||
@SuppressWarnings("Duplicates")
|
||||
public class ClientConnectTest
|
||||
{
|
||||
@Rule
|
||||
|
@ -161,7 +162,34 @@ public class ClientConnectTest
|
|||
IBlockheadServerConnection connection = server.accept();
|
||||
connection.upgrade();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpgradeWithAuthorizationHeader() throws Exception
|
||||
{
|
||||
JettyTrackingSocket wsocket = new JettyTrackingSocket();
|
||||
|
||||
URI wsUri = server.getWsUri();
|
||||
ClientUpgradeRequest upgradeRequest = new ClientUpgradeRequest();
|
||||
// actual value for this test is irrelevant, its important that this
|
||||
// header actually be sent with a value (the value specified)
|
||||
upgradeRequest.setHeader("Authorization", "Bogus SHA1");
|
||||
Future<Session> future = client.connect(wsocket,wsUri,upgradeRequest);
|
||||
|
||||
IBlockheadServerConnection connection = server.accept();
|
||||
List<String> requestLines = connection.upgrade();
|
||||
|
||||
Session sess = future.get(30,TimeUnit.SECONDS);
|
||||
sess.close();
|
||||
|
||||
String authLine = requestLines.stream()
|
||||
.filter((line) -> line.startsWith("Authorization:"))
|
||||
.findFirst().get();
|
||||
|
||||
assertThat("Request Container Authorization", authLine, is("Authorization: Bogus SHA1"));
|
||||
assertThat("Connect.UpgradeRequest", wsocket.connectUpgradeRequest, notNullValue());
|
||||
assertThat("Connect.UpgradeResponse", wsocket.connectUpgradeResponse, notNullValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBadHandshake() throws Exception
|
||||
{
|
||||
|
|
|
@ -66,6 +66,7 @@ GIT_USER_EMAIL=`git config --get user.email`
|
|||
#fi
|
||||
|
||||
VER_CURRENT=`sed -e "s/xmlns/ignore/" pom.xml | xmllint --xpath "/project/version/text()" -`
|
||||
echo "Current pom.xml Version: ${VER_CURRENT}"
|
||||
read -e -p "Release Version ? " VER_RELEASE
|
||||
read -e -p "Next Dev Version ? " VER_NEXT
|
||||
# VER_RELEASE=9.3.5.v20151012
|
||||
|
@ -87,8 +88,8 @@ if [ ! -d "$ALT_DEPLOY_DIR" ] ; then
|
|||
mkdir -p "$ALT_DEPLOY_DIR"
|
||||
fi
|
||||
|
||||
DEPLOY_OPTS="-Dmaven.test.failure.ignore=true"
|
||||
# DEPLOY_OPTS="-Dtest=None"
|
||||
# DEPLOY_OPTS="-Dmaven.test.failure.ignore=true"
|
||||
DEPLOY_OPTS="-Dtest=None"
|
||||
# DEPLOY_OPTS="$DEPLOY_OPTS -DaltDeploymentRepository=intarget::default::file://$ALT_DEPLOY_DIR/"
|
||||
|
||||
echo ""
|
||||
|
@ -129,10 +130,13 @@ echo ""
|
|||
if proceedyn "Are you sure you want to release using above? (y/N)" n; then
|
||||
echo ""
|
||||
if proceedyn "Update VERSION.txt for $VER_RELEASE? (Y/n)" y; then
|
||||
mvn -N -Pupdate-version
|
||||
mvn -N -Pupdate-version generate-resources
|
||||
cp VERSION.txt VERSION.txt.backup
|
||||
cat VERSION.txt.backup | sed -e "s/$VER_CURRENT/$VER_RELEASE/" > VERSION.txt
|
||||
rm VERSION.txt.backup
|
||||
echo "VERIFY the following files (in a different console window) before continuing."
|
||||
echo " VERSION.txt - top section"
|
||||
echo " target/vers-tag.txt - for the tag commit message"
|
||||
fi
|
||||
|
||||
# This is equivalent to 'mvn release:prepare'
|
||||
|
@ -146,7 +150,8 @@ if proceedyn "Are you sure you want to release using above? (y/N)" n; then
|
|||
fi
|
||||
if proceedyn "Create Tag $TAG_NAME? (Y/n)" y; then
|
||||
echo "TODO: Sign tags with GIT_USER_EMAIL=$GIT_USER_EMAIL"
|
||||
git tag -m "Creating tag $TAG_NAME" $TAG_NAME
|
||||
echo "Using target/vers-tag.txt as tag text"
|
||||
git tag --file=target/vers-tag.txt $TAG_NAME
|
||||
fi
|
||||
|
||||
# This is equivalent to 'mvn release:perform'
|
||||
|
|
|
@ -0,0 +1,163 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.server.session;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
import javax.servlet.http.HttpSessionBindingEvent;
|
||||
import javax.servlet.http.HttpSessionBindingListener;
|
||||
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* SessionListenerTest
|
||||
*
|
||||
* Test that the HttpSessionBindingListeners are called.
|
||||
*/
|
||||
public class SessionListenerTest extends AbstractTestBase
|
||||
{
|
||||
public static class MySessionBindingListener implements HttpSessionBindingListener, Serializable
|
||||
{
|
||||
boolean unbound = false;
|
||||
boolean bound = false;
|
||||
|
||||
public void valueUnbound(HttpSessionBindingEvent event)
|
||||
{
|
||||
unbound = true;
|
||||
}
|
||||
|
||||
public void valueBound(HttpSessionBindingEvent event)
|
||||
{
|
||||
bound = true;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Foo implements Serializable
|
||||
{
|
||||
public boolean bar = false;
|
||||
|
||||
public boolean getBar() { return bar;};
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public AbstractTestServer createServer(int port, int max, int scavenge, int evictionPolicy) throws Exception
|
||||
{
|
||||
return new HashTestServer(port,max,scavenge,evictionPolicy);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListener() throws Exception
|
||||
{
|
||||
String contextPath = "";
|
||||
String servletMapping = "/server";
|
||||
int inactivePeriod = 6;
|
||||
int scavengePeriod = 3;
|
||||
AbstractTestServer server = createServer(0, inactivePeriod, scavengePeriod, SessionCache.NEVER_EVICT);
|
||||
ServletContextHandler context = server.addContext(contextPath);
|
||||
TestServlet servlet = new TestServlet();
|
||||
ServletHolder holder = new ServletHolder(servlet);
|
||||
context.addServlet(holder, servletMapping);
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
server.start();
|
||||
int port1 = server.getPort();
|
||||
|
||||
HttpClient client = new HttpClient();
|
||||
client.start();
|
||||
try
|
||||
{
|
||||
String url = "http://localhost:" + port1 + contextPath + servletMapping;
|
||||
|
||||
|
||||
// Create the session
|
||||
ContentResponse response1 = client.GET(url + "?action=init");
|
||||
assertEquals(HttpServletResponse.SC_OK,response1.getStatus());
|
||||
String sessionCookie = response1.getHeaders().get("Set-Cookie");
|
||||
assertTrue(sessionCookie != null);
|
||||
// Mangle the cookie, replacing Path with $Path, etc.
|
||||
sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=", "$1\\$Path=");
|
||||
|
||||
assertTrue (servlet.listener.bound);
|
||||
|
||||
|
||||
// Make a request which will invalidate the existing session
|
||||
Request request2 = client.newRequest(url + "?action=test");
|
||||
request2.header("Cookie", sessionCookie);
|
||||
ContentResponse response2 = request2.send();
|
||||
assertEquals(HttpServletResponse.SC_OK,response2.getStatus());
|
||||
|
||||
assertTrue (servlet.listener.unbound);
|
||||
}
|
||||
finally
|
||||
{
|
||||
client.stop();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
server.stop();
|
||||
}
|
||||
}
|
||||
|
||||
public static class TestServlet extends HttpServlet
|
||||
{
|
||||
public static final MySessionBindingListener listener = new MySessionBindingListener();
|
||||
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse httpServletResponse) throws ServletException, IOException
|
||||
{
|
||||
String action = request.getParameter("action");
|
||||
|
||||
if ("init".equals(action))
|
||||
{
|
||||
HttpSession session = request.getSession(true);
|
||||
session.setAttribute("foo", listener);
|
||||
assertNotNull(session);
|
||||
|
||||
}
|
||||
else if ("test".equals(action))
|
||||
{
|
||||
HttpSession session = request.getSession(false);
|
||||
assertNotNull(session);
|
||||
|
||||
//invalidate existing session
|
||||
session.invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue