[exo-jcr-commits] exo-jcr SVN: r4038 - in jcr/trunk/exo.jcr.component.webdav/src: main/java/org/exoplatform/services/jcr/webdav/command and 1 other directories.

do-not-reply at jboss.org do-not-reply at jboss.org
Wed Mar 2 03:08:02 EST 2011


Author: dkuleshov
Date: 2011-03-02 03:08:02 -0500 (Wed, 02 Mar 2011)
New Revision: 4038

Modified:
   jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/WebDavServiceImpl.java
   jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/CopyCommand.java
   jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/MoveCommand.java
   jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestCopy.java
   jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestMove.java
Log:
EXOJCR-1217: fixed COPY, MOVE methods parsing 'destination' header 

Modified: jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/WebDavServiceImpl.java
===================================================================
--- jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/WebDavServiceImpl.java	2011-03-01 21:30:45 UTC (rev 4037)
+++ jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/WebDavServiceImpl.java	2011-03-02 08:08:02 UTC (rev 4038)
@@ -73,6 +73,7 @@
 import java.io.InputStream;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Method;
+import java.net.URI;
 import java.net.URLEncoder;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -466,6 +467,8 @@
       @HeaderParam(ExtHttpHeaders.DEPTH) String depthHeader,
       @HeaderParam(ExtHttpHeaders.OVERWRITE) String overwriteHeader, @Context UriInfo uriInfo, HierarchicalProperty body)
    {
+      // to trace if an item on destination path exists
+      boolean itemExisted = false;
 
       if (log.isDebugEnabled())
       {
@@ -478,17 +481,27 @@
       {
          String serverURI = uriInfo.getBaseUriBuilder().path(getClass()).path(repoName).build().toString();
 
-         destinationHeader = TextUtil.unescape(destinationHeader, '%');
+         URI dest = new URI(destinationHeader);
+         URI base = new URI(serverURI);
 
-         if (!destinationHeader.startsWith(serverURI))
+         String destPath = dest.getPath();
+         int repoIndex = destPath.indexOf(repoName);
+
+         // check if destination corresponds to base uri
+         // if the destination is on another server
+         // or destination header is malformed
+         // we return BAD_GATEWAY(502) HTTP status
+         // more info here http://www.webdav.org/specs/rfc2518.html#METHOD_COPY
+         if (!base.getHost().equals(dest.getHost()) || repoIndex == -1)
          {
             return Response.status(HTTPStatus.BAD_GATEWAY).entity("Bad Gateway").build();
          }
 
+         destPath = normalizePath(dest.getPath().substring(repoIndex + repoName.length() + 1));
+
          String srcWorkspace = workspaceName(repoPath);
          String srcNodePath = path(repoPath);
 
-         String destPath = destinationHeader.substring(serverURI.length() + 1);
          String destWorkspace = workspaceName(destPath);
          String destNodePath = path(destPath);
 
@@ -500,7 +513,8 @@
 
          if (overwrite)
          {
-            delete(repoName, destPath, lockTokenHeader, ifHeader);
+            Response delResponse = delete(repoName, destPath, lockTokenHeader, ifHeader);
+            itemExisted = (delResponse.getStatus() == HTTPStatus.NO_CONTENT);
          }
          else
          {
@@ -519,12 +533,14 @@
             if (srcWorkspace.equals(destWorkspace))
             {
                Session session = session(repoName, destWorkspace, lockTokens);
-               return new CopyCommand(uriInfo.getBaseUriBuilder().path(getClass()).path(repoName)).copy(session,
+               return new CopyCommand(uriInfo.getBaseUriBuilder().path(getClass()).path(repoName), itemExisted).copy(
+                  session,
                   srcNodePath, destNodePath);
             }
 
             Session destSession = session(repoName, destWorkspace, lockTokens);
-            return new CopyCommand(uriInfo.getBaseUriBuilder().path(getClass()).path(repoName)).copy(destSession,
+            return new CopyCommand(uriInfo.getBaseUriBuilder().path(getClass()).path(repoName), itemExisted).copy(
+               destSession,
                srcWorkspace, srcNodePath, destNodePath);
 
          }
@@ -857,7 +873,9 @@
       @HeaderParam(ExtHttpHeaders.DEPTH) String depthHeader,
       @HeaderParam(ExtHttpHeaders.OVERWRITE) String overwriteHeader, @Context UriInfo uriInfo, HierarchicalProperty body)
    {
-
+      // to trace if an item on destination path exists
+      boolean itemExisted = false;
+      
       if (log.isDebugEnabled())
       {
          log.debug("MOVE " + repoName + "/" + repoPath);
@@ -869,14 +887,25 @@
       {
          String serverURI = uriInfo.getBaseUriBuilder().path(getClass()).path(repoName).build().toString();
 
-         destinationHeader = TextUtil.unescape(destinationHeader, '%');
+         URI dest = new URI(destinationHeader);
+         URI base = new URI(serverURI);
+         
 
-         if (!destinationHeader.startsWith(serverURI))
+         String destPath = dest.getPath();
+         int repoIndex = destPath.indexOf(repoName);
+
+         // check if destination corresponds to base uri
+         // if the destination is on another server
+         // or destination header is malformed
+         // we return BAD_GATEWAY(502) HTTP status
+         // more info here http://www.webdav.org/specs/rfc2518.html#METHOD_MOVE
+         if (!base.getHost().equals(dest.getHost()) || repoIndex == -1)
          {
             return Response.status(HTTPStatus.BAD_GATEWAY).entity("Bad Gateway").build();
          }
+         
+         destPath = normalizePath(dest.getPath().substring(repoIndex + repoName.length() + 1));
 
-         String destPath = destinationHeader.substring(serverURI.length() + 1);
          String destWorkspace = workspaceName(destPath);
          String destNodePath = path(destPath);
 
@@ -891,7 +920,8 @@
 
          if (overwrite)
          {
-            delete(repoName, destPath, lockTokenHeader, ifHeader);
+            Response delResponse = delete(repoName, destPath, lockTokenHeader, ifHeader);
+            itemExisted = (delResponse.getStatus() == HTTPStatus.NO_CONTENT);
          }
          else
          {
@@ -911,13 +941,13 @@
             if (srcWorkspace.equals(destWorkspace))
             {
                Session session = session(repoName, srcWorkspace, lockTokens);
-               return new MoveCommand(uriInfo.getBaseUriBuilder().path(getClass()).path(repoName)).move(session,
+               return new MoveCommand(uriInfo.getBaseUriBuilder().path(getClass()).path(repoName), itemExisted).move(session,
                   srcNodePath, destNodePath);
             }
 
             Session srcSession = session(repoName, srcWorkspace, lockTokens);
             Session destSession = session(repoName, destWorkspace, lockTokens);
-            return new MoveCommand(uriInfo.getBaseUriBuilder().path(getClass()).path(repoName)).move(srcSession,
+            return new MoveCommand(uriInfo.getBaseUriBuilder().path(getClass()).path(repoName), itemExisted).move(srcSession,
                destSession, srcNodePath, destNodePath);
          }
          else

Modified: jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/CopyCommand.java
===================================================================
--- jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/CopyCommand.java	2011-03-01 21:30:45 UTC (rev 4037)
+++ jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/CopyCommand.java	2011-03-02 08:08:02 UTC (rev 4038)
@@ -54,21 +54,34 @@
    private final UriBuilder uriBuilder;
 
    /**
+    * To trace if an item on destination path existed. 
+    */
+   private final boolean itemExisted;
+
+   /**
     * Empty constructor
     */
    public CopyCommand()
    {
       this.uriBuilder = null;
+      this.itemExisted = false;
    }
 
    /**
-    * Constructor
+    * Here we pass URI builder and info about pre-existence of item on the move
+    * destination path If an item existed, we must respond with NO_CONTENT (204)
+    * HTTP status.
+    * If an item did not exist, we must respond with CREATED (201) HTTP status
+    * More info can be found <a
+    * href=http://www.webdav.org/specs/rfc2518.html#METHOD_MOVE>here</a>.
     * 
     * @param uriBuilder - provide data used in 'location' header
+    * @param itemExisted - indicates if an item existed on copy destination
     */
-   public CopyCommand(UriBuilder uriBuilder)
+   public CopyCommand(UriBuilder uriBuilder, boolean itemExisted)
    {
       this.uriBuilder = uriBuilder;
+      this.itemExisted = itemExisted;
    }
 
    /**
@@ -85,13 +98,26 @@
       {
          Workspace workspace = destSession.getWorkspace();
          workspace.copy(sourcePath, destPath);
-         if (uriBuilder != null)
+
+         // If the source resource was successfully moved
+         // to a pre-existing destination resource.
+         if (itemExisted)
          {
-            return Response.created(uriBuilder.path(workspace.getName()).path(destPath).build()).build();
+            return Response.noContent().build();
          }
+         // If the source resource was successfully moved,
+         // and a new resource was created at the destination.
+         else
+         {
+            if (uriBuilder != null)
+            {
+               return Response.created(uriBuilder.path(workspace.getName()).path(destPath).build()).build();
+            }
 
-         // to save compatibility if uribuilder is not provided
-         return Response.status(HTTPStatus.CREATED).build();
+            // to save compatibility if uribuilder is not provided
+            return Response.status(HTTPStatus.CREATED).build();
+         }
+
       }
       catch (ItemExistsException e)
       {
@@ -131,13 +157,26 @@
       {
          Workspace destWorkspace = destSession.getWorkspace();
          destWorkspace.copy(sourceWorkspace, sourcePath, destPath);
-         if (uriBuilder != null)
+
+         // If the source resource was successfully moved
+         // to a pre-existing destination resource.
+         if (itemExisted)
          {
-            return Response.created(uriBuilder.path(destWorkspace.getName()).path(destPath).build()).build();
+            return Response.noContent().build();
          }
+         // If the source resource was successfully moved,
+         // and a new resource was created at the destination.
+         else
+         {
+            if (uriBuilder != null)
+            {
+               return Response.created(uriBuilder.path(destWorkspace.getName()).path(destPath).build()).build();
+            }
 
-         // to save compatibility if uriBuilder is not provided
-         return Response.status(HTTPStatus.CREATED).build();
+            // to save compatibility if uriBuilder is not provided
+            return Response.status(HTTPStatus.CREATED).build();
+         }
+
       }
       catch (ItemExistsException e)
       {

Modified: jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/MoveCommand.java
===================================================================
--- jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/MoveCommand.java	2011-03-01 21:30:45 UTC (rev 4037)
+++ jcr/trunk/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/command/MoveCommand.java	2011-03-02 08:08:02 UTC (rev 4038)
@@ -53,6 +53,11 @@
     * Provides URI information needed for 'location' header in 'CREATED' response
     */
    private final UriBuilder uriBuilder;
+   
+   /**
+    * To trace if an item on destination path existed. 
+    */
+   private final boolean itemExisted;
 
    // Fix problem with moving under Windows Explorer.
    static
@@ -66,16 +71,23 @@
    public MoveCommand()
    {
       this.uriBuilder = null;
+      this.itemExisted = false;
    }
 
    /**
-    * Constructor to receive URI Info
-    * 
+    * Here we pass URI builder and info about pre-existence of item on the move
+    * destination path If an item existed, we must respond with NO_CONTENT (204)
+    * HTTP status.
+    * If an item did not exist, we must respond with CREATED (201) HTTP status
+    * More info can be found <a
+    * href=http://www.webdav.org/specs/rfc2518.html#METHOD_MOVE>here</a>.
     * @param uriBuilder - provide data used in 'location' header
+    * @param itemExisted - indicates if an item existed on copy destination
     */
-   public MoveCommand(UriBuilder uriBuilder)
+   public MoveCommand(UriBuilder uriBuilder, boolean itemExisted)
    {
       this.uriBuilder = uriBuilder;
+      this.itemExisted = itemExisted;
    }
 
    /**
@@ -90,20 +102,17 @@
    {
       try
       {
-
-         boolean itemExisted = session.itemExists(destPath);
-         if (itemExisted)
-         {
-            session.getItem(destPath).remove();
-         }
-
          session.move(srcPath, destPath);
          session.save();
 
+         // If the source resource was successfully moved
+         // to a pre-existing destination resource.
          if (itemExisted)
          {
             return Response.status(HTTPStatus.NO_CONTENT).cacheControl(cacheControl).build();
          }
+         // If the source resource was successfully moved,
+         // and a new resource was created at the destination.
          else
          {
             if (uriBuilder != null)

Modified: jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestCopy.java
===================================================================
--- jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestCopy.java	2011-03-01 21:30:45 UTC (rev 4037)
+++ jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestCopy.java	2011-03-02 08:08:02 UTC (rev 4038)
@@ -41,6 +41,8 @@
 public class TestCopy extends BaseStandaloneTest
 {
 
+   static final String host = "http://localhost:8080";
+
    public void testeCopyForNonCollectionSingleWorkSpace() throws Exception
    {
       String content = TestUtils.getFileContent();
@@ -49,8 +51,8 @@
       TestUtils.addContent(session, filename, inputStream, defaultFileNodeType, "");
       String destFilename = TestUtils.getFileName();
       MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
-      headers.add(ExtHttpHeaders.DESTINATION, getPathWS() + destFilename);
-      ContainerResponse response = service(WebDAVMethods.COPY, getPathWS() + filename, "", headers, null);
+      headers.add(ExtHttpHeaders.DESTINATION, host + getPathWS() + destFilename);
+      ContainerResponse response = service(WebDAVMethods.COPY, getPathWS() + filename, host, headers, null);
       assertEquals(HTTPStatus.CREATED, response.getStatus());
       assertTrue(session.getRootNode().hasNode(TextUtil.relativizePath(destFilename)));
       Node nodeDest = session.getRootNode().getNode(TextUtil.relativizePath(destFilename));
@@ -79,8 +81,8 @@
       TestUtils.addContent(session, filename, inputStream, defaultFileNodeType, "");
       String destFilename = TestUtils.getFileName();
       MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
-      headers.add(ExtHttpHeaders.DESTINATION, getPathDestWS() + destFilename);
-      ContainerResponse response = service(WebDAVMethods.COPY, getPathWS() + filename, "", headers, null);
+      headers.add(ExtHttpHeaders.DESTINATION, host + getPathDestWS() + destFilename);
+      ContainerResponse response = service(WebDAVMethods.COPY, getPathWS() + filename, host, headers, null);
       assertEquals(HTTPStatus.CREATED, response.getStatus());
 
       assertTrue(destSession.getRootNode().hasNode(TextUtil.relativizePath(destFilename)));
@@ -118,18 +120,114 @@
 
       // prepare headers
       MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
-      headers.add(ExtHttpHeaders.DESTINATION, getPathWS() + destFilename);
+      headers.add(ExtHttpHeaders.DESTINATION, host + getPathWS() + destFilename);
 
       // execute query
-      ContainerResponse response = service(WebDAVMethods.COPY, getPathWS() + filename, "", headers, null);
+      ContainerResponse response = service(WebDAVMethods.COPY, getPathWS() + filename, host, headers, null);
       // check if operation completed successfully, we expect a new resource to be created
       assertEquals(HTTPStatus.CREATED, response.getStatus());
       // check if response 'CREATED' contains 'LOCATION' header
       assertTrue(response.getHttpHeaders().containsKey(ExtHttpHeaders.LOCATION));
       // check if 'CREATED' response 'LOCATION' header contains correct location path
-      assertEquals(getPathWS() + destFilename, response.getHttpHeaders().getFirst(ExtHttpHeaders.LOCATION).toString());
+      assertEquals(host + getPathWS() + destFilename, response.getHttpHeaders().getFirst(ExtHttpHeaders.LOCATION)
+         .toString());
    }
 
+   /**
+    * Testing for correct destination header parsing in COPY method.
+    * We pass a path which contains escaped space - "%20" 
+    * and escaped space with quote symbol "%20'"
+    * @throws Exception
+    */
+   public void testDestinationHeaderParsing() throws Exception
+   {
+      String content = TestUtils.getFileContent();
+      String filename = TestUtils.getFileName();
+      InputStream inputStream = new ByteArrayInputStream(content.getBytes());
+      TestUtils.addContent(session, filename, inputStream, defaultFileNodeType, "");
+
+      String destFilename = TestUtils.getFileName() + "%20test";
+
+      // prepare headers
+      MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
+      headers.add(ExtHttpHeaders.DESTINATION, host + getPathWS() + destFilename);
+
+      // execute the query
+      ContainerResponse response = service(WebDAVMethods.COPY, getPathWS() + filename, host, headers, null);
+      // check if operation completed successfully, we expect a new resource to be created
+      assertEquals(HTTPStatus.CREATED, response.getStatus());
+
+      filename = destFilename;
+
+      destFilename = TestUtils.getFileName() + "%20'test";
+
+      // prepare headers
+      headers = new MultivaluedMapImpl();
+      headers.add(ExtHttpHeaders.DESTINATION, host + getPathWS() + destFilename);
+
+      // execute the query
+      response = service(WebDAVMethods.COPY, getPathWS() + filename, host, headers, null);
+      // check if operation completed successfully, we expect a new resource to be created
+      assertEquals(HTTPStatus.CREATED, response.getStatus());
+
+   }
+
+   /**
+    * Testing for correct response after COPY a resource to the destination,
+    * where another resource already existed
+    * For more info see <a href=http://www.webdav.org/specs/rfc2518.html#METHOD_MOVE>this</a>.
+    * @throws Exception
+    */
+   public void testNoContentResponses() throws Exception
+   {
+      String content = TestUtils.getFileContent();
+      String filename = TestUtils.getFileName();
+      InputStream inputStream = new ByteArrayInputStream(content.getBytes());
+      TestUtils.addContent(session, filename, inputStream, defaultFileNodeType, "");
+
+      String destFilename = TestUtils.getFileName();
+      inputStream = new ByteArrayInputStream(content.getBytes());
+      TestUtils.addContent(session, destFilename, inputStream, defaultFileNodeType, "");
+
+      // prepare headers
+      MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
+      headers.add(ExtHttpHeaders.DESTINATION, host + getPathWS() + destFilename);
+      headers.add(ExtHttpHeaders.OVERWRITE, "T");
+
+      // execute the query
+      ContainerResponse response = service(WebDAVMethods.COPY, getPathWS() + filename, host, headers, null);
+      // check if operation completed successfully, we expect a new resource to be created
+      assertEquals(HTTPStatus.NO_CONTENT, response.getStatus());
+
+   }
+
+   /**
+    * Testing for correct destination header parsing using "https" 
+    * instead of usual "http" scheme.
+    * @throws Exception
+    */
+   public void testHttpsSchemeInDestinationHeaderParsing() throws Exception
+   {
+      String httpsHost = "https://localhost:8080";
+
+      String content = TestUtils.getFileContent();
+      String filename = TestUtils.getFileName();
+      InputStream inputStream = new ByteArrayInputStream(content.getBytes());
+      TestUtils.addContent(session, filename, inputStream, defaultFileNodeType, "");
+
+      String destFilename = TestUtils.getFileName();
+
+      // prepare headers
+      MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
+      headers.add(ExtHttpHeaders.DESTINATION, httpsHost + getPathWS() + destFilename);
+
+      // execute the query
+      ContainerResponse response = service(WebDAVMethods.COPY, getPathWS() + filename, host, headers, null);
+      // check if operation completed successfully, we expect a new resource to be created
+      assertEquals(HTTPStatus.CREATED, response.getStatus());
+
+   }
+
    @Override
    protected String getRepositoryName()
    {

Modified: jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestMove.java
===================================================================
--- jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestMove.java	2011-03-01 21:30:45 UTC (rev 4037)
+++ jcr/trunk/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestMove.java	2011-03-02 08:08:02 UTC (rev 4038)
@@ -40,6 +40,7 @@
  */
 public class TestMove extends BaseStandaloneTest
 {
+   final static String host = "http://localhost:8080";
 
    public void testMoveForNonCollectionSingleWorkspace() throws Exception
    {
@@ -49,8 +50,8 @@
       TestUtils.addContent(session, filename, inputStream, defaultFileNodeType, "");
       String destFilename = TestUtils.getFileName();
       MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
-      headers.add(ExtHttpHeaders.DESTINATION, getPathWS() + destFilename);
-      ContainerResponse response = service(WebDAVMethods.MOVE, getPathWS() + filename, "", headers, null);
+      headers.add(ExtHttpHeaders.DESTINATION, host + getPathWS() + destFilename);
+      ContainerResponse response = service(WebDAVMethods.MOVE, getPathWS() + filename, host, headers, null);
       assertEquals(HTTPStatus.CREATED, response.getStatus());
       assertTrue(session.getRootNode().hasNode(TextUtil.relativizePath(destFilename)));
       Node nodeDest = session.getRootNode().getNode(TextUtil.relativizePath(destFilename));
@@ -72,8 +73,8 @@
       TestUtils.addContent(session, filename, inputStream, defaultFileNodeType, "");
       String destFilename = TestUtils.getFileName();
       MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
-      headers.add(ExtHttpHeaders.DESTINATION, getPathDestWS() + destFilename);
-      ContainerResponse response = service(WebDAVMethods.MOVE, getPathWS() + filename, "", headers, null);
+      headers.add(ExtHttpHeaders.DESTINATION, host + getPathDestWS() + destFilename);
+      ContainerResponse response = service(WebDAVMethods.MOVE, getPathWS() + filename, host, headers, null);
       assertEquals(HTTPStatus.NO_CONTENT, response.getStatus());
       assertTrue(destSession.getRootNode().hasNode(TextUtil.relativizePath(destFilename)));
       Node nodeDest = destSession.getRootNode().getNode(TextUtil.relativizePath(destFilename));
@@ -102,19 +103,115 @@
 
       // prepare headers
       MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
-      headers.add(ExtHttpHeaders.DESTINATION, getPathWS() + destFilename);
+      headers.add(ExtHttpHeaders.DESTINATION, host + getPathWS() + destFilename);
 
       // execute the query
-      ContainerResponse response = service(WebDAVMethods.MOVE, getPathWS() + filename, "", headers, null);
+      ContainerResponse response = service(WebDAVMethods.MOVE, getPathWS() + filename, host, headers, null);
       // check if operation completed successfully, we expect a new resource to be created
       assertEquals(HTTPStatus.CREATED, response.getStatus());
 
       // check if 'CREATED' response contains 'LOCATION' header
       assertTrue(response.getHttpHeaders().containsKey(ExtHttpHeaders.LOCATION));
       // check if 'CREATED' response 'LOCATION' header contains correct location path
-      assertEquals(getPathWS() + destFilename, response.getHttpHeaders().getFirst(ExtHttpHeaders.LOCATION).toString());
+      assertEquals(host + getPathWS() + destFilename,
+         response.getHttpHeaders().getFirst(ExtHttpHeaders.LOCATION).toString());
    }
 
+   /**
+    * Testing for correct destination header parsing in MOVE method.
+    * We pass a path which contains escaped space - "%20" 
+    * and escaped space with quote symbol "%20'"
+    * @throws Exception
+    */
+   public void testDestinationHeaderParsing() throws Exception
+   {
+      String content = TestUtils.getFileContent();
+      String filename = TestUtils.getFileName();
+      InputStream inputStream = new ByteArrayInputStream(content.getBytes());
+      TestUtils.addContent(session, filename, inputStream, defaultFileNodeType, "");
+
+      String destFilename = TestUtils.getFileName() + "%20test";
+
+      // prepare headers
+      MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
+      headers.add(ExtHttpHeaders.DESTINATION, host + getPathWS() + destFilename);
+
+      // execute the query
+      ContainerResponse response = service(WebDAVMethods.MOVE, getPathWS() + filename, host, headers, null);
+      // check if operation completed successfully, we expect a new resource to be created
+      assertEquals(HTTPStatus.CREATED, response.getStatus());
+
+      filename = destFilename;
+
+      destFilename = TestUtils.getFileName() + "%20'test";
+
+      // prepare headers
+      headers = new MultivaluedMapImpl();
+      headers.add(ExtHttpHeaders.DESTINATION, host + getPathWS() + destFilename);
+
+      // execute the query
+      response = service(WebDAVMethods.MOVE, getPathWS() + filename, host, headers, null);
+      // check if operation completed successfully, we expect a new resource to be created
+      assertEquals(HTTPStatus.CREATED, response.getStatus());
+
+   }
+
+   /**
+    * Testing for correct response after MOVE a resource to the destination,
+    * where another resource already existed
+    * For more info see <a href=http://www.webdav.org/specs/rfc2518.html#METHOD_MOVE>this</a>.
+    * @throws Exception
+    */
+   public void testNoContentResponses() throws Exception
+   {
+      String content = TestUtils.getFileContent();
+      String filename = TestUtils.getFileName();
+      InputStream inputStream = new ByteArrayInputStream(content.getBytes());
+      TestUtils.addContent(session, filename, inputStream, defaultFileNodeType, "");
+
+      String destFilename = TestUtils.getFileName();
+      inputStream = new ByteArrayInputStream(content.getBytes());
+      TestUtils.addContent(session, destFilename, inputStream, defaultFileNodeType, "");
+
+      // prepare headers
+      MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
+      headers.add(ExtHttpHeaders.DESTINATION, host + getPathWS() + destFilename);
+      headers.add(ExtHttpHeaders.OVERWRITE, "T");
+
+      // execute the query
+      ContainerResponse response = service(WebDAVMethods.MOVE, getPathWS() + filename, host, headers, null);
+      // check if operation completed successfully, we expect a new resource to be created
+      assertEquals(HTTPStatus.NO_CONTENT, response.getStatus());
+
+   }
+
+   /**
+    * Testing for correct destination header parsing using "https" 
+    * instead of usual "http" scheme.
+    * @throws Exception
+    */
+   public void testHttpsSchemeInDestinationHeaderParsing() throws Exception
+   {
+      String httpsHost = "https://localhost:8080";
+
+      String content = TestUtils.getFileContent();
+      String filename = TestUtils.getFileName();
+      InputStream inputStream = new ByteArrayInputStream(content.getBytes());
+      TestUtils.addContent(session, filename, inputStream, defaultFileNodeType, "");
+
+      String destFilename = TestUtils.getFileName();
+
+      // prepare headers
+      MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
+      headers.add(ExtHttpHeaders.DESTINATION, httpsHost + getPathWS() + destFilename);
+
+      // execute the query
+      ContainerResponse response = service(WebDAVMethods.MOVE, getPathWS() + filename, host, headers, null);
+      // check if operation completed successfully, we expect a new resource to be created
+      assertEquals(HTTPStatus.CREATED, response.getStatus());
+
+   }
+
    @Override
    protected String getRepositoryName()
    {



More information about the exo-jcr-commits mailing list