Merge remote-tracking branch 'origin/jetty-9.4.x'

This commit is contained in:
Joakim Erdfelt 2017-08-28 11:33:12 -07:00
commit 02f0649840
9 changed files with 99 additions and 117 deletions

View File

@ -597,6 +597,9 @@ The available configuration parameters - in addition to those for the `jetty:run
jvmArgs::
Optional.
A string representing arbitrary arguments to pass to the forked JVM.
env::
Optional.
Map of key/value pairs to pass as environment to the forked JVM.
waitForChild::
Default is `true`.
This causes the parent process to wait for the forked process to exit.

View File

@ -25,7 +25,6 @@ import java.security.Principal;
import javax.security.auth.Subject;
import javax.servlet.ServletRequest;
import org.eclipse.jetty.server.UserIdentity;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
import org.eclipse.jetty.util.log.Log;
@ -203,7 +202,6 @@ public abstract class AbstractLoginService extends AbstractLifeCycle implements
if (user.getUserPrincipal() instanceof UserPrincipal)
{
System.err.println("VALIDATING user "+fresh.getName());
return fresh.authenticate(((UserPrincipal)user.getUserPrincipal())._credential);
}

View File

@ -18,17 +18,8 @@
package org.eclipse.jetty.security;
import org.eclipse.jetty.util.PathWatcher;
import org.eclipse.jetty.util.PathWatcher.PathWatchEvent;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.resource.JarResource;
import org.eclipse.jetty.util.resource.PathResource;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.util.security.Credential;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
@ -41,6 +32,17 @@ import java.util.Map;
import java.util.Properties;
import java.util.Set;
import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.PathWatcher;
import org.eclipse.jetty.util.PathWatcher.PathWatchEvent;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.resource.JarFileResource;
import org.eclipse.jetty.util.resource.PathResource;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.util.security.Credential;
/**
* PropertyUserStore
* <p>
@ -59,13 +61,10 @@ public class PropertyUserStore extends UserStore implements PathWatcher.Listener
{
private static final Logger LOG = Log.getLogger(PropertyUserStore.class);
private static final String JAR_FILE = "jar:file:";
protected Path _configPath;
protected Resource _configResource;
protected PathWatcher pathWatcher;
protected boolean hotReload = false; // default is not to reload
protected PathWatcher _pathWatcher;
protected boolean _hotReload = false; // default is not to reload
protected boolean _firstLoad = true; // true if first load, false from that point on
protected List<UserListener> _listeners;
@ -73,9 +72,7 @@ public class PropertyUserStore extends UserStore implements PathWatcher.Listener
/**
* Get the config (as a string)
* @return the config path as a string
* @deprecated use {@link #getConfigPath()} instead
*/
@Deprecated
public String getConfig()
{
if (_configPath != null)
@ -89,16 +86,28 @@ public class PropertyUserStore extends UserStore implements PathWatcher.Listener
*/
public void setConfig(String config)
{
if (config == null)
{
_configPath = null;
return;
}
try
{
Resource configResource = Resource.newResource(config);
if (configResource.getFile() != null)
setConfigPath(configResource.getFile());
if (configResource instanceof JarFileResource)
_configPath = extractPackedFile((JarFileResource)configResource);
else if (configResource instanceof PathResource)
_configPath = ((PathResource)configResource).getPath();
else if (configResource.getFile() != null)
setConfigFile(configResource.getFile());
else
throw new IllegalArgumentException(config+" is not a file");
throw new IllegalArgumentException(config);
}
catch (Exception e)
{
_configPath = null;
throw new IllegalStateException(e);
}
@ -117,44 +126,33 @@ public class PropertyUserStore extends UserStore implements PathWatcher.Listener
* Set the Config Path from a String reference to a file
* @param configFile the config file can a be a file path or a reference to a file within a jar file <code>jar:file:</code>
*/
@Deprecated
public void setConfigPath(String configFile)
{
if (configFile == null)
{
_configPath = null;
}
else if (new File( configFile ).exists())
{
_configPath = new File(configFile).toPath();
}
if ( !new File( configFile ).exists() && configFile.startsWith( JAR_FILE ))
{
// format of the url is jar:file:/foo/bar/beer.jar!/mountain_goat/pale_ale.txt
// ideally we'd like to extract this to Resource class?
try
{
_configPath = extractPackedFile( configFile );
}
catch ( IOException e )
{
throw new RuntimeException( "cannot extract file from url:" + configFile, e );
}
}
setConfig(configFile);
}
private Path extractPackedFile( String configFile )
private Path extractPackedFile( JarFileResource configResource )
throws IOException
{
int fileIndex = configFile.indexOf( "!" );
String entryPath = configFile.substring( fileIndex + 1, configFile.length() );
String uri = configResource.getURI().toASCIIString();
int colon = uri.lastIndexOf(":");
int bang_slash = uri.indexOf("!/");
if (colon<0 || bang_slash<0 || colon>bang_slash)
throw new IllegalArgumentException("Not resolved JarFile resource: "+uri);
String entry_path = uri.substring(colon+2).replace("!/","__").replace('/','_').replace('.','_');
Path tmpDirectory = Files.createTempDirectory( "users_store" );
Path extractedPath = Paths.get(tmpDirectory.toString(), entryPath);
// delete if exists as copyTo do not overwrite
tmpDirectory.toFile().deleteOnExit();
Path extractedPath = Paths.get(tmpDirectory.toString(), entry_path);
Files.deleteIfExists( extractedPath );
// delete on shutdown
extractedPath.toFile().deleteOnExit();
JarResource.newResource( configFile ).copyTo( tmpDirectory.toFile() );
IO.copy(configResource.getInputStream(),new FileOutputStream(extractedPath.toFile()));
if (isHotReload())
{
LOG.warn("Cannot hot reload from packed configuration: {}",configResource);
setHotReload(false);
}
return extractedPath;
}
@ -162,7 +160,17 @@ public class PropertyUserStore extends UserStore implements PathWatcher.Listener
* Set the Config Path from a {@link File} reference
* @param configFile the config file
*/
@Deprecated
public void setConfigPath(File configFile)
{
setConfigFile(configFile);
}
/**
* Set the Config Path from a {@link File} reference
* @param configFile the config file
*/
public void setConfigFile(File configFile)
{
if(configFile == null)
{
@ -182,19 +190,15 @@ public class PropertyUserStore extends UserStore implements PathWatcher.Listener
_configPath = configPath;
}
/* ------------------------------------------------------------ */
/**
* @return the resource associated with the configured properties file, creating it if necessary
* @throws IOException if unable to get the resource
*/
public Resource getConfigResource() throws IOException
{
if (_configResource == null)
{
_configResource = new PathResource(_configPath);
}
return _configResource;
if (_configPath==null)
return null;
return new PathResource(_configPath);
}
/**
@ -204,7 +208,7 @@ public class PropertyUserStore extends UserStore implements PathWatcher.Listener
*/
public boolean isHotReload()
{
return hotReload;
return _hotReload;
}
/**
@ -218,7 +222,7 @@ public class PropertyUserStore extends UserStore implements PathWatcher.Listener
{
throw new IllegalStateException("Cannot set hot reload while user store is running");
}
this.hotReload = enable;
this._hotReload = enable;
}
@ -247,8 +251,9 @@ public class PropertyUserStore extends UserStore implements PathWatcher.Listener
}
Properties properties = new Properties();
if (getConfigResource().exists())
properties.load(getConfigResource().getInputStream());
Resource config = getConfigResource();
if (config!=null && config.exists())
properties.load(config.getInputStream());
Set<String> known = new HashSet<>();
@ -297,7 +302,6 @@ public class PropertyUserStore extends UserStore implements PathWatcher.Listener
}
}
/*
* set initial load to false as there should be no more initial loads
*/
@ -324,11 +328,11 @@ public class PropertyUserStore extends UserStore implements PathWatcher.Listener
loadUsers();
if ( isHotReload() && (_configPath != null) )
{
this.pathWatcher = new PathWatcher();
this.pathWatcher.watch(_configPath);
this.pathWatcher.addListener(this);
this.pathWatcher.setNotifyExistingOnStart(false);
this.pathWatcher.start();
this._pathWatcher = new PathWatcher();
this._pathWatcher.watch(_configPath);
this._pathWatcher.addListener(this);
this._pathWatcher.setNotifyExistingOnStart(false);
this._pathWatcher.start();
}
}
@ -357,9 +361,9 @@ public class PropertyUserStore extends UserStore implements PathWatcher.Listener
protected void doStop() throws Exception
{
super.doStop();
if (this.pathWatcher != null)
this.pathWatcher.stop();
this.pathWatcher = null;
if (this._pathWatcher != null)
this._pathWatcher.stop();
this._pathWatcher = null;
}
/**

View File

@ -169,7 +169,7 @@ public class PropertyUserStoreTest
final File usersFile = initUsersText();
PropertyUserStore store = new PropertyUserStore();
store.setConfigPath(usersFile);
store.setConfigFile(usersFile);
store.registerUserListener(userCount);
@ -189,7 +189,7 @@ public class PropertyUserStoreTest
final String usersFile = initUsersPackedFileText();
PropertyUserStore store = new PropertyUserStore();
store.setConfigPath(usersFile);
store.setConfig(usersFile);
store.registerUserListener(userCount);
@ -215,7 +215,7 @@ public class PropertyUserStoreTest
PropertyUserStore store = new PropertyUserStore();
store.setHotReload(true);
store.setConfigPath(usersFile);
store.setConfigFile(usersFile);
store.registerUserListener(userCount);
@ -246,7 +246,7 @@ public class PropertyUserStoreTest
PropertyUserStore store = new PropertyUserStore();
store.setHotReload(true);
store.setConfigPath(usersFile);
store.setConfigFile(usersFile);
store.registerUserListener(userCount);

View File

@ -34,7 +34,7 @@ import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
/* ------------------------------------------------------------ */
class JarFileResource extends JarResource
public class JarFileResource extends JarResource
{
private static final Logger LOG = Log.getLogger(JarFileResource.class);
private JarFile _jarFile;

View File

@ -19,18 +19,14 @@
package org.eclipse.jetty.websocket.jsr356;
import java.lang.reflect.Method;
import java.util.concurrent.Executor;
import javax.websocket.ContainerProvider;
import javax.websocket.WebSocketContainer;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.MappedByteBufferPool;
import org.eclipse.jetty.util.component.ContainerLifeCycle;
import org.eclipse.jetty.util.component.LifeCycle;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.eclipse.jetty.util.thread.ShutdownThread;
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
import org.eclipse.jetty.websocket.common.scopes.SimpleContainerScope;
@ -48,10 +44,8 @@ public class JettyClientContainerProvider extends ContainerProvider
private static final Logger LOG = Log.getLogger(JettyClientContainerProvider.class);
private static boolean useSingleton = false;
private static WebSocketContainer INSTANCE;
private static boolean useServerContainer = false;
private static Executor commonExecutor;
private static ByteBufferPool commonBufferPool;
private static WebSocketContainer INSTANCE;
private static Object lock = new Object();
@ -83,7 +77,7 @@ public class JettyClientContainerProvider extends ContainerProvider
/**
* Add ability of calls to {@link ContainerProvider#getWebSocketContainer()} to
* find and return the {@link javax.websocket.server.ServerContainer} from the
* find and return the {@code javax.websocket.server.ServerContainer} from the
* active {@code javax.servlet.ServletContext}.
* <p>
* <p>
@ -91,7 +85,7 @@ public class JettyClientContainerProvider extends ContainerProvider
* occurs within a thread being processed by the Servlet container.
* </p>
*
* @param flag true to to use return the {@link javax.websocket.server.ServerContainer}
* @param flag true to to use return the {@code javax.websocket.server.ServerContainer}
* from the active {@code javax.servlet.ServletContext} for all calls to
* {@link ContainerProvider#getWebSocketContainer()} from within a Servlet thread.
*/
@ -103,13 +97,13 @@ public class JettyClientContainerProvider extends ContainerProvider
/**
* Test if {@link ContainerProvider#getWebSocketContainer()} has the ability to
* find and return the {@link javax.websocket.server.ServerContainer} from the
* find and return the {@code javax.websocket.server.ServerContainer} from the
* active {@code javax.servlet.ServletContext}, before creating a new client based
* {@link WebSocketContainer}.
*
* @return true if {@link WebSocketContainer} returned from
* calls to {@link ContainerProvider#getWebSocketContainer()} could be the
* {@link javax.websocket.server.ServerContainer}
* {@code javax.websocket.server.ServerContainer}
* from the active {@code javax.servlet.ServletContext}
*/
@SuppressWarnings("unused")
@ -194,28 +188,14 @@ public class JettyClientContainerProvider extends ContainerProvider
// Still no instance?
if (webSocketContainer == null)
{
if (commonExecutor == null)
{
QueuedThreadPool threadPool = new QueuedThreadPool();
String name = "Jsr356Client@" + hashCode();
threadPool.setName(name);
threadPool.setDaemon(true);
commonExecutor = threadPool;
}
if (commonBufferPool == null)
{
commonBufferPool = new MappedByteBufferPool();
}
SimpleContainerScope containerScope = new SimpleContainerScope(WebSocketPolicy.newClientPolicy(), commonBufferPool, commonExecutor, null);
SimpleContainerScope containerScope = new SimpleContainerScope(WebSocketPolicy.newClientPolicy());
ClientContainer clientContainer = new ClientContainer(containerScope);
if (contextHandler != null && contextHandler instanceof ContainerLifeCycle)
{
// Add as bean to contextHandler
// Allow startup to follow Jetty lifecycle
((ContainerLifeCycle) contextHandler).addBean(clientContainer);
((ContainerLifeCycle) contextHandler).addManaged(clientContainer);
}
else
{

View File

@ -66,16 +66,16 @@ import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope;
public class WebSocketClient extends ContainerLifeCycle implements WebSocketContainerScope
{
private static final Logger LOG = Log.getLogger(WebSocketClient.class);
// From HttpClient
private final HttpClient httpClient;
// The container
private final WebSocketContainerScope containerScope;
private final WebSocketExtensionFactory extensionRegistry;
private SessionFactory sessionFactory;
private final List<WebSocketSession.Listener> listeners = new CopyOnWriteArrayList<>();
private final int id = ThreadLocalRandom.current().nextInt();
/**
@ -125,7 +125,7 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont
{
this(new HttpClient());
this.httpClient.setExecutor(executor);
}
/**
@ -237,7 +237,7 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont
this.sessionFactory = new WebSocketSessionFactory(containerScope);
}
/**
* Create WebSocketClient based on pre-existing Container Scope, to allow sharing of
* internal features like Executor, ByteBufferPool, SSLContextFactory, etc.
@ -388,10 +388,7 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont
if (LOG.isDebugEnabled())
LOG.debug("Stopping {}",this);
if (ShutdownThread.isRegistered(this))
{
ShutdownThread.deregister(this);
}
ShutdownThread.deregister(this);
super.doStop();
@ -434,7 +431,7 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont
{
return httpClient.getCookieStore();
}
public Executor getExecutor()
{
return httpClient.getExecutor();
@ -451,10 +448,10 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont
threadPool.setDaemon(true);
return threadPool;
}
return executor;
}
public ExtensionFactory getExtensionFactory()
{
return extensionRegistry;
@ -698,7 +695,7 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont
getPolicy().setIdleTimeout(ms);
httpClient.setIdleTimeout(ms);
}
/**
* @deprecated see {@link WebSocketPolicy#setMaxTextMessageBufferSize(int)}
*/

View File

@ -250,7 +250,7 @@ public class DelayedStartClientOnServerTest
List<String> threadNames = getThreadNames(server, (ContainerLifeCycle)container);
assertNoHttpClientPoolThreads(threadNames);
assertThat("Threads", threadNames, hasItem(containsString("Jsr356Client@")));
assertThat("Threads", threadNames, hasItem(containsString("WebSocketContainer@")));
}
finally
{

View File

@ -933,7 +933,7 @@
<dependency>
<groupId>org.eclipse.jetty.toolchain</groupId>
<artifactId>jetty-test-helper</artifactId>
<version>4.1</version>
<version>4.2</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.toolchain</groupId>