diff --git a/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/repository/PolicingServletRequest.java b/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/repository/PolicingServletRequest.java new file mode 100644 index 000000000..0076988ae --- /dev/null +++ b/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/repository/PolicingServletRequest.java @@ -0,0 +1,69 @@ +package org.apache.maven.archiva.web.repository; + +/* + * 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. + */ + +import org.apache.commons.lang.StringUtils; +import org.codehaus.plexus.util.FileUtils; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; + +/** + * PolicingServletRequest is for policing the incoming request for naughty bits, such as a double slashes, + * or paths that include "/../" type syntax, or query string. Stripping out all things that are + * not appropriate. + * + * @author Joakim Erdfelt + * @version $Id$ + */ +public class PolicingServletRequest + extends HttpServletRequestWrapper + implements HttpServletRequest +{ + private String fixedPathInfo; + + public PolicingServletRequest( HttpServletRequest originalRequest ) + { + super( originalRequest ); + + fixedPathInfo = originalRequest.getPathInfo(); + + if ( StringUtils.isNotBlank( fixedPathInfo ) ) + { + /* Perform a simple security normalization of the requested pathinfo. + * This is to cleanup requests that use "/../" or "///" type hacks. + */ + fixedPathInfo = FileUtils.normalize( fixedPathInfo ); + } + } + + @Override + public String getPathInfo() + { + return fixedPathInfo; + } + + @Override + public String getQueryString() + { + // No query string allowed. + return null; + } +} diff --git a/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/repository/ProxiedDavServer.java b/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/repository/ProxiedDavServer.java index 7dedee43b..bdf8fa97f 100644 --- a/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/repository/ProxiedDavServer.java +++ b/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/repository/ProxiedDavServer.java @@ -138,7 +138,62 @@ public class ProxiedDavServer if ( isGet ) { - fetchContentFromProxies( request ); + // Default behaviour is to treat the resource natively. + String resource = request.getLogicalResource(); + File resourceFile = new File( managedRepository.getRepoRoot(), resource ); + + // If this a directory resource, then we are likely browsing. + if ( resourceFile.exists() && resourceFile.isDirectory() ) + { + // TODO: [MRM-440] - If webdav URL lacks a trailing /, navigating to all links in the listing return 404. + // TODO: Issue redirect with proper pathing. + + // Process the request. + davServer.process( request, response ); + + // All done. + return; + } + + // At this point the incoming request can either be in default or legacy layout format. + try + { + // Perform an adjustment of the resource to the managed repository expected path. + resource = repositoryRequest.toNativePath( request.getLogicalResource(), managedRepository ); + resourceFile = new File( managedRepository.getRepoRoot(), resource ); + + // Adjust the pathInfo resource to be in the format that the dav server impl expects. + request.getRequest().setPathInfo( resource ); + + // Attempt to fetch the resource from any defined proxy. + fetchContentFromProxies( request, resource ); + } + catch ( LayoutException e ) + { + // Invalid resource, pass it on. + respondResourceMissing( request, response, e ); + + // All done. + return; + } + + if ( resourceFile.exists() ) + { + // [MRM-503] - Metadata file need Pragma:no-cache response header. + if ( request.getLogicalResource().endsWith( "/maven-metadata.xml" ) ) + { + response.addHeader( "Pragma", "no-cache" ); + response.addHeader( "Cache-Control", "no-cache" ); + } + + // TODO: [MRM-524] determine http caching options for other types of files (artifacts, sha1, md5, snapshots) + + davServer.process( request, response ); + } + else + { + respondResourceMissing( request, response, null ); + } } if ( isPut ) @@ -156,36 +211,16 @@ public class ProxiedDavServer { new File( rootDirectory, request.getLogicalResource() ).getParentFile().mkdirs(); } - } - - if ( isGet ) - { - if ( resourceExists( request ) ) - { - // [MRM-503] - Metadata file need Pragma:no-cache response header. - if ( request.getLogicalResource().endsWith( "/maven-metadata.xml" ) ) - { - response.addHeader( "Pragma", "no-cache" ); - response.addHeader( "Cache-Control", "no-cache" ); - } - - // TODO: [MRM-524] determine http caching options for other types of files (artifacts, sha1, md5, snapshots) - - davServer.process( request, response ); - } - else - { - respondResourceMissing( request, response ); - } - } - - if ( isPut ) - { + + // Allow the dav server to process the put request. davServer.process( request, response ); + + // All done. + return; } } - private void respondResourceMissing( DavServerRequest request, HttpServletResponse response ) + private void respondResourceMissing( DavServerRequest request, HttpServletResponse response, Throwable t ) { response.setStatus( HttpServletResponse.SC_NOT_FOUND ); @@ -196,7 +231,6 @@ public class ProxiedDavServer missingUrl.append( request.getRequest().getServerName() ).append( ":" ); missingUrl.append( request.getRequest().getServerPort() ); missingUrl.append( request.getRequest().getServletPath() ); - // missingUrl.append( request.getRequest().getPathInfo() ); String message = "Error 404 Not Found"; @@ -217,6 +251,13 @@ public class ProxiedDavServer out.println( "\">" ); out.print( missingUrl.toString() ); out.println( "
" ); + + if ( t != null ) + { + out.println( "" ); + t.printStackTrace( out ); + out.println( "" ); + } out.println( "