/*
* Copyright (c) 2002-2012 Alibaba Group Holding Limited.
* All rights reserved.
*
* Licensed 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 com.alibaba.citrus.service.requestcontext.parser.filter;
import static com.alibaba.citrus.springext.util.SpringExtUtil.*;
import static com.alibaba.citrus.util.BasicConstant.*;
import static com.alibaba.citrus.util.FileUtil.*;
import static com.alibaba.citrus.util.StringUtil.*;
import javax.servlet.http.HttpServletRequest;
import com.alibaba.citrus.logconfig.support.SecurityLogger;
import com.alibaba.citrus.service.requestcontext.parser.UploadedFileFilter;
import com.alibaba.citrus.springext.support.BeanSupport;
import com.alibaba.citrus.springext.support.parser.AbstractSingleBeanDefinitionParser;
import com.alibaba.citrus.util.FileUtil;
import org.apache.commons.fileupload.FileItem;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.ParserContext;
import org.w3c.dom.Element;
/**
* 根据文件名后缀过滤上传文件。
*
* @author Michael Zhou
*/
public class UploadedFileExtensionWhitelist extends BeanSupport implements UploadedFileFilter {
private final SecurityLogger log = new SecurityLogger();
private String[] extensions;
public void setAllowedExtensions(String[] extensions) {
this.extensions = extensions;
}
public void setLogName(String logName) {
log.setLogName(logName);
}
public boolean isFiltering(HttpServletRequest request) {
return true;
}
@Override
protected void init() throws Exception {
if (extensions == null) {
extensions = EMPTY_STRING_ARRAY;
}
for (int i = 0; i < extensions.length; i++) {
extensions[i] = FileUtil.normalizeExtension(extensions[i]);
}
}
public FileItem filter(String key, FileItem file) {
if (file == null) {
return null;
}
boolean allowed = false;
// 未指定文件名 - 返回null
// 文件名没有后缀 - 返回字符串“null”
// 后缀被规格化为小写字母
String ext = getExtension(file.getName(), "null", true);
if (ext != null) {
for (String allowedExtension : extensions) {
if (allowedExtension.equals(ext)) {
allowed = true;
break;
}
}
}
if (!allowed) {
log.getLogger().warn("Uploaded file type \"{}\" is denied: {}", ext, file.getName());
return null;
} else {
return file;
}
}
public static class DefinitionParser extends AbstractSingleBeanDefinitionParser<UploadedFileExtensionWhitelist> {
@Override
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
attributesToProperties(element, builder, "logName");
String extensions = trimToNull(element.getAttribute("extensions"));
if (extensions != null) {
builder.addPropertyValue("allowedExtensions", extensions);
}
}
}
}