Merge remote-tracking branch 'origin/jetty-9.4.x'
This commit is contained in:
commit
02f0649840
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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)}
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue