--- /dev/null
+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 <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
+ * @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;
+ }
+}
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" ) )
}
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 );
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";
out.println( "\">" );
out.print( missingUrl.toString() );
out.println( "</a></p>" );
+
+ if ( t != null )
+ {
+ out.println( "<pre>" );
+ t.printStackTrace( out );
+ out.println( "</pre>" );
+ }
out.println( "</body></html>" );
}
}
- 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
- {
-
- 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 )
+ if ( fetchMetadataFromProxies( request, resource ) )
{
- 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;
}
}
}
}
+ 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
// Invalid POM : ignore
}
}
+
+ @Override
+ public void setUseIndexHtml( boolean useIndexHtml )
+ {
+ super.setUseIndexHtml( useIndexHtml );
+ davServer.setUseIndexHtml( useIndexHtml );
+ }
public ManagedRepositoryContent getRepository()
{
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 )
{
--- /dev/null
+# 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 <http://www.iana.org/assignments/media-types/>.
+
+# 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
* 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 <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
+ * @version $Id$
+ */
public class RepositoryServletTest
extends PlexusTestCase
{
{
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 );
}
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;
}
}
<lifecycle-handler>basic</lifecycle-handler>
</component>
+ <!--
+ | Configuration
+ -->
+ <component>
+ <role>org.apache.maven.archiva.configuration.ArchivaConfiguration</role>
+ <implementation>org.apache.maven.archiva.configuration.DefaultArchivaConfiguration</implementation>
+ <requirements>
+ <requirement>
+ <role>org.codehaus.plexus.registry.Registry</role>
+ <role-hint>configured</role-hint>
+ </requirement>
+ </requirements>
+ </component>
+ <component>
+ <role>org.codehaus.plexus.registry.Registry</role>
+ <role-hint>configured</role-hint>
+ <implementation>org.codehaus.plexus.registry.commons.CommonsConfigurationRegistry</implementation>
+ <configuration>
+ <properties>
+ <system/>
+ <xml fileName="${appserver.base}/conf/archiva.xml"
+ config-name="org.apache.maven.archiva.base" config-at="org.apache.maven.archiva"/>
+ </properties>
+ </configuration>
+ </component>
+
<component>
<role>org.codehaus.plexus.webdav.DavServerManager</role>
<role-hint>default</role-hint>
<implementation>org.codehaus.plexus.webdav.DefaultDavServerManager</implementation>
+ <description>DefaultDavServerManager</description>
<configuration>
<provider-hint>proxied</provider-hint>
</configuration>
</component>
-
+
+ <component>
+ <role>org.codehaus.plexus.cache.Cache</role>
+ <role-hint>url-failures-cache</role-hint>
+ <implementation>org.codehaus.plexus.cache.ehcache.EhcacheCache</implementation>
+ <description>URL Failure Cache</description>
+ <configuration>
+ <disk-expiry-thread-interval-seconds>600</disk-expiry-thread-interval-seconds>
+ <disk-persistent>false</disk-persistent> <!--disabling disk persistence for unit testing. -->
+ <disk-store-path>${java.io.tmpdir}/archiva/urlcache</disk-store-path>
+ <eternal>false</eternal>
+ <max-elements-in-memory>1000</max-elements-in-memory>
+ <memory-eviction-policy>LRU</memory-eviction-policy>
+ <name>url-failures-cache</name>
+ <overflow-to-disk>false</overflow-to-disk>
+ <!-- 45 minutes = 2700 seconds -->
+ <time-to-idle-seconds>2700</time-to-idle-seconds>
+ <!-- 30 minutes = 1800 seconds -->
+ <time-to-live-seconds>1800</time-to-live-seconds>
+ </configuration>
+ </component>
+
+
<!-- Don't drag in the world just to test this -->
<component>
<role>org.apache.maven.archiva.repository.scanner.RepositoryContentConsumers</role>
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ ~ 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.
+ -->
+
+<configuration>
+
+ <version>2</version>
+
+ <repositoryScanning>
+ <fileTypes>
+ <fileType>
+ <id>artifacts</id>
+ <patterns>
+ <pattern>**/*.pom</pattern>
+ <pattern>**/*.jar</pattern>
+ <pattern>**/*.ear</pattern>
+ <pattern>**/*.war</pattern>
+ <pattern>**/*.car</pattern>
+ <pattern>**/*.sar</pattern>
+ <pattern>**/*.mar</pattern>
+ <pattern>**/*.rar</pattern>
+ <pattern>**/*.dtd</pattern>
+ <pattern>**/*.tld</pattern>
+ <pattern>**/*.tar.gz</pattern>
+ <pattern>**/*.tar.bz2</pattern>
+ <pattern>**/*.zip</pattern>
+ </patterns>
+ </fileType>
+ <fileType>
+ <id>indexable-content</id>
+ <patterns>
+ <pattern>**/*.txt</pattern>
+ <pattern>**/*.TXT</pattern>
+ <pattern>**/*.block</pattern>
+ <pattern>**/*.config</pattern>
+ <pattern>**/*.pom</pattern>
+ <pattern>**/*.xml</pattern>
+ <pattern>**/*.xsd</pattern>
+ <pattern>**/*.dtd</pattern>
+ <pattern>**/*.tld</pattern>
+ </patterns>
+ </fileType>
+ <fileType>
+ <id>auto-remove</id>
+ <patterns>
+ <pattern>**/*.bak</pattern>
+ <pattern>**/*~</pattern>
+ <pattern>**/*-</pattern>
+ </patterns>
+ </fileType>
+ <fileType>
+ <id>ignored</id>
+ <patterns>
+ <pattern>**/.htaccess</pattern>
+ <pattern>**/KEYS</pattern>
+ <pattern>**/*.rb</pattern>
+ <pattern>**/*.sh</pattern>
+ <pattern>**/.svn/**</pattern>
+ <pattern>**/.DAV/**</pattern>
+ </patterns>
+ </fileType>
+ </fileTypes>
+ <knownContentConsumers>
+ <knownContentConsumer>update-db-artifact</knownContentConsumer>
+ <knownContentConsumer>create-missing-checksums</knownContentConsumer>
+ <knownContentConsumer>update-db-repository-metadata</knownContentConsumer>
+ <knownContentConsumer>validate-checksum</knownContentConsumer>
+ <knownContentConsumer>validate-signature</knownContentConsumer>
+ <knownContentConsumer>index-content</knownContentConsumer>
+ <knownContentConsumer>auto-remove</knownContentConsumer>
+ <knownContentConsumer>auto-rename</knownContentConsumer>
+ </knownContentConsumers>
+ <invalidContentConsumers>
+ <invalidContentConsumer>update-db-bad-content</invalidContentConsumer>
+ </invalidContentConsumers>
+ </repositoryScanning>
+
+ <databaseScanning>
+ <cronExpression>0 0 * * ?</cronExpression>
+ <unprocessedConsumers>
+ <unprocessedConsumer>index-artifact</unprocessedConsumer>
+ <unprocessedConsumer>update-db-project</unprocessedConsumer>
+ <unprocessedConsumer>validate-repository-metadata</unprocessedConsumer>
+ <unprocessedConsumer>index-archive-toc</unprocessedConsumer>
+ <unprocessedConsumer>update-db-bytecode-stats</unprocessedConsumer>
+ <unprocessedConsumer>index-public-methods</unprocessedConsumer>
+ </unprocessedConsumers>
+ <cleanupConsumers>
+ <cleanupConsumer>not-present-remove-db-artifact</cleanupConsumer>
+ <cleanupConsumer>not-present-remove-db-project</cleanupConsumer>
+ <cleanupConsumer>not-present-remove-indexed</cleanupConsumer>
+ </cleanupConsumers>
+ </databaseScanning>
+
+</configuration>