blob: a9beeb8cb6804a91f825716e9141f74298b10614 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.sling.engine.impl.parameters;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.settings.SlingSettingsService;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.propertytypes.ServiceDescription;
import org.osgi.service.component.propertytypes.ServiceRanking;
import org.osgi.service.component.propertytypes.ServiceVendor;
import org.osgi.service.http.whiteboard.propertytypes.HttpWhiteboardContextSelect;
import org.osgi.service.http.whiteboard.propertytypes.HttpWhiteboardFilterPattern;
import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.Designate;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Component(name = RequestParameterSupportConfigurer.PID, service = Filter.class)
@HttpWhiteboardContextSelect("(osgi.http.whiteboard.context.name=org.apache.sling)")
@HttpWhiteboardFilterPattern("/")
@ServiceDescription("Filter for request parameter support")
@ServiceVendor("The Apache Software Foundation")
@ServiceRanking(Integer.MAX_VALUE)
@Designate(ocd = RequestParameterSupportConfigurer.Config.class)
public class RequestParameterSupportConfigurer implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
if (request instanceof HttpServletRequest
&& !(request instanceof ParameterSupportHttpServletRequestWrapper)
&& !(request instanceof SlingHttpServletRequest)) {
chain.doFilter(ParameterSupport.getParameterSupportRequestWrapper((HttpServletRequest) request), response);
} else {
chain.doFilter(request, response);
}
}
@Override
public void destroy() {}
@ObjectClassDefinition(
name = "Apache Sling Request Parameter Handling",
description = "Configures Sling's request parameter handling.")
public @interface Config {
@AttributeDefinition(
name = "Default Parameter Encoding",
description = "The default request parameter encoding used to decode request "
+ "parameters into strings. If this property is not set the default encoding "
+ "is 'ISO-8859-1' as mandated by the Servlet API spec. This default encoding "
+ "is used if the '_charset_' request parameter is not set to another "
+ "(supported) character encoding. Applications being sure to always use the "
+ "same encoding (e.g. UTF-8) can set this default here and may omit the "
+ "'_charset_' request parameter")
String sling_default_parameter_encoding() default Util.ENCODING_DIRECT;
@AttributeDefinition(
name = "Maximum POST Parameters",
description = "The maximum number of parameters supported. To prevent a DOS-style attack with an "
+ "overrunning number of parameters the number of parameters supported can be limited. This "
+ "includes all of the query string as well as application/x-www-form-urlencoded and "
+ "multipart/form-data parameters. The default value is " + ParameterMap.DEFAULT_MAX_PARAMS
+ ".")
int sling_default_max_parameters() default ParameterMap.DEFAULT_MAX_PARAMS;
@AttributeDefinition(
name = "Temporary File Location",
description = "The temporary directory where uploaded files are written to disk. The default is "
+ "null, which means the directory given by the 'java.io.tmpdir' system property.")
String file_location();
@AttributeDefinition(
name = "File Save Threshold",
description = "The size threshold after which the file will be written to disk. The default is 256KB.")
int file_threshold() default 256000;
@AttributeDefinition(
name = "Maximum File Size",
description = "The maximum size allowed for uploaded files. The default is -1, which means unlimited.")
long file_max() default -1;
@AttributeDefinition(
name = "Maximum Request Size",
description =
"The maximum size allowed for multipart/form-data requests. The default is -1, which means unlimited.")
long request_max() default -1;
@AttributeDefinition(
name = "Check Additional Parameters",
description =
"Enable this if you want to include request parameters added through the container, e.g through a valve.")
boolean sling_default_parameter_checkForAdditionalContainerParameters() default false;
@AttributeDefinition(
name = "Maximum File Count",
description =
"The maximum number of files allowed for multipart/form-data requests in a single request. The default is 50.")
long request_max_file_count() default 50;
}
static final String PID = "org.apache.sling.engine.parameters";
/** default log */
private final Logger log = LoggerFactory.getLogger(PID);
@Reference
private SlingSettingsService settignsService;
@Activate
private void configure(final Config config) {
final String fixEncoding = config.sling_default_parameter_encoding();
final int maxParams = config.sling_default_max_parameters();
final long maxRequestSize = config.request_max();
final String fileLocation = getFileLocation(config.file_location());
final long maxFileSize = config.file_max();
final int fileSizeThreshold = config.file_threshold();
final boolean checkAddParameters = config.sling_default_parameter_checkForAdditionalContainerParameters();
if (log.isInfoEnabled()) {
log.info("Default Character Encoding: {}", fixEncoding);
log.info("Parameter Number Limit: {}", (maxParams < 0) ? "unlimited" : maxParams);
log.info("Maximum Request Size: {}", (maxParams < 0) ? "unlimited" : maxRequestSize);
log.info("Temporary File Location: {}", fileLocation);
log.info("Maximum File Size: {}", maxFileSize);
log.info("Tempory File Creation Threshold: {}", fileSizeThreshold);
log.info("Check for additional container parameters: {}", checkAddParameters);
log.info("Maximum File Count: {}", config.request_max_file_count());
}
Util.setDefaultFixEncoding(fixEncoding);
ParameterMap.setMaxParameters(maxParams);
ParameterSupport.configure(
maxRequestSize,
fileLocation,
maxFileSize,
fileSizeThreshold,
checkAddParameters,
config.request_max_file_count());
}
private String getFileLocation(String fileLocation) {
if (fileLocation != null) {
File file = new File(fileLocation);
if (!file.isAbsolute()) {
file = new File(this.settignsService.getSlingHomePath(), fileLocation);
fileLocation = file.getAbsolutePath();
}
if (file.exists()) {
if (!file.isDirectory()) {
log.error(
"Configured temporary file location {} exists but is not a directory; using java.io.tmpdir instead",
fileLocation);
fileLocation = null;
}
} else {
if (!file.mkdirs()) {
log.error("Cannot create temporary file directory {}; using java.io.tmpdir instead", fileLocation);
fileLocation = null;
}
}
}
return fileLocation;
}
}