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

io.milton.servlet.StaticResourceFactory Maven / Gradle / Ivy

Go to download

Milton Community Edition: Supports DAV level 1 and is available on Apache2 license

There is a newer version: 4.0.3.2215
Show newest version
/*
 * 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 io.milton.servlet;

import io.milton.common.Path;
import io.milton.http.ResourceFactory;
import io.milton.resource.Resource;
import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Used for providing simple readonly access to resources which are files in a
 * conventional file system.
 *
 * Can be provided with a single or multiple root directories. If multiple they
 * are searched in turn for a matching resource
 *
 * Will check for a system property static.resource.roots which, if present, is
 * expected to be a comma delimited list of absolute paths to root locations. An
 * exception will be thrown if a path is given which does not exist
 *
 * @author brad
 */
public class StaticResourceFactory implements ResourceFactory {

	private static final Logger log = LoggerFactory.getLogger(StaticResourceFactory.class);
	public static final String FILE_ROOTS_SYS_PROP_NAME = "static.resource.roots";
	private final List roots;
	private String contextPath;
	private Date modDate = new Date();

	public StaticResourceFactory() {
		roots = new ArrayList<>();
		String sRoots = System.getProperty(FILE_ROOTS_SYS_PROP_NAME);
		if (sRoots != null && sRoots.length() > 0) {
			for (String s : sRoots.split(",")) {
				s = s.trim();
				if (s.length() > 0) {
					File root = new File(s);
					if (root.exists()) {
						if (root.isDirectory()) {
							roots.add(root);
						} else {
							throw new RuntimeException("Extra file root is not a directory: " + root.getAbsolutePath());
						}
					} else {
						throw new RuntimeException("Extra file root does not exist: " + root.getAbsolutePath());
					}
				}
			}

		}
	}

	public StaticResourceFactory(File root) {
		this();
		roots.add(root);
	}

	public StaticResourceFactory(List roots) {
		this();
		this.roots.addAll(roots);
	}

	@Override
	public Resource getResource(String host, String url) {
		Path p = Path.path(url);
		String path = stripContext(url);
		// Fix for possible attack - see https://nvd.nist.gov/vuln/detail/CVE-2000-0920
		if( path.contains("../") || path.contains("/..") ) {
			log.error("getResource: Invalid path {}, attempt to use relative notation", path);
			return null;
		}


		for (File root : roots) {
			File file = new File(root, path);
			if (file.exists() && file.isFile()) {
				return new StaticResource(file);
			}
		}
		return null;
	}

	private String stripContext(String url) {
		if (this.contextPath != null && contextPath.length() > 0) {
			url = url.replaceFirst('/' + contextPath, "");
			log.debug("stripped context: " + url);
		}
		return url;
	}

	public String getContextPath() {
		return contextPath;
	}

	public void setContextPath(String contextPath) {
		this.contextPath = contextPath;
	}

	public Date getModDate() {
		return modDate;
	}

	public void setModDate(Date modDate) {
		this.modDate = modDate;
	}

	public List getRoots() {
		return roots;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy