Bug 442576 - Allow to disable WebDav support

Added configuration property aether.connector.http.webDav[.repoId] to 
forcefully disable WebDAV mode during uploads


Project: http://git-wip-us.apache.org/repos/asf/maven-aether/repo
Commit: http://git-wip-us.apache.org/repos/asf/maven-aether/commit/cd3cb86f
Tree: http://git-wip-us.apache.org/repos/asf/maven-aether/tree/cd3cb86f
Diff: http://git-wip-us.apache.org/repos/asf/maven-aether/diff/cd3cb86f

Branch: refs/heads/master
Commit: cd3cb86f23644784e43b8fc2ae166b6a312b6073
Parents: 6ac187b
Author: Benjamin Bentmann <bentm...@sonatype.com>
Authored: Sat Aug 30 21:25:06 2014 +0200
Committer: Benjamin Bentmann <bentm...@sonatype.com>
Committed: Sat Aug 30 21:25:06 2014 +0200

----------------------------------------------------------------------
 .../aether/transport/http/HttpTransporter.java  | 36 +++++++++++++-------
 .../aether/transport/http/LocalState.java       | 30 +++++++++++++---
 .../aether/transport/http/HttpServer.java       | 25 ++++++++++----
 .../transport/http/HttpTransporterTest.java     | 33 ++++++++++++++++--
 4 files changed, 99 insertions(+), 25 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/maven-aether/blob/cd3cb86f/aether-transport-http/src/main/java/org/eclipse/aether/transport/http/HttpTransporter.java
----------------------------------------------------------------------
diff --git 
a/aether-transport-http/src/main/java/org/eclipse/aether/transport/http/HttpTransporter.java
 
b/aether-transport-http/src/main/java/org/eclipse/aether/transport/http/HttpTransporter.java
index 4e21949..a801373 100644
--- 
a/aether-transport-http/src/main/java/org/eclipse/aether/transport/http/HttpTransporter.java
+++ 
b/aether-transport-http/src/main/java/org/eclipse/aether/transport/http/HttpTransporter.java
@@ -1,5 +1,5 @@
 
/*******************************************************************************
- * Copyright (c) 2013 Sonatype, Inc.
+ * Copyright (c) 2013, 2014 Sonatype, Inc.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -304,26 +304,38 @@ final class HttpTransporter
     private void prepare( HttpUriRequest request, SharingHttpContext context )
     {
         boolean put = HttpPut.METHOD_NAME.equalsIgnoreCase( 
request.getMethod() );
-        if ( state.getWebDav() == null && ( put || isPayloadPresent( request ) 
) )
+        if ( ( put || isPayloadPresent( request ) ) && !state.isProbed() )
         {
-            try
-            {
-                HttpOptions req = commonHeaders( new HttpOptions( 
request.getURI() ) );
-                HttpResponse response = client.execute( server, req, context );
-                state.setWebDav( isWebDav( response ) );
-                EntityUtils.consumeQuietly( response.getEntity() );
-            }
-            catch ( IOException e )
+            synchronized ( state )
             {
-                logger.debug( "Failed to prepare HTTP context", e );
+                if ( !state.isProbed() )
+                {
+                    probe( request, context );
+                    state.setProbed();
+                }
             }
         }
-        if ( put && Boolean.TRUE.equals( state.getWebDav() ) )
+        if ( put && state.isWebDav() )
         {
             mkdirs( request.getURI(), context );
         }
     }
 
+    private void probe( HttpUriRequest request, SharingHttpContext context )
+    {
+        try
+        {
+            HttpOptions req = commonHeaders( new HttpOptions( request.getURI() 
) );
+            HttpResponse response = client.execute( server, req, context );
+            state.setWebDav( isWebDav( response ) );
+            EntityUtils.consumeQuietly( response.getEntity() );
+        }
+        catch ( IOException e )
+        {
+            logger.debug( "Failed to probe HTTP server", e );
+        }
+    }
+
     private boolean isWebDav( HttpResponse response )
     {
         return response.containsHeader( HttpHeaders.DAV );

http://git-wip-us.apache.org/repos/asf/maven-aether/blob/cd3cb86f/aether-transport-http/src/main/java/org/eclipse/aether/transport/http/LocalState.java
----------------------------------------------------------------------
diff --git 
a/aether-transport-http/src/main/java/org/eclipse/aether/transport/http/LocalState.java
 
b/aether-transport-http/src/main/java/org/eclipse/aether/transport/http/LocalState.java
index 8275973..1cc771d 100644
--- 
a/aether-transport-http/src/main/java/org/eclipse/aether/transport/http/LocalState.java
+++ 
b/aether-transport-http/src/main/java/org/eclipse/aether/transport/http/LocalState.java
@@ -1,5 +1,5 @@
 
/*******************************************************************************
- * Copyright (c) 2013 Sonatype, Inc.
+ * Copyright (c) 2013, 2014 Sonatype, Inc.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -20,6 +20,7 @@ import org.apache.http.conn.ClientConnectionManager;
 import org.eclipse.aether.RepositorySystemSession;
 import org.eclipse.aether.repository.RemoteRepository;
 import org.eclipse.aether.transport.http.GlobalState.CompoundKey;
+import org.eclipse.aether.util.ConfigUtils;
 
 /**
  * Container for HTTP-related state that can be shared across invocations of 
the transporter to optimize the
@@ -29,6 +30,8 @@ final class LocalState
     implements Closeable
 {
 
+    private static final String CONFIG_PROP_WEBDAV = 
"aether.connector.http.webDav";
+
     private final GlobalState global;
 
     private final ClientConnectionManager connMgr;
@@ -39,6 +42,8 @@ final class LocalState
 
     private final CompoundKey expectContinueKey;
 
+    private volatile boolean probed;
+
     private volatile Boolean expectContinue;
 
     private volatile Boolean webDav;
@@ -63,6 +68,10 @@ final class LocalState
             expectContinueKey = new CompoundKey( repo.getUrl(), 
repo.getProxy() );
             authSchemePools = global.getAuthSchemePools();
         }
+        if ( !ConfigUtils.getBoolean( session, true, CONFIG_PROP_WEBDAV + '.' 
+ repo.getId(), CONFIG_PROP_WEBDAV ) )
+        {
+            webDav = false;
+        }
     }
 
     public ClientConnectionManager getConnectionManager()
@@ -88,6 +97,16 @@ final class LocalState
         }
     }
 
+    public boolean isProbed()
+    {
+        return probed;
+    }
+
+    public void setProbed()
+    {
+        probed = true;
+    }
+
     public boolean isExpectContinue()
     {
         if ( expectContinue == null )
@@ -107,14 +126,17 @@ final class LocalState
         }
     }
 
-    public Boolean getWebDav()
+    public boolean isWebDav()
     {
-        return webDav;
+        return Boolean.TRUE.equals( webDav );
     }
 
     public void setWebDav( boolean webDav )
     {
-        this.webDav = webDav;
+        if ( this.webDav == null )
+        {
+            this.webDav = webDav;
+        }
     }
 
     public AuthScheme getAuthScheme( HttpHost host )

http://git-wip-us.apache.org/repos/asf/maven-aether/blob/cd3cb86f/aether-transport-http/src/test/java/org/eclipse/aether/transport/http/HttpServer.java
----------------------------------------------------------------------
diff --git 
a/aether-transport-http/src/test/java/org/eclipse/aether/transport/http/HttpServer.java
 
b/aether-transport-http/src/test/java/org/eclipse/aether/transport/http/HttpServer.java
index a0f6a54..60f316a 100644
--- 
a/aether-transport-http/src/test/java/org/eclipse/aether/transport/http/HttpServer.java
+++ 
b/aether-transport-http/src/test/java/org/eclipse/aether/transport/http/HttpServer.java
@@ -72,9 +72,22 @@ public class HttpServer
 
     }
 
+    public enum WebDav
+    {
+        /** DAV header advertised, MKCOL required for missing parent 
directories */
+        REQUIRED,
+        /** DAV header advertised, MKCOL supported but not required */
+        OPTIONAL
+    }
+
     public enum ExpectContinue
     {
-        FAIL, PROPER, BROKEN
+        /** reject request with "Expectation Failed" */
+        FAIL,
+        /** send "Continue" only if request made it past authentication */
+        PROPER,
+        /** send "Continue" before authentication has been checked */
+        BROKEN
     }
 
     public enum ChecksumHeader
@@ -90,7 +103,7 @@ public class HttpServer
 
     private boolean rangeSupport = true;
 
-    private boolean webDav;
+    private WebDav webDav;
 
     private ExpectContinue expectContinue = ExpectContinue.PROPER;
 
@@ -186,7 +199,7 @@ public class HttpServer
         return this;
     }
 
-    public HttpServer setWebDav( boolean webDav )
+    public HttpServer setWebDav( WebDav webDav )
     {
         this.webDav = webDav;
         return this;
@@ -405,7 +418,7 @@ public class HttpServer
             }
             else if ( HttpMethods.PUT.equals( req.getMethod() ) )
             {
-                if ( !webDav )
+                if ( !WebDav.REQUIRED.equals( webDav ) )
                 {
                     file.getParentFile().mkdirs();
                 }
@@ -437,14 +450,14 @@ public class HttpServer
             }
             else if ( HttpMethods.OPTIONS.equals( req.getMethod() ) )
             {
-                if ( webDav )
+                if ( webDav != null )
                 {
                     response.setHeader( "DAV", "1,2" );
                 }
                 response.setHeader( HttpHeaders.ALLOW, "GET, PUT, HEAD, 
OPTIONS" );
                 response.setStatus( HttpServletResponse.SC_OK );
             }
-            else if ( webDav && "MKCOL".equals( req.getMethod() ) )
+            else if ( webDav != null && "MKCOL".equals( req.getMethod() ) )
             {
                 if ( file.exists() )
                 {

http://git-wip-us.apache.org/repos/asf/maven-aether/blob/cd3cb86f/aether-transport-http/src/test/java/org/eclipse/aether/transport/http/HttpTransporterTest.java
----------------------------------------------------------------------
diff --git 
a/aether-transport-http/src/test/java/org/eclipse/aether/transport/http/HttpTransporterTest.java
 
b/aether-transport-http/src/test/java/org/eclipse/aether/transport/http/HttpTransporterTest.java
index 8a36861..14ec31e 100644
--- 
a/aether-transport-http/src/test/java/org/eclipse/aether/transport/http/HttpTransporterTest.java
+++ 
b/aether-transport-http/src/test/java/org/eclipse/aether/transport/http/HttpTransporterTest.java
@@ -64,6 +64,8 @@ public class HttpTransporterTest
         System.setProperty( "javax.net.ssl.keyStorePassword", "client-pwd" );
     }
 
+    private static final String REPO_ID = "test";
+
     @Rule
     public TestName testName = new TestName();
 
@@ -83,7 +85,7 @@ public class HttpTransporterTest
 
     private RemoteRepository newRepo( String url )
     {
-        return new RemoteRepository.Builder( "test", "default", url 
).setAuthentication( auth ).setProxy( proxy ).build();
+        return new RemoteRepository.Builder( REPO_ID, "default", url 
).setAuthentication( auth ).setProxy( proxy ).build();
     }
 
     private void newTransporter( String url )
@@ -406,7 +408,7 @@ public class HttpTransporterTest
     public void testGet_WebDav()
         throws Exception
     {
-        httpServer.setWebDav( true );
+        httpServer.setWebDav( HttpServer.WebDav.REQUIRED );
         RecordingTransportListener listener = new RecordingTransportListener();
         GetTask task = new GetTask( URI.create( "repo/dir/file.txt" ) 
).setListener( listener );
         ( (HttpTransporter) transporter ).getState().setWebDav( true );
@@ -801,7 +803,7 @@ public class HttpTransporterTest
     public void testPut_WebDav()
         throws Exception
     {
-        httpServer.setWebDav( true );
+        httpServer.setWebDav( HttpServer.WebDav.REQUIRED );
         RecordingTransportListener listener = new RecordingTransportListener();
         PutTask task =
             new PutTask( URI.create( "repo/dir1/dir2/file.txt" ) 
).setListener( listener ).setDataString( "upload" );
@@ -824,6 +826,31 @@ public class HttpTransporterTest
     }
 
     @Test
+    public void testPut_WebDavOptional_ManuallyDisabled()
+        throws Exception
+    {
+        session.setConfigProperty( "aether.connector.http.webDav." + REPO_ID, 
"false" );
+        httpServer.setWebDav( HttpServer.WebDav.OPTIONAL );
+        httpServer.setAuthentication( "testuser", "testpass" );
+        auth = new AuthenticationBuilder().addUsername( "testuser" 
).addPassword( "testpass" ).build();
+        newTransporter( httpServer.getHttpUrl() );
+        RecordingTransportListener listener = new RecordingTransportListener();
+        PutTask task =
+            new PutTask( URI.create( "repo/dir1/dir2/file.txt" ) 
).setListener( listener ).setDataString( "upload" );
+        transporter.put( task );
+        assertEquals( 0, listener.dataOffset );
+        assertEquals( 6, listener.dataLength );
+        assertEquals( 1, listener.startedCount );
+        assertTrue( "Count: " + listener.progressedCount, 
listener.progressedCount > 0 );
+        assertEquals( "upload", TestFileUtils.readString( new File( repoDir, 
"dir1/dir2/file.txt" ) ) );
+
+        assertEquals( httpServer.getLogEntries().toString(), 3, 
httpServer.getLogEntries().size() );
+        assertEquals( "OPTIONS", httpServer.getLogEntries().get( 0 ).method );
+        assertEquals( "OPTIONS", httpServer.getLogEntries().get( 1 ).method );
+        assertEquals( "PUT", httpServer.getLogEntries().get( 2 ).method );
+    }
+
+    @Test
     public void testPut_FileHandleLeak()
         throws Exception
     {

Reply via email to