From e0d19c4d9744caa54342eeb079b7f67ff11526c7 Mon Sep 17 00:00:00 2001
From: Joakim Erdfelt
Date: Wed, 24 Oct 2007 00:16:40 +0000
Subject: [PATCH] [MRM-565] Archiva 1.0-beta-3 fails in 404 on all legacy
request. Using new methods in RepositoryRequest to identify native resource
path early and using it. Adding PolicingServletRequest to deal with bad
formatted request paths. Beefing up RepositoryServletTest to test proxy-less
(for now) requests ... * Browse * Get Checksum (default layout) * Get
Checksum (legacy layout) * Get Metadata (versioned + default layout) * Get
Metadata (project + default layout) * Get Artifact (default layout) Adding
custom mime-types.txt to get proper "Content-Type" headers on GET requests.
git-svn-id: https://svn.apache.org/repos/asf/maven/archiva/trunk@587708 13f79535-47bb-0310-9956-ffa450edef68
---
.../repository/PolicingServletRequest.java | 69 +++++
.../web/repository/ProxiedDavServer.java | 201 ++++++++-----
.../web/repository/RepositoryServlet.java | 9 +
.../plexus/webdav/util/mime-types.txt | 129 +++++++++
.../web/repository/RepositoryServletTest.java | 272 ++++++++++++++++--
.../web/repository/RepositoryServletTest.xml | 51 +++-
.../src/test/resources/repository-archiva.xml | 111 +++++++
7 files changed, 736 insertions(+), 106 deletions(-)
create mode 100644 archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/repository/PolicingServletRequest.java
create mode 100644 archiva-web/archiva-webapp/src/main/resources/org/codehaus/plexus/webdav/util/mime-types.txt
create mode 100644 archiva-web/archiva-webapp/src/test/resources/repository-archiva.xml
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,29 +138,46 @@ 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 ( isPut )
- {
- /* Create parent directories that don't exist when writing a file
- * This actually makes this implementation not compliant to the
- * WebDAV RFC - but we have enough knowledge
- * about how the collection is being used to do this reasonably and
- * some versions of Maven's WebDAV don't
- * correctly create the collections themselves.
- */
+ // 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;
+ }
- File rootDirectory = getRootDirectory();
- if ( rootDirectory != null )
+ // At this point the incoming request can either be in default or legacy layout format.
+ try
{
- new File( rootDirectory, request.getLogicalResource() ).getParentFile().mkdirs();
+ // 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 );
- if ( isGet )
- {
- if ( resourceExists( request ) )
+ // All done.
+ return;
+ }
+
+ if ( resourceFile.exists() )
{
// [MRM-503] - Metadata file need Pragma:no-cache response header.
if ( request.getLogicalResource().endsWith( "/maven-metadata.xml" ) )
@@ -175,17 +192,35 @@ public class ProxiedDavServer
}
else
{
- respondResourceMissing( request, response );
+ respondResourceMissing( request, response, null );
}
}
if ( isPut )
{
+ /* Create parent directories that don't exist when writing a file
+ * This actually makes this implementation not compliant to the
+ * WebDAV RFC - but we have enough knowledge
+ * about how the collection is being used to do this reasonably and
+ * some versions of Maven's WebDAV don't
+ * correctly create the collections themselves.
+ */
+
+ File rootDirectory = getRootDirectory();
+ if ( rootDirectory != null )
+ {
+ new File( rootDirectory, request.getLogicalResource() ).getParentFile().mkdirs();
+ }
+
+ // 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( "