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( "" ); @@ -228,74 +269,23 @@ public class ProxiedDavServer } } - private boolean resourceExists( DavServerRequest request ) - { - String resource = request.getLogicalResource(); - File resourceFile = new File( managedRepository.getRepoRoot(), resource ); - return resourceFile.exists(); - } - - private void fetchContentFromProxies( DavServerRequest request ) + private void fetchContentFromProxies( DavServerRequest request, String resource ) throws ServletException { - String resource = request.getLogicalResource(); - - // Cleanup bad requests from maven 1. - // Often seen is a double slash. - // example: http://hostname:8080/archiva/repository/internal//pmd/jars/pmd-3.0.jar - if ( resource.startsWith( "/" ) ) - { - resource = resource.substring( 1 ); - } - - if ( resource.endsWith( ".sha1" ) || resource.endsWith( ".md5" ) ) + if ( repositoryRequest.isSupportFile( resource ) ) { // Checksums are fetched with artifact / metadata. + + // Need to adjust the path for the checksum resource. return; } // Is it a Metadata resource? - if ( resource.endsWith( "/" + MetadataTools.MAVEN_METADATA ) ) + if ( repositoryRequest.isDefault( resource ) && repositoryRequest.isMetadata( resource ) ) { - ProjectReference project; - VersionedReference versioned; - - try + if ( fetchMetadataFromProxies( request, resource ) ) { - - versioned = metadataTools.toVersionedReference( resource ); - if ( versioned != null ) - { - connectors.fetchFromProxies( managedRepository, versioned ); - request.getRequest().setPathInfo( metadataTools.toPath( versioned ) ); - return; - } - } - catch ( RepositoryMetadataException e ) - { - /* eat it */ - } - catch ( ProxyException e ) - { - throw new ServletException( "Unable to fetch versioned metadata resource.", e ); - } - - try - { - project = metadataTools.toProjectReference( resource ); - if ( project != null ) - { - connectors.fetchFromProxies( managedRepository, project ); - request.getRequest().setPathInfo( metadataTools.toPath( project ) ); - } - } - catch ( RepositoryMetadataException e ) - { - /* eat it */ - } - catch ( ProxyException e ) - { - throw new ServletException( "Unable to fetch project metadata resource.", e ); + return; } } @@ -326,6 +316,52 @@ public class ProxiedDavServer } } + private boolean fetchMetadataFromProxies( DavServerRequest request, String resource ) + throws ServletException + { + ProjectReference project; + VersionedReference versioned; + + try + { + + versioned = metadataTools.toVersionedReference( resource ); + if ( versioned != null ) + { + connectors.fetchFromProxies( managedRepository, versioned ); + return true; + } + } + catch ( RepositoryMetadataException e ) + { + /* eat it */ + } + catch ( ProxyException e ) + { + throw new ServletException( "Unable to fetch versioned metadata resource.", e ); + } + + try + { + project = metadataTools.toProjectReference( resource ); + if ( project != null ) + { + connectors.fetchFromProxies( managedRepository, project ); + return true; + } + } + catch ( RepositoryMetadataException e ) + { + /* eat it */ + } + catch ( ProxyException e ) + { + throw new ServletException( "Unable to fetch project metadata resource.", e ); + } + + return false; + } + /** * A relocation capable client will request the POM prior to the artifact, * and will then read meta-data and do client side relocation. A simplier @@ -400,6 +436,13 @@ public class ProxiedDavServer // Invalid POM : ignore } } + + @Override + public void setUseIndexHtml( boolean useIndexHtml ) + { + super.setUseIndexHtml( useIndexHtml ); + davServer.setUseIndexHtml( useIndexHtml ); + } public ManagedRepositoryContent getRepository() { diff --git a/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/repository/RepositoryServlet.java b/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/repository/RepositoryServlet.java index 28856ef6f..9bd9596e6 100644 --- a/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/repository/RepositoryServlet.java +++ b/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/repository/RepositoryServlet.java @@ -103,9 +103,18 @@ public class RepositoryServlet DavServerComponent server = createServer( repo.getId(), repoDir, servletConfig ); + server.setUseIndexHtml( true ); server.addListener( audit ); } } + + @Override + protected void service( HttpServletRequest httpRequest, HttpServletResponse httpResponse ) + throws ServletException, IOException + { + // Wrap the incoming request to adjust paths and whatnot. + super.service( new PolicingServletRequest( httpRequest ), httpResponse ); + } public synchronized ManagedRepositoryConfiguration getRepository( String prefix ) { diff --git a/archiva-web/archiva-webapp/src/main/resources/org/codehaus/plexus/webdav/util/mime-types.txt b/archiva-web/archiva-webapp/src/main/resources/org/codehaus/plexus/webdav/util/mime-types.txt new file mode 100644 index 000000000..3c580357b --- /dev/null +++ b/archiva-web/archiva-webapp/src/main/resources/org/codehaus/plexus/webdav/util/mime-types.txt @@ -0,0 +1,129 @@ +# This is a comment. I love comments. + +# This file controls what Internet media types are sent to the client for +# given file extension(s). Sending the correct media type to the client +# is important so they know how to handle the content of the file. +# Extra types can either be added here or by using an AddType directive +# in your config files. For more information about Internet media types, +# please read RFC 2045, 2046, 2047, 2048, and 2077. The Internet media type +# registry is at . + +# MIME type Extensions + +application/andrew-inset ez +application/atom+xml atom +application/mac-binhex40 hqx +application/mac-compactpro cpt +application/mathml+xml mathml +application/msword doc +application/octet-stream bin dms lha lzh exe class so dll dmg +application/oda oda +application/ogg ogg +application/pdf pdf +application/pgp-encrypted pgp +application/postscript ai eps ps +application/rdf+xml rdf +application/smil smi smil +application/srgs gram +application/srgs+xml grxml +application/vnd.mif mif +application/vnd.mozilla.xul+xml xul +application/vnd.ms-excel xls +application/vnd.ms-powerpoint ppt +application/vnd.rn-realmedia rm +application/vnd.wap.wbxml wbxml +application/vnd.wap.wmlc wmlc +application/vnd.wap.wmlscriptc wmlsc +application/voicexml+xml vxml +application/x-bcpio bcpio +application/x-cdlink vcd +application/x-chess-pgn pgn +application/x-cpio cpio +application/x-csh csh +application/x-director dcr dir dxr +application/x-dvi dvi +application/x-futuresplash spl +application/x-gtar gtar +application/x-hdf hdf +application/x-jar jar +application/x-java-jnlp-file jnlp +application/x-javascript js +application/x-koan skp skd skt skm +application/x-latex latex +application/x-netcdf nc cdf +application/x-sh sh +application/x-shar shar +application/x-shockwave-flash swf +application/x-stuffit sit +application/x-sv4cpio sv4cpio +application/x-sv4crc sv4crc +application/x-tar tar +application/x-tcl tcl +application/x-tex tex +application/x-texinfo texinfo texi +application/x-troff t tr roff +application/x-troff-man man +application/x-troff-me me +application/x-troff-ms ms +application/x-ustar ustar +application/x-wais-source src +application/xhtml+xml xhtml xht +application/xml xml xsl +application/xml-dtd dtd +application/xslt+xml xslt +application/zip zip +audio/basic au snd +audio/midi mid midi kar +audio/mpeg mpga mp2 mp3 +audio/x-aiff aif aiff aifc +audio/x-mpegurl m3u +audio/x-pn-realaudio ram ra +audio/x-wav wav +chemical/x-pdb pdb +chemical/x-xyz xyz +image/bmp bmp +image/cgm cgm +image/gif gif +image/ief ief +image/jp2 jp2 +image/jpeg jpeg jpg jpe +image/pict pict pic pct +image/png png +image/svg+xml svg +image/tiff tiff tif +image/vnd.djvu djvu djv +image/vnd.wap.wbmp wbmp +image/x-cmu-raster ras +image/x-icon ico +image/x-macpaint pntg pnt mac +image/x-portable-anymap pnm +image/x-portable-bitmap pbm +image/x-portable-graymap pgm +image/x-portable-pixmap ppm +image/x-quicktime qtif qti +image/x-rgb rgb +image/x-xbitmap xbm +image/x-xpixmap xpm +image/x-xwindowdump xwd +model/iges igs iges +model/mesh msh mesh silo +model/vrml wrl vrml +text/calendar ics ifb +text/css css +text/html html htm +text/plain asc txt sha1 md5 +text/richtext rtx +text/rtf rtf +text/sgml sgml sgm +text/tab-separated-values tsv +text/vnd.wap.wml wml +text/vnd.wap.wmlscript wmls +text/x-setext etx +video/mp4 mp4 +video/mpeg mpeg mpg mpe +video/quicktime qt mov +video/vnd.mpegurl mxu m4u +video/x-dv dv dif +video/x-msvideo avi +video/x-sgi-movie movie +x-conference/x-cooltalk ice diff --git a/archiva-web/archiva-webapp/src/test/java/org/apache/maven/archiva/web/repository/RepositoryServletTest.java b/archiva-web/archiva-webapp/src/test/java/org/apache/maven/archiva/web/repository/RepositoryServletTest.java index 604e2b432..c0b24cee5 100644 --- a/archiva-web/archiva-webapp/src/test/java/org/apache/maven/archiva/web/repository/RepositoryServletTest.java +++ b/archiva-web/archiva-webapp/src/test/java/org/apache/maven/archiva/web/repository/RepositoryServletTest.java @@ -19,26 +19,36 @@ package org.apache.maven.archiva.web.repository; * under the License. */ +import com.meterware.httpunit.GetMethodWebRequest; import com.meterware.httpunit.PutMethodWebRequest; +import com.meterware.httpunit.WebLink; import com.meterware.httpunit.WebRequest; import com.meterware.httpunit.WebResponse; import com.meterware.servletunit.ServletRunner; import com.meterware.servletunit.ServletUnitClient; + +import org.apache.commons.io.FileUtils; import org.apache.maven.archiva.configuration.ArchivaConfiguration; import org.apache.maven.archiva.configuration.Configuration; -import org.apache.maven.archiva.configuration.ConfigurationEvent; -import org.apache.maven.archiva.configuration.IndeterminateConfigurationException; import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration; +import org.apache.maven.archiva.configuration.RemoteRepositoryConfiguration; import org.codehaus.plexus.PlexusConstants; import org.codehaus.plexus.PlexusTestCase; -import org.codehaus.plexus.registry.RegistryException; -import org.codehaus.plexus.util.FileUtils; -import org.xml.sax.SAXException; +import org.codehaus.plexus.webdav.util.MimeTypes; -import javax.servlet.ServletException; import java.io.File; import java.io.IOException; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +/** + * RepositoryServletTest + * + * @author Joakim Erdfelt + * @version $Id$ + */ public class RepositoryServletTest extends PlexusTestCase { @@ -61,61 +71,66 @@ public class RepositoryServletTest { super.setUp(); - // TODO: purely to quiet logging - shouldn't be needed String appserverBase = getTestFile( "target/appserver-base" ).getAbsolutePath(); System.setProperty( "appserver.base", appserverBase ); - configuration = (ArchivaConfiguration) lookup( ArchivaConfiguration.ROLE ); + File testConf = getTestFile( "src/test/resources/repository-archiva.xml" ); + File testConfDest = new File( appserverBase, "conf/archiva.xml" ); + FileUtils.copyFile( testConf, testConfDest ); + configuration = (ArchivaConfiguration) lookup( ArchivaConfiguration.ROLE ); repositoryLocation = new File( appserverBase, "data/repositories/internal" ); + Configuration config = configuration.getConfiguration(); + + config.addManagedRepository( createManagedRepository( "internal", "Internal Test Repo", repositoryLocation ) ); + saveConfiguration(); ServletRunner sr = new ServletRunner(); sr.registerServlet( "/repository/*", UnauthenticatedRepositoryServlet.class.getName() ); sc = sr.newClient(); - sc.getSession( true ).getServletContext().setAttribute( PlexusConstants.PLEXUS_KEY, getContainer() ); + HttpSession session = sc.getSession( true ); + ServletContext servletContext = session.getServletContext(); + servletContext.setAttribute( PlexusConstants.PLEXUS_KEY, getContainer() ); } public void testPutWithMissingParentCollection() - throws IOException, SAXException + throws Exception { FileUtils.deleteDirectory( repositoryLocation ); WebRequest request = new PutMethodWebRequest( REQUEST_PATH, getClass().getResourceAsStream( "/artifact.jar" ), "application/octet-stream" ); WebResponse response = sc.getResponse( request ); - assertNotNull( "No response received", response ); - assertEquals( "file contents", "artifact.jar\n", - FileUtils.fileRead( new File( repositoryLocation, "path/to/artifact.jar" ) ) ); + assertNotNull( "Should have received response", response ); + assertEquals( "file contents", "artifact.jar\n", FileUtils + .readFileToString( new File( repositoryLocation, "path/to/artifact.jar" ), null ) ); } public void testGetRepository() - throws IOException, ServletException + throws Exception { RepositoryServlet servlet = (RepositoryServlet) sc.newInvocation( REQUEST_PATH ).getServlet(); assertNotNull( servlet ); - ManagedRepositoryConfiguration repository = servlet.getRepository( REPOSITORY_ID ); - assertNotNull( repository ); - assertEquals( "Archiva Managed Internal Repository", repository.getName() ); + assertRepositoryValid( servlet, REPOSITORY_ID ); } public void testGetRepositoryAfterDelete() - throws IOException, ServletException, RegistryException, IndeterminateConfigurationException + throws Exception { RepositoryServlet servlet = (RepositoryServlet) sc.newInvocation( REQUEST_PATH ).getServlet(); assertNotNull( servlet ); Configuration c = configuration.getConfiguration(); c.removeManagedRepository( c.findManagedRepositoryById( REPOSITORY_ID ) ); - // TODO it would be better to use a mock configuration and "save" to more accurately reflect the calls made - servlet.configurationEvent( new ConfigurationEvent( ConfigurationEvent.SAVED) ); + saveConfiguration(); ManagedRepositoryConfiguration repository = servlet.getRepository( REPOSITORY_ID ); assertNull( repository ); } public void testGetRepositoryAfterAdd() - throws IOException, ServletException, RegistryException, IndeterminateConfigurationException + throws Exception { RepositoryServlet servlet = (RepositoryServlet) sc.newInvocation( REQUEST_PATH ).getServlet(); assertNotNull( servlet ); @@ -131,16 +146,221 @@ public class RepositoryServletTest } repo.setLocation( repoRoot.getAbsolutePath() ); c.addManagedRepository( repo ); - // TODO it would be better to use a mock configuration and "save" to more accurately reflect the calls made - servlet.configurationEvent( new ConfigurationEvent( ConfigurationEvent.SAVED) ); + saveConfiguration(); ManagedRepositoryConfiguration repository = servlet.getRepository( NEW_REPOSITORY_ID ); assertNotNull( repository ); assertEquals( NEW_REPOSITORY_NAME, repository.getName() ); // check other is still intact - repository = servlet.getRepository( REPOSITORY_ID ); - assertNotNull( repository ); - assertEquals( "Archiva Managed Internal Repository", repository.getName() ); + assertRepositoryValid( servlet, REPOSITORY_ID ); + } + + public void testBrowse() + throws Exception + { + RepositoryServlet servlet = (RepositoryServlet) sc.newInvocation( REQUEST_PATH ).getServlet(); + assertNotNull( servlet ); + assertRepositoryValid( servlet, REPOSITORY_ID ); + + new File( repositoryLocation, "org/apache/archiva" ).mkdirs(); + new File( repositoryLocation, "net/sourceforge" ).mkdirs(); + new File( repositoryLocation, "commons-lang" ).mkdirs(); + + WebRequest request = new GetMethodWebRequest( "http://machine.com/repository/internal/" ); + WebResponse response = sc.getResponse( request ); + assertEquals( "Response", HttpServletResponse.SC_OK, response.getResponseCode() ); + + // dumpResponse( response ); + + WebLink links[] = response.getLinks(); + String expectedLinks[] = new String[] { "./commons-lang/", "./net/", "./org/", "./path/" }; + + assertEquals( "Links.length", expectedLinks.length, links.length ); + for ( int i = 0; i < links.length; i++ ) + { + assertEquals( "Link[" + i + "]", expectedLinks[i], links[i].getURLString() ); + } + } + + public void testGetNoProxyChecksumDefaultLayout() + throws Exception + { + RepositoryServlet servlet = (RepositoryServlet) sc.newInvocation( REQUEST_PATH ).getServlet(); + assertNotNull( servlet ); + assertRepositoryValid( servlet, REPOSITORY_ID ); + + String commonsLangSha1 = "commons-lang/commons-lang/2.1/commons-lang-2.1.jar.sha1"; + + File checksumFile = new File( repositoryLocation, commonsLangSha1 ); + checksumFile.getParentFile().mkdirs(); + + FileUtils.writeStringToFile( checksumFile, "dummy-checksum", null ); + + WebRequest request = new GetMethodWebRequest( "http://machine.com/repository/internal/" + commonsLangSha1 ); + WebResponse response = sc.getResponse( request ); + assertEquals( "Response OK", HttpServletResponse.SC_OK, response.getResponseCode() ); + + assertEquals( "Expected file contents", "dummy-checksum", response.getText() ); + } + + public void testGetNoProxyChecksumLegacyLayout() + throws Exception + { + RepositoryServlet servlet = (RepositoryServlet) sc.newInvocation( REQUEST_PATH ).getServlet(); + assertNotNull( servlet ); + assertRepositoryValid( servlet, REPOSITORY_ID ); + + String commonsLangSha1 = "commons-lang/commons-lang/2.1/commons-lang-2.1.jar.sha1"; + + File checksumFile = new File( repositoryLocation, commonsLangSha1 ); + checksumFile.getParentFile().mkdirs(); + + FileUtils.writeStringToFile( checksumFile, "dummy-checksum", null ); + + WebRequest request = new GetMethodWebRequest( "http://machine.com/repository/internal/" + + "commons-lang/jars/commons-lang-2.1.jar.sha1" ); + WebResponse response = sc.getResponse( request ); + assertEquals( "Response OK", HttpServletResponse.SC_OK, response.getResponseCode() ); + + assertEquals( "Expected file contents", "dummy-checksum", response.getText() ); + } + + public void testGetNoProxyVersionedMetadataDefaultLayout() + throws Exception + { + RepositoryServlet servlet = (RepositoryServlet) sc.newInvocation( REQUEST_PATH ).getServlet(); + assertNotNull( servlet ); + assertRepositoryValid( servlet, REPOSITORY_ID ); + + String commonsLangMetadata = "commons-lang/commons-lang/2.1/maven-metadata.xml"; + String expectedMetadataContents = "dummy-versioned-metadata"; + + File metadataFile = new File( repositoryLocation, commonsLangMetadata ); + metadataFile.getParentFile().mkdirs(); + + FileUtils.writeStringToFile( metadataFile, expectedMetadataContents, null ); + + WebRequest request = new GetMethodWebRequest( "http://machine.com/repository/internal/" + commonsLangMetadata ); + WebResponse response = sc.getResponse( request ); + assertEquals( "Response OK", HttpServletResponse.SC_OK, response.getResponseCode() ); + + assertEquals( "Expected file contents", expectedMetadataContents, response.getText() ); + } + + public void testGetNoProxyProjectMetadataDefaultLayout() + throws Exception + { + RepositoryServlet servlet = (RepositoryServlet) sc.newInvocation( REQUEST_PATH ).getServlet(); + assertNotNull( servlet ); + assertRepositoryValid( servlet, REPOSITORY_ID ); + + String commonsLangMetadata = "commons-lang/commons-lang/maven-metadata.xml"; + String expectedMetadataContents = "dummy-project-metadata"; + + File metadataFile = new File( repositoryLocation, commonsLangMetadata ); + metadataFile.getParentFile().mkdirs(); + + FileUtils.writeStringToFile( metadataFile, expectedMetadataContents, null ); + + WebRequest request = new GetMethodWebRequest( "http://machine.com/repository/internal/" + commonsLangMetadata ); + WebResponse response = sc.getResponse( request ); + assertEquals( "Response OK", HttpServletResponse.SC_OK, response.getResponseCode() ); + + assertEquals( "Expected file contents", expectedMetadataContents, response.getText() ); + } + + public void testGetNoProxyArtifactDefaultLayout() + throws Exception + { + RepositoryServlet servlet = (RepositoryServlet) sc.newInvocation( REQUEST_PATH ).getServlet(); + assertNotNull( servlet ); + assertRepositoryValid( servlet, REPOSITORY_ID ); + + String commonsLangJar = "commons-lang/commons-lang/2.1/commons-lang-2.1.jar"; + String expectedArtifactContents = "dummy-commons-lang-artifact"; + + File artifactFile = new File( repositoryLocation, commonsLangJar ); + artifactFile.getParentFile().mkdirs(); + + FileUtils.writeStringToFile( artifactFile, expectedArtifactContents, null ); + + WebRequest request = new GetMethodWebRequest( "http://machine.com/repository/internal/" + commonsLangJar ); + WebResponse response = sc.getResponse( request ); + assertEquals( "Response OK", HttpServletResponse.SC_OK, response.getResponseCode() ); + + assertEquals( "Expected file contents", expectedArtifactContents, response.getText() ); + } + + public void testMimeTypesAvailable() + throws Exception + { + MimeTypes mimeTypes = (MimeTypes) lookup( MimeTypes.class ); + assertNotNull( mimeTypes ); + + // Test for some added types. + assertEquals( "sha1", "text/plain", mimeTypes.getMimeType( "foo.sha1" ) ); + assertEquals( "md5", "text/plain", mimeTypes.getMimeType( "foo.md5" ) ); + assertEquals( "pgp", "application/pgp-encrypted", mimeTypes.getMimeType( "foo.pgp" ) ); + } + + private void dumpResponse( WebResponse response ) + { + System.out.println( "---(response)---" ); + System.out.println( "" + response.getResponseCode() + " " + response.getResponseMessage() ); + + String headerNames[] = response.getHeaderFieldNames(); + for ( String headerName : headerNames ) + { + System.out.println( "[header] " + headerName + ": " + response.getHeaderField( headerName ) ); + } + + System.out.println( "---(text)---" ); + try + { + System.out.println( response.getText() ); + } + catch ( IOException e ) + { + System.err.print( "[Exception] : " ); + e.printStackTrace( System.err ); + } + } + + private void assertRepositoryValid( RepositoryServlet servlet, String repoId ) + { + ManagedRepositoryConfiguration repository = servlet.getRepository( repoId ); + assertNotNull( "Archiva Managed Repository id:<" + repoId + "> should exist.", repository ); + File repoRoot = new File( repository.getLocation() ); + assertTrue( "Archiva Managed Repository id:<" + repoId + "> should have a valid location on disk.", repoRoot + .exists() + && repoRoot.isDirectory() ); + } + + private void saveConfiguration() + throws Exception + { + configuration.save( configuration.getConfiguration() ); + // TODO it would be better to use a mock configuration and "save" to more accurately reflect the calls made + // RepositoryServlet servlet + // servlet.configurationEvent( new ConfigurationEvent( ConfigurationEvent.SAVED ) ); + } + + private ManagedRepositoryConfiguration createManagedRepository( String id, String name, File location ) + { + ManagedRepositoryConfiguration repo = new ManagedRepositoryConfiguration(); + repo.setId( id ); + repo.setName( name ); + repo.setLocation( location.getAbsolutePath() ); + return repo; + } + + private RemoteRepositoryConfiguration createRemoteRepository( String id, String name, String url ) + { + RemoteRepositoryConfiguration repo = new RemoteRepositoryConfiguration(); + repo.setId( id ); + repo.setName( name ); + repo.setUrl( url ); + return repo; } } diff --git a/archiva-web/archiva-webapp/src/test/resources/org/apache/maven/archiva/web/repository/RepositoryServletTest.xml b/archiva-web/archiva-webapp/src/test/resources/org/apache/maven/archiva/web/repository/RepositoryServletTest.xml index 5356abb87..beccf43c9 100644 --- a/archiva-web/archiva-webapp/src/test/resources/org/apache/maven/archiva/web/repository/RepositoryServletTest.xml +++ b/archiva-web/archiva-webapp/src/test/resources/org/apache/maven/archiva/web/repository/RepositoryServletTest.xml @@ -29,15 +29,64 @@ basic + + + org.apache.maven.archiva.configuration.ArchivaConfiguration + org.apache.maven.archiva.configuration.DefaultArchivaConfiguration + + + org.codehaus.plexus.registry.Registry + configured + + + + + org.codehaus.plexus.registry.Registry + configured + org.codehaus.plexus.registry.commons.CommonsConfigurationRegistry + + + + + + + + org.codehaus.plexus.webdav.DavServerManager default org.codehaus.plexus.webdav.DefaultDavServerManager + DefaultDavServerManager proxied - + + + org.codehaus.plexus.cache.Cache + url-failures-cache + org.codehaus.plexus.cache.ehcache.EhcacheCache + URL Failure Cache + + 600 + false + ${java.io.tmpdir}/archiva/urlcache + false + 1000 + LRU + url-failures-cache + false + + 2700 + + 1800 + + + + org.apache.maven.archiva.repository.scanner.RepositoryContentConsumers diff --git a/archiva-web/archiva-webapp/src/test/resources/repository-archiva.xml b/archiva-web/archiva-webapp/src/test/resources/repository-archiva.xml new file mode 100644 index 000000000..f642851be --- /dev/null +++ b/archiva-web/archiva-webapp/src/test/resources/repository-archiva.xml @@ -0,0 +1,111 @@ + + + + + + 2 + + + + + artifacts + + **/*.pom + **/*.jar + **/*.ear + **/*.war + **/*.car + **/*.sar + **/*.mar + **/*.rar + **/*.dtd + **/*.tld + **/*.tar.gz + **/*.tar.bz2 + **/*.zip + + + + indexable-content + + **/*.txt + **/*.TXT + **/*.block + **/*.config + **/*.pom + **/*.xml + **/*.xsd + **/*.dtd + **/*.tld + + + + auto-remove + + **/*.bak + **/*~ + **/*- + + + + ignored + + **/.htaccess + **/KEYS + **/*.rb + **/*.sh + **/.svn/** + **/.DAV/** + + + + + update-db-artifact + create-missing-checksums + update-db-repository-metadata + validate-checksum + validate-signature + index-content + auto-remove + auto-rename + + + update-db-bad-content + + + + + 0 0 * * ? + + index-artifact + update-db-project + validate-repository-metadata + index-archive-toc + update-db-bytecode-stats + index-public-methods + + + not-present-remove-db-artifact + not-present-remove-db-project + not-present-remove-indexed + + + +