/*
 * Copyright (c) 2010, 2017 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package org.glassfish.grizzly.http.server;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.net.ssl.SSLEngine;

import org.glassfish.grizzly.Connection;
import org.glassfish.grizzly.EmptyCompletionHandler;
import org.glassfish.grizzly.GracefulShutdownListener;
import org.glassfish.grizzly.Grizzly;
import org.glassfish.grizzly.GrizzlyFuture;
import org.glassfish.grizzly.PortRange;
import org.glassfish.grizzly.ShutdownContext;
import org.glassfish.grizzly.filterchain.Filter;
import org.glassfish.grizzly.filterchain.FilterChain;
import org.glassfish.grizzly.filterchain.FilterChainContext;
import org.glassfish.grizzly.filterchain.ShutdownEvent;
import org.glassfish.grizzly.http.CompressionConfig;
import org.glassfish.grizzly.http.CompressionConfig.CompressionMode;
import org.glassfish.grizzly.http.HttpCodecFilter;
import org.glassfish.grizzly.http.KeepAlive;
import org.glassfish.grizzly.http.server.filecache.FileCache;
import org.glassfish.grizzly.http.util.MimeHeaders;
import org.glassfish.grizzly.impl.FutureImpl;
import org.glassfish.grizzly.monitoring.MonitoringUtils;
import org.glassfish.grizzly.nio.transport.TCPNIOServerConnection;
import org.glassfish.grizzly.nio.transport.TCPNIOTransport;
import org.glassfish.grizzly.nio.transport.TCPNIOTransportBuilder;
import org.glassfish.grizzly.ssl.SSLEngineConfigurator;
import org.glassfish.grizzly.strategies.SameThreadIOStrategy;
import org.glassfish.grizzly.threadpool.ThreadPoolConfig;
import org.glassfish.grizzly.utils.ArraySet;
import org.glassfish.grizzly.utils.Futures;

public class NetworkListener {
    private static final Logger LOGGER = Grizzly.logger(NetworkListener.class);

    
The default network host to which the HttpServer will bind to in order to service HTTP requests.
/** * The default network host to which the {@link HttpServer} will bind to in order to service <code>HTTP</code> * requests. */
public static final String DEFAULT_NETWORK_HOST = "0.0.0.0";
The default network port to which the HttpServer will bind to in order to service HTTP requests.
/** * The default network port to which the {@link HttpServer} will bind to in order to service <code>HTTP</code> * requests. */
public static final int DEFAULT_NETWORK_PORT = 8080;
The network host to which the HttpServer will bind to in order to service HTTP requests. If not explicitly set, the value of DEFAULT_NETWORK_HOST will be used.
/** * The network host to which the <code>HttpServer<code> will bind to in order to service <code>HTTP</code> requests. * If not explicitly set, the value of {@link #DEFAULT_NETWORK_HOST} will be used. */
private String host = DEFAULT_NETWORK_HOST;
The network port to which the HttpServer will bind to in order to service HTTP requests. If not explicitly set, the value of DEFAULT_NETWORK_PORT will be used.
/** * The network port to which the <code>HttpServer<code> will bind to in order to service <code>HTTP</code> requests. * If not explicitly set, the value of {@link #DEFAULT_NETWORK_PORT} will be used. */
private int port = DEFAULT_NETWORK_PORT;
The flag indicates if the HttpServer will be bounnd to an inherited Channel. If not explicitly set, the HttpServer will be bound to DEFAULT_NETWORK_HOST:DEFAULT_NETWORK_PORT.
/** * The flag indicates if the <code>HttpServer<code> will be bounnd to an inherited Channel. * If not explicitly set, the <code>HttpServer</code> will be bound to {@link #DEFAULT_NETWORK_HOST}:{@link #DEFAULT_NETWORK_PORT}. */
private final boolean isBindToInherited;
The time, in seconds, for which a request must complete processing.
/** * The time, in seconds, for which a request must complete processing. */
private int transactionTimeout = -1;
The network port range to which the HttpServer will bind to in order to service HTTP requests. If not explicitly set, the value of port will be used.
/** * The network port range to which the <code>HttpServer<code> will bind to * in order to service <code>HTTP</code> requests. * If not explicitly set, the value of {@link #port} will be used. */
private PortRange portRange;
The logical name of this particular NetworkListener instance.
/** * The logical <code>name</code> of this particular <code>NetworkListener</code> instance. */
private final String name;
The configuration for HTTP keep-alive connections
/** * The configuration for HTTP keep-alive connections */
private final KeepAlive keepAliveConfig = new KeepAlive();
The Grizzly FilterChain used to process incoming and outgoing network I/O.
/** * The Grizzly {@link FilterChain} used to process incoming and outgoing network I/O. */
private FilterChain filterChain;
The TCPNIOTransport used by this NetworkListener
/** * The {@link TCPNIOTransport} used by this <code>NetworkListener</code> */
private TCPNIOTransport transport;
TCP Server Connection responsible for accepting client connections
/** * TCP Server {@link Connection} responsible for accepting client connections */
private TCPNIOServerConnection serverConnection;
The default error page generator
/** * The default error page generator */
private ErrorPageGenerator defaultErrorPageGenerator;
The HTTP server SessionManager.
/** * The HTTP server {@link SessionManager}. */
private SessionManager sessionManager; { final TCPNIOTransportBuilder builder = TCPNIOTransportBuilder.newInstance(); final int coresCount = Runtime.getRuntime().availableProcessors() * 2; transport = builder .setIOStrategy(SameThreadIOStrategy.getInstance()) .setWorkerThreadPoolConfig(ThreadPoolConfig.defaultConfig() .setPoolName("Grizzly-worker") .setCorePoolSize(coresCount) .setMaxPoolSize(coresCount) .setMemoryManager(builder.getMemoryManager())) .build(); }
Flag indicating whether or not this listener is secure. Defaults to false
/** * Flag indicating whether or not this listener is secure. Defaults to <code>false</code> */
private boolean secure;
AddOns registered for the network listener
/** * AddOns registered for the network listener */
private final ArraySet<AddOn> addons = new ArraySet<>(AddOn.class);
Flag indicating whether or not the chunked transfer encoding is enabled. Defaults to true.
/** * Flag indicating whether or not the chunked transfer encoding is enabled. Defaults to <code>true</code>. */
private boolean chunkingEnabled = true;
Configuration for the SSLEngine that will be used for secure listeners.
/** * Configuration for the {@link SSLEngine} that will be used for secure listeners. */
private SSLEngineConfigurator sslEngineConfig;
The maximum size of an incoming HTTP message.
/** * The maximum size of an incoming <code>HTTP</code> message. */
private int maxHttpHeaderSize = -1;
FileCache to be used by this NetworkListener.
/** * {@link FileCache} to be used by this <code>NetworkListener</code>. */
private final FileCache fileCache = new FileCache();
Maximum size, in bytes, of all data waiting to be written.
/** * Maximum size, in bytes, of all data waiting to be written. */
private volatile int maxPendingBytes = -1;
Flag indicating the state of this listener.
/** * Flag indicating the state of this listener. */
private State state = State.STOPPED;
Future to control graceful shutdown status
/** * Future to control graceful shutdown status */
private FutureImpl<NetworkListener> shutdownFuture;
Shutdown event.
/** * Shutdown event. */
private ShutdownEvent shutdownEvent;
HttpServerFilter associated with this listener.
/** * {@link HttpServerFilter} associated with this listener. */
private HttpServerFilter httpServerFilter;
HttpCodecFilter associated with this listener.
/** * {@link HttpCodecFilter} associated with this listener. */
private HttpCodecFilter httpCodecFilter; /** * {@link CompressionConfig} */ private final CompressionConfig compressionConfig = new CompressionConfig(); private boolean authPassThroughEnabled; private int maxFormPostSize = 2 * 1024 * 1024; private int maxBufferedPostSize = 2 * 1024 * 1024; private String restrictedUserAgents; private int uploadTimeout; private boolean disableUploadTimeout; private boolean traceEnabled; private String uriEncoding; private Boolean sendFileEnabled;
The auxiliary configuration, which might be used, when Grizzly HttpServer is running behind some HTTP gateway like reverse proxy or load balancer.
/** * The auxiliary configuration, which might be used, when Grizzly HttpServer * is running behind some HTTP gateway like reverse proxy or load balancer. */
private BackendConfiguration backendConfiguration; private int maxRequestHeaders = MimeHeaders.MAX_NUM_HEADERS_DEFAULT; private int maxResponseHeaders = MimeHeaders.MAX_NUM_HEADERS_DEFAULT; // ------------------------------------------------------------ Constructors

Constructs a new NetworkListener using the specified name. The listener's host and port will default to DEFAULT_NETWORK_HOST and DEFAULT_NETWORK_PORT.

Params:
  • name – the logical name of the listener.
/** * <p> Constructs a new <code>NetworkListener</code> using the specified <code>name</code>. The listener's host and * port will default to {@link #DEFAULT_NETWORK_HOST} and {@link #DEFAULT_NETWORK_PORT}. </p> * * @param name the logical name of the listener. */
public NetworkListener(final String name) { this(name, false); }

Constructs a new NetworkListener using the specified name, which, depending on isBindToInherited will or will not be bound to an inherited Channel.

Params:
  • name – the logical name of the listener.
  • isBindToInherited – if true the NetworkListener will be bound to an inherited Channel, otherwise default DEFAULT_NETWORK_HOST and DEFAULT_NETWORK_PORT will be used.
See Also:
/** * <p> Constructs a new <code>NetworkListener</code> using the specified <code>name</code>, which, * depending on <code>isBindToInherited</code> will or will not be bound to an inherited Channel.</p> * * @param name the logical name of the listener. * @param isBindToInherited if <tt>true</tt> the <code>NetworkListener</code> will be * bound to an inherited Channel, otherwise default {@link #DEFAULT_NETWORK_HOST} and {@link #DEFAULT_NETWORK_PORT} * will be used. * * @see System#inheritedChannel() */
public NetworkListener(final String name, final boolean isBindToInherited) { validateArg("name", name); this.name = name; this.isBindToInherited = isBindToInherited; }

Constructs a new NetworkListener using the specified name and host. The listener's port will default to DEFAULT_NETWORK_PORT.

Params:
  • name – the logical name of the listener.
  • host – the network host to which this listener will bind.
/** * <p> Constructs a new <code>NetworkListener</code> using the specified <code>name</code> and <code>host</code>. * The listener's port will default to {@link #DEFAULT_NETWORK_PORT}. </p> * * @param name the logical name of the listener. * @param host the network host to which this listener will bind. */
public NetworkListener(final String name, final String host) { this(name, host, DEFAULT_NETWORK_PORT); }

Constructs a new NetworkListener using the specified name, host, and port.

Params:
  • name – the logical name of the listener.
  • host – the network host to which this listener will bind.
  • port – the network port to which this listener will bind..
/** * <p> Constructs a new <code>NetworkListener</code> using the specified <code>name</code>, <code>host</code>, and * <code>port</code>. </p> * * @param name the logical name of the listener. * @param host the network host to which this listener will bind. * @param port the network port to which this listener will bind.. */
public NetworkListener(final String name, final String host, final int port) { validateArg("name", name); validateArg("host", host); if (port < 0) { throw new IllegalArgumentException("Invalid port"); } this.name = name; this.host = host; this.port = port; isBindToInherited = false; }

Constructs a new NetworkListener using the specified name, host, and port.

Params:
  • name – the logical name of the listener.
  • host – the network host to which this listener will bind.
  • portRange – the network port range to which this listener will bind..
/** * <p> Constructs a new <code>NetworkListener</code> using the specified <code>name</code>, <code>host</code>, and * <code>port</code>. </p> * * @param name the logical name of the listener. * @param host the network host to which this listener will bind. * @param portRange the network port range to which this listener will bind.. */
public NetworkListener(final String name, final String host, final PortRange portRange) { validateArg("name", name); validateArg("host", host); this.name = name; this.host = host; this.port = -1; this.portRange = portRange; isBindToInherited = false; } // ----------------------------------------------------------- Configuration
Returns:the logical name of this listener.
/** * @return the logical name of this listener. */
public String getName() { return name; }
Returns:the network host to which this listener is configured to bind to.
/** * @return the network host to which this listener is configured to bind to. */
public String getHost() { return host; }
Returns:the network port to which this listener is configured to bind to. If the HttpServer has not been started yet - the returned value may be: -1, if PortRange will be used to bind the listener; 0, if the port will be assigned by OS; 0 < N < 65536, the port this listener will be bound to. If HttpServer has been started - the value returned is the port the this listener is bound to.
/** * @return the network port to which this listener is configured to bind to. * If the {@link HttpServer} has not been started yet - the returned value * may be: * <tt>-1</tt>, if {@link PortRange} will be used to bind the listener; * <tt>0</tt>, if the port will be assigned by OS; * <tt>0 < N < 65536</tt>, the port this listener will be bound to. * If {@link HttpServer} has been started - the value returned is the port the * this listener is bound to. */
public int getPort() { return port; }
Returns:the network port range to which this listener is configured to bind to.
/** * @return the network port range to which this listener is configured to bind to. */
public PortRange getPortRange() { return portRange; }
Returns:the configuration for the keep-alive HTTP connections.
/** * @return the configuration for the keep-alive HTTP connections. */
public KeepAlive getKeepAlive() { return keepAliveConfig; }
Returns:the TCPNIOTransport used by this listener.
/** * @return the {@link TCPNIOTransport} used by this listener. */
public TCPNIOTransport getTransport() { return transport; }

This allows the developer to specify a custom TCPNIOTransport implementation to be used by this listener.

Attempts to change the transport implementation while the listener is running will be ignored.

Params:
/** * <p> This allows the developer to specify a custom {@link TCPNIOTransport} implementation to be used by this * listener. </p> * <p/> * <p> Attempts to change the transport implementation while the listener is running will be ignored. </p> * * @param transport a custom {@link TCPNIOTransport} implementation. */
public void setTransport(final TCPNIOTransport transport) { if (transport == null) { return; } if (!transport.isStopped()) { return; } this.transport = transport; }
Returns:Grizzly server Connection, that is responsible for accepting incoming client connections
Since:2.3.24
/** * @return Grizzly server {@link Connection}, that is responsible for * accepting incoming client connections * @since 2.3.24 */
public Connection getServerConnection() { return serverConnection; }
Return the array of the registered AddOns. Please note, possible array modifications wont affect the NetworkListener's addons list.
Returns:the array of the registered AddOns.
/** * Return the array of the registered {@link AddOn}s. * Please note, possible array modifications wont affect the * {@link NetworkListener}'s addons list. * * @return the array of the registered {@link AddOn}s. */
public AddOn[] getAddOns() { return addons.obtainArrayCopy(); }
Returns the direct addons collection, registered on the NetworkListener.
Returns:the direct addons collection, registered on the NetworkListener.
/** * Returns the direct addons collection, registered on the NetworkListener. * @return the direct addons collection, registered on the NetworkListener. */
protected ArraySet<AddOn> getAddOnSet() { return addons; }
Registers AddOn on this NetworkListener.
Params:
  • addon – the AddOn to be registered.
Returns:true, if the AddOn wasn't registered before, otherwise the existing AddOn will be replaced and this method returns false.
/** * Registers {@link AddOn} on this NetworkListener. * @param addon the {@link AddOn} to be registered. * * @return <tt>true</tt>, if the {@link AddOn} wasn't registered before, * otherwise the existing {@link AddOn} will be replaced and this method * returns <tt>false</tt>. */
public boolean registerAddOn(final AddOn addon) { return addons.add(addon); }
Deregisters AddOn from this NetworkListener.
Params:
  • addon – the AddOn to deregister.
Returns:true, if the AddOn was successfully removed, or false the the AddOn wasn't registered on the NetworkListener.
/** * Deregisters {@link AddOn} from this NetworkListener. * @param addon the {@link AddOn} to deregister. * * @return <tt>true</tt>, if the {@link AddOn} was successfully removed, or * <tt>false</tt> the the {@link AddOn} wasn't registered on the * NetworkListener. */
public boolean deregisterAddOn(final AddOn addon) { return addons.remove(addon); }
Returns:true if the HTTP response bodies should be chunked if not content length has been explicitly specified.
/** * @return <code>true</code> if the HTTP response bodies should be chunked if not content length has been explicitly * specified. */
public boolean isChunkingEnabled() { return chunkingEnabled; }
Enable/disable chunking of an HTTP response body if no content length has been explictly specified. Chunking is enabled by default.
Params:
  • chunkingEnabled – true to enable chunking; false to disable.
/** * Enable/disable chunking of an HTTP response body if no content length has been explictly specified. Chunking is * enabled by default. * * @param chunkingEnabled <code>true</code> to enable chunking; <code>false</code> to disable. */
public void setChunkingEnabled(boolean chunkingEnabled) { this.chunkingEnabled = chunkingEnabled; }
Returns:true if this is a secure listener, otherwise false. Listeners are not secure by default.
/** * @return <code>true</code> if this is a secure listener, otherwise <code>false</code>. Listeners are not secure * by default. */
public boolean isSecure() { return secure; }

Enable or disable security for this listener.

Attempts to change this value while the listener is running will be ignored.

Params:
  • secure – if true this listener will be secure.
/** * <p> Enable or disable security for this listener. </p> * <p/> * <p> Attempts to change this value while the listener is running will be ignored. </p> * * @param secure if <code>true</code> this listener will be secure. */
public void setSecure(final boolean secure) { if (!isStopped()) { return; } this.secure = secure; }
Get the HTTP request scheme, which if non-null overrides default one picked up by framework during runtime.
Returns:the HTTP request scheme
Since:2.2.4
/** * Get the HTTP request scheme, which if non-null overrides default one * picked up by framework during runtime. * * @return the HTTP request scheme * * @since 2.2.4 */
public String getScheme() { final BackendConfiguration config = backendConfiguration; return config != null ? config.getScheme() : null; }
Set the HTTP request scheme, which if non-null overrides default one picked up by framework during runtime.
Params:
  • scheme – the HTTP request scheme
Since:2.2.4
/** * Set the HTTP request scheme, which if non-null overrides default one * picked up by framework during runtime. * * @param scheme the HTTP request scheme * * @since 2.2.4 */
public void setScheme(String scheme) { BackendConfiguration config = backendConfiguration; if (config == null) { config = new BackendConfiguration(); } config.setScheme(scheme); this.backendConfiguration = config; }
Returns:the auxiliary configuration, which might be used, when Grizzly HttpServer is running behind HTTP gateway like reverse proxy or load balancer.
Since:2.3.18
/** * @return the auxiliary configuration, which might be used, when Grizzly * HttpServer is running behind HTTP gateway like reverse proxy or load balancer. * * @since 2.3.18 */
public BackendConfiguration getBackendConfiguration() { return backendConfiguration; }
Sets the auxiliary configuration, which might be used, when Grizzly HttpServer is running behind HTTP gateway like reverse proxy or load balancer.
Params:
Since:2.3.18
/** * Sets the auxiliary configuration, which might be used, when Grizzly HttpServer * is running behind HTTP gateway like reverse proxy or load balancer. * * @param backendConfiguration {@link BackendConfiguration} * @since 2.3.18 */
public void setBackendConfiguration(BackendConfiguration backendConfiguration) { this.backendConfiguration = backendConfiguration; }
Returns the maximum number of headers allowed for a request.
Since:2.2.11
/** * Returns the maximum number of headers allowed for a request. * * @since 2.2.11 */
public int getMaxRequestHeaders() { return maxRequestHeaders; }
Sets the maximum number of headers allowed for a request. If the specified value is less than zero, then there may be an unlimited number of headers (memory permitting).
Since:2.2.11
/** * Sets the maximum number of headers allowed for a request. * * If the specified value is less than zero, then there may be an * unlimited number of headers (memory permitting). * * @since 2.2.11 */
public void setMaxRequestHeaders(int maxRequestHeaders) { this.maxRequestHeaders = maxRequestHeaders; }
Returns the maximum number of headers allowed for a response.
Since:2.2.11
/** * Returns the maximum number of headers allowed for a response. * * @since 2.2.11 */
public int getMaxResponseHeaders() { return maxResponseHeaders; }
Sets the maximum number of headers allowed for a response. If the specified value is less than zero, then there may be an unlimited number of headers (memory permitting).
Since:2.2.11
/** * Sets the maximum number of headers allowed for a response. * * If the specified value is less than zero, then there may be an * unlimited number of headers (memory permitting). * * @since 2.2.11 */
public void setMaxResponseHeaders(int maxResponseHeaders) { this.maxResponseHeaders = maxResponseHeaders; }
Returns:the SSLEngine configuration for this listener.
/** * @return the {@link SSLEngine} configuration for this listener. */
public SSLEngineConfigurator getSslEngineConfig() { return sslEngineConfig; }

Provides customization of the SSLEngine used by this listener.

Attempts to change this value while the listener is running will be ignored.

Params:
  • sslEngineConfig – custom SSL configuration.
/** * <p> Provides customization of the {@link SSLEngine} used by this listener. </p> * <p/> * <p> Attempts to change this value while the listener is running will be ignored. </p> * * @param sslEngineConfig custom SSL configuration. */
public void setSSLEngineConfig(final SSLEngineConfigurator sslEngineConfig) { if (!isStopped()) { return; } this.sslEngineConfig = sslEngineConfig; }
Returns:the maximum header size for an HTTP request.
/** * @return the maximum header size for an HTTP request. */
public int getMaxHttpHeaderSize() { return maxHttpHeaderSize; }

Configures the maximum header size for an HTTP request.

Attempts to change this value while the listener is running will be ignored.

Params:
  • maxHttpHeaderSize – the maximum header size for an HTTP request.
/** * <p> Configures the maximum header size for an HTTP request. </p> * <p/> * <p> Attempts to change this value while the listener is running will be ignored. </p> * * @param maxHttpHeaderSize the maximum header size for an HTTP request. */
public void setMaxHttpHeaderSize(final int maxHttpHeaderSize) { if (!isStopped()) { return; } this.maxHttpHeaderSize = maxHttpHeaderSize; }
Returns:the FilterChain used to by the TCPNIOTransport associated with this listener.
/** * @return the {@link FilterChain} used to by the {@link TCPNIOTransport} associated with this listener. */
public FilterChain getFilterChain() { return filterChain; }

Specifies the FilterChain to be used by the TCPNIOTransport associated with this listener.

Attempts to change this value while the listener is running will be ignored.

Params:
/** * <p> Specifies the {@link FilterChain} to be used by the {@link TCPNIOTransport} associated with this listener. * </p> * <p/> * <p> Attempts to change this value while the listener is running will be ignored. </p> * * @param filterChain the {@link FilterChain}. */
void setFilterChain(final FilterChain filterChain) { if (!isStopped()) { return; } if (filterChain != null) { this.filterChain = filterChain; } }
Returns:the FileCache associated with this listener.
/** * @return the {@link FileCache} associated with this listener. */
public FileCache getFileCache() { return fileCache; }
Returns:the maximum size, in bytes, of all data waiting to be written to the associated Connection. If not explicitly set, the value will be -1 which effectively disables resource enforcement.
/** * @return the maximum size, in bytes, of all data waiting to be written to the associated {@link Connection}. * If not explicitly set, the value will be -1 which effectively disables * resource enforcement. */
public int getMaxPendingBytes() { return maxPendingBytes; }
The maximum size, in bytes, of all data waiting to be written to the associated Connection. If the value is zero or less, then no resource enforcement will take place.
Params:
  • maxPendingBytes – the maximum size, in bytes, of all data waiting to be written to the associated Connection.
/** * The maximum size, in bytes, of all data waiting to be written to the associated {@link Connection}. * If the value is zero or less, then no resource enforcement will take place. * * @param maxPendingBytes the maximum size, in bytes, of all data waiting to be written to the associated {@link * Connection}. */
public void setMaxPendingBytes(int maxPendingBytes) { this.maxPendingBytes = maxPendingBytes; transport.getAsyncQueueIO().getWriter().setMaxPendingBytesPerConnection(maxPendingBytes); } // ---------------------------------------------------------- Public Methods
Returns:true if this listener has been paused, otherwise false
/** * @return <code>true</code> if this listener has been paused, otherwise <code>false</code> */
public boolean isPaused() { return state == State.PAUSED; }
Returns:true if the listener has been started, otherwise false.
/** * @return <code>true</code> if the listener has been started, otherwise <code>false</code>. */
public boolean isStarted() { return state != State.STOPPED; }

Starts the listener.

Throws:
  • IOException – if an error occurs when attempting to start the listener.
/** * <p> Starts the listener. </p> * * @throws IOException if an error occurs when attempting to start the listener. */
public synchronized void start() throws IOException { if (isStarted()) { return; } shutdownFuture = null; if (filterChain == null) { throw new IllegalStateException("No FilterChain available."); // i18n } transport.setProcessor(filterChain); if (isBindToInherited) { serverConnection = transport.bindToInherited(); } else { serverConnection = (port != -1) ? transport.bind(host, port) : transport.bind(host, portRange, transport.getServerConnectionBackLog()); } port = ((InetSocketAddress) serverConnection.getLocalAddress()).getPort(); transport.addShutdownListener(new GracefulShutdownListener() { @Override public void shutdownRequested(final ShutdownContext shutdownContext) { final FutureImpl<NetworkListener> shutdownFutureLocal = shutdownFuture; filterChain.fireEventDownstream(serverConnection, shutdownEvent, new EmptyCompletionHandler<FilterChainContext>() { @Override public void completed(final FilterChainContext result) { final Set<Callable<Filter>> tasks = shutdownEvent.getShutdownTasks(); if (!tasks.isEmpty()) { final ExecutorService shutdownService = Executors.newFixedThreadPool(Math.min(5, tasks.size()) + 1); shutdownService.submit(new Runnable() { @Override public void run() { try { final List<Future<Filter>> futures; if (shutdownEvent.getGracePeriod() == -1) { futures = shutdownService.invokeAll(tasks); } else { futures = shutdownService.invokeAll(tasks, shutdownEvent.getGracePeriod(), shutdownEvent.getTimeUnit()); } for (Future<Filter> future : futures) { try { future.get(); } catch (ExecutionException e) { if (LOGGER.isLoggable(Level.SEVERE)) { LOGGER.log(Level.SEVERE, "Error processing shutdown task filter.", e); } } } shutdownFutureLocal.result(NetworkListener.this); shutdownContext.ready(); shutdownService.shutdownNow(); } catch (InterruptedException e) { if (LOGGER.isLoggable(Level.WARNING)) { LOGGER.warning("NetworkListener shutdown interrupted."); } if (LOGGER.isLoggable(Level.FINE)) { LOGGER.log(Level.FINE, e.toString(), e); } } } }); } } }); } @Override public void shutdownForced() { serverConnection = null; if (shutdownFuture != null) { shutdownFuture.result(NetworkListener.this); } } }); transport.start(); state = State.RUNNING; if (LOGGER.isLoggable(Level.INFO)) { LOGGER.log(Level.INFO, "Started listener bound to [{0}]", host + ':' + port); } } public synchronized GrizzlyFuture<NetworkListener> shutdown(final long gracePeriod, final TimeUnit timeUnit) { if (state == State.STOPPING || state == State.STOPPED) { return shutdownFuture != null ? shutdownFuture : Futures.createReadyFuture(this); } else if (state == State.PAUSED) { resume(); } shutdownEvent = new ShutdownEvent(gracePeriod, timeUnit); state = State.STOPPING; shutdownFuture = Futures.createSafeFuture(); transport.shutdown(gracePeriod, timeUnit); return shutdownFuture; }

Gracefully shuts down the listener.

Any exceptions thrown during the shutdown process will be propagated to the returned GrizzlyFuture.
Returns:GrizzlyFuture
/** * <p> Gracefully shuts down the listener. </p> Any exceptions * thrown during the shutdown process will be propagated to the returned * {@link GrizzlyFuture}. * @return {@link GrizzlyFuture} */
public synchronized GrizzlyFuture<NetworkListener> shutdown() { return shutdown(-1, TimeUnit.MILLISECONDS); }

Immediately shuts down the listener.

Throws:
  • IOException – if an error occurs when attempting to shut down the listener
/** * <p> Immediately shuts down the listener. </p> * * @throws IOException if an error occurs when attempting to shut down the listener */
public synchronized void shutdownNow() throws IOException { if (state == State.STOPPED) { return; } try { serverConnection = null; transport.shutdownNow(); if (LOGGER.isLoggable(Level.INFO)) { LOGGER.log(Level.INFO, "Stopped listener bound to [{0}]", host + ':' + port); } } finally { state = State.STOPPED; if (shutdownFuture != null) { shutdownFuture.result(this); } } }

Immediately shuts down the listener.

Throws:
  • IOException – if an error occurs when attempting to shut down the listener
Deprecated:use shutdownNow()
/** * <p> Immediately shuts down the listener. </p> * * @throws IOException if an error occurs when attempting to shut down the listener * @deprecated use {@link #shutdownNow()} */
public void stop() throws IOException { shutdownNow(); }

Pauses the listener.

/** * <p> Pauses the listener. </p> */
public synchronized void pause() { if (state != State.RUNNING) { return; } transport.pause(); state = State.PAUSED; if (LOGGER.isLoggable(Level.INFO)) { LOGGER.log(Level.INFO, "Paused listener bound to [{0}]", host + ':' + port); } }

Resumes a paused listener.

/** * <p> Resumes a paused listener. </p> */
public synchronized void resume() { if (state != State.PAUSED) { return; } transport.resume(); state = State.RUNNING; if (LOGGER.isLoggable(Level.INFO)) { LOGGER.log(Level.INFO, "Resumed listener bound to [{0}]", host + ':' + port); } }
Returns:a value containing the name, host, port, and secure status of this listener.
/** * @return a value containing the name, host, port, and secure status of this listener. */
@Override public String toString() { return "NetworkListener{" + "name='" + name + '\'' + ", host='" + host + '\'' + ", port=" + port + ", secure=" + secure + ", state=" + state + '}'; } public Object createManagementObject() { return MonitoringUtils.loadJmxObject( "org.glassfish.grizzly.http.server.jmx.NetworkListener", this, NetworkListener.class); } public HttpServerFilter getHttpServerFilter() { if (httpServerFilter == null) { final int idx = filterChain.indexOfType(HttpServerFilter.class); if (idx == -1) { return null; } httpServerFilter = (HttpServerFilter) filterChain.get(idx); } return httpServerFilter; } public HttpCodecFilter getHttpCodecFilter() { if (httpCodecFilter == null) { final int idx = filterChain.indexOfType(HttpCodecFilter.class); if (idx == -1) { return null; } httpCodecFilter = (HttpCodecFilter) filterChain.get(idx); } return httpCodecFilter; } // --------------------------------------------------------- Private Methods private static void validateArg(final String name, final String value) { if (value == null || value.length() == 0) { throw new IllegalArgumentException("Argument " + name + " cannot be " + (value == null ? "null" : "have a zero length")); // I18n } } public boolean isAuthPassThroughEnabled() { return authPassThroughEnabled; } public void setAuthPassThroughEnabled(final boolean authPassthroughEnabled) { this.authPassThroughEnabled = authPassthroughEnabled; }
Returns CompressionConfig configuration.
Since:2.3.5
/** * Returns {@link CompressionConfig} configuration. * * @since 2.3.5 */
public CompressionConfig getCompressionConfig() { return compressionConfig; }
Deprecated:use getCompressionConfig().getCompressionMode().name()
/** * @deprecated use <tt>getCompressionConfig().getCompressionMode().name()</tt> */
public String getCompression() { return compressionConfig.getCompressionMode().name(); }
Deprecated:use getCompressionConfig().setCompressionMode(mode)
/** * @deprecated use <tt>getCompressionConfig().setCompressionMode(mode)</tt> */
public void setCompression(final String compression) { compressionConfig.setCompressionMode(CompressionMode.fromString(compression)); }
Deprecated:use getCompressionConfig().getCompressionMinSize()
/** * @deprecated use <tt>getCompressionConfig().getCompressionMinSize()</tt> */
public int getCompressionMinSize() { return compressionConfig.getCompressionMinSize(); }
Deprecated:use getCompressionConfig().setCompressionMinSize(int)
/** * @deprecated use <tt>getCompressionConfig().setCompressionMinSize(int)</tt> */
public void setCompressionMinSize(final int compressionMinSize) { compressionConfig.setCompressionMinSize(compressionMinSize); }
Deprecated:use getCompressionConfig().getCompressibleMimeTypes()
/** * @deprecated use <tt>getCompressionConfig().getCompressibleMimeTypes()</tt> */
public String getCompressibleMimeTypes() { return setToString(compressionConfig.getCompressibleMimeTypes()); }
Deprecated:use getCompressionConfig().setCompressibleMimeTypes(Set<String>)
/** * @deprecated use <tt>getCompressionConfig().setCompressibleMimeTypes(Set&lt;String&gt;)</tt> */
public void setCompressibleMimeTypes(final String compressibleMimeTypes) { compressionConfig.setCompressibleMimeTypes(stringToSet(compressibleMimeTypes)); }
Deprecated:use getCompressionConfig().getNoCompressionUserAgents()
/** * @deprecated use <tt>getCompressionConfig().getNoCompressionUserAgents()</tt> */
public String getNoCompressionUserAgents() { return setToString(compressionConfig.getNoCompressionUserAgents()); }
Deprecated:use getCompressionConfig().setNoCompressionUserAgents(Set<String>)
/** * @deprecated use <tt>getCompressionConfig().setNoCompressionUserAgents(Set&lt;String&gt;)</tt> */
public void setNoCompressionUserAgents(final String noCompressionUserAgents) { compressionConfig.setNoCompressionUserAgents(stringToSet(noCompressionUserAgents)); } public boolean isDisableUploadTimeout() { return disableUploadTimeout; } public void setDisableUploadTimeout(final boolean disableUploadTimeout) { this.disableUploadTimeout = disableUploadTimeout; }
Gets the maximum size of the POST body generated by an HTML form. -1 value means no size limits applied.
Since:2.3
/** * Gets the maximum size of the POST body generated by an HTML form. * <code>-1</code> value means no size limits applied. * * @since 2.3 */
public int getMaxFormPostSize() { return maxFormPostSize; }
Sets the maximum size of the POST body generated by an HTML form. -1 value means no size limits applied.
Since:2.3
/** * Sets the maximum size of the POST body generated by an HTML form. * <code>-1</code> value means no size limits applied. * * @since 2.3 */
public void setMaxFormPostSize(final int maxFormPostSize) { this.maxFormPostSize = maxFormPostSize < 0 ? -1 : maxFormPostSize; }
Gets the maximum POST body size, which can buffered in memory. -1 value means no size limits applied.
Since:2.3
/** * Gets the maximum POST body size, which can buffered in memory. * <code>-1</code> value means no size limits applied. * * @since 2.3 */
public int getMaxBufferedPostSize() { return maxBufferedPostSize; }
Sets the maximum POST body size, which can buffered in memory. -1 value means no size limits applied.
Since:2.3
/** * Sets the maximum POST body size, which can buffered in memory. * <code>-1</code> value means no size limits applied. * * @since 2.3 */
public void setMaxBufferedPostSize(final int maxBufferedPostSize) { this.maxBufferedPostSize = maxBufferedPostSize < 0 ? -1 : maxBufferedPostSize; } public String getRestrictedUserAgents() { return restrictedUserAgents; } public void setRestrictedUserAgents(final String restrictedUserAgents) { this.restrictedUserAgents = restrictedUserAgents; } public boolean isTraceEnabled() { return traceEnabled; } public void setTraceEnabled(final boolean traceEnabled) { this.traceEnabled = traceEnabled; } public int getUploadTimeout() { return uploadTimeout; } public void setUploadTimeout(final int uploadTimeout) { this.uploadTimeout = uploadTimeout; } public String getUriEncoding() { return uriEncoding; } public void setUriEncoding(final String uriEncoding) { this.uriEncoding = uriEncoding; }
Returns:The timeout, in seconds, within which a request must complete its processing. If not explicitly set, no transaction timeout will be enforced.
/** * @return The timeout, in seconds, within which a request must complete * its processing. If not explicitly set, no transaction timeout will * be enforced. */
public int getTransactionTimeout() { return transactionTimeout; }
Sets the time, in seconds, within which a request must complete its processing. A value less than or equal to zero will disable this timeout. Note that this configuration option is only considered when the transport's Transport.getWorkerThreadPool() thread pool is used to run a HttpHandler.
Params:
  • transactionTimeout – timeout in seconds
/** * Sets the time, in seconds, within which a request must complete its * processing. A value less than or equal to zero will disable this * timeout. Note that this configuration option is only considered when the * transport's {@link org.glassfish.grizzly.Transport#getWorkerThreadPool()} * thread pool is used to run a {@link HttpHandler}. * * @param transactionTimeout timeout in seconds */
public void setTransactionTimeout(final int transactionTimeout) { this.transactionTimeout = transactionTimeout; }
See Also:
  • isSendFileEnabled.isSendFileEnabled()
Since:2.2
/** * @see org.glassfish.grizzly.http.server.ServerFilterConfiguration#isSendFileEnabled() * * @since 2.2 */
public boolean isSendFileEnabled() { return sendFileEnabled; }
See Also:
  • setSendFileEnabled.setSendFileEnabled(boolean)
Since:2.2
/** * @see ServerFilterConfiguration#setSendFileEnabled(boolean) * * @since 2.2 */
public void setSendFileEnabled(boolean sendFileEnabled) { this.sendFileEnabled = sendFileEnabled; }
Returns:the NetworkListener default ErrorPageGenerator.
/** * @return the <tt>NetworkListener</tt> default {@link ErrorPageGenerator}. */
public ErrorPageGenerator getDefaultErrorPageGenerator() { return defaultErrorPageGenerator; }
Sets the NetworkListener default ErrorPageGenerator.
Params:
  • defaultErrorPageGenerator –
/** * Sets the <tt>NetworkListener</tt> default {@link ErrorPageGenerator}. * * @param defaultErrorPageGenerator */
public void setDefaultErrorPageGenerator( final ErrorPageGenerator defaultErrorPageGenerator) { this.defaultErrorPageGenerator = defaultErrorPageGenerator; }
See Also:
Returns:the HTTP server SessionManager
/** * @return the HTTP server {@link SessionManager} * * @see #setSessionManager */
public SessionManager getSessionManager() { return sessionManager; }
Sets the HTTP server SessionManager.
Params:
/** * Sets the HTTP server {@link SessionManager}. * * @param sessionManager {@link SessionManager} */
public void setSessionManager(SessionManager sessionManager) { this.sessionManager = sessionManager; } boolean isSendFileExplicitlyConfigured() { return (sendFileEnabled != null); } private boolean isStopped() { return state == State.STOPPED || state == State.STOPPING; } private static String setToString(final Set<String> set) { final StringBuilder sb = new StringBuilder(set.size() * 10); for (String elem : set) { if (sb.length() > 0) { sb.append(','); } sb.append(elem); } return sb.toString(); } private static Set<String> stringToSet(final String s) { if (s == null) { return null; } return new HashSet<>(Arrays.asList(s.split(","))); } }