Java tutorial
/* * Copyright 2009-2011 Jon Stevens et al. * * Licensed 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. */ package com.github.sardine; import com.github.sardine.DavPrincipal.PrincipalType; import com.github.sardine.impl.SardineException; import com.github.sardine.impl.SardineImpl; import com.github.sardine.util.SardineUtil; import org.apache.http.HttpException; import org.apache.http.HttpHeaders; import org.apache.http.HttpRequest; import org.apache.http.HttpRequestInterceptor; import org.apache.http.HttpResponse; import org.apache.http.HttpResponseInterceptor; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.protocol.HttpContext; import org.junit.Before; import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import javax.xml.bind.JAXBException; import javax.xml.namespace.QName; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.EOFException; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.ProxySelector; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.UUID; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import static org.junit.Assert.*; /** */ public class FunctionalSardineTest { private static final String TEST_PROPERTIES_FILENAME = "test.properties"; protected Properties properties; @Rule public ExpectedException thrown = ExpectedException.none(); @Before public void properties() throws Exception { thrown.expect(NullPointerException.class); properties = new Properties(); properties.load(ClassLoader.getSystemResourceAsStream(TEST_PROPERTIES_FILENAME)); } @Test public void testRead() throws Exception { Sardine sardine = SardineFactory.begin(); final String url = "http://sardine.googlecode.com/svn/trunk/README.html"; final InputStream in = sardine.get(url); assertNotNull(in); in.close(); } @Test public void testGetSingleFileGzip() throws Exception { final HttpClientBuilder client = HttpClientBuilder.create(); client.addInterceptorFirst(new HttpResponseInterceptor() { public void process(final HttpResponse r, final HttpContext context) throws HttpException, IOException { assertEquals(200, r.getStatusLine().getStatusCode()); assertNotNull(r.getHeaders(HttpHeaders.CONTENT_ENCODING)); assertEquals(1, r.getHeaders(HttpHeaders.CONTENT_ENCODING).length); assertEquals("gzip", r.getHeaders(HttpHeaders.CONTENT_ENCODING)[0].getValue()); } }); Sardine sardine = new SardineImpl(client); sardine.enableCompression(); // final String url = "http://sardine.googlecode.com/svn/trunk/README.html"; final String url = "http://sudo.ch/dav/anon/sardine/single/file"; final InputStream in = sardine.get(url); assertNotNull(in); assertNotNull(in.read()); try { in.close(); } catch (EOFException e) { fail("Issue https://issues.apache.org/jira/browse/HTTPCLIENT-1075 pending"); } } @Test public void testGetFileNotFound() throws Exception { Sardine sardine = SardineFactory.begin(); InputStream in = null; try { in = sardine.get("http://sardine.googlecode.com/svn/trunk/NOTFOUND"); fail("Expected 404"); } catch (SardineException e) { assertEquals(404, e.getStatusCode()); } assertNull(in); } @Test public void testGetTimestamps() throws Exception { Sardine sardine = SardineFactory.begin(); // Google Code SVN does not support Range header final String url = "http://sardine.googlecode.com/svn/trunk/README.html"; final List<DavResource> resources = sardine.list(url); assertEquals(1, resources.size()); assertNotNull(resources.iterator().next().getModified()); assertNotNull(resources.iterator().next().getCreation()); } @Test public void testGetLength() throws Exception { Sardine sardine = SardineFactory.begin(); // Google Code SVN does not support Range header final String url = "http://sardine.googlecode.com/svn/trunk/README.html"; final List<DavResource> resources = sardine.list(url); assertEquals(1, resources.size()); assertNotNull(resources.iterator().next().getContentLength()); } @Test @Ignore public void testSetAcl() throws IOException { final String url = String.format("http://demo.sabredav.org/public/folder-%s/", UUID.randomUUID().toString()); Sardine sardine = SardineFactory.begin("testuser", "test"); sardine.createDirectory(url); List<DavAce> aces = new ArrayList<DavAce>(); sardine.setAcl(url, aces); DavAcl acls = sardine.getAcl(url); for (DavAce davace : acls.getAces()) { if (davace.getInherited() == null) fail("We have cleared all ACEs, should not have anymore non inherited ACEs"); } aces.clear(); DavAce ace = new DavAce(new DavPrincipal(PrincipalType.HREF, "/users/someone", null)); ace.getGranted().add("read"); aces.add(ace); ace = new DavAce(new DavPrincipal(PrincipalType.PROPERTY, new QName("DAV:", "owner", "somespace"), null)); ace.getGranted().add("read"); aces.add(ace); sardine.setAcl(url, aces); int count = 0; for (DavAce davace : sardine.getAcl(url).getAces()) { if (davace.getInherited() == null) { count++; } } sardine.delete(url); assertEquals("After setting two ACL, should find them back", 2, count); } @Test @Ignore public void testDavOwner() throws IOException { final String url = String.format("http://demo.sabredav.org/public/folder-%s/", UUID.randomUUID().toString()); Sardine sardine = SardineFactory.begin("testuser", "test"); sardine.createDirectory(url); DavAcl acl = sardine.getAcl(url); sardine.delete(url); assertNotNull(acl.getOwner()); assertNotNull(acl.getGroup()); } @Test public void testDavPrincipals() throws IOException, URISyntaxException { final String url = String.format("http://demo.sabredav.org/public/folder-%s/", UUID.randomUUID().toString()); Sardine sardine = SardineFactory.begin("testuser", "test"); sardine.createDirectory(url); List<String> principals = sardine.getPrincipalCollectionSet(url); sardine.delete(url); assertNotNull(principals); for (String p : principals) { assertNotNull(p); } } @Test public void testPutRange() throws Exception { final HttpClientBuilder client = HttpClientBuilder.create(); client.addInterceptorFirst(new HttpResponseInterceptor() { public void process(final HttpResponse r, final HttpContext context) throws HttpException, IOException { assertEquals(201, r.getStatusLine().getStatusCode()); } }); Sardine sardine = new SardineImpl(client); // mod_dav supports Range headers for PUT final String url = "http://sudo.ch/dav/anon/sardine/" + UUID.randomUUID().toString(); sardine.put(url, new ByteArrayInputStream("Te".getBytes("UTF-8"))); try { // Append to existing file final Map<String, String> header = Collections.singletonMap(HttpHeaders.CONTENT_RANGE, "bytes " + 2 + "-" + 3 + "/" + 4); client.addInterceptorFirst(new HttpRequestInterceptor() { public void process(final HttpRequest r, final HttpContext context) throws HttpException, IOException { assertNotNull(r.getHeaders(HttpHeaders.CONTENT_RANGE)); assertEquals(1, r.getHeaders(HttpHeaders.CONTENT_RANGE).length); } }); client.addInterceptorFirst(new HttpResponseInterceptor() { public void process(final HttpResponse r, final HttpContext context) throws HttpException, IOException { assertEquals(204, r.getStatusLine().getStatusCode()); } }); sardine.put(url, new ByteArrayInputStream("st".getBytes("UTF-8")), header); assertEquals("Test", new BufferedReader(new InputStreamReader(sardine.get(url), "UTF-8")).readLine()); } finally { sardine.delete(url); } } @Test public void testGetRange() throws Exception { final HttpClientBuilder client = HttpClientBuilder.create(); client.addInterceptorFirst(new HttpResponseInterceptor() { public void process(final HttpResponse r, final HttpContext context) throws HttpException, IOException { // Verify partial content response assertEquals(206, r.getStatusLine().getStatusCode()); assertNotNull(r.getHeaders(HttpHeaders.CONTENT_RANGE)); assertEquals(1, r.getHeaders(HttpHeaders.CONTENT_RANGE).length); } }); Sardine sardine = new SardineImpl(client); // mod_dav supports Range headers for GET final String url = "http://sudo.ch/dav/anon/sardine/single/file"; // Resume final Map<String, String> header = Collections.singletonMap(HttpHeaders.RANGE, "bytes=" + 1 + "-"); final InputStream in = sardine.get(url, header); assertNotNull(in); } @Test public void testPutExpectContinue() throws Exception { // Anonymous PUT to restricted resource Sardine sardine = SardineFactory.begin(); final String url = "http://sudo.ch/dav/basic/sardine/" + UUID.randomUUID().toString(); try { sardine.put(url, new InputStream() { @Override public int read() throws IOException { fail("Expected authentication to fail without sending any body"); return -1; } }); fail("Expected authorization failure"); } catch (SardineException e) { // Expect Authorization Required assertEquals(401, e.getStatusCode()); } } @Test public void testProxyConfiguration() throws Exception { Sardine sardine = SardineFactory.begin(null, null, ProxySelector.getDefault()); try { final List<DavResource> resources = sardine.list("http://sardine.googlecode.com/svn/trunk/"); assertNotNull(resources); assertFalse(resources.isEmpty()); } catch (SardineException e) { fail(e.getMessage()); } } @Test public void testPath() throws Exception { Sardine sardine = SardineFactory.begin(); List<DavResource> resources = sardine.list("http://sardine.googlecode.com/svn/trunk/"); assertFalse(resources.isEmpty()); DavResource folder = resources.get(0); assertEquals("trunk", folder.getName()); assertEquals("/svn/trunk/", folder.getPath()); assertEquals(new Long(-1), folder.getContentLength()); } @Test public void testPut() throws Exception { Sardine sardine = SardineFactory.begin(); final String url = "http://sudo.ch/dav/anon/sardine/" + UUID.randomUUID().toString(); sardine.put(url, new ByteArrayInputStream("Test".getBytes())); try { assertTrue(sardine.exists(url)); assertEquals("Test", new BufferedReader(new InputStreamReader(sardine.get(url), "UTF-8")).readLine()); } finally { sardine.delete(url); } } @Test public void testDepth() throws Exception { Sardine sardine = SardineFactory.begin(); final String url = "http://sudo.ch/dav/anon/sardine/"; List<DavResource> resources = sardine.list(url, 0); assertNotNull(resources); assertEquals(1, resources.size()); } @Test public void testDelete() throws Exception { Sardine sardine = SardineFactory.begin(); String filename = UUID.randomUUID().toString(); final String url = "http://sudo.ch/dav/anon/sardine/" + filename; sardine.put(url, new ByteArrayInputStream("Test".getBytes())); sardine.delete(url); assertFalse(sardine.exists(url)); } @Test public void testMove() throws Exception { Sardine sardine = SardineFactory.begin(); final String source = "http://sudo.ch/dav/anon/sardine/" + UUID.randomUUID().toString(); final String destination = "http://sudo.ch/dav/anon/sardine/" + UUID.randomUUID().toString(); sardine.put(source, new ByteArrayInputStream("Test".getBytes())); assertTrue(sardine.exists(source)); sardine.move(source, destination); assertFalse(sardine.exists(source)); assertTrue(sardine.exists(destination)); sardine.delete(destination); } @Test public void testMkdir() throws Exception { Sardine sardine = SardineFactory.begin(); final String url = "http://sudo.ch/dav/anon/sardine/" + UUID.randomUUID().toString() + "/"; sardine.createDirectory(url); assertTrue(sardine.exists(url)); final List<DavResource> resources = sardine.list(url); assertNotNull(resources); assertEquals(1, resources.size()); sardine.delete(url); } @Test public void testExists() throws Exception { Sardine sardine = SardineFactory.begin(); assertTrue(sardine.exists("http://sardine.googlecode.com/svn/trunk/")); assertTrue(sardine.exists("http://sardine.googlecode.com/svn/trunk/README.html")); assertFalse(sardine.exists("http://sardine.googlecode.com/svn/false/")); } @Test public void testDirectoryContentType() throws Exception { Sardine sardine = SardineFactory.begin(); final String url = "http://sardine.googlecode.com/svn/trunk/"; final List<DavResource> resources = sardine.list(url); assertNotNull(resources); assertFalse(resources.isEmpty()); DavResource file = resources.get(0); assertEquals(DavResource.HTTPD_UNIX_DIRECTORY_CONTENT_TYPE, file.getContentType()); } @Test public void testFileContentType() throws Exception { Sardine sardine = SardineFactory.begin(); final String url = "http://sardine.googlecode.com/svn/trunk/README.html"; final List<DavResource> resources = sardine.list(url); assertFalse(resources.isEmpty()); assertEquals(1, resources.size()); DavResource file = resources.get(0); assertEquals("text/html", file.getContentType()); } @Test public void testRedirectPermanently() throws Exception { Sardine sardine = SardineFactory.begin(); final String url = "http://sudo.ch/dav/anon/sardine"; try { // Test extended redirect handler for PROPFIND assertNotNull(sardine.list(url)); // Test another attempt. Must not fail with circular redirect assertNotNull(sardine.list(url)); } catch (SardineException e) { // Should handle a 301 response transparently fail("Redirect handling failed"); } } @Test public void testDisallowLoadExternalDtd() throws Exception { final CountDownLatch entry = new CountDownLatch(1); Thread t = new Thread(new Runnable() { public void run() { try { String html = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n" + "<html xmlns=\"http://www.w3.org/1999/xhtml\"></html>"; SardineUtil.unmarshal(new ByteArrayInputStream(html.getBytes())); fail("Expected parsing failure for invalid namespace"); } catch (IOException e) { // Success assertTrue(e.getCause() instanceof JAXBException); } finally { entry.countDown(); } } }); t.start(); assertTrue( "Timeout for listing resources. Possibly the XML parser is trying to read the DTD in the response.", entry.await(5, TimeUnit.SECONDS)); } @Test public void testMetadata() throws Exception { // 1 prepare dav test ressource final String url = "http://sudo.ch/dav/anon/sardine/metadata.txt"; Sardine sardine = SardineFactory.begin(); if (sardine.exists(url)) { sardine.delete(url); } sardine.put(url, "Hello".getBytes("UTF-8"), "text/plain"); // 2 setup some custom properties, with custom namespaces Map<QName, String> newProps = new HashMap<QName, String>(); newProps.put(new QName("http://my.namespace.com", "mykey", "ns1"), "myvalue"); newProps.put(new QName(SardineUtil.CUSTOM_NAMESPACE_URI, "mykey", SardineUtil.CUSTOM_NAMESPACE_PREFIX), "my&value2"); newProps.put(new QName("hello", "mykey", "ns2"), "my<value3"); sardine.patch(url, newProps); // 3 check properties are properly re-read List<DavResource> resources = sardine.list(url); assertEquals(resources.size(), 1); assertEquals(resources.get(0).getContentLength(), (Long) 5L); Map<QName, String> props = resources.get(0).getCustomPropsNS(); for (Map.Entry<QName, String> entry : newProps.entrySet()) { assertEquals(entry.getValue(), props.get(entry.getKey())); } // 4 check i can properly delete some of those added properties List<QName> removeProps = new ArrayList<QName>(); removeProps.add(new QName("http://my.namespace.com", "mykey", "ns1")); sardine.patch(url, Collections.<QName, String>emptyMap(), removeProps); props = sardine.list(url).get(0).getCustomPropsNS(); assertNull(props.get(new QName("http://my.namespace.com", "mykey"))); assertEquals(props.get(new QName(SardineUtil.CUSTOM_NAMESPACE_URI, "mykey")), "my&value2"); assertEquals(props.get(new QName("hello", "mykey")), "my<value3"); } }