All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.glassfish.grizzly.http.server.NetworkListener Maven / Gradle / Ivy

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License.  You can
 * obtain a copy of the License at
 * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
 * or packager/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 *
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at packager/legal/LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 *
 * Contributor(s):
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */
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.Set;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.net.ssl.SSLEngine;
import org.glassfish.grizzly.CompletionHandler;

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.FilterChain;
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 {@link HttpServer} will bind to in order to service HTTP
     * requests.
     */
    public static final String DEFAULT_NETWORK_HOST = "0.0.0.0";

    /**
     * The default network port to which the {@link HttpServer} will bind to in order to service HTTP
     * 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 {@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 {@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  {@link #DEFAULT_NETWORK_HOST}:{@link #DEFAULT_NETWORK_PORT}.
     */
    private final boolean isBindToInherited;
    
    /**
     * 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 {@link #port} will be used.
     */
    private PortRange portRange;

    /**
     * The logical name of this particular NetworkListener instance.
     */
    private final String name;
    /**
     * The configuration for HTTP keep-alive connections
     */
    private final KeepAlive keepAliveConfig = new KeepAlive();
    /**
     * The Grizzly {@link FilterChain} used to process incoming and outgoing network I/O.
     */
    private FilterChain filterChain;
    /**
     * The {@link TCPNIOTransport} used by this NetworkListener
     */
    private TCPNIOTransport transport;
    /**
     * TCP Server {@link Connection} responsible for accepting client connections
     */
    private TCPNIOServerConnection serverConnection;    
    
    /**
     * The default error page generator
     */
    private ErrorPageGenerator defaultErrorPageGenerator;    
    
    {
        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
     */
    private boolean secure;

    /**
     * AddOns registered for the network listener
     */
    private final ArraySet addons = new ArraySet(AddOn.class);

    /**
     * Flag indicating whether or not the chunked transfer encoding is enabled.  Defaults to true.
     */
    private boolean chunkingEnabled = true;
    /**
     * Configuration for the {@link SSLEngine} that will be used for secure listeners.
     */
    private SSLEngineConfigurator sslEngineConfig;
    /**
     * The maximum size of an incoming HTTP message.
     */
    private int maxHttpHeaderSize = -1;
    /**
     * {@link FileCache} to be used by this NetworkListener.
     */
    private final FileCache fileCache = new FileCache();
    /**
     * Maximum size, in bytes, of all data waiting to be written.
     */
    private volatile int maxPendingBytes = -1;
    /**
     * Flag indicating the state of this listener.
     */
    private State state = State.STOPPED;
    /**
     * Future to control graceful shutdown status
     */
    private FutureImpl shutdownFuture;
    /**
     * CompletionHandler for filter shutdown notification.
     */
    private CompletionHandler shutdownCompletionHandler;
    /**
     * {@link HttpServerFilter} associated with this listener.
     */
    private HttpServerFilter httpServerFilter;
    /**
     * {@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.
     */
    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 {@link #DEFAULT_NETWORK_HOST} and {@link #DEFAULT_NETWORK_PORT}.

* * @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.

* * @param name the logical name of the listener. * @param isBindToInherited if true the NetworkListener 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 {@link #DEFAULT_NETWORK_PORT}.

* * @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.

* * @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.

* * @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 /** * @return the logical name of this listener. */ public String getName() { return name; } /** * @return the network host to which this listener is configured to bind to. */ public String getHost() { return host; } /** * @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: * -1, if {@link 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 {@link HttpServer} has been started - the value returned is the port the * this listener is bound to. */ public int getPort() { return port; } /** * @return the network port range to which this listener is configured to bind to. */ public PortRange getPortRange() { return portRange; } /** * @return the configuration for the keep-alive HTTP connections. */ public KeepAlive getKeepAlive() { return keepAliveConfig; } /** * @return the {@link TCPNIOTransport} used by this listener. */ public TCPNIOTransport getTransport() { return transport; } /** *

This allows the developer to specify a custom {@link TCPNIOTransport} implementation to be used by this * listener.

*

*

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

* * @param transport a custom {@link TCPNIOTransport} implementation. */ public void setTransport(final TCPNIOTransport transport) { if (transport == null) { return; } if (!transport.isStopped()) { return; } this.transport = transport; } /** * 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. * @return the direct addons collection, registered on the NetworkListener. */ protected ArraySet getAddOnSet() { return addons; } /** * Registers {@link AddOn} on this NetworkListener. * @param addon the {@link AddOn} to be registered. * * @return true, if the {@link AddOn} wasn't registered before, * otherwise the existing {@link AddOn} will be replaced and this method * returns false. */ public boolean registerAddOn(final AddOn addon) { return addons.add(addon); } /** * Deregisters {@link AddOn} from this NetworkListener. * @param addon the {@link AddOn} to deregister. * * @return true, if the {@link AddOn} was successfully removed, or * false the the {@link AddOn} wasn't registered on the * NetworkListener. */ public boolean deregisterAddOn(final AddOn addon) { return addons.remove(addon); } /** * @return true 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. * * @param chunkingEnabled true to enable chunking; false to disable. */ public void setChunkingEnabled(boolean chunkingEnabled) { this.chunkingEnabled = chunkingEnabled; } /** * @return true if this is a secure listener, otherwise false. 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.

* * @param secure if true 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. * * @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. * * @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; } /** * @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. * * @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 */ 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 */ public void setMaxRequestHeaders(int maxRequestHeaders) { this.maxRequestHeaders = maxRequestHeaders; } /** * 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 */ public void setMaxResponseHeaders(int maxResponseHeaders) { this.maxResponseHeaders = maxResponseHeaders; } /** * @return the {@link SSLEngine} configuration for this listener. */ public SSLEngineConfigurator getSslEngineConfig() { return sslEngineConfig; } /** *

Provides customization of the {@link SSLEngine} used by this listener.

*

*

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

* * @param sslEngineConfig custom SSL configuration. */ public void setSSLEngineConfig(final SSLEngineConfigurator sslEngineConfig) { if (!isStopped()) { return; } this.sslEngineConfig = sslEngineConfig; } /** * @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.

* * @param maxHttpHeaderSize the maximum header size for an HTTP request. */ public void setMaxHttpHeaderSize(final int maxHttpHeaderSize) { if (!isStopped()) { return; } this.maxHttpHeaderSize = maxHttpHeaderSize; } /** * @return the {@link FilterChain} used to by the {@link TCPNIOTransport} associated with this listener. */ public FilterChain getFilterChain() { return filterChain; } /** *

Specifies the {@link FilterChain} to be used by the {@link TCPNIOTransport} associated with this listener. *

*

*

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

* * @param filterChain the {@link FilterChain}. */ void setFilterChain(final FilterChain filterChain) { if (!isStopped()) { return; } if (filterChain != null) { this.filterChain = filterChain; } } /** * @return the {@link FileCache} associated with this listener. */ public FileCache getFileCache() { return fileCache; } /** * @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 {@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 /** * @return true if this listener has been paused, otherwise false */ public boolean isPaused() { return state == State.PAUSED; } /** * @return true if the listener has been started, otherwise false. */ public boolean isStarted() { return state != State.STOPPED; } /** *

Starts the listener.

* * @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 shutdownFutureLocal = shutdownFuture; shutdownCompletionHandler = new EmptyCompletionHandler() { @Override public void completed(final HttpServerFilter filter) { try { shutdownContext.ready(); shutdownFutureLocal.result(NetworkListener.this); } catch (Throwable e) { shutdownFutureLocal.failure(e); } } }; getHttpServerFilter().prepareForShutdown(shutdownCompletionHandler); } @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 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(); } state = State.STOPPING; shutdownFuture = Futures.createSafeFuture(); getHttpServerFilter().prepareForShutdown(shutdownCompletionHandler); transport.shutdown(gracePeriod, timeUnit); return shutdownFuture; } /** *

Gracefully shuts down the listener.

Any exceptions * thrown during the shutdown process will be propagated to the returned * {@link GrizzlyFuture}. */ public synchronized GrizzlyFuture shutdown() { return shutdown(-1, TimeUnit.MILLISECONDS); } /** *

Immediately shuts down the listener.

* * @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 {@link #shutdownNow()} */ public void stop() throws IOException { shutdownNow(); } /** *

Pauses the listener.

* * @throws IOException if an error occurs when attempting to pause the listener. */ 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.

*/ 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); } } /** * @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 {@link CompressionConfig} configuration. * * @since 2.3.5 */ public CompressionConfig getCompressionConfig() { return compressionConfig; } /** * @deprecated use getCompressionConfig().getCompressionMode().name() */ public String getCompression() { return compressionConfig.getCompressionMode().name(); } /** * @deprecated use getCompressionConfig().setCompressionMode(mode) */ public void setCompression(final String compression) { compressionConfig.setCompressionMode(CompressionMode.fromString(compression)); } /** * @deprecated use getCompressionConfig().getCompressionMinSize() */ public int getCompressionMinSize() { return compressionConfig.getCompressionMinSize(); } /** * @deprecated use getCompressionConfig().setCompressionMinSize(int) */ public void setCompressionMinSize(final int compressionMinSize) { compressionConfig.setCompressionMinSize(compressionMinSize); } /** * @deprecated use getCompressionConfig().getCompressableMimeTypes() */ public String getCompressibleMimeTypes() { return setToString(compressionConfig.getCompressableMimeTypes()); } /** * @deprecated use getCompressionConfig().setCompressableMimeTypes(Set<String>) */ public void setCompressibleMimeTypes(final String compressibleMimeTypes) { compressionConfig.setCompressableMimeTypes(stringToSet(compressibleMimeTypes)); } /** * @deprecated use getCompressionConfig().getNoCompressionUserAgents() */ public String getNoCompressionUserAgents() { return setToString(compressionConfig.getNoCompressionUserAgents()); } /** * @deprecated use getCompressionConfig().setNoCompressionUserAgents(Set<String>) */ 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 */ 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 */ 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 */ 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 */ 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; } /** * @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 {@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 org.glassfish.grizzly.http.server.ServerFilterConfiguration#isSendFileEnabled() * * @since 2.2 */ public boolean isSendFileEnabled() { return sendFileEnabled; } /** * @see ServerFilterConfiguration#setSendFileEnabled(boolean) * * @since 2.2 */ public void setSendFileEnabled(boolean sendFileEnabled) { this.sendFileEnabled = sendFileEnabled; } /** * Returns the NetworkListener default {@link ErrorPageGenerator}. */ public ErrorPageGenerator getDefaultErrorPageGenerator() { return defaultErrorPageGenerator; } /** * Sets the NetworkListener default {@link ErrorPageGenerator}. * * @param defaultErrorPageGenerator */ public void setDefaultErrorPageGenerator( final ErrorPageGenerator defaultErrorPageGenerator) { this.defaultErrorPageGenerator = defaultErrorPageGenerator; } boolean isSendFileExplicitlyConfigured() { return (sendFileEnabled != null); } private boolean isStopped() { return state == State.STOPPED || state == State.STOPPING; } private static String setToString(final Set 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 stringToSet(final String s) { if (s == null) { return null; } return new HashSet(Arrays.asList(s.split(","))); } }