Java tutorial
package org.eclipse.aether.transport.http; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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. */ import static org.junit.Assert.*; import java.io.File; import java.io.FileNotFoundException; import java.net.ConnectException; import java.net.ServerSocket; import java.net.SocketTimeoutException; import java.net.URI; import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicReference; import org.apache.http.client.HttpResponseException; import org.apache.http.conn.ConnectTimeoutException; import org.apache.http.pool.ConnPoolControl; import org.apache.http.pool.PoolStats; import org.eclipse.aether.ConfigurationProperties; import org.eclipse.aether.DefaultRepositoryCache; import org.eclipse.aether.DefaultRepositorySystemSession; import org.eclipse.aether.internal.test.util.TestFileUtils; import org.eclipse.aether.internal.test.util.TestUtils; import org.eclipse.aether.repository.Authentication; import org.eclipse.aether.repository.Proxy; import org.eclipse.aether.repository.RemoteRepository; import org.eclipse.aether.spi.connector.transport.GetTask; import org.eclipse.aether.spi.connector.transport.PeekTask; import org.eclipse.aether.spi.connector.transport.PutTask; import org.eclipse.aether.spi.connector.transport.Transporter; import org.eclipse.aether.spi.connector.transport.TransporterFactory; import org.eclipse.aether.transfer.NoTransporterException; import org.eclipse.aether.transfer.TransferCancelledException; import org.eclipse.aether.util.repository.AuthenticationBuilder; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestName; /** */ public class HttpTransporterTest { static { System.setProperty("javax.net.ssl.trustStore", new File("src/test/resources/ssl/server-store").getAbsolutePath()); System.setProperty("javax.net.ssl.trustStorePassword", "server-pwd"); System.setProperty("javax.net.ssl.keyStore", new File("src/test/resources/ssl/client-store").getAbsolutePath()); System.setProperty("javax.net.ssl.keyStorePassword", "client-pwd"); } @Rule public TestName testName = new TestName(); private DefaultRepositorySystemSession session; private TransporterFactory factory; private Transporter transporter; private File repoDir; private HttpServer httpServer; private Authentication auth; private Proxy proxy; private RemoteRepository newRepo(String url) { return new RemoteRepository.Builder("test", "default", url).setAuthentication(auth).setProxy(proxy).build(); } private void newTransporter(String url) throws Exception { if (transporter != null) { transporter.close(); transporter = null; } transporter = factory.newInstance(session, newRepo(url)); } @Before public void setUp() throws Exception { System.out.println("=== " + testName.getMethodName() + " ==="); session = TestUtils.newSession(); factory = new HttpTransporterFactory(); repoDir = TestFileUtils.createTempDir(); TestFileUtils.writeString(new File(repoDir, "file.txt"), "test"); TestFileUtils.writeString(new File(repoDir, "dir/file.txt"), "test"); TestFileUtils.writeString(new File(repoDir, "empty.txt"), ""); TestFileUtils.writeString(new File(repoDir, "some space.txt"), "space"); File resumable = new File(repoDir, "resume.txt"); TestFileUtils.writeString(resumable, "resumable"); resumable.setLastModified(System.currentTimeMillis() - 90 * 1000); httpServer = new HttpServer().setRepoDir(repoDir).start(); newTransporter(httpServer.getHttpUrl()); } @After public void tearDown() throws Exception { if (transporter != null) { transporter.close(); transporter = null; } if (httpServer != null) { httpServer.stop(); httpServer = null; } factory = null; session = null; } @Test public void testClassify() { assertEquals(Transporter.ERROR_OTHER, transporter.classify(new FileNotFoundException())); assertEquals(Transporter.ERROR_OTHER, transporter.classify(new HttpResponseException(403, "Forbidden"))); assertEquals(Transporter.ERROR_NOT_FOUND, transporter.classify(new HttpResponseException(404, "Not Found"))); } @Test public void testPeek() throws Exception { transporter.peek(new PeekTask(URI.create("repo/file.txt"))); } @Test public void testPeek_NotFound() throws Exception { try { transporter.peek(new PeekTask(URI.create("repo/missing.txt"))); fail("Expected error"); } catch (HttpResponseException e) { assertEquals(404, e.getStatusCode()); assertEquals(Transporter.ERROR_NOT_FOUND, transporter.classify(e)); } } @Test public void testPeek_Closed() throws Exception { transporter.close(); try { transporter.peek(new PeekTask(URI.create("repo/missing.txt"))); fail("Expected error"); } catch (IllegalStateException e) { assertEquals(Transporter.ERROR_OTHER, transporter.classify(e)); } } @Test public void testPeek_Authenticated() throws Exception { httpServer.setAuthentication("testuser", "testpass"); auth = new AuthenticationBuilder().addUsername("testuser").addPassword("testpass").build(); newTransporter(httpServer.getHttpUrl()); transporter.peek(new PeekTask(URI.create("repo/file.txt"))); } @Test public void testPeek_Unauthenticated() throws Exception { httpServer.setAuthentication("testuser", "testpass"); try { transporter.peek(new PeekTask(URI.create("repo/file.txt"))); fail("Expected error"); } catch (HttpResponseException e) { assertEquals(401, e.getStatusCode()); assertEquals(Transporter.ERROR_OTHER, transporter.classify(e)); } } @Test public void testPeek_ProxyAuthenticated() throws Exception { httpServer.setProxyAuthentication("testuser", "testpass"); auth = new AuthenticationBuilder().addUsername("testuser").addPassword("testpass").build(); proxy = new Proxy(Proxy.TYPE_HTTP, httpServer.getHost(), httpServer.getHttpPort(), auth); newTransporter("http://bad.localhost:1/"); transporter.peek(new PeekTask(URI.create("repo/file.txt"))); } @Test public void testPeek_ProxyUnauthenticated() throws Exception { httpServer.setProxyAuthentication("testuser", "testpass"); proxy = new Proxy(Proxy.TYPE_HTTP, httpServer.getHost(), httpServer.getHttpPort()); newTransporter("http://bad.localhost:1/"); try { transporter.peek(new PeekTask(URI.create("repo/file.txt"))); fail("Expected error"); } catch (HttpResponseException e) { assertEquals(407, e.getStatusCode()); assertEquals(Transporter.ERROR_OTHER, transporter.classify(e)); } } @Test public void testPeek_SSL() throws Exception { httpServer.addSslConnector(); newTransporter(httpServer.getHttpsUrl()); transporter.peek(new PeekTask(URI.create("repo/file.txt"))); } @Test public void testPeek_Redirect() throws Exception { httpServer.addSslConnector(); transporter.peek(new PeekTask(URI.create("redirect/file.txt"))); transporter.peek(new PeekTask(URI.create("redirect/file.txt?scheme=https"))); } @Test public void testGet_ToMemory() throws Exception { RecordingTransportListener listener = new RecordingTransportListener(); GetTask task = new GetTask(URI.create("repo/file.txt")).setListener(listener); transporter.get(task); assertEquals("test", task.getDataString()); assertEquals(0L, listener.dataOffset); assertEquals(4L, listener.dataLength); assertEquals(1, listener.startedCount); assertTrue("Count: " + listener.progressedCount, listener.progressedCount > 0); assertEquals(task.getDataString(), new String(listener.baos.toByteArray(), StandardCharsets.UTF_8)); } @Test public void testGet_ToFile() throws Exception { File file = TestFileUtils.createTempFile("failure"); RecordingTransportListener listener = new RecordingTransportListener(); GetTask task = new GetTask(URI.create("repo/file.txt")).setDataFile(file).setListener(listener); transporter.get(task); assertEquals("test", TestFileUtils.readString(file)); assertEquals(0L, listener.dataOffset); assertEquals(4L, listener.dataLength); assertEquals(1, listener.startedCount); assertTrue("Count: " + listener.progressedCount, listener.progressedCount > 0); assertEquals("test", new String(listener.baos.toByteArray(), StandardCharsets.UTF_8)); } @Test public void testGet_EmptyResource() throws Exception { File file = TestFileUtils.createTempFile("failure"); RecordingTransportListener listener = new RecordingTransportListener(); GetTask task = new GetTask(URI.create("repo/empty.txt")).setDataFile(file).setListener(listener); transporter.get(task); assertEquals("", TestFileUtils.readString(file)); assertEquals(0L, listener.dataOffset); assertEquals(0L, listener.dataLength); assertEquals(1, listener.startedCount); assertEquals(0, listener.progressedCount); assertEquals("", new String(listener.baos.toByteArray(), StandardCharsets.UTF_8)); } @Test public void testGet_EncodedResourcePath() throws Exception { GetTask task = new GetTask(URI.create("repo/some%20space.txt")); transporter.get(task); assertEquals("space", task.getDataString()); } @Test public void testGet_Authenticated() throws Exception { httpServer.setAuthentication("testuser", "testpass"); auth = new AuthenticationBuilder().addUsername("testuser").addPassword("testpass").build(); newTransporter(httpServer.getHttpUrl()); RecordingTransportListener listener = new RecordingTransportListener(); GetTask task = new GetTask(URI.create("repo/file.txt")).setListener(listener); transporter.get(task); assertEquals("test", task.getDataString()); assertEquals(0L, listener.dataOffset); assertEquals(4L, listener.dataLength); assertEquals(1, listener.startedCount); assertTrue("Count: " + listener.progressedCount, listener.progressedCount > 0); assertEquals(task.getDataString(), new String(listener.baos.toByteArray(), StandardCharsets.UTF_8)); } @Test public void testGet_Unauthenticated() throws Exception { httpServer.setAuthentication("testuser", "testpass"); try { transporter.get(new GetTask(URI.create("repo/file.txt"))); fail("Expected error"); } catch (HttpResponseException e) { assertEquals(401, e.getStatusCode()); assertEquals(Transporter.ERROR_OTHER, transporter.classify(e)); } } @Test public void testGet_ProxyAuthenticated() throws Exception { httpServer.setProxyAuthentication("testuser", "testpass"); Authentication auth = new AuthenticationBuilder().addUsername("testuser").addPassword("testpass").build(); proxy = new Proxy(Proxy.TYPE_HTTP, httpServer.getHost(), httpServer.getHttpPort(), auth); newTransporter("http://bad.localhost:1/"); RecordingTransportListener listener = new RecordingTransportListener(); GetTask task = new GetTask(URI.create("repo/file.txt")).setListener(listener); transporter.get(task); assertEquals("test", task.getDataString()); assertEquals(0L, listener.dataOffset); assertEquals(4L, listener.dataLength); assertEquals(1, listener.startedCount); assertTrue("Count: " + listener.progressedCount, listener.progressedCount > 0); assertEquals(task.getDataString(), new String(listener.baos.toByteArray(), StandardCharsets.UTF_8)); } @Test public void testGet_ProxyUnauthenticated() throws Exception { httpServer.setProxyAuthentication("testuser", "testpass"); proxy = new Proxy(Proxy.TYPE_HTTP, httpServer.getHost(), httpServer.getHttpPort()); newTransporter("http://bad.localhost:1/"); try { transporter.get(new GetTask(URI.create("repo/file.txt"))); fail("Expected error"); } catch (HttpResponseException e) { assertEquals(407, e.getStatusCode()); assertEquals(Transporter.ERROR_OTHER, transporter.classify(e)); } } @Test public void testGet_SSL() throws Exception { httpServer.addSslConnector(); newTransporter(httpServer.getHttpsUrl()); RecordingTransportListener listener = new RecordingTransportListener(); GetTask task = new GetTask(URI.create("repo/file.txt")).setListener(listener); transporter.get(task); assertEquals("test", task.getDataString()); assertEquals(0L, listener.dataOffset); assertEquals(4L, listener.dataLength); assertEquals(1, listener.startedCount); assertTrue("Count: " + listener.progressedCount, listener.progressedCount > 0); assertEquals(task.getDataString(), new String(listener.baos.toByteArray(), StandardCharsets.UTF_8)); } @Test public void testGet_WebDav() throws Exception { httpServer.setWebDav(true); RecordingTransportListener listener = new RecordingTransportListener(); GetTask task = new GetTask(URI.create("repo/dir/file.txt")).setListener(listener); ((HttpTransporter) transporter).getState().setWebDav(true); transporter.get(task); assertEquals("test", task.getDataString()); assertEquals(0L, listener.dataOffset); assertEquals(4L, listener.dataLength); assertEquals(1, listener.startedCount); assertTrue("Count: " + listener.progressedCount, listener.progressedCount > 0); assertEquals(task.getDataString(), new String(listener.baos.toByteArray(), StandardCharsets.UTF_8)); assertEquals(httpServer.getLogEntries().toString(), 1, httpServer.getLogEntries().size()); } @Test public void testGet_Redirect() throws Exception { httpServer.addSslConnector(); RecordingTransportListener listener = new RecordingTransportListener(); GetTask task = new GetTask(URI.create("redirect/file.txt?scheme=https")).setListener(listener); transporter.get(task); assertEquals("test", task.getDataString()); assertEquals(0L, listener.dataOffset); assertEquals(4L, listener.dataLength); assertEquals(1, listener.startedCount); assertTrue("Count: " + listener.progressedCount, listener.progressedCount > 0); assertEquals(task.getDataString(), new String(listener.baos.toByteArray(), StandardCharsets.UTF_8)); } @Test public void testGet_Resume() throws Exception { File file = TestFileUtils.createTempFile("re"); RecordingTransportListener listener = new RecordingTransportListener(); GetTask task = new GetTask(URI.create("repo/resume.txt")).setDataFile(file, true).setListener(listener); transporter.get(task); assertEquals("resumable", TestFileUtils.readString(file)); assertEquals(1L, listener.startedCount); assertEquals(2L, listener.dataOffset); assertEquals(9, listener.dataLength); assertTrue("Count: " + listener.progressedCount, listener.progressedCount > 0); assertEquals("sumable", new String(listener.baos.toByteArray(), StandardCharsets.UTF_8)); } @Test public void testGet_ResumeLocalContentsOutdated() throws Exception { File file = TestFileUtils.createTempFile("re"); file.setLastModified(System.currentTimeMillis() - 5 * 60 * 1000); RecordingTransportListener listener = new RecordingTransportListener(); GetTask task = new GetTask(URI.create("repo/resume.txt")).setDataFile(file, true).setListener(listener); transporter.get(task); assertEquals("resumable", TestFileUtils.readString(file)); assertEquals(1L, listener.startedCount); assertEquals(0L, listener.dataOffset); assertEquals(9, listener.dataLength); assertTrue("Count: " + listener.progressedCount, listener.progressedCount > 0); assertEquals("resumable", new String(listener.baos.toByteArray(), StandardCharsets.UTF_8)); } @Test public void testGet_ResumeRangesNotSupportedByServer() throws Exception { httpServer.setRangeSupport(false); File file = TestFileUtils.createTempFile("re"); RecordingTransportListener listener = new RecordingTransportListener(); GetTask task = new GetTask(URI.create("repo/resume.txt")).setDataFile(file, true).setListener(listener); transporter.get(task); assertEquals("resumable", TestFileUtils.readString(file)); assertEquals(1L, listener.startedCount); assertEquals(0L, listener.dataOffset); assertEquals(9, listener.dataLength); assertTrue("Count: " + listener.progressedCount, listener.progressedCount > 0); assertEquals("resumable", new String(listener.baos.toByteArray(), StandardCharsets.UTF_8)); } @Test public void testGet_Checksums_Nexus() throws Exception { httpServer.setChecksumHeader(HttpServer.ChecksumHeader.NEXUS); GetTask task = new GetTask(URI.create("repo/file.txt")); transporter.get(task); assertEquals("test", task.getDataString()); assertEquals("a94a8fe5ccb19ba61c4c0873d391e987982fbbd3", task.getChecksums().get("SHA-1")); } @Test public void testGet_FileHandleLeak() throws Exception { for (int i = 0; i < 100; i++) { File file = TestFileUtils.createTempFile("failure"); transporter.get(new GetTask(URI.create("repo/file.txt")).setDataFile(file)); assertTrue(i + ", " + file.getAbsolutePath(), file.delete()); } } @Test public void testGet_NotFound() throws Exception { try { transporter.get(new GetTask(URI.create("repo/missing.txt"))); fail("Expected error"); } catch (HttpResponseException e) { assertEquals(404, e.getStatusCode()); assertEquals(Transporter.ERROR_NOT_FOUND, transporter.classify(e)); } } @Test public void testGet_Closed() throws Exception { transporter.close(); try { transporter.get(new GetTask(URI.create("repo/file.txt"))); fail("Expected error"); } catch (IllegalStateException e) { assertEquals(Transporter.ERROR_OTHER, transporter.classify(e)); } } @Test public void testGet_StartCancelled() throws Exception { RecordingTransportListener listener = new RecordingTransportListener(); listener.cancelStart = true; GetTask task = new GetTask(URI.create("repo/file.txt")).setListener(listener); try { transporter.get(task); fail("Expected error"); } catch (TransferCancelledException e) { assertEquals(Transporter.ERROR_OTHER, transporter.classify(e)); } assertEquals(0L, listener.dataOffset); assertEquals(4L, listener.dataLength); assertEquals(1, listener.startedCount); assertEquals(0, listener.progressedCount); } @Test public void testGet_ProgressCancelled() throws Exception { RecordingTransportListener listener = new RecordingTransportListener(); listener.cancelProgress = true; GetTask task = new GetTask(URI.create("repo/file.txt")).setListener(listener); try { transporter.get(task); fail("Expected error"); } catch (TransferCancelledException e) { assertEquals(Transporter.ERROR_OTHER, transporter.classify(e)); } assertEquals(0L, listener.dataOffset); assertEquals(4L, listener.dataLength); assertEquals(1, listener.startedCount); assertEquals(1, listener.progressedCount); } @Test public void testPut_FromMemory() throws Exception { RecordingTransportListener listener = new RecordingTransportListener(); PutTask task = new PutTask(URI.create("repo/file.txt")).setListener(listener).setDataString("upload"); transporter.put(task); assertEquals(0L, listener.dataOffset); assertEquals(6L, listener.dataLength); assertEquals(1, listener.startedCount); assertTrue("Count: " + listener.progressedCount, listener.progressedCount > 0); assertEquals("upload", TestFileUtils.readString(new File(repoDir, "file.txt"))); } @Test public void testPut_FromFile() throws Exception { File file = TestFileUtils.createTempFile("upload"); RecordingTransportListener listener = new RecordingTransportListener(); PutTask task = new PutTask(URI.create("repo/file.txt")).setListener(listener).setDataFile(file); transporter.put(task); assertEquals(0L, listener.dataOffset); assertEquals(6L, listener.dataLength); assertEquals(1, listener.startedCount); assertTrue("Count: " + listener.progressedCount, listener.progressedCount > 0); assertEquals("upload", TestFileUtils.readString(new File(repoDir, "file.txt"))); } @Test public void testPut_EmptyResource() throws Exception { RecordingTransportListener listener = new RecordingTransportListener(); PutTask task = new PutTask(URI.create("repo/file.txt")).setListener(listener); transporter.put(task); assertEquals(0L, listener.dataOffset); assertEquals(0L, listener.dataLength); assertEquals(1, listener.startedCount); assertEquals(0, listener.progressedCount); assertEquals("", TestFileUtils.readString(new File(repoDir, "file.txt"))); } @Test public void testPut_EncodedResourcePath() throws Exception { RecordingTransportListener listener = new RecordingTransportListener(); PutTask task = new PutTask(URI.create("repo/some%20space.txt")).setListener(listener).setDataString("OK"); transporter.put(task); assertEquals(0L, listener.dataOffset); assertEquals(2L, listener.dataLength); assertEquals(1, listener.startedCount); assertTrue("Count: " + listener.progressedCount, listener.progressedCount > 0); assertEquals("OK", TestFileUtils.readString(new File(repoDir, "some space.txt"))); } @Test public void testPut_Authenticated_ExpectContinue() throws Exception { 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/file.txt")).setListener(listener).setDataString("upload"); transporter.put(task); assertEquals(0L, listener.dataOffset); assertEquals(6L, listener.dataLength); assertEquals(1, listener.startedCount); assertTrue("Count: " + listener.progressedCount, listener.progressedCount > 0); assertEquals("upload", TestFileUtils.readString(new File(repoDir, "file.txt"))); } @Test public void testPut_Authenticated_ExpectContinueBroken() throws Exception { httpServer.setAuthentication("testuser", "testpass"); httpServer.setExpectSupport(HttpServer.ExpectContinue.BROKEN); auth = new AuthenticationBuilder().addUsername("testuser").addPassword("testpass").build(); newTransporter(httpServer.getHttpUrl()); RecordingTransportListener listener = new RecordingTransportListener(); PutTask task = new PutTask(URI.create("repo/file.txt")).setListener(listener).setDataString("upload"); transporter.put(task); assertEquals(0L, listener.dataOffset); assertEquals(6L, listener.dataLength); assertEquals(1, listener.startedCount); assertTrue("Count: " + listener.progressedCount, listener.progressedCount > 0); assertEquals("upload", TestFileUtils.readString(new File(repoDir, "file.txt"))); } @Test public void testPut_Authenticated_ExpectContinueRejected() throws Exception { httpServer.setAuthentication("testuser", "testpass"); httpServer.setExpectSupport(HttpServer.ExpectContinue.FAIL); auth = new AuthenticationBuilder().addUsername("testuser").addPassword("testpass").build(); newTransporter(httpServer.getHttpUrl()); RecordingTransportListener listener = new RecordingTransportListener(); PutTask task = new PutTask(URI.create("repo/file.txt")).setListener(listener).setDataString("upload"); transporter.put(task); assertEquals(0L, listener.dataOffset); assertEquals(6L, listener.dataLength); assertEquals(1, listener.startedCount); assertTrue("Count: " + listener.progressedCount, listener.progressedCount > 0); assertEquals("upload", TestFileUtils.readString(new File(repoDir, "file.txt"))); } @Test public void testPut_Authenticated_ExpectContinueRejected_ExplicitlyConfiguredHeader() throws Exception { Map<String, String> headers = new HashMap<String, String>(); headers.put("Expect", "100-continue"); session.setConfigProperty(ConfigurationProperties.HTTP_HEADERS + ".test", headers); httpServer.setAuthentication("testuser", "testpass"); httpServer.setExpectSupport(HttpServer.ExpectContinue.FAIL); auth = new AuthenticationBuilder().addUsername("testuser").addPassword("testpass").build(); newTransporter(httpServer.getHttpUrl()); RecordingTransportListener listener = new RecordingTransportListener(); PutTask task = new PutTask(URI.create("repo/file.txt")).setListener(listener).setDataString("upload"); transporter.put(task); assertEquals(0L, listener.dataOffset); assertEquals(6L, listener.dataLength); assertEquals(1, listener.startedCount); assertTrue("Count: " + listener.progressedCount, listener.progressedCount > 0); assertEquals("upload", TestFileUtils.readString(new File(repoDir, "file.txt"))); } @Test public void testPut_Unauthenticated() throws Exception { httpServer.setAuthentication("testuser", "testpass"); RecordingTransportListener listener = new RecordingTransportListener(); PutTask task = new PutTask(URI.create("repo/file.txt")).setListener(listener).setDataString("upload"); try { transporter.put(task); fail("Expected error"); } catch (HttpResponseException e) { assertEquals(401, e.getStatusCode()); assertEquals(Transporter.ERROR_OTHER, transporter.classify(e)); } assertEquals(0, listener.startedCount); assertEquals(0, listener.progressedCount); } @Test public void testPut_ProxyAuthenticated() throws Exception { httpServer.setProxyAuthentication("testuser", "testpass"); Authentication auth = new AuthenticationBuilder().addUsername("testuser").addPassword("testpass").build(); proxy = new Proxy(Proxy.TYPE_HTTP, httpServer.getHost(), httpServer.getHttpPort(), auth); newTransporter("http://bad.localhost:1/"); RecordingTransportListener listener = new RecordingTransportListener(); PutTask task = new PutTask(URI.create("repo/file.txt")).setListener(listener).setDataString("upload"); transporter.put(task); assertEquals(0L, listener.dataOffset); assertEquals(6L, listener.dataLength); assertEquals(1, listener.startedCount); assertTrue("Count: " + listener.progressedCount, listener.progressedCount > 0); assertEquals("upload", TestFileUtils.readString(new File(repoDir, "file.txt"))); } @Test public void testPut_ProxyUnauthenticated() throws Exception { httpServer.setProxyAuthentication("testuser", "testpass"); proxy = new Proxy(Proxy.TYPE_HTTP, httpServer.getHost(), httpServer.getHttpPort()); newTransporter("http://bad.localhost:1/"); RecordingTransportListener listener = new RecordingTransportListener(); PutTask task = new PutTask(URI.create("repo/file.txt")).setListener(listener).setDataString("upload"); try { transporter.put(task); fail("Expected error"); } catch (HttpResponseException e) { assertEquals(407, e.getStatusCode()); assertEquals(Transporter.ERROR_OTHER, transporter.classify(e)); } assertEquals(0, listener.startedCount); assertEquals(0, listener.progressedCount); } @Test public void testPut_SSL() throws Exception { httpServer.addSslConnector(); httpServer.setAuthentication("testuser", "testpass"); auth = new AuthenticationBuilder().addUsername("testuser").addPassword("testpass").build(); newTransporter(httpServer.getHttpsUrl()); RecordingTransportListener listener = new RecordingTransportListener(); PutTask task = new PutTask(URI.create("repo/file.txt")).setListener(listener).setDataString("upload"); transporter.put(task); assertEquals(0L, listener.dataOffset); assertEquals(6L, listener.dataLength); assertEquals(1, listener.startedCount); assertTrue("Count: " + listener.progressedCount, listener.progressedCount > 0); assertEquals("upload", TestFileUtils.readString(new File(repoDir, "file.txt"))); } @Test public void testPut_WebDav() throws Exception { httpServer.setWebDav(true); RecordingTransportListener listener = new RecordingTransportListener(); PutTask task = new PutTask(URI.create("repo/dir1/dir2/file.txt")).setListener(listener) .setDataString("upload"); transporter.put(task); assertEquals(0L, listener.dataOffset); assertEquals(6L, 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(5, httpServer.getLogEntries().size()); assertEquals("OPTIONS", httpServer.getLogEntries().get(0).method); assertEquals("MKCOL", httpServer.getLogEntries().get(1).method); assertEquals("/repo/dir1/dir2/", httpServer.getLogEntries().get(1).path); assertEquals("MKCOL", httpServer.getLogEntries().get(2).method); assertEquals("/repo/dir1/", httpServer.getLogEntries().get(2).path); assertEquals("MKCOL", httpServer.getLogEntries().get(3).method); assertEquals("/repo/dir1/dir2/", httpServer.getLogEntries().get(3).path); assertEquals("PUT", httpServer.getLogEntries().get(4).method); } @Test public void testPut_FileHandleLeak() throws Exception { for (int i = 0; i < 100; i++) { File src = TestFileUtils.createTempFile("upload"); File dst = new File(repoDir, "file.txt"); transporter.put(new PutTask(URI.create("repo/file.txt")).setDataFile(src)); assertTrue(i + ", " + src.getAbsolutePath(), src.delete()); assertTrue(i + ", " + dst.getAbsolutePath(), dst.delete()); } } @Test public void testPut_Closed() throws Exception { transporter.close(); try { transporter.put(new PutTask(URI.create("repo/missing.txt"))); fail("Expected error"); } catch (IllegalStateException e) { assertEquals(Transporter.ERROR_OTHER, transporter.classify(e)); } } @Test public void testPut_StartCancelled() throws Exception { RecordingTransportListener listener = new RecordingTransportListener(); listener.cancelStart = true; PutTask task = new PutTask(URI.create("repo/file.txt")).setListener(listener).setDataString("upload"); try { transporter.put(task); fail("Expected error"); } catch (TransferCancelledException e) { assertEquals(Transporter.ERROR_OTHER, transporter.classify(e)); } assertEquals(0L, listener.dataOffset); assertEquals(6L, listener.dataLength); assertEquals(1, listener.startedCount); assertEquals(0, listener.progressedCount); } @Test public void testPut_ProgressCancelled() throws Exception { RecordingTransportListener listener = new RecordingTransportListener(); listener.cancelProgress = true; PutTask task = new PutTask(URI.create("repo/file.txt")).setListener(listener).setDataString("upload"); try { transporter.put(task); fail("Expected error"); } catch (TransferCancelledException e) { assertEquals(Transporter.ERROR_OTHER, transporter.classify(e)); } assertEquals(0L, listener.dataOffset); assertEquals(6L, listener.dataLength); assertEquals(1, listener.startedCount); assertEquals(1, listener.progressedCount); } @Test public void testGetPut_AuthCache() throws Exception { httpServer.setAuthentication("testuser", "testpass"); auth = new AuthenticationBuilder().addUsername("testuser").addPassword("testpass").build(); newTransporter(httpServer.getHttpUrl()); GetTask get = new GetTask(URI.create("repo/file.txt")); transporter.get(get); RecordingTransportListener listener = new RecordingTransportListener(); PutTask task = new PutTask(URI.create("repo/file.txt")).setListener(listener).setDataString("upload"); transporter.put(task); assertEquals(1, listener.startedCount); } @Test(timeout = 20000L) public void testConcurrency() throws Exception { httpServer.setAuthentication("testuser", "testpass"); auth = new AuthenticationBuilder().addUsername("testuser").addPassword("testpass").build(); newTransporter(httpServer.getHttpUrl()); final AtomicReference<Throwable> error = new AtomicReference<Throwable>(); Thread threads[] = new Thread[20]; for (int i = 0; i < threads.length; i++) { final String path = "repo/file.txt?i=" + i; threads[i] = new Thread() { @Override public void run() { try { for (int j = 0; j < 100; j++) { GetTask task = new GetTask(URI.create(path)); transporter.get(task); assertEquals("test", task.getDataString()); } } catch (Throwable t) { error.compareAndSet(null, t); System.err.println(path); t.printStackTrace(); } } }; threads[i].setName("Task-" + i); } for (Thread thread : threads) { thread.start(); } for (Thread thread : threads) { thread.join(); } assertNull(String.valueOf(error.get()), error.get()); } @Test(timeout = 1000L) public void testConnectTimeout() throws Exception { session.setConfigProperty(ConfigurationProperties.CONNECT_TIMEOUT, 100); int port = 1; newTransporter("http://localhost:" + port); try { transporter.get(new GetTask(URI.create("repo/file.txt"))); fail("Expected error"); } catch (ConnectTimeoutException e) { assertEquals(Transporter.ERROR_OTHER, transporter.classify(e)); } catch (ConnectException e) { assertEquals(Transporter.ERROR_OTHER, transporter.classify(e)); } } @Test(timeout = 1000L) public void testRequestTimeout() throws Exception { session.setConfigProperty(ConfigurationProperties.REQUEST_TIMEOUT, 100); ServerSocket server = new ServerSocket(0); newTransporter("http://localhost:" + server.getLocalPort()); try { try { transporter.get(new GetTask(URI.create("repo/file.txt"))); fail("Expected error"); } catch (SocketTimeoutException e) { assertEquals(Transporter.ERROR_OTHER, transporter.classify(e)); } } finally { server.close(); } } @Test public void testUserAgent() throws Exception { session.setConfigProperty(ConfigurationProperties.USER_AGENT, "SomeTest/1.0"); newTransporter(httpServer.getHttpUrl()); transporter.get(new GetTask(URI.create("repo/file.txt"))); assertEquals(1, httpServer.getLogEntries().size()); for (HttpServer.LogEntry log : httpServer.getLogEntries()) { assertEquals("SomeTest/1.0", log.headers.get("User-Agent")); } } @Test public void testCustomHeaders() throws Exception { Map<String, String> headers = new HashMap<String, String>(); headers.put("User-Agent", "Custom/1.0"); headers.put("X-CustomHeader", "Custom-Value"); session.setConfigProperty(ConfigurationProperties.USER_AGENT, "SomeTest/1.0"); session.setConfigProperty(ConfigurationProperties.HTTP_HEADERS + ".test", headers); newTransporter(httpServer.getHttpUrl()); transporter.get(new GetTask(URI.create("repo/file.txt"))); assertEquals(1, httpServer.getLogEntries().size()); for (HttpServer.LogEntry log : httpServer.getLogEntries()) { for (Map.Entry<String, String> entry : headers.entrySet()) { assertEquals(entry.getKey(), entry.getValue(), log.headers.get(entry.getKey())); } } } @Test public void testServerAuthScope_NotUsedForProxy() throws Exception { String username = "testuser", password = "testpass"; httpServer.setProxyAuthentication(username, password); auth = new AuthenticationBuilder().addUsername(username).addPassword(password).build(); proxy = new Proxy(Proxy.TYPE_HTTP, httpServer.getHost(), httpServer.getHttpPort()); newTransporter("http://" + httpServer.getHost() + ":12/"); try { transporter.get(new GetTask(URI.create("repo/file.txt"))); fail("Server auth must not be used as proxy auth"); } catch (HttpResponseException e) { assertEquals(407, e.getStatusCode()); } } @Test public void testProxyAuthScope_NotUsedForServer() throws Exception { String username = "testuser", password = "testpass"; httpServer.setAuthentication(username, password); Authentication auth = new AuthenticationBuilder().addUsername(username).addPassword(password).build(); proxy = new Proxy(Proxy.TYPE_HTTP, httpServer.getHost(), httpServer.getHttpPort(), auth); newTransporter("http://" + httpServer.getHost() + ":12/"); try { transporter.get(new GetTask(URI.create("repo/file.txt"))); fail("Proxy auth must not be used as server auth"); } catch (HttpResponseException e) { assertEquals(401, e.getStatusCode()); } } @Test public void testAuthSchemeReuse() throws Exception { httpServer.setAuthentication("testuser", "testpass"); httpServer.setProxyAuthentication("proxyuser", "proxypass"); session.setCache(new DefaultRepositoryCache()); auth = new AuthenticationBuilder().addUsername("testuser").addPassword("testpass").build(); Authentication auth = new AuthenticationBuilder().addUsername("proxyuser").addPassword("proxypass").build(); proxy = new Proxy(Proxy.TYPE_HTTP, httpServer.getHost(), httpServer.getHttpPort(), auth); newTransporter("http://bad.localhost:1/"); GetTask task = new GetTask(URI.create("repo/file.txt")); transporter.get(task); assertEquals("test", task.getDataString()); assertEquals(3, httpServer.getLogEntries().size()); httpServer.getLogEntries().clear(); newTransporter("http://bad.localhost:1/"); task = new GetTask(URI.create("repo/file.txt")); transporter.get(task); assertEquals("test", task.getDataString()); assertEquals(1, httpServer.getLogEntries().size()); assertNotNull(httpServer.getLogEntries().get(0).headers.get("Authorization")); assertNotNull(httpServer.getLogEntries().get(0).headers.get("Proxy-Authorization")); } @Test public void testConnectionReuse() throws Exception { httpServer.addSslConnector(); session.setCache(new DefaultRepositoryCache()); for (int i = 0; i < 3; i++) { newTransporter(httpServer.getHttpsUrl()); GetTask task = new GetTask(URI.create("repo/file.txt")); transporter.get(task); assertEquals("test", task.getDataString()); } PoolStats stats = ((ConnPoolControl<?>) ((HttpTransporter) transporter).getState().getConnectionManager()) .getTotalStats(); assertEquals(stats.toString(), 1, stats.getAvailable()); } @Test(expected = NoTransporterException.class) public void testInit_BadProtocol() throws Exception { newTransporter("bad:/void"); } @Test(expected = NoTransporterException.class) public void testInit_BadUrl() throws Exception { newTransporter("http://localhost:NaN"); } @Test public void testInit_CaseInsensitiveProtocol() throws Exception { newTransporter("http://localhost"); newTransporter("HTTP://localhost"); newTransporter("Http://localhost"); newTransporter("https://localhost"); newTransporter("HTTPS://localhost"); newTransporter("HttpS://localhost"); } }