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

io.milton.servlet.WebResourceFactory 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.ContentTypeUtils;
import io.milton.common.Path;
import io.milton.http.HttpManager;
import io.milton.http.ResourceFactory;
import io.milton.resource.Resource;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Date;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Provides access to resources exposed by the servlet context.
 *
 * Attempts to locate a physical file, via getRealPath. This will usually work,
 * but may not in cases where the webapp is running from a war file, or if
 * overlays are used.
 *
 * If not found it attempts to locate a URL with servletContext.getResource
 *
 * @author brad
 */
public class WebResourceFactory implements ResourceFactory, Initable {

	private static final Logger log = LoggerFactory.getLogger(WebResourceFactory.class);

	private Config config;
	private File fileHome;
	private String basePath = "WEB-INF/static";
	private final Date modDate = new Date();

	public WebResourceFactory() {
	}

	public WebResourceFactory(Config config) {
		this.config = config;
	}

	public WebResourceFactory(File fileHome) {
		this.config = null;
		this.fileHome = fileHome;
		log.info("init fileHome={}", fileHome.getAbsoluteFile());
	}

	@Override
	public void init(Config config, HttpManager manager) {
		this.config = config;
	}

	@Override
	public Resource getResource(String host, String url) {
		Path p = Path.path(url);
		String contentType;
		if (config != null) {
			contentType = MiltonUtils.getContentType(config.getServletContext(), p.getName());
		} else {
			contentType = ContentTypeUtils.findContentTypes(p.getName());
		}

		File file;
		String path = stripContext(url);
		path = basePath + path;
		path = path.trim();

		// 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;
		}

		String realPath;
		if (config != null) {
			realPath = config.getServletContext().getRealPath(path);
		} else {
			realPath = fileHome.getAbsolutePath() + path;
		}
		if (realPath != null) {
			file = new File(realPath);
		} else {
			file = null;
		}
		
		
		if ( config != null && ( file == null || !file.exists())) {
			URL resource;
			try {
				resource = config.getServletContext().getResource(path);
			} catch (MalformedURLException ex) {
				//throw new RuntimeException(ex);
				log.warn("malformed url when attempting to locate servlet resource {}", path);
				return null;
			}
			if (resource != null) {
				return new UrlResource(p.getName(), resource, contentType, modDate);
			}
			return null;
		} else {
			if (file.isFile()) {
				return new StaticResource(file);
			} else {
				return null;
			}
		}
	}

	@Override
	public void destroy(HttpManager manager) {
	}

	public String getBasePath() {
		return basePath;
	}

	public void setBasePath(String basePath) {
		this.basePath = basePath;
	}

	private String stripContext(String url) {
		if (config == null) {
			return url;
		}
		String contextName = config.getServletContext().getServletContextName();
		if (contextName == null || contextName.isEmpty() || config.getServletContext().getServletContextName().equals("/")) {
			return url;
		}
		String contextPath = "/" + contextName;
		url = url.replaceFirst('/' + contextPath, "");
		return url;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy