/* * Copyright (C) 2009 eXo Platform SAS. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.exoplatform.services.jcr.webdav.command; import org.exoplatform.common.http.HTTPStatus; import org.exoplatform.services.jcr.impl.core.PropertyImpl; import org.exoplatform.services.jcr.util.IdGenerator; import org.exoplatform.services.jcr.webdav.BaseStandaloneTest; import org.exoplatform.services.jcr.webdav.WebDavConstants.WebDAVMethods; import org.exoplatform.services.jcr.webdav.WebDavServiceImpl; import org.exoplatform.services.jcr.webdav.util.TextUtil; import org.exoplatform.services.jcr.webdav.utils.TestUtils; import org.exoplatform.services.rest.ExtHttpHeaders; import org.exoplatform.services.rest.impl.ContainerResponse; import org.exoplatform.services.rest.impl.MultivaluedMapImpl; import javax.jcr.Node; import javax.jcr.nodetype.NodeType; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MultivaluedMap; /** * Created by The eXo Platform SAS Author : Dmytro Katayev * work.visor.ck@gmail.com Aug 13, 2008 */ public class TestPut extends BaseStandaloneTest { public void testPut() throws Exception { testPut(getPathWS()); } public void testPutWithFakePathWS() throws Exception { testPut(getFakePathWS()); } private void testPut(String pathWs) throws Exception { String content = TestUtils.getFileContent(); String path = TestUtils.getFileName(); ContainerResponse containerResponse = service(WebDAVMethods.PUT, pathWs + path, "", null, content.getBytes()); assertEquals(HTTPStatus.CREATED, containerResponse.getStatus()); assertTrue(session.getRootNode().hasNode(TextUtil.relativizePath(path))); path = path + "[2]"; containerResponse = serviceWithEscape(WebDAVMethods.PUT, getPathWS() + path, "", null, content.getBytes()); assertEquals(HTTPStatus.CREATED, containerResponse.getStatus()); assertTrue(session.getRootNode().hasNode(TextUtil.relativizePath(path))); } public void testPutNotFound() throws Exception { String content = TestUtils.getFileContent(); String path = TestUtils.getFileName(); ContainerResponse containerResponse = service(WebDAVMethods.PUT, getPathWS() + "/not-found" + path, "", null, content.getBytes()); assertEquals(HTTPStatus.CONFLICT, containerResponse.getStatus()); } /** * Here we're testing the case when we are trying to put some resource C to a path /A/B/C * and a A collection does not exist. According to the <a href=http://www.webdav.org/specs/rfc4918.html> * RFC 4918</a> section we are to receive 409(conflict) HTTP status. * @throws Exception */ public void testPutToNonExistingWorkspace() throws Exception { String content = TestUtils.getFileContent(); String path = TestUtils.getFileName(); ContainerResponse containerResponse = service(WebDAVMethods.PUT, getPathWS() + "_" + path, "", null, content.getBytes()); assertEquals(HTTPStatus.CONFLICT, containerResponse.getStatus()); } public void testPutFileNodeTypeHeader() throws Exception { String content = TestUtils.getFileContent(); ContainerResponse containerResponse = service(WebDAVMethods.PUT, getPathWS() + TestUtils.getFileName(), "", null, content.getBytes()); assertEquals(HTTPStatus.CREATED, containerResponse.getStatus()); MultivaluedMap<String, String> headers = new MultivaluedMapImpl(); headers.add(ExtHttpHeaders.FILE_NODETYPE, "nt:folder"); containerResponse = service(WebDAVMethods.PUT, getPathWS() + TestUtils.getFileName(), "", headers, content.getBytes()); assertEquals(HTTPStatus.BAD_REQUEST, containerResponse.getStatus()); String fileName = TestUtils.getFileName(); headers = new MultivaluedMapImpl(); headers.add(ExtHttpHeaders.FILE_NODETYPE, "nt:file"); containerResponse = service(WebDAVMethods.PUT, getPathWS() + fileName, "", headers, content.getBytes()); assertEquals(HTTPStatus.CREATED, containerResponse.getStatus()); assertEquals("nt:file", TestUtils.getFileNodeType(session, fileName)); } public void testPutContentTypeHeader() throws Exception { String content = TestUtils.getFileContent(); String fileName = TestUtils.getFileName(); MultivaluedMap<String, String> headers = new MultivaluedMapImpl(); headers.add(ExtHttpHeaders.CONTENT_NODETYPE, "webdav:goodres"); ContainerResponse containerResponse = service(WebDAVMethods.PUT, getPathWS() + fileName, "", headers, content.getBytes()); assertEquals(HTTPStatus.CREATED, containerResponse.getStatus()); assertEquals("webdav:goodres", TestUtils.getContentNodeType(session, fileName)); headers = new MultivaluedMapImpl(); headers.add(ExtHttpHeaders.CONTENT_NODETYPE, "webdav:badres"); containerResponse = service(WebDAVMethods.PUT, getPathWS() + TestUtils.getFileName(), "", headers, content.getBytes()); assertEquals(HTTPStatus.BAD_REQUEST, containerResponse.getStatus()); } public void testPutMixinsHeader() throws Exception { String content = TestUtils.getFileContent(); String fileName = TestUtils.getFileName(); MultivaluedMap<String, String> headers = new MultivaluedMapImpl(); headers.add(ExtHttpHeaders.CONTENT_NODETYPE, "webdav:goodres"); headers.add(ExtHttpHeaders.CONTENT_MIXINTYPES, "mix:wdTestMixin1,mix:wdTestMixin2"); ContainerResponse containerResponse = service(WebDAVMethods.PUT, getPathWS() + fileName, "", headers, content.getBytes()); assertEquals(HTTPStatus.CREATED, containerResponse.getStatus()); NodeType[] mixins = TestUtils.getContentMixins(session, fileName); assertEquals(2, mixins.length); for (NodeType mixin : mixins) { assertTrue(mixin.getName().equals("mix:wdTestMixin1") || mixin.getName().equals("mix:wdTestMixin2")); } } public void testMimeType() throws Exception { String content = TestUtils.getFileContent(); String path = TestUtils.getFileName(); MultivaluedMap<String, String> headers = new MultivaluedMapImpl(); headers.add(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_XML); ContainerResponse containerResponse = service(WebDAVMethods.PUT, getPathWS() + path, "", headers, content.getBytes()); assertEquals(HTTPStatus.CREATED, containerResponse.getStatus()); assertTrue(session.getRootNode().hasNode(TextUtil.relativizePath(path))); Node node = session.getRootNode().getNode(TextUtil.relativizePath(path)); assertTrue(node.hasNode("jcr:content")); Node node2 = node.getNode("jcr:content"); assertTrue(node2.hasProperty("jcr:mimeType")); PropertyImpl property = (PropertyImpl)node2.getProperty("jcr:mimeType"); assertEquals(headers.getFirst(HttpHeaders.CONTENT_TYPE), property.getString()); } /** * Testing {@link WebDavServiceImpl} PUT method for correct response * building. According to 'RFC-2616' it is expected to contain 'location' header. * More info is introduced <a href=http://tools.ietf.org/html/rfc2616#section-14.30>here</a>. * @throws Exception */ public void testLocationHeaderInPutResponse() throws Exception { String content = TestUtils.getFileContent(); String filename = TestUtils.getFileName(); // now we execute the query ContainerResponse containerResponse = service(WebDAVMethods.PUT, getPathWS() + filename, "", null, content.getBytes()); // check if operation completed successfully, we expect a new resource to be created assertEquals(HTTPStatus.CREATED, containerResponse.getStatus()); // check if response 'CREATED' contains 'LOCATION' header assertTrue(containerResponse.getHttpHeaders().containsKey(ExtHttpHeaders.LOCATION)); // check if 'CREATED' response 'LOCATION' header contains correct location path assertEquals(getPathWS() + filename, containerResponse.getHttpHeaders().getFirst(ExtHttpHeaders.LOCATION) .toString()); } /** * Testing if we use MimeTypeResolver to define jcr:mimeType property * for untrusted user agents during resource creation. */ public void testUntrustedUserAgentResourceCreation() throws Exception { String content = TestUtils.getFileContent(); String path = TestUtils.getFileName(); // create User-Agent header indicating that the resource we create // has application/octet-stream type // though it's extension is .txt MultivaluedMap<String, String> headers = new MultivaluedMapImpl(); headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM); headers.add(HttpHeaders.USER_AGENT, "test-user-agent"); // fullfiling the request service(WebDAVMethods.PUT, getPathWS() + path, "", headers, content.getBytes()); Node node = session.getRootNode().getNode(TextUtil.relativizePath(path)).getNode("jcr:content"); // though that we passed application/octet-stream mime type // the user agent is within untrusted user agents set // so we use MimeTypeResolver to define the mimeType and // ignore Content-Type header assertEquals(MediaType.TEXT_PLAIN, node.getProperty("jcr:mimeType").getString()); } /** * Testing if we use MimeTypeResolver to define jcr:mimeType property * for untrusted user agents during resource modification. */ public void testUntrustedUserAgentResourceModification() throws Exception { String content = TestUtils.getFileContent(); String path = TestUtils.getFileName(); // create data with 'trusted' user agent // (all user agents are considered to be trusted // if they are not listed as untrusted) MultivaluedMap<String, String> headers = new MultivaluedMapImpl(); headers.add(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN); service(WebDAVMethods.PUT, getPathWS() + path, "", headers, content.getBytes()); headers.clear(); content = TestUtils.getFileContent(); // define user agent to be among untrusted user agents headers.add(HttpHeaders.USER_AGENT, "test-user-agent"); // define incorrect mime-type via seting Content-Type header headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM); service(WebDAVMethods.PUT, getPathWS() + path, "", headers, content.getBytes()); Node node = session.getRootNode().getNode(TextUtil.relativizePath(path)).getNode("jcr:content"); // mime-type should still be correct assertEquals(MediaType.TEXT_PLAIN, node.getProperty("jcr:mimeType").getString()); } /** * Testing if we can modify mime-type of previously defined resource * via trusted user agent */ public void testTrustedUserAgentResourceModification() throws Exception { String content = TestUtils.getFileContent(); String path = TestUtils.getFileName() + ".html"; service(WebDAVMethods.PUT, getPathWS() + path, "", null, content.getBytes()); Node node = session.getRootNode().getNode(TextUtil.relativizePath(path)); // mime-type is defined according to resource's extension assertEquals(MediaType.TEXT_HTML, node.getNode("jcr:content").getProperty("jcr:mimeType").getString()); MultivaluedMap<String, String> headers = new MultivaluedMapImpl(); headers.add(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_XML); service(WebDAVMethods.PUT, getPathWS() + path, "", headers, content.getBytes()); // mime-type modified according to Content-Type header content assertEquals(MediaType.TEXT_XML, node.getNode("jcr:content").getProperty("jcr:mimeType").getString()); } public void testMimeTypeDefinedCorrectIfNoExtensionSet() throws Exception { String filename = IdGenerator.generate(); MultivaluedMap<String, String> headers = new MultivaluedMapImpl(); headers.add(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_HTML); ContainerResponse containerResponse = service(WebDAVMethods.PUT, getPathWS() + "/" + filename, "", headers, "".getBytes()); assertEquals(HTTPStatus.CREATED, containerResponse.getStatus()); headers.clear(); containerResponse = service(WebDAVMethods.PUT, getPathWS() + "/" + filename, "", headers, IdGenerator.generate().getBytes()); Node node = session.getRootNode().getNode(TextUtil.relativizePath(filename)); assertTrue(node.hasNode("jcr:content")); Node node2 = node.getNode("jcr:content"); assertTrue(node2.hasProperty("jcr:mimeType")); PropertyImpl property = (PropertyImpl)node2.getProperty("jcr:mimeType"); assertEquals(MediaType.TEXT_HTML, property.getString()); containerResponse = service(WebDAVMethods.GET, getPathWS() + "/" + filename, "", null, null); assertEquals(MediaType.TEXT_HTML, containerResponse.getHttpHeaders().getFirst(HttpHeaders.CONTENT_TYPE)); } public void testPutContentTypeHeaderWithEncoding() throws Exception { String content = TestUtils.getFileContent(); String fileName = TestUtils.getFileName(); MultivaluedMap<String, String> headers = new MultivaluedMapImpl(); headers.add(ExtHttpHeaders.CONTENT_TYPE, "webdav:goodres; charset=test-char-set"); ContainerResponse containerResponse = service(WebDAVMethods.PUT, getPathWS() + fileName, "", headers, content.getBytes()); assertEquals(HTTPStatus.CREATED, containerResponse.getStatus()); assertTrue("Content node is expected to have 'jcr:encoding' property set during PUT method", TestUtils .getContentNode(session, fileName).hasProperty("jcr:encoding")); assertEquals("test-char-set", TestUtils.getContentNode(session, fileName).getProperty("jcr:encoding").getString()); } @Override protected String getRepositoryName() { return null; } }