1 //
2 // ========================================================================
3 // Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
4 // ------------------------------------------------------------------------
5 // All rights reserved. This program and the accompanying materials
6 // are made available under the terms of the Eclipse Public License v1.0
7 // and Apache License v2.0 which accompanies this distribution.
8 //
9 // The Eclipse Public License is available at
10 // http://www.eclipse.org/legal/epl-v10.html
11 //
12 // The Apache License v2.0 is available at
13 // http://www.opensource.org/licenses/apache2.0.php
14 //
15 // You may elect to redistribute this code under either of these licenses.
16 // ========================================================================
17 //
18
19 package org.eclipse.jetty.server;
20
21 import java.util.List;
22 import java.util.concurrent.CopyOnWriteArrayList;
23
24 import org.eclipse.jetty.http.HttpScheme;
25 import org.eclipse.jetty.util.Jetty;
26 import org.eclipse.jetty.util.annotation.ManagedAttribute;
27 import org.eclipse.jetty.util.annotation.ManagedObject;
28
29
30 /* ------------------------------------------------------------ */
31 /** HTTP Configuration.
32 * <p>This class is a holder of HTTP configuration for use by the
33 * {@link HttpChannel} class. Typically a HTTPConfiguration instance
34 * is instantiated and passed to a {@link ConnectionFactory} that can
35 * create HTTP channels (eg HTTP, AJP or SPDY).</p>
36 * <p>The configuration held by this class is not for the wire protocol,
37 * but for the interpretation and handling of HTTP requests that could
38 * be transported by a variety of protocols.
39 * </p>
40 */
41 @ManagedObject("HTTP Configuration")
42 public class HttpConfiguration
43 {
44 public static final String SERVER_VERSION = "Jetty(" + Jetty.VERSION + ")";
45
46 private List<Customizer> _customizers=new CopyOnWriteArrayList<>();
47 private int _outputBufferSize=32*1024;
48 private int _requestHeaderSize=8*1024;
49 private int _responseHeaderSize=8*1024;
50 private int _headerCacheSize=512;
51 private int _securePort;
52 private String _secureScheme = HttpScheme.HTTPS.asString();
53 private boolean _sendServerVersion = true; //send Server: header
54 private boolean _sendXPoweredBy = false; //send X-Powered-By: header
55 private boolean _sendDateHeader = true; //send Date: header
56
57
58 /* ------------------------------------------------------------ */
59 /**
60 * <p>An interface that allows a request object to be customized
61 * for a particular HTTP connector configuration. Unlike Filters, customizer are
62 * applied before the request is submitted for processing and can be specific to the
63 * connector on which the request was received.
64 *
65 * <p>Typically Customizers perform tasks such as: <ul>
66 * <li>process header fields that may be injected by a proxy or load balancer.
67 * <li>setup attributes that may come from the connection/connector such as SSL Session IDs
68 * <li>Allow a request to be marked as secure or authenticated if those have been offloaded
69 * and communicated by header, cookie or other out-of-band mechanism
70 * <li>Set request attributes/fields that are determined by the connector on which the
71 * request was received
72 * </ul>
73 */
74 public interface Customizer
75 {
76 public void customize(Connector connector, HttpConfiguration channelConfig, Request request);
77 }
78
79 public interface ConnectionFactory
80 {
81 HttpConfiguration getHttpConfiguration();
82 }
83
84 public HttpConfiguration()
85 {
86 }
87
88 /* ------------------------------------------------------------ */
89 /** Create a configuration from another.
90 * @param config The configuration to copy.
91 */
92 public HttpConfiguration(HttpConfiguration config)
93 {
94 _customizers.addAll(config._customizers);
95 _outputBufferSize=config._outputBufferSize;
96 _requestHeaderSize=config._requestHeaderSize;
97 _responseHeaderSize=config._responseHeaderSize;
98 _securePort=config._securePort;
99 _secureScheme=config._secureScheme;
100 _sendDateHeader=config._sendDateHeader;
101 _sendServerVersion=config._sendServerVersion;
102 _headerCacheSize=config._headerCacheSize;
103 }
104
105 /* ------------------------------------------------------------ */
106 /**
107 * <p>Add a {@link Customizer} that is invoked for every
108 * request received.</p>
109 * <p>Customiser are often used to interpret optional headers (eg {@link ForwardedRequestCustomizer}) or
110 * optional protocol semantics (eg {@link SecureRequestCustomizer}).
111 * @param customizer A request customizer
112 */
113 public void addCustomizer(Customizer customizer)
114 {
115 _customizers.add(customizer);
116 }
117
118 /* ------------------------------------------------------------ */
119 public List<Customizer> getCustomizers()
120 {
121 return _customizers;
122 }
123
124 /* ------------------------------------------------------------ */
125 public <T> T getCustomizer(Class<T> type)
126 {
127 for (Customizer c : _customizers)
128 if (type.isAssignableFrom(c.getClass()))
129 return (T)c;
130 return null;
131 }
132
133 @ManagedAttribute("The size in bytes of the output buffer used to aggregate HTTP output")
134 public int getOutputBufferSize()
135 {
136 return _outputBufferSize;
137 }
138
139 @ManagedAttribute("The maximum allowed size in bytes for a HTTP request header")
140 public int getRequestHeaderSize()
141 {
142 return _requestHeaderSize;
143 }
144
145 @ManagedAttribute("The maximum allowed size in bytes for a HTTP response header")
146 public int getResponseHeaderSize()
147 {
148 return _responseHeaderSize;
149 }
150
151 @ManagedAttribute("The maximum allowed size in bytes for a HTTP header field cache")
152 public int getHeaderCacheSize()
153 {
154 return _headerCacheSize;
155 }
156
157 @ManagedAttribute("The port to which Integral or Confidential security constraints are redirected")
158 public int getSecurePort()
159 {
160 return _securePort;
161 }
162
163 @ManagedAttribute("The scheme with which Integral or Confidential security constraints are redirected")
164 public String getSecureScheme()
165 {
166 return _secureScheme;
167 }
168
169 public void setSendServerVersion (boolean sendServerVersion)
170 {
171 _sendServerVersion = sendServerVersion;
172 }
173
174 @ManagedAttribute("if true, send the Server header in responses")
175 public boolean getSendServerVersion()
176 {
177 return _sendServerVersion;
178 }
179
180 public void setSendXPoweredBy (boolean sendXPoweredBy)
181 {
182 _sendXPoweredBy=sendXPoweredBy;
183 }
184
185 @ManagedAttribute("if true, send the X-Powered-By header in responses")
186 public boolean getSendXPoweredBy()
187 {
188 return _sendXPoweredBy;
189 }
190
191 public void setSendDateHeader(boolean sendDateHeader)
192 {
193 _sendDateHeader = sendDateHeader;
194 }
195
196 @ManagedAttribute("if true, include the date in HTTP headers")
197 public boolean getSendDateHeader()
198 {
199 return _sendDateHeader;
200 }
201
202 /* ------------------------------------------------------------ */
203 /**
204 * <p>Set the {@link Customizer}s that are invoked for every
205 * request received.</p>
206 * <p>Customisers are often used to interpret optional headers (eg {@link ForwardedRequestCustomizer}) or
207 * optional protocol semantics (eg {@link SecureRequestCustomizer}).
208 * @param customizers
209 */
210 public void setCustomizers(List<Customizer> customizers)
211 {
212 _customizers.clear();
213 _customizers.addAll(customizers);
214 }
215
216 /* ------------------------------------------------------------ */
217 /**
218 * Set the size of the buffer into which response content is aggregated
219 * before being sent to the client. A larger buffer can improve performance by allowing
220 * a content producer to run without blocking, however larger buffers consume more memory and
221 * may induce some latency before a client starts processing the content.
222 * @param responseBufferSize buffer size in bytes.
223 */
224 public void setOutputBufferSize(int responseBufferSize)
225 {
226 _outputBufferSize = responseBufferSize;
227 }
228
229 /* ------------------------------------------------------------ */
230 /** Set the maximum size of a request header.
231 * <p>Larger headers will allow for more and/or larger cookies plus larger form content encoded
232 * in a URL. However, larger headers consume more memory and can make a server more vulnerable to denial of service
233 * attacks.</p>
234 * @param requestHeaderSize Max header size in bytes
235 */
236 public void setRequestHeaderSize(int requestHeaderSize)
237 {
238 _requestHeaderSize = requestHeaderSize;
239 }
240
241 /* ------------------------------------------------------------ */
242 /** Set the maximum size of a response header.
243 *
244 * <p>Larger headers will allow for more and/or larger cookies and longer HTTP headers (eg for redirection).
245 * However, larger headers will also consume more memory.</p>
246 * @param responseHeaderSize Response header size in bytes.
247 */
248 public void setResponseHeaderSize(int responseHeaderSize)
249 {
250 _responseHeaderSize = responseHeaderSize;
251 }
252
253 /* ------------------------------------------------------------ */
254 /** Set the header field cache size.
255 * @param headerCacheSize The size in bytes of the header field cache.
256 */
257 public void setHeaderCacheSize(int headerCacheSize)
258 {
259 _headerCacheSize = headerCacheSize;
260 }
261
262 /* ------------------------------------------------------------ */
263 /** Set the TCP/IP port used for CONFIDENTIAL and INTEGRAL
264 * redirections.
265 * @param confidentialPort
266 */
267 public void setSecurePort(int confidentialPort)
268 {
269 _securePort = confidentialPort;
270 }
271
272 /* ------------------------------------------------------------ */
273 /** Set the URI scheme used for CONFIDENTIAL and INTEGRAL
274 * redirections.
275 * @param confidentialScheme A string like"https"
276 */
277 public void setSecureScheme(String confidentialScheme)
278 {
279 _secureScheme = confidentialScheme;
280 }
281
282 @Override
283 public String toString()
284 {
285 return String.format("%s@%x{%d,%d/%d,%s://:%d,%s}",this.getClass().getSimpleName(),hashCode(),_outputBufferSize,_requestHeaderSize,_responseHeaderSize,_secureScheme,_securePort,_customizers);
286 }
287 }