Browse files

Merge remote-tracking branch 'origin/master' into nexus-5368-stale-co…

…nnections
  • Loading branch information...
2 parents ffd25cc + 17aa13f commit effb7c343aacb84c1650fb31737d332bec6009c3 @cstamas cstamas committed Nov 23, 2012
View
2 nexus/nexus-api/src/main/java/org/sonatype/nexus/proxy/item/ReadLockingContentLocator.java
@@ -66,7 +66,7 @@ public InputStream getContent()
// ==
- private class ReadLockingInputStream
+ private static class ReadLockingInputStream
extends WrappingInputStream
{
private volatile RepositoryItemUidLock lock;
View
14 nexus/nexus-app/pom.xml
@@ -39,6 +39,10 @@
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </dependency>
+ <dependency>
<groupId>org.sonatype.nexus</groupId>
<artifactId>nexus-oss-edition</artifactId>
</dependency>
@@ -115,16 +119,6 @@
<scope>test</scope>
</dependency>
<dependency>
- <groupId>org.restlet</groupId>
- <artifactId>org.restlet</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>com.noelios.restlet</groupId>
- <artifactId>com.noelios.restlet</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
<groupId>org.sonatype.sisu.pr</groupId>
<artifactId>sisu-pr-testutil</artifactId>
<scope>test</scope>
View
29 .../java/org/sonatype/nexus/repositories/metadata/DefaultNexusRepositoryMetadataHandler.java
@@ -16,14 +16,14 @@
import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.component.annotations.Requirement;
+import org.sonatype.nexus.apachehttpclient.Hc4Provider;
import org.sonatype.nexus.logging.AbstractLoggingComponent;
import org.sonatype.nexus.proxy.NoSuchRepositoryException;
import org.sonatype.nexus.proxy.registry.RepositoryRegistry;
import org.sonatype.nexus.proxy.repository.Repository;
import org.sonatype.nexus.repository.metadata.MetadataHandlerException;
import org.sonatype.nexus.repository.metadata.RepositoryMetadataHandler;
import org.sonatype.nexus.repository.metadata.model.RepositoryMetadata;
-import org.sonatype.nexus.repository.metadata.restlet.RestletRawTransport;
@Component( role = NexusRepositoryMetadataHandler.class )
public class DefaultNexusRepositoryMetadataHandler
@@ -36,37 +36,34 @@
@Requirement
private RepositoryMetadataHandler repositoryMetadataHandler;
- public RepositoryMetadata readRemoteRepositoryMetadata( String url )
+ @Requirement
+ private Hc4Provider hc4Provider;
+
+ public RepositoryMetadata readRemoteRepositoryMetadata( final String url )
throws MetadataHandlerException,
IOException
{
- // TODO: honor global proxy? Current solution will neglect it
- RestletRawTransport restletRawTransport = new RestletRawTransport( url );
-
- return repositoryMetadataHandler.readRepositoryMetadata( restletRawTransport );
+ final Hc4RawTransport hc4RawTransport = new Hc4RawTransport( hc4Provider.createHttpClient(), url );
+ return repositoryMetadataHandler.readRepositoryMetadata( hc4RawTransport );
}
- public RepositoryMetadata readRepositoryMetadata( String repositoryId )
+ public RepositoryMetadata readRepositoryMetadata( final String repositoryId )
throws NoSuchRepositoryException,
MetadataHandlerException,
IOException
{
- Repository repository = repositoryRegistry.getRepository( repositoryId );
-
- NexusRawTransport nrt = new NexusRawTransport( repository, false, true );
-
+ final Repository repository = repositoryRegistry.getRepository( repositoryId );
+ final NexusRawTransport nrt = new NexusRawTransport( repository, false, true );
return repositoryMetadataHandler.readRepositoryMetadata( nrt );
}
- public void writeRepositoryMetadata( String repositoryId, RepositoryMetadata repositoryMetadata )
+ public void writeRepositoryMetadata( final String repositoryId, final RepositoryMetadata repositoryMetadata )
throws NoSuchRepositoryException,
MetadataHandlerException,
IOException
{
- Repository repository = repositoryRegistry.getRepository( repositoryId );
-
- NexusRawTransport nrt = new NexusRawTransport( repository, true, false );
-
+ final Repository repository = repositoryRegistry.getRepository( repositoryId );
+ final NexusRawTransport nrt = new NexusRawTransport( repository, true, false );
repositoryMetadataHandler.writeRepositoryMetadata( repositoryMetadata, nrt );
}
View
105 nexus/nexus-app/src/main/java/org/sonatype/nexus/repositories/metadata/Hc4RawTransport.java
@@ -0,0 +1,105 @@
+/**
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2007-2012 Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.repositories.metadata;
+
+import java.io.IOException;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPut;
+import org.apache.http.entity.ByteArrayEntity;
+import org.apache.http.entity.ContentType;
+import org.apache.http.util.EntityUtils;
+import org.sonatype.nexus.repository.metadata.RawTransport;
+import com.google.common.base.Preconditions;
+
+/**
+ * RawTransport implementation using HC4, and hence, obeying global proxy settings.
+ *
+ * @since 2.3
+ */
+public class Hc4RawTransport
+ implements RawTransport
+{
+
+ private final HttpClient httpClient;
+
+ private final String baseUrl;
+
+ public Hc4RawTransport( final HttpClient httpClient, final String baseUrl )
+ {
+ this.httpClient = Preconditions.checkNotNull( httpClient );
+ this.baseUrl = Preconditions.checkNotNull( baseUrl );
+ }
+
+ @Override
+ public byte[] readRawData( final String path )
+ throws IOException
+ {
+ final HttpGet get = new HttpGet( createUrlWithPath( path ) );
+ get.setHeader( "Accept", ContentType.APPLICATION_XML.getMimeType() );
+ final HttpResponse response = httpClient.execute( get );
+ try
+ {
+ final int statusCode = response.getStatusLine().getStatusCode();
+ if ( statusCode == 200 && response.getEntity() != null )
+ {
+ return EntityUtils.toByteArray( response.getEntity() );
+ }
+ else if ( statusCode == 404 )
+ {
+ return null;
+ }
+ else
+ {
+ throw new IOException( "The response was not successful: " + response.getStatusLine() );
+ }
+ }
+ finally
+ {
+ EntityUtils.consume( response.getEntity() );
+ }
+ }
+
+ @Override
+ public void writeRawData( final String path, final byte[] bytes )
+ throws IOException
+ {
+ final HttpPut put = new HttpPut( createUrlWithPath( path ) );
+ put.setEntity( new ByteArrayEntity( bytes, ContentType.APPLICATION_XML ) );
+ final HttpResponse response = httpClient.execute( put );
+ try
+ {
+ if ( response.getStatusLine().getStatusCode() > 299 )
+ {
+ throw new IOException( "The response was not successful: " + response.getStatusLine() );
+ }
+ }
+ finally
+ {
+ EntityUtils.consume( response.getEntity() );
+ }
+ }
+
+ // ==
+
+ protected String createUrlWithPath( String path )
+ {
+ while ( path.startsWith( "/" ) )
+ {
+ path = path.substring( 1 );
+ }
+ return baseUrl + ( baseUrl.endsWith( "/" ) ? "" : "/" ) + path;
+ }
+}
View
2 nexus/nexus-logging-extras/src/main/resources/META-INF/log/logback-nexus.xml
@@ -35,7 +35,7 @@
<logger name="org.sonatype.nexus.rest.NexusApplication" level="ERROR" />
<logger name="httpclient" level="INFO" />
<logger name="org.apache.http" level="INFO" />
- <logger name="org.restlet" level="WARN" />
+ <logger name="org.restlet" level="INFO" />
<logger name="org.apache.commons" level="WARN" />
<logger name="org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter" level="INFO" />
<logger name="org.apache.shiro.web.filter.mgt.DefaultFilterChainManager" level="INFO"/>
View
31 ...t/java/org/sonatype/nexus/integrationtests/nexus3615/Nexus3615ArtifactInfoSecurityIT.java
@@ -12,24 +12,24 @@
*/
package org.sonatype.nexus.integrationtests.nexus3615;
+import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasItems;
+import static org.hamcrest.Matchers.is;
import static org.sonatype.nexus.integrationtests.AbstractPrivilegeTest.TEST_USER_NAME;
import static org.sonatype.nexus.integrationtests.AbstractPrivilegeTest.TEST_USER_PASSWORD;
import java.io.IOException;
-import org.hamcrest.MatcherAssert;
+import org.apache.maven.index.artifact.Gav;
import org.restlet.data.MediaType;
import org.sonatype.nexus.integrationtests.TestContainer;
import org.sonatype.nexus.rest.model.ArtifactInfoResource;
import org.sonatype.nexus.test.utils.RoleMessageUtil;
import org.sonatype.nexus.test.utils.UserMessageUtil;
import org.sonatype.security.rest.model.RoleResource;
import org.sonatype.security.rest.model.UserResource;
-import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
-
import com.thoughtworks.xstream.XStream;
public class Nexus3615ArtifactInfoSecurityIT
@@ -110,24 +110,31 @@ protected void giveUserPrivilege( String userId, String priv )
public void checkViewAccess()
throws Exception
{
+ // force re-indexing to ensure that our artifact will be found by artifact info
+ final Gav gav = new Gav( "nexus3615", "artifact", "1.0" );
+ getSearchMessageUtil().reindexGAV( REPO_TEST_HARNESS_RELEASE_REPO, gav );
+ getSearchMessageUtil().reindexGAV( REPO_TEST_HARNESS_REPO2, gav );
+ getSearchMessageUtil().reindexGAV( REPO_TEST_HARNESS_REPO, gav );
+
this.giveUserRole( TEST_USER_NAME, "ui-search", true );
this.giveUserPrivilege( TEST_USER_NAME, "T1" ); // all m2 repo, read
this.giveUserPrivilege( TEST_USER_NAME, "repository-" + REPO_TEST_HARNESS_REPO );
TestContainer.getInstance().getTestContext().setUsername( TEST_USER_NAME );
TestContainer.getInstance().getTestContext().setPassword( TEST_USER_PASSWORD );
- ArtifactInfoResource info =
- getSearchMessageUtil().getInfo( REPO_TEST_HARNESS_REPO, "nexus3615/artifact/1.0/artifact-1.0.jar" );
+ final ArtifactInfoResource info = getSearchMessageUtil().getInfo(
+ REPO_TEST_HARNESS_REPO, "nexus3615/artifact/1.0/artifact-1.0.jar"
+ );
- Assert.assertEquals( REPO_TEST_HARNESS_REPO, info.getRepositoryId() );
- Assert.assertEquals( "/nexus3615/artifact/1.0/artifact-1.0.jar", info.getRepositoryPath() );
- Assert.assertEquals( "b354a0022914a48daf90b5b203f90077f6852c68", info.getSha1Hash() );
+ assertThat( info.getRepositoryId(), is( REPO_TEST_HARNESS_REPO ) );
+ assertThat( info.getRepositoryPath(), is( "/nexus3615/artifact/1.0/artifact-1.0.jar" ) );
+ assertThat( info.getSha1Hash(), is( "b354a0022914a48daf90b5b203f90077f6852c68" ) );
// view priv no longer controls search results, only read priv
- Assert.assertEquals( 3, info.getRepositories().size() );
- MatcherAssert.assertThat( getRepositoryId( info.getRepositories() ), hasItems( REPO_TEST_HARNESS_REPO ) );
- Assert.assertEquals( "application/java-archive", info.getMimeType() );
- Assert.assertEquals( 1364, info.getSize() );
+ assertThat( info.getRepositories().size(), is( 3 ) );
+ assertThat( getRepositoryId( info.getRepositories() ), hasItems( REPO_TEST_HARNESS_REPO ) );
+ assertThat( info.getMimeType(), is( "application/java-archive" ) );
+ assertThat( info.getSize(), is( 1364L ) );
}
}
View
4 nexus/nexus-webapp/src/main/webapp/js/repoServer/RepoMaintPanel.js
@@ -205,7 +205,9 @@ Sonatype.repoServer.RepositoryPanel = function(config) {
header : 'Repository Path',
autoExpand : true,
renderer : function(s) {
- if (/^http(s)?:/.test(s)) {
+ if ( typeof s !== 'string' ) {
+ return '';
+ } else if (/^http(s)?:/.test(s)) {
return '<a href="' + s + ((s != null && (s.charAt(s.length)) == '/') ? '' : '/') + '" target="_blank">' + s + '</a>';
} else {
return '' + s;
View
7 nexus/nexus-webapp/src/main/webapp/style/Sonatype.css
@@ -513,3 +513,10 @@ button.st-icon-refresh {
.st-server-panel .x-panel-collapsed .x-panel-bwrap {
display: none;
}
+
+/*
+ * The combo box arrow is position:absolute, so afterText would overlap without the additional padding.
+ */
+.x-form-arrow-trigger + .form-label-after-field {
+ padding-left: 20px;
+}
View
8 ...gin/src/main/java/org/sonatype/nexus/rest/AbstractResourceStoreContentPlexusResource.java
@@ -195,10 +195,12 @@ public Object get( Context context, Request request, Response response, Variant
private void addNoCacheHeaders( final Response response )
{
- // NXCM-5155 Force browsers to not cache this page
+ // NEXUS-5155 Force browsers to not cache this page
final Series<Parameter> headers = ( (HttpResponse) response ).getHttpCall().getResponseHeaders();
- headers.add( "Pragma", "no-cache" );
- headers.add( "Cache-Control", "no-cache, no-store, max-age=0, must-revalidate" );
+ headers.add( "Pragma", "no-cache" ); // HTTP/1.0
+ headers.add( "Cache-Control", "no-cache, no-store, max-age=0, must-revalidate" ); // HTTP/1.1
+ headers.add( "Cache-Control", "post-check=0, pre-check=0" ); // MS IE
+ headers.add( "Expires", "0" ); // No caching on Proxies in between client and Nexus
}
@Override
View
7 ...s-restlet1x-plugin/src/main/java/org/sonatype/nexus/rest/IndexTemplatePlexusResource.java
@@ -44,6 +44,7 @@
import org.sonatype.nexus.Nexus;
import org.sonatype.nexus.plugins.rest.NexusIndexHtmlCustomizer;
import org.sonatype.nexus.plugins.restlet1x.BuildNumberService;
+import org.sonatype.plexus.rest.ReferenceFactory;
import org.sonatype.plexus.rest.representation.VelocityRepresentation;
import org.sonatype.plexus.rest.resource.AbstractPlexusResource;
import org.sonatype.plexus.rest.resource.ManagedPlexusResource;
@@ -58,6 +59,8 @@
{
private Nexus nexus;
+ private ReferenceFactory referenceFactory;
+
private Map<String, NexusIndexHtmlCustomizer> bundles;
private Velocity velocity;
@@ -68,13 +71,15 @@
@Inject
public IndexTemplatePlexusResource( final Map<String, NexusIndexHtmlCustomizer> bundles, final Nexus nexus,
+ final ReferenceFactory referenceFactory,
final @Named("${index.template.file:-templates/index.vm}") String templateFilename,
final Velocity velocity, final BuildNumberService buildNumberService )
{
this();
this.bundles = bundles;
this.nexus = nexus;
+ this.referenceFactory = referenceFactory;
this.templateFilename = templateFilename;
this.velocity = velocity;
this.buildNumberService = buildNumberService;
@@ -135,7 +140,7 @@ protected VelocityRepresentation render( Context context, Request request, Respo
templatingContext.put( "nexusVersion", nexus.getSystemStatus().getVersion() );
- templatingContext.put( "nexusRoot", request.getRootRef().toString() );
+ templatingContext.put( "nexusRoot", referenceFactory.getContextRoot(request).toString() );
// gather plugin stuff
View
2 ...estlet1x/nexus-restlet1x-plugin/src/main/java/org/sonatype/nexus/rest/RemoteIPFinder.java
@@ -92,7 +92,7 @@ private static String resolveIp( List<String> ipAddresses )
InetAddress ipAdd;
try
{
- ipAdd = InetAddress.getByAddress( ip.getBytes() );
+ ipAdd = InetAddress.getByName( ip );
}
catch ( UnknownHostException e )
{
View
2 nexus/plugins/restlet1x/nexus-restlet1x-plugin/src/main/resources/templates/index.vm
@@ -99,7 +99,7 @@
}
#foreach( $js in $pluginJsFiles )
- require([ '$nexusRoot/$js' ], init, errorCallback);
+ require([ '$js' ], init, errorCallback);
#end
});
</script>
View
34 ...et1x/nexus-restlet1x-plugin/src/test/java/org/sonatype/nexus/rest/RemoteIPFinderTest.java
@@ -0,0 +1,34 @@
+/**
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2007-2012 Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.rest;
+
+import javax.servlet.http.HttpServletRequest;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+import org.mockito.Mockito;
+
+public class RemoteIPFinderTest
+{
+ @Test
+ public void testResolveIP()
+ {
+ /*
+ * Broken resolveIP method always returned first element, check it now skips non-resolvable IPs:
+ */
+ HttpServletRequest request = Mockito.mock( HttpServletRequest.class );
+ Mockito.doReturn( "[missing],127.0.0.1,{unknown}" ).when( request ).getHeader( "X-Forwarded-For" );
+ Assert.assertEquals( "127.0.0.1", RemoteIPFinder.findIP( request ) );
+ }
+}
View
2 nexus/pom.xml
@@ -172,7 +172,7 @@
<jetty.version>8.1.8.v20121106</jetty.version>
<maven.version>3.0.4</maven.version>
<plexus-security.version>3.0-SNAPSHOT</plexus-security.version>
- <restlet.version>1.1.6-SONATYPE-5348-V4</restlet.version>
+ <restlet.version>1.1.6-SONATYPE-5348-V7</restlet.version>
<shiro.version>1.2.1</shiro.version>
<surefire.version>2.12.4</surefire.version>
<jackson.version>1.9.10</jackson.version>

0 comments on commit effb7c3

Please sign in to comment.