blob: f72679d4264674f11e84a3b0a09bc039974158b7 [file] [log] [blame]
/*
* Copyright 1999-2011 Alibaba Group.
*
* 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.dubbo.container.page;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
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 javax.servlet.http.HttpServletResponse;
import com.alibaba.dubbo.common.Constants;
/**
* ResourceServlet
*
* @author william.liangf
*/
public class ResourceFilter implements Filter {
private static final String CLASSPATH_PREFIX = "classpath:";
private final long start = System.currentTimeMillis();
private final List<String> resources = new ArrayList<String>();
public void init(FilterConfig filterConfig) throws ServletException {
String config = filterConfig.getInitParameter("resources");
if (config != null && config.length() > 0) {
String[] configs = Constants.COMMA_SPLIT_PATTERN.split(config);
for (String c : configs) {
if (c != null && c.length() > 0) {
c = c.replace('\\', '/');
if (c.endsWith("/")) {
c = c.substring(0, c.length() - 1);
}
resources.add(c);
}
}
}
}
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
if (response.isCommitted()) {
return;
}
String uri = request.getRequestURI();
String context = request.getContextPath();
if (uri.endsWith("/favicon.ico")) {
uri = "/favicon.ico";
} else if (context != null && ! "/".equals(context)) {
uri = uri.substring(context.length());
}
if (! uri.startsWith("/")) {
uri = "/" + uri;
}
long lastModified = getLastModified(uri);
long since = request.getDateHeader("If-Modified-Since");
if (since >= lastModified) {
response.sendError(HttpServletResponse.SC_NOT_MODIFIED);
return;
}
byte[] data;
InputStream input = getInputStream(uri);
if (input == null) {
chain.doFilter(req, res);
return;
}
try {
ByteArrayOutputStream output = new ByteArrayOutputStream();
byte[] buffer = new byte[8192];
int n = 0;
while (-1 != (n = input.read(buffer))) {
output.write(buffer, 0, n);
}
data = output.toByteArray();
} finally {
input.close();
}
response.setDateHeader("Last-Modified", lastModified);
OutputStream output = response.getOutputStream();
output.write(data);
output.flush();
}
private boolean isFile(String path) {
return path.startsWith("/") || path.indexOf(":") <= 1;
}
private long getLastModified(String uri) {
for (String resource : resources) {
if (resource != null && resource.length() > 0) {
String path = resource + uri;
if (isFile(path)) {
File file = new File(path);
if (file.exists()) {
return file.lastModified();
}
}
}
}
return start;
}
private InputStream getInputStream(String uri) {
for (String resource : resources) {
String path = resource + uri;
try {
if (isFile(path)) {
return new FileInputStream(path);
} else if (path.startsWith(CLASSPATH_PREFIX)) {
return Thread.currentThread().getContextClassLoader().getResourceAsStream(path.substring(CLASSPATH_PREFIX.length()));
} else {
return new URL(path).openStream();
}
} catch (IOException e) {
}
}
return null;
}
}