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

org.eclipse.jetty.server.HttpConfiguration Maven / Gradle / Ivy

There is a newer version: 2024.11.18751.20241128T090041Z-241100
Show newest version
// 
// ========================================================================
// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
// 
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
// 
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
// 
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
// 
package org.eclipse.jetty.server;

import java.io.IOException;
import java.net.SocketAddress;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import org.eclipse.jetty.http.CookieCompliance;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpScheme;
import org.eclipse.jetty.util.ArrayTernaryTrie;
import org.eclipse.jetty.util.HostPort;
import org.eclipse.jetty.util.Jetty;
import org.eclipse.jetty.util.TreeTrie;
import org.eclipse.jetty.util.Trie;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
import org.eclipse.jetty.util.component.Dumpable;
import org.eclipse.jetty.util.component.DumpableCollection;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;

/**
 *  HTTP Configuration.
 *  

This class is a holder of HTTP configuration for use by the * {@link HttpChannel} class. Typically an HTTPConfiguration instance * is instantiated and passed to a {@link ConnectionFactory} that can * create HTTP channels (e.g. HTTP, AJP or FCGI).

*

The configuration held by this class is not for the wire protocol, * but for the interpretation and handling of HTTP requests that could * be transported by a variety of protocols. *

* * @deprecated The Eclipse Jetty and Apache Felix Http Jetty packages are no longer supported. */ @ManagedObject("HTTP Configuration") @Deprecated(since = "2021-05-27") public class HttpConfiguration implements Dumpable { private static final Logger LOG = Log.getLogger(HttpConfiguration.class); public static final String SERVER_VERSION = "Jetty(" + Jetty.VERSION + ")"; private final List _customizers = new CopyOnWriteArrayList<>(); private final Trie _formEncodedMethods = new TreeTrie<>(); private int _outputBufferSize = 32 * 1024; private int _outputAggregationSize = _outputBufferSize / 4; private int _requestHeaderSize = 8 * 1024; private int _responseHeaderSize = 8 * 1024; private int _headerCacheSize = 1024; private int _securePort; private long _idleTimeout = -1; private long _blockingTimeout = -1; private String _secureScheme = HttpScheme.HTTPS.asString(); private boolean _sendServerVersion = true; private boolean _sendXPoweredBy = false; private boolean _sendDateHeader = true; private boolean _delayDispatchUntilContent = true; private boolean _persistentConnectionsEnabled = true; private int _maxErrorDispatches = 10; private long _minRequestDataRate; private long _minResponseDataRate; private CookieCompliance _requestCookieCompliance = CookieCompliance.RFC6265; private CookieCompliance _responseCookieCompliance = CookieCompliance.RFC6265; // TODO change default in jetty-10 private MultiPartFormDataCompliance _multiPartCompliance = MultiPartFormDataCompliance.LEGACY; private boolean _notifyRemoteAsyncErrors = true; private boolean _relativeRedirectAllowed; private HostPort _serverAuthority; private SocketAddress _localAddress; /** *

An interface that allows a request object to be customized * for a particular HTTP connector configuration. Unlike Filters, customizer are * applied before the request is submitted for processing and can be specific to the * connector on which the request was received.

* *

Typically Customizers perform tasks such as:

*
    *
  • process header fields that may be injected by a proxy or load balancer. *
  • setup attributes that may come from the connection/connector such as SSL Session IDs *
  • Allow a request to be marked as secure or authenticated if those have been offloaded * and communicated by header, cookie or other out-of-band mechanism *
  • Set request attributes/fields that are determined by the connector on which the * request was received *
* * @deprecated The Eclipse Jetty and Apache Felix Http Jetty packages are no longer supported. */ @Deprecated(since = "2021-05-27") public interface Customizer { void customize(Connector connector, HttpConfiguration channelConfig, Request request); } // @deprecated The Eclipse Jetty and Apache Felix Http Jetty packages are no longer supported. @Deprecated(since = "2021-05-27") public interface ConnectionFactory { HttpConfiguration getHttpConfiguration(); } public HttpConfiguration() { _formEncodedMethods.put(HttpMethod.POST.asString(), Boolean.TRUE); _formEncodedMethods.put(HttpMethod.PUT.asString(), Boolean.TRUE); } /** * Creates a configuration from another. * * @param config The configuration to copy. */ public HttpConfiguration(HttpConfiguration config) { _customizers.addAll(config._customizers); for (String s : config._formEncodedMethods.keySet()) { _formEncodedMethods.put(s, Boolean.TRUE); } _outputBufferSize = config._outputBufferSize; _outputAggregationSize = config._outputAggregationSize; _requestHeaderSize = config._requestHeaderSize; _responseHeaderSize = config._responseHeaderSize; _headerCacheSize = config._headerCacheSize; _secureScheme = config._secureScheme; _securePort = config._securePort; _idleTimeout = config._idleTimeout; _blockingTimeout = config._blockingTimeout; _sendDateHeader = config._sendDateHeader; _sendServerVersion = config._sendServerVersion; _sendXPoweredBy = config._sendXPoweredBy; _delayDispatchUntilContent = config._delayDispatchUntilContent; _persistentConnectionsEnabled = config._persistentConnectionsEnabled; _maxErrorDispatches = config._maxErrorDispatches; _minRequestDataRate = config._minRequestDataRate; _minResponseDataRate = config._minResponseDataRate; _requestCookieCompliance = config._requestCookieCompliance; _responseCookieCompliance = config._responseCookieCompliance; _multiPartCompliance = config._multiPartCompliance; _notifyRemoteAsyncErrors = config._notifyRemoteAsyncErrors; _relativeRedirectAllowed = config._relativeRedirectAllowed; _serverAuthority = config._serverAuthority; _localAddress = config._localAddress; } /** *

Adds a {@link Customizer} that is invoked for every * request received.

*

Customizers are often used to interpret optional headers (eg {@link ForwardedRequestCustomizer}) or * optional protocol semantics (eg {@link SecureRequestCustomizer}). * * @param customizer A request customizer */ public void addCustomizer(Customizer customizer) { _customizers.add(customizer); } public List getCustomizers() { return _customizers; } public T getCustomizer(Class type) { for (Customizer c : _customizers) { if (type.isAssignableFrom(c.getClass())) return (T) c; } return null; } @ManagedAttribute("The size in bytes of the output buffer used to aggregate HTTP output") public int getOutputBufferSize() { return _outputBufferSize; } @ManagedAttribute("The maximum size in bytes for HTTP output to be aggregated") public int getOutputAggregationSize() { return _outputAggregationSize; } @ManagedAttribute("The maximum allowed size in bytes for an HTTP request header") public int getRequestHeaderSize() { return _requestHeaderSize; } @ManagedAttribute("The maximum allowed size in bytes for an HTTP response header") public int getResponseHeaderSize() { return _responseHeaderSize; } @ManagedAttribute("The maximum allowed size in Trie nodes for an HTTP header field cache") public int getHeaderCacheSize() { return _headerCacheSize; } @ManagedAttribute("The port to which Integral or Confidential security constraints are redirected") public int getSecurePort() { return _securePort; } @ManagedAttribute("The scheme with which Integral or Confidential security constraints are redirected") public String getSecureScheme() { return _secureScheme; } @ManagedAttribute("Whether persistent connections are enabled") public boolean isPersistentConnectionsEnabled() { return _persistentConnectionsEnabled; } /** *

The max idle time is applied to an HTTP request for IO operations and * delayed dispatch.

* * @return the max idle time in ms or if == 0 implies an infinite timeout, <0 * implies no HTTP channel timeout and the connection timeout is used instead. */ @ManagedAttribute("The idle timeout in ms for I/O operations during the handling of an HTTP request") public long getIdleTimeout() { return _idleTimeout; } /** *

The max idle time is applied to an HTTP request for IO operations and * delayed dispatch.

* * @param timeoutMs the max idle time in ms or if == 0 implies an infinite timeout, <0 * implies no HTTP channel timeout and the connection timeout is used instead. */ public void setIdleTimeout(long timeoutMs) { _idleTimeout = timeoutMs; } /** *

This timeout is in addition to the {@link Connector#getIdleTimeout()}, and applies * to the total operation (as opposed to the idle timeout that applies to the time no * data is being sent). This applies only to blocking operations and does not affect * asynchronous read and write.

* * @return -1, for no blocking timeout (default), 0 for a blocking timeout equal to the * idle timeout; >0 for a timeout in ms applied to the total blocking operation. * @deprecated Replaced by {@link #getMinResponseDataRate()} and {@link #getMinRequestDataRate()} */ @ManagedAttribute(value = "Total timeout in ms for blocking I/O operations. DEPRECATED!", readonly = true) @Deprecated public long getBlockingTimeout() { return _blockingTimeout; } /** *

This timeout is in addition to the {@link Connector#getIdleTimeout()}, and applies * to the total operation (as opposed to the idle timeout that applies to the time no * data is being sent).This applies only to blocking operations and does not affect * asynchronous read and write.

* * @param blockingTimeout -1, for no blocking timeout (default), 0 for a blocking timeout equal to the * idle timeout; >0 for a timeout in ms applied to the total blocking operation. * @deprecated Replaced by {@link #setMinResponseDataRate(long)} and {@link #setMinRequestDataRate(long)} */ @Deprecated public void setBlockingTimeout(long blockingTimeout) { if (blockingTimeout > 0) LOG.warn("HttpConfiguration.setBlockingTimeout is deprecated!"); _blockingTimeout = blockingTimeout; } public void setPersistentConnectionsEnabled(boolean persistentConnectionsEnabled) { _persistentConnectionsEnabled = persistentConnectionsEnabled; } public void setSendServerVersion(boolean sendServerVersion) { _sendServerVersion = sendServerVersion; } @ManagedAttribute("Whether to send the Server header in responses") public boolean getSendServerVersion() { return _sendServerVersion; } public void writePoweredBy(Appendable out, String preamble, String postamble) throws IOException { if (getSendServerVersion()) { if (preamble != null) out.append(preamble); out.append(Jetty.POWERED_BY); if (postamble != null) out.append(postamble); } } public void setSendXPoweredBy(boolean sendXPoweredBy) { _sendXPoweredBy = sendXPoweredBy; } @ManagedAttribute("Whether to send the X-Powered-By header in responses") public boolean getSendXPoweredBy() { return _sendXPoweredBy; } /** * Indicates if the {@code Date} header should be sent in responses. * * @param sendDateHeader true if the {@code Date} header should be sent in responses * @see HTTP/1.1 Standard Header: Date * @see #getSendDateHeader() */ public void setSendDateHeader(boolean sendDateHeader) { _sendDateHeader = sendDateHeader; } /** * Indicates if the {@code Date} header will be sent in responses. * * @return true by default */ @ManagedAttribute("Whether to send the Date header in responses") public boolean getSendDateHeader() { return _sendDateHeader; } /** * @param delay if true, delays the application dispatch until content is available (defaults to true) */ public void setDelayDispatchUntilContent(boolean delay) { _delayDispatchUntilContent = delay; } @ManagedAttribute("Whether to delay the application dispatch until content is available") public boolean isDelayDispatchUntilContent() { return _delayDispatchUntilContent; } /** *

Sets the {@link Customizer}s that are invoked for every * request received.

*

Customizers are often used to interpret optional headers (eg {@link ForwardedRequestCustomizer}) or * optional protocol semantics (eg {@link SecureRequestCustomizer}).

* * @param customizers the list of customizers */ public void setCustomizers(List customizers) { _customizers.clear(); _customizers.addAll(customizers); } /** * Set the size of the buffer into which response content is aggregated * before being sent to the client. A larger buffer can improve performance by allowing * a content producer to run without blocking, however larger buffers consume more memory and * may induce some latency before a client starts processing the content. * * @param outputBufferSize buffer size in bytes. */ public void setOutputBufferSize(int outputBufferSize) { _outputBufferSize = outputBufferSize; setOutputAggregationSize(outputBufferSize / 4); } /** * Set the max size of the response content write that is copied into the aggregate buffer. * Writes that are smaller of this size are copied into the aggregate buffer, while * writes that are larger of this size will cause the aggregate buffer to be flushed * and the write to be executed without being copied. * * @param outputAggregationSize the max write size that is aggregated */ public void setOutputAggregationSize(int outputAggregationSize) { _outputAggregationSize = outputAggregationSize; } /** *

Larger headers will allow for more and/or larger cookies plus larger form content encoded * in a URL. However, larger headers consume more memory and can make a server more vulnerable to denial of service * attacks.

* * @param requestHeaderSize the maximum size in bytes of the request header */ public void setRequestHeaderSize(int requestHeaderSize) { _requestHeaderSize = requestHeaderSize; } /** *

Larger headers will allow for more and/or larger cookies and longer HTTP headers (eg for redirection). * However, larger headers will also consume more memory.

* * @param responseHeaderSize the maximum size in bytes of the response header */ public void setResponseHeaderSize(int responseHeaderSize) { _responseHeaderSize = responseHeaderSize; } /** * @param headerCacheSize The size of the header field cache, in terms of unique characters branches * in the lookup {@link Trie} and associated data structures. */ public void setHeaderCacheSize(int headerCacheSize) { if (headerCacheSize > ArrayTernaryTrie.MAX_CAPACITY) { throw new IllegalArgumentException("headerCacheSize " + headerCacheSize + " exceeds maximum value of " + ArrayTernaryTrie.MAX_CAPACITY); } _headerCacheSize = headerCacheSize; } /** *

Sets the TCP/IP port used for CONFIDENTIAL and INTEGRAL redirections.

* * @param securePort the secure port to redirect to. */ public void setSecurePort(int securePort) { _securePort = securePort; } /** *

Set the URI scheme used for CONFIDENTIAL and INTEGRAL redirections.

* * @param secureScheme A scheme string like "https" */ public void setSecureScheme(String secureScheme) { _secureScheme = secureScheme; } /** * Sets the form encoded HTTP methods. * * @param methods the HTTP methods of requests that can be decoded as * {@code x-www-form-urlencoded} content to be made available via the * {@link Request#getParameter(String)} and associated APIs */ public void setFormEncodedMethods(String... methods) { _formEncodedMethods.clear(); for (String method : methods) { addFormEncodedMethod(method); } } /** * @return the set of HTTP methods of requests that can be decoded as * {@code x-www-form-urlencoded} content to be made available via the * {@link Request#getParameter(String)} and associated APIs */ public Set getFormEncodedMethods() { return _formEncodedMethods.keySet(); } /** * Adds a form encoded HTTP Method * * @param method the HTTP method of requests that can be decoded as * {@code x-www-form-urlencoded} content to be made available via the * {@link Request#getParameter(String)} and associated APIs */ public void addFormEncodedMethod(String method) { _formEncodedMethods.put(method, Boolean.TRUE); } /** * Tests whether the HTTP method supports {@code x-www-form-urlencoded} content * * @param method the HTTP method * @return true if requests with this method can be * decoded as {@code x-www-form-urlencoded} content to be made available via the * {@link Request#getParameter(String)} and associated APIs */ public boolean isFormEncodedMethod(String method) { return Boolean.TRUE.equals(_formEncodedMethods.get(method)); } /** * @return The maximum error dispatches for a request to prevent looping on an error */ @ManagedAttribute("The maximum ERROR dispatches for a request for loop prevention (default 10)") public int getMaxErrorDispatches() { return _maxErrorDispatches; } /** * @param max The maximum error dispatches for a request to prevent looping on an error */ public void setMaxErrorDispatches(int max) { _maxErrorDispatches = max; } /** * @return The minimum request data rate in bytes per second; or <=0 for no limit */ @ManagedAttribute("The minimum request content data rate in bytes per second") public long getMinRequestDataRate() { return _minRequestDataRate; } /** * @param bytesPerSecond The minimum request data rate in bytes per second; or <=0 for no limit */ public void setMinRequestDataRate(long bytesPerSecond) { _minRequestDataRate = bytesPerSecond; } /** * @return The minimum response data rate in bytes per second; or <=0 for no limit */ @ManagedAttribute("The minimum response content data rate in bytes per second") public long getMinResponseDataRate() { return _minResponseDataRate; } /** *

Sets an minimum response content data rate.

*

The value is enforced only approximately - not precisely - due to the fact that * for efficiency reasons buffer writes may be comprised of both response headers and * response content.

* * @param bytesPerSecond The minimum response data rate in bytes per second; or <=0 for no limit */ public void setMinResponseDataRate(long bytesPerSecond) { _minResponseDataRate = bytesPerSecond; } /** * @return The CookieCompliance used for parsing request Cookie headers. * @see #getResponseCookieCompliance() */ public CookieCompliance getRequestCookieCompliance() { return _requestCookieCompliance; } /** * @return The CookieCompliance used for generating response Set-Cookie headers * @see #getRequestCookieCompliance() */ public CookieCompliance getResponseCookieCompliance() { return _responseCookieCompliance; } /** * @param cookieCompliance The CookieCompliance to use for parsing request Cookie headers. * @see #setRequestCookieCompliance(CookieCompliance) */ public void setRequestCookieCompliance(CookieCompliance cookieCompliance) { _requestCookieCompliance = cookieCompliance == null ? CookieCompliance.RFC6265 : cookieCompliance; } /** * @param cookieCompliance The CookieCompliance to use for generating response Set-Cookie headers * @see #setResponseCookieCompliance(CookieCompliance) */ public void setResponseCookieCompliance(CookieCompliance cookieCompliance) { _responseCookieCompliance = cookieCompliance == null ? CookieCompliance.RFC6265 : cookieCompliance; } @Deprecated public void setCookieCompliance(CookieCompliance compliance) { setRequestCookieCompliance(compliance); } @Deprecated public CookieCompliance getCookieCompliance() { return getRequestCookieCompliance(); } @Deprecated public boolean isCookieCompliance(CookieCompliance compliance) { return _requestCookieCompliance.equals(compliance); } /** * Sets the compliance level for multipart/form-data handling. * * @param multiPartCompliance The multipart/form-data compliance level. */ public void setMultiPartFormDataCompliance(MultiPartFormDataCompliance multiPartCompliance) { // TODO change default in jetty-10 _multiPartCompliance = multiPartCompliance == null ? MultiPartFormDataCompliance.LEGACY : multiPartCompliance; } public MultiPartFormDataCompliance getMultipartFormDataCompliance() { return _multiPartCompliance; } /** * @param notifyRemoteAsyncErrors whether remote errors, when detected, are notified to async applications */ public void setNotifyRemoteAsyncErrors(boolean notifyRemoteAsyncErrors) { this._notifyRemoteAsyncErrors = notifyRemoteAsyncErrors; } /** * @return whether remote errors, when detected, are notified to async applications */ @ManagedAttribute("Whether remote errors, when detected, are notified to async applications") public boolean isNotifyRemoteAsyncErrors() { return _notifyRemoteAsyncErrors; } /** * @param allowed True if relative redirection locations are allowed */ public void setRelativeRedirectAllowed(boolean allowed) { _relativeRedirectAllowed = allowed; } /** * @return True if relative redirection locations are allowed */ @ManagedAttribute("Whether relative redirection locations are allowed") public boolean isRelativeRedirectAllowed() { return _relativeRedirectAllowed; } /** * Get the SocketAddress override to be reported as the local address of all connections * * @return Returns the connection local address override or null. */ @ManagedAttribute("Local SocketAddress override") public SocketAddress getLocalAddress() { return _localAddress; } /** *

* Specify the connection local address used within application API layer * when identifying the local host name/port of a connected endpoint. *

*

* This allows an override of higher level APIs, such as * {@code ServletRequest.getLocalName()}, {@code ServletRequest.getLocalAddr()}, * and {@code ServletRequest.getLocalPort()}. *

* * @param localAddress the address to use for host/addr/port, or null to reset to default behavior */ public void setLocalAddress(SocketAddress localAddress) { _localAddress = localAddress; } /** * Get the Server authority override to be used if no authority is provided by a request. * * @return Returns the connection server authority (name/port) or null */ @ManagedAttribute("The server authority if none provided by requests") public HostPort getServerAuthority() { return _serverAuthority; } /** *

* Specify the connection server authority (name/port) used within application API layer * when identifying the server host name/port of a connected endpoint. *

* *

* This allows an override of higher level APIs, such as * {@code ServletRequest.getServerName()}, and {@code ServletRequest.getServerPort()}. *

* * @param authority the authority host (and optional port), or null to reset to default behavior */ public void setServerAuthority(HostPort authority) { if (authority == null) _serverAuthority = null; else if (!authority.hasHost()) throw new IllegalStateException("Server Authority must have host declared"); else _serverAuthority = authority; } @Override public String dump() { return Dumpable.dump(this); } @Override public void dump(Appendable out, String indent) throws IOException { Dumpable.dumpObjects(out, indent, this, new DumpableCollection("customizers", _customizers), new DumpableCollection("formEncodedMethods", _formEncodedMethods.keySet()), "outputBufferSize=" + _outputBufferSize, "outputAggregationSize=" + _outputAggregationSize, "requestHeaderSize=" + _requestHeaderSize, "responseHeaderSize=" + _responseHeaderSize, "headerCacheSize=" + _headerCacheSize, "secureScheme=" + _secureScheme, "securePort=" + _securePort, "idleTimeout=" + _idleTimeout, "blockingTimeout=" + _blockingTimeout, "sendDateHeader=" + _sendDateHeader, "sendServerVersion=" + _sendServerVersion, "sendXPoweredBy=" + _sendXPoweredBy, "delayDispatchUntilContent=" + _delayDispatchUntilContent, "persistentConnectionsEnabled=" + _persistentConnectionsEnabled, "maxErrorDispatches=" + _maxErrorDispatches, "minRequestDataRate=" + _minRequestDataRate, "minResponseDataRate=" + _minResponseDataRate, "cookieCompliance=" + _requestCookieCompliance, "setRequestCookieCompliance=" + _responseCookieCompliance, "notifyRemoteAsyncErrors=" + _notifyRemoteAsyncErrors, "relativeRedirectAllowed=" + _relativeRedirectAllowed); } @Override public String toString() { return String.format("%s@%x{%d/%d,%d/%d,%s://:%d,%s}", this.getClass().getSimpleName(), hashCode(), _outputBufferSize, _outputAggregationSize, _requestHeaderSize, _responseHeaderSize, _secureScheme, _securePort, _customizers); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy