1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.aether.internal.test.util.http;
20
21 import java.io.*;
22 import java.net.ServerSocket;
23 import java.net.URI;
24 import java.net.URL;
25 import java.nio.charset.StandardCharsets;
26 import java.nio.file.Files;
27 import java.nio.file.Path;
28 import java.nio.file.Paths;
29 import java.nio.file.StandardCopyOption;
30 import java.util.HashMap;
31 import java.util.Map;
32 import java.util.concurrent.atomic.AtomicReference;
33 import java.util.function.Supplier;
34
35 import org.eclipse.aether.ConfigurationProperties;
36 import org.eclipse.aether.DefaultRepositoryCache;
37 import org.eclipse.aether.DefaultSessionData;
38 import org.eclipse.aether.internal.test.util.TestFileUtils;
39 import org.eclipse.aether.internal.test.util.TestLocalRepositoryManager;
40 import org.eclipse.aether.internal.test.util.TestRepositorySystemSession;
41 import org.eclipse.aether.repository.Authentication;
42 import org.eclipse.aether.repository.Proxy;
43 import org.eclipse.aether.repository.RemoteRepository;
44 import org.eclipse.aether.spi.connector.transport.GetTask;
45 import org.eclipse.aether.spi.connector.transport.PeekTask;
46 import org.eclipse.aether.spi.connector.transport.PutTask;
47 import org.eclipse.aether.spi.connector.transport.Transporter;
48 import org.eclipse.aether.spi.connector.transport.http.HttpTransporter;
49 import org.eclipse.aether.spi.connector.transport.http.HttpTransporterException;
50 import org.eclipse.aether.spi.connector.transport.http.HttpTransporterFactory;
51 import org.eclipse.aether.transfer.NoTransporterException;
52 import org.eclipse.aether.transfer.TransferCancelledException;
53 import org.eclipse.aether.util.repository.AuthenticationBuilder;
54 import org.junit.jupiter.api.*;
55
56 import static java.util.Objects.requireNonNull;
57 import static org.junit.jupiter.api.Assertions.*;
58
59
60
61
62 @SuppressWarnings({"checkstyle:MagicNumber", "checkstyle:MethodName"})
63 public class HttpTransporterTest {
64
65 protected static final Path KEY_STORE_PATH = Paths.get("target/keystore");
66
67 protected static final Path KEY_STORE_SELF_SIGNED_PATH = Paths.get("target/keystore-self-signed");
68
69 protected static final Path TRUST_STORE_PATH = Paths.get("target/trustStore");
70
71 static {
72
73 System.setProperty(
74 "javax.net.ssl.trustStore", KEY_STORE_PATH.toAbsolutePath().toString());
75 System.setProperty("javax.net.ssl.trustStorePassword", "server-pwd");
76 System.setProperty(
77 "javax.net.ssl.keyStore", TRUST_STORE_PATH.toAbsolutePath().toString());
78 System.setProperty("javax.net.ssl.keyStorePassword", "client-pwd");
79
80 System.setProperty("javax.net.ssl.trustStoreType", "jks");
81 System.setProperty("javax.net.ssl.keyStoreType", "jks");
82 System.setProperty("javax.net.debug", "all");
83 }
84
85 private final Supplier<HttpTransporterFactory> transporterFactorySupplier;
86
87 protected TestRepositorySystemSession session;
88
89 protected HttpTransporterFactory factory;
90
91 protected HttpTransporter transporter;
92
93 protected Runnable closer;
94
95 protected File repoDir;
96
97 protected HttpServer httpServer;
98
99 protected Authentication auth;
100
101 protected Proxy proxy;
102
103 protected HttpTransporterTest(Supplier<HttpTransporterFactory> transporterFactorySupplier) {
104 this.transporterFactorySupplier = requireNonNull(transporterFactorySupplier);
105
106 if (!Files.isRegularFile(KEY_STORE_PATH)) {
107 URL keyStoreUrl = HttpTransporterTest.class.getClassLoader().getResource("ssl/server-store");
108 URL keyStoreSelfSignedUrl =
109 HttpTransporterTest.class.getClassLoader().getResource("ssl/server-store-selfsigned");
110 URL trustStoreUrl = HttpTransporterTest.class.getClassLoader().getResource("ssl/client-store");
111
112 try {
113 try (InputStream keyStoreStream = keyStoreUrl.openStream();
114 InputStream keyStoreSelfSignedStream = keyStoreSelfSignedUrl.openStream();
115 InputStream trustStoreStream = trustStoreUrl.openStream()) {
116 Files.copy(keyStoreStream, KEY_STORE_PATH, StandardCopyOption.REPLACE_EXISTING);
117 Files.copy(
118 keyStoreSelfSignedStream, KEY_STORE_SELF_SIGNED_PATH, StandardCopyOption.REPLACE_EXISTING);
119 Files.copy(trustStoreStream, TRUST_STORE_PATH, StandardCopyOption.REPLACE_EXISTING);
120 }
121 } catch (IOException e) {
122 throw new UncheckedIOException(e);
123 }
124 }
125 }
126
127 protected RemoteRepository newRepo(String url) {
128 return new RemoteRepository.Builder("test", "default", url)
129 .setAuthentication(auth)
130 .setProxy(proxy)
131 .build();
132 }
133
134 protected void newTransporter(String url) throws Exception {
135 if (transporter != null) {
136 transporter.close();
137 transporter = null;
138 }
139 if (closer != null) {
140 closer.run();
141 closer = null;
142 }
143 session = new TestRepositorySystemSession(session);
144 session.setData(new DefaultSessionData());
145 transporter = factory.newInstance(session, newRepo(url));
146 }
147
148 protected static final long OLD_FILE_TIMESTAMP = 160660800000L;
149
150 @BeforeEach
151 protected void setUp(TestInfo testInfo) throws Exception {
152 System.out.println("=== " + testInfo.getDisplayName() + " ===");
153 session = new TestRepositorySystemSession(h -> this.closer = h);
154 session.setLocalRepositoryManager(new TestLocalRepositoryManager());
155 factory = transporterFactorySupplier.get();
156 repoDir = TestFileUtils.createTempDir();
157 TestFileUtils.writeString(new File(repoDir, "file.txt"), "test");
158 TestFileUtils.writeString(new File(repoDir, "dir/file.txt"), "test");
159 TestFileUtils.writeString(new File(repoDir, "dir/oldFile.txt"), "oldTest", OLD_FILE_TIMESTAMP);
160 TestFileUtils.writeString(new File(repoDir, "empty.txt"), "");
161 TestFileUtils.writeString(new File(repoDir, "some space.txt"), "space");
162 File resumable = new File(repoDir, "resume.txt");
163 TestFileUtils.writeString(resumable, "resumable");
164 resumable.setLastModified(System.currentTimeMillis() - 90 * 1000);
165 httpServer = new HttpServer().setRepoDir(repoDir).start();
166 newTransporter(httpServer.getHttpUrl());
167 }
168
169 @AfterEach
170 protected void tearDown() throws Exception {
171 if (transporter != null) {
172 transporter.close();
173 transporter = null;
174 }
175 if (closer != null) {
176 closer.run();
177 closer = null;
178 }
179 if (httpServer != null) {
180 httpServer.stop();
181 httpServer = null;
182 }
183 factory = null;
184 session = null;
185 }
186
187 @Test
188 protected void testClassify() {
189 assertEquals(Transporter.ERROR_OTHER, transporter.classify(new FileNotFoundException()));
190 assertEquals(Transporter.ERROR_OTHER, transporter.classify(new HttpTransporterException(403)));
191 assertEquals(Transporter.ERROR_NOT_FOUND, transporter.classify(new HttpTransporterException(404)));
192 }
193
194 @Test
195 protected void testPeek() throws Exception {
196 transporter.peek(new PeekTask(URI.create("repo/file.txt")));
197 }
198
199 @Test
200 protected void testRetryHandler_defaultCount_positive() throws Exception {
201 httpServer.setConnectionsToClose(3);
202 transporter.peek(new PeekTask(URI.create("repo/file.txt")));
203 }
204
205 @Test
206 protected void testRetryHandler_defaultCount_negative() throws Exception {
207 httpServer.setConnectionsToClose(4);
208 try {
209 transporter.peek(new PeekTask(URI.create("repo/file.txt")));
210 fail("Expected error");
211 } catch (Exception expected) {
212 }
213 }
214
215 @Test
216 protected void testRetryHandler_explicitCount_positive() throws Exception {
217 session.setConfigProperty(ConfigurationProperties.HTTP_RETRY_HANDLER_COUNT, 10);
218 newTransporter(httpServer.getHttpUrl());
219 httpServer.setConnectionsToClose(10);
220 transporter.peek(new PeekTask(URI.create("repo/file.txt")));
221 }
222
223 @Test
224 protected void testRetryHandler_disabled() throws Exception {
225 session.setConfigProperty(ConfigurationProperties.HTTP_RETRY_HANDLER_COUNT, 0);
226 newTransporter(httpServer.getHttpUrl());
227 httpServer.setConnectionsToClose(1);
228 try {
229 transporter.peek(new PeekTask(URI.create("repo/file.txt")));
230 } catch (Exception expected) {
231 }
232 }
233
234 @Test
235 protected void testPeek_NotFound() throws Exception {
236 try {
237 transporter.peek(new PeekTask(URI.create("repo/missing.txt")));
238 fail("Expected error");
239 } catch (HttpTransporterException e) {
240 assertEquals(404, e.getStatusCode());
241 assertEquals(Transporter.ERROR_NOT_FOUND, transporter.classify(e));
242 }
243 }
244
245 @Test
246 protected void testPeek_Closed() throws Exception {
247 transporter.close();
248 try {
249 transporter.peek(new PeekTask(URI.create("repo/missing.txt")));
250 fail("Expected error");
251 } catch (IllegalStateException e) {
252 assertEquals(Transporter.ERROR_OTHER, transporter.classify(e));
253 }
254 }
255
256 @Test
257 protected void testPeek_Authenticated() throws Exception {
258 httpServer.setAuthentication("testuser", "testpass");
259 auth = new AuthenticationBuilder()
260 .addUsername("testuser")
261 .addPassword("testpass")
262 .build();
263 newTransporter(httpServer.getHttpUrl());
264 transporter.peek(new PeekTask(URI.create("repo/file.txt")));
265 }
266
267 @Test
268 protected void testPeek_Unauthenticated() throws Exception {
269 httpServer.setAuthentication("testuser", "testpass");
270 try {
271 transporter.peek(new PeekTask(URI.create("repo/file.txt")));
272 fail("Expected error");
273 } catch (HttpTransporterException e) {
274 assertEquals(401, e.getStatusCode());
275 assertEquals(Transporter.ERROR_OTHER, transporter.classify(e));
276 }
277 }
278
279 @Test
280 protected void testPeek_ProxyAuthenticated() throws Exception {
281 httpServer.setProxyAuthentication("testuser", "testpass");
282 auth = new AuthenticationBuilder()
283 .addUsername("testuser")
284 .addPassword("testpass")
285 .build();
286 proxy = new Proxy(Proxy.TYPE_HTTP, httpServer.getHost(), httpServer.getHttpPort(), auth);
287 newTransporter("http://bad.localhost:1/");
288 transporter.peek(new PeekTask(URI.create("repo/file.txt")));
289 }
290
291 @Test
292 protected void testPeek_ProxyUnauthenticated() throws Exception {
293 httpServer.setProxyAuthentication("testuser", "testpass");
294 proxy = new Proxy(Proxy.TYPE_HTTP, httpServer.getHost(), httpServer.getHttpPort());
295 newTransporter("http://bad.localhost:1/");
296 try {
297 transporter.peek(new PeekTask(URI.create("repo/file.txt")));
298 fail("Expected error");
299 } catch (HttpTransporterException e) {
300 assertEquals(407, e.getStatusCode());
301 assertEquals(Transporter.ERROR_OTHER, transporter.classify(e));
302 }
303 }
304
305 @Test
306 protected void testPeek_SSL() throws Exception {
307 httpServer.addSslConnector();
308 newTransporter(httpServer.getHttpsUrl());
309 transporter.peek(new PeekTask(URI.create("repo/file.txt")));
310 }
311
312 @Test
313 protected void testPeek_Redirect() throws Exception {
314 httpServer.addSslConnector();
315 transporter.peek(new PeekTask(URI.create("redirect/file.txt")));
316 transporter.peek(new PeekTask(URI.create("redirect/file.txt?scheme=https")));
317 }
318
319 @Test
320 protected void testGet_ToMemory() throws Exception {
321 RecordingTransportListener listener = new RecordingTransportListener();
322 GetTask task = new GetTask(URI.create("repo/file.txt")).setListener(listener);
323 transporter.get(task);
324 assertEquals("test", task.getDataString());
325 assertEquals(0L, listener.getDataOffset());
326 assertEquals(4L, listener.getDataLength());
327 assertEquals(1, listener.getStartedCount());
328 assertTrue(listener.getProgressedCount() > 0, "Count: " + listener.getProgressedCount());
329 assertEquals(task.getDataString(), listener.getBaos().toString(StandardCharsets.UTF_8));
330 }
331
332 @Test
333 protected void testGet_ToFile() throws Exception {
334 File file = TestFileUtils.createTempFile("failure");
335 RecordingTransportListener listener = new RecordingTransportListener();
336 GetTask task =
337 new GetTask(URI.create("repo/file.txt")).setDataFile(file).setListener(listener);
338 transporter.get(task);
339 assertEquals("test", TestFileUtils.readString(file));
340 assertEquals(0L, listener.getDataOffset());
341 assertEquals(4L, listener.getDataLength());
342 assertEquals(1, listener.getStartedCount());
343 assertTrue(listener.getProgressedCount() > 0, "Count: " + listener.getProgressedCount());
344 assertEquals("test", listener.getBaos().toString(StandardCharsets.UTF_8));
345 }
346
347 @Test
348 protected void testGet_ToFileTimestamp() throws Exception {
349 File file = TestFileUtils.createTempFile("failure");
350 RecordingTransportListener listener = new RecordingTransportListener();
351 GetTask task = new GetTask(URI.create("repo/dir/oldFile.txt"))
352 .setDataFile(file)
353 .setListener(listener);
354 transporter.get(task);
355 assertEquals("oldTest", TestFileUtils.readString(file));
356 assertEquals(0L, listener.getDataOffset());
357 assertEquals(7L, listener.getDataLength());
358 assertEquals(1, listener.getStartedCount());
359 assertTrue(listener.getProgressedCount() > 0, "Count: " + listener.getProgressedCount());
360 assertEquals("oldTest", listener.getBaos().toString(StandardCharsets.UTF_8));
361 assertEquals(file.lastModified(), OLD_FILE_TIMESTAMP);
362 }
363
364 @Test
365 protected void testGet_EmptyResource() throws Exception {
366 File file = TestFileUtils.createTempFile("failure");
367 RecordingTransportListener listener = new RecordingTransportListener();
368 GetTask task =
369 new GetTask(URI.create("repo/empty.txt")).setDataFile(file).setListener(listener);
370 transporter.get(task);
371 assertEquals("", TestFileUtils.readString(file));
372 assertEquals(0L, listener.getDataOffset());
373 assertEquals(0L, listener.getDataLength());
374 assertEquals(1, listener.getStartedCount());
375 assertEquals(0, listener.getProgressedCount());
376 assertEquals("", listener.getBaos().toString(StandardCharsets.UTF_8));
377 }
378
379 @Test
380 protected void testGet_EncodedResourcePath() throws Exception {
381 GetTask task = new GetTask(URI.create("repo/some%20space.txt"));
382 transporter.get(task);
383 assertEquals("space", task.getDataString());
384 }
385
386 @Test
387 protected void testGet_Authenticated() throws Exception {
388 httpServer.setAuthentication("testuser", "testpass");
389 auth = new AuthenticationBuilder()
390 .addUsername("testuser")
391 .addPassword("testpass")
392 .build();
393 newTransporter(httpServer.getHttpUrl());
394 RecordingTransportListener listener = new RecordingTransportListener();
395 GetTask task = new GetTask(URI.create("repo/file.txt")).setListener(listener);
396 transporter.get(task);
397 assertEquals("test", task.getDataString());
398 assertEquals(0L, listener.getDataOffset());
399 assertEquals(4L, listener.getDataLength());
400 assertEquals(1, listener.getStartedCount());
401 assertTrue(listener.getProgressedCount() > 0, "Count: " + listener.getProgressedCount());
402 assertEquals(task.getDataString(), listener.getBaos().toString(StandardCharsets.UTF_8));
403 }
404
405 @Test
406 protected void testGet_Unauthenticated() throws Exception {
407 httpServer.setAuthentication("testuser", "testpass");
408 try {
409 transporter.get(new GetTask(URI.create("repo/file.txt")));
410 fail("Expected error");
411 } catch (HttpTransporterException e) {
412 assertEquals(401, e.getStatusCode());
413 assertEquals(Transporter.ERROR_OTHER, transporter.classify(e));
414 }
415 }
416
417 @Test
418 protected void testGet_ProxyAuthenticated() throws Exception {
419 httpServer.setProxyAuthentication("testuser", "testpass");
420 Authentication auth = new AuthenticationBuilder()
421 .addUsername("testuser")
422 .addPassword("testpass")
423 .build();
424 proxy = new Proxy(Proxy.TYPE_HTTP, httpServer.getHost(), httpServer.getHttpPort(), auth);
425 newTransporter("http://bad.localhost:1/");
426 RecordingTransportListener listener = new RecordingTransportListener();
427 GetTask task = new GetTask(URI.create("repo/file.txt")).setListener(listener);
428 transporter.get(task);
429 assertEquals("test", task.getDataString());
430 assertEquals(0L, listener.getDataOffset());
431 assertEquals(4L, listener.getDataLength());
432 assertEquals(1, listener.getStartedCount());
433 assertTrue(listener.getProgressedCount() > 0, "Count: " + listener.getProgressedCount());
434 assertEquals(task.getDataString(), listener.getBaos().toString(StandardCharsets.UTF_8));
435 }
436
437 @Test
438 protected void testGet_ProxyUnauthenticated() throws Exception {
439 httpServer.setProxyAuthentication("testuser", "testpass");
440 proxy = new Proxy(Proxy.TYPE_HTTP, httpServer.getHost(), httpServer.getHttpPort());
441 newTransporter("http://bad.localhost:1/");
442 try {
443 transporter.get(new GetTask(URI.create("repo/file.txt")));
444 fail("Expected error");
445 } catch (HttpTransporterException e) {
446 assertEquals(407, e.getStatusCode());
447 assertEquals(Transporter.ERROR_OTHER, transporter.classify(e));
448 }
449 }
450
451 @Test
452 protected void testGet_SSL() throws Exception {
453 httpServer.addSslConnector();
454 newTransporter(httpServer.getHttpsUrl());
455 RecordingTransportListener listener = new RecordingTransportListener();
456 GetTask task = new GetTask(URI.create("repo/file.txt")).setListener(listener);
457 transporter.get(task);
458 assertEquals("test", task.getDataString());
459 assertEquals(0L, listener.getDataOffset());
460 assertEquals(4L, listener.getDataLength());
461 assertEquals(1, listener.getStartedCount());
462 assertTrue(listener.getProgressedCount() > 0, "Count: " + listener.getProgressedCount());
463 assertEquals(task.getDataString(), listener.getBaos().toString(StandardCharsets.UTF_8));
464 }
465
466 @Test
467 protected void testGet_SSL_WithServerErrors() throws Exception {
468 httpServer.setServerErrorsBeforeWorks(1);
469 httpServer.addSslConnector();
470 newTransporter(httpServer.getHttpsUrl());
471 for (int i = 1; i < 3; i++) {
472 try {
473 RecordingTransportListener listener = new RecordingTransportListener();
474 GetTask task = new GetTask(URI.create("repo/file.txt")).setListener(listener);
475 transporter.get(task);
476 assertEquals("test", task.getDataString());
477 assertEquals(0L, listener.getDataOffset());
478 assertEquals(4L, listener.getDataLength());
479 assertEquals(1, listener.getStartedCount());
480 assertTrue(listener.getProgressedCount() > 0, "Count: " + listener.getProgressedCount());
481 assertEquals(task.getDataString(), listener.getBaos().toString(StandardCharsets.UTF_8));
482 } catch (HttpTransporterException e) {
483 assertEquals(500, e.getStatusCode());
484 }
485 }
486 }
487
488 @Test
489 protected void testGet_HTTPS_Unknown_SecurityMode() throws Exception {
490 session.setConfigProperty(ConfigurationProperties.HTTPS_SECURITY_MODE, "unknown");
491 httpServer.addSelfSignedSslConnector();
492 try {
493 newTransporter(httpServer.getHttpsUrl());
494 fail("Unsupported security mode");
495 } catch (IllegalArgumentException a) {
496
497 }
498 }
499
500 @Test
501 protected void testGet_HTTPS_Insecure_SecurityMode() throws Exception {
502
503
504 session.setConfigProperty(
505 ConfigurationProperties.HTTPS_SECURITY_MODE, ConfigurationProperties.HTTPS_SECURITY_MODE_INSECURE);
506 httpServer.addSelfSignedSslConnector();
507 newTransporter(httpServer.getHttpsUrl());
508 RecordingTransportListener listener = new RecordingTransportListener();
509 GetTask task = new GetTask(URI.create("repo/file.txt")).setListener(listener);
510 transporter.get(task);
511 assertEquals("test", task.getDataString());
512 assertEquals(0L, listener.getDataOffset());
513 assertEquals(4L, listener.getDataLength());
514 assertEquals(1, listener.getStartedCount());
515 assertTrue(listener.getProgressedCount() > 0, "Count: " + listener.getProgressedCount());
516 assertEquals(task.getDataString(), listener.getBaos().toString(StandardCharsets.UTF_8));
517 }
518
519 @Test
520 protected void testGet_Redirect() throws Exception {
521 httpServer.addSslConnector();
522 RecordingTransportListener listener = new RecordingTransportListener();
523 GetTask task = new GetTask(URI.create("redirect/file.txt?scheme=https")).setListener(listener);
524 transporter.get(task);
525 assertEquals("test", task.getDataString());
526 assertEquals(0L, listener.getDataOffset());
527 assertEquals(4L, listener.getDataLength());
528 assertEquals(1, listener.getStartedCount());
529 assertTrue(listener.getProgressedCount() > 0, "Count: " + listener.getProgressedCount());
530 assertEquals(task.getDataString(), listener.getBaos().toString(StandardCharsets.UTF_8));
531 }
532
533 @Test
534 protected void testGet_Resume() throws Exception {
535 File file = TestFileUtils.createTempFile("re");
536 RecordingTransportListener listener = new RecordingTransportListener();
537 GetTask task = new GetTask(URI.create("repo/resume.txt"))
538 .setDataFile(file, true)
539 .setListener(listener);
540 transporter.get(task);
541 assertEquals("resumable", TestFileUtils.readString(file));
542 assertEquals(1L, listener.getStartedCount());
543 assertEquals(2L, listener.getDataOffset());
544 assertEquals(9, listener.getDataLength());
545 assertTrue(listener.getProgressedCount() > 0, "Count: " + listener.getProgressedCount());
546 assertEquals("sumable", listener.getBaos().toString(StandardCharsets.UTF_8));
547 }
548
549 @Test
550 protected void testGet_ResumeLocalContentsOutdated() throws Exception {
551 File file = TestFileUtils.createTempFile("re");
552 file.setLastModified(System.currentTimeMillis() - 5 * 60 * 1000);
553 RecordingTransportListener listener = new RecordingTransportListener();
554 GetTask task = new GetTask(URI.create("repo/resume.txt"))
555 .setDataFile(file, true)
556 .setListener(listener);
557 transporter.get(task);
558 assertEquals("resumable", TestFileUtils.readString(file));
559 assertEquals(1L, listener.getStartedCount());
560 assertEquals(0L, listener.getDataOffset());
561 assertEquals(9, listener.getDataLength());
562 assertTrue(listener.getProgressedCount() > 0, "Count: " + listener.getProgressedCount());
563 assertEquals("resumable", listener.getBaos().toString(StandardCharsets.UTF_8));
564 }
565
566 @Test
567 protected void testGet_ResumeRangesNotSupportedByServer() throws Exception {
568 httpServer.setRangeSupport(false);
569 File file = TestFileUtils.createTempFile("re");
570 RecordingTransportListener listener = new RecordingTransportListener();
571 GetTask task = new GetTask(URI.create("repo/resume.txt"))
572 .setDataFile(file, true)
573 .setListener(listener);
574 transporter.get(task);
575 assertEquals("resumable", TestFileUtils.readString(file));
576 assertEquals(1L, listener.getStartedCount());
577 assertEquals(0L, listener.getDataOffset());
578 assertEquals(9, listener.getDataLength());
579 assertTrue(listener.getProgressedCount() > 0, "Count: " + listener.getProgressedCount());
580 assertEquals("resumable", listener.getBaos().toString(StandardCharsets.UTF_8));
581 }
582
583 @Test
584 protected void testGet_Checksums_Nexus() throws Exception {
585 httpServer.setChecksumHeader(HttpServer.ChecksumHeader.NEXUS);
586 GetTask task = new GetTask(URI.create("repo/file.txt"));
587 transporter.get(task);
588 assertEquals("test", task.getDataString());
589 assertEquals(
590 "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3", task.getChecksums().get("SHA-1"));
591 }
592
593 @Test
594 protected void testGet_Checksums_XChecksum() throws Exception {
595 httpServer.setChecksumHeader(HttpServer.ChecksumHeader.XCHECKSUM);
596 GetTask task = new GetTask(URI.create("repo/file.txt"));
597 transporter.get(task);
598 assertEquals("test", task.getDataString());
599 assertEquals(
600 "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3", task.getChecksums().get("SHA-1"));
601 }
602
603 @Test
604 protected void testGet_FileHandleLeak() throws Exception {
605 for (int i = 0; i < 100; i++) {
606 File file = TestFileUtils.createTempFile("failure");
607 transporter.get(new GetTask(URI.create("repo/file.txt")).setDataFile(file));
608 assertTrue(file.delete(), i + ", " + file.getAbsolutePath());
609 }
610 }
611
612 @Test
613 protected void testGet_NotFound() throws Exception {
614 try {
615 transporter.get(new GetTask(URI.create("repo/missing.txt")));
616 fail("Expected error");
617 } catch (HttpTransporterException e) {
618 assertEquals(404, e.getStatusCode());
619 assertEquals(Transporter.ERROR_NOT_FOUND, transporter.classify(e));
620 }
621 }
622
623 @Test
624 protected void testGet_Closed() throws Exception {
625 transporter.close();
626 try {
627 transporter.get(new GetTask(URI.create("repo/file.txt")));
628 fail("Expected error");
629 } catch (IllegalStateException e) {
630 assertEquals(Transporter.ERROR_OTHER, transporter.classify(e));
631 }
632 }
633
634 @Test
635 protected void testGet_StartCancelled() throws Exception {
636 RecordingTransportListener listener = new RecordingTransportListener();
637 listener.cancelStart();
638 GetTask task = new GetTask(URI.create("repo/file.txt")).setListener(listener);
639 try {
640 transporter.get(task);
641 fail("Expected error");
642 } catch (TransferCancelledException e) {
643 assertEquals(Transporter.ERROR_OTHER, transporter.classify(e));
644 }
645 assertEquals(0L, listener.getDataOffset());
646 assertEquals(4L, listener.getDataLength());
647 assertEquals(1, listener.getStartedCount());
648 assertEquals(0, listener.getProgressedCount());
649 }
650
651 @Test
652 protected void testGet_ProgressCancelled() throws Exception {
653 RecordingTransportListener listener = new RecordingTransportListener();
654 listener.cancelProgress();
655 GetTask task = new GetTask(URI.create("repo/file.txt")).setListener(listener);
656 try {
657 transporter.get(task);
658 fail("Expected error");
659 } catch (TransferCancelledException e) {
660 assertEquals(Transporter.ERROR_OTHER, transporter.classify(e));
661 }
662 assertEquals(0L, listener.getDataOffset());
663 assertEquals(4L, listener.getDataLength());
664 assertEquals(1, listener.getStartedCount());
665 assertEquals(1, listener.getProgressedCount());
666 }
667
668 @Test
669 protected void testPut_FromMemory() throws Exception {
670 RecordingTransportListener listener = new RecordingTransportListener();
671 PutTask task =
672 new PutTask(URI.create("repo/file.txt")).setListener(listener).setDataString("upload");
673 transporter.put(task);
674 assertEquals(0L, listener.getDataOffset());
675 assertEquals(6L, listener.getDataLength());
676 assertEquals(1, listener.getStartedCount());
677 assertTrue(listener.getProgressedCount() > 0, "Count: " + listener.getProgressedCount());
678 assertEquals("upload", TestFileUtils.readString(new File(repoDir, "file.txt")));
679 }
680
681 @Test
682 protected void testPut_FromFile() throws Exception {
683 File file = TestFileUtils.createTempFile("upload");
684 RecordingTransportListener listener = new RecordingTransportListener();
685 PutTask task =
686 new PutTask(URI.create("repo/file.txt")).setListener(listener).setDataFile(file);
687 transporter.put(task);
688 assertEquals(0L, listener.getDataOffset());
689 assertEquals(6L, listener.getDataLength());
690 assertEquals(1, listener.getStartedCount());
691 assertTrue(listener.getProgressedCount() > 0, "Count: " + listener.getProgressedCount());
692 assertEquals("upload", TestFileUtils.readString(new File(repoDir, "file.txt")));
693 }
694
695 @Test
696 protected void testPut_EmptyResource() throws Exception {
697 RecordingTransportListener listener = new RecordingTransportListener();
698 PutTask task = new PutTask(URI.create("repo/file.txt")).setListener(listener);
699 transporter.put(task);
700 assertEquals(0L, listener.getDataOffset());
701 assertEquals(0L, listener.getDataLength());
702 assertEquals(1, listener.getStartedCount());
703 assertEquals(0, listener.getProgressedCount());
704 assertEquals("", TestFileUtils.readString(new File(repoDir, "file.txt")));
705 }
706
707 @Test
708 protected void testPut_EncodedResourcePath() throws Exception {
709 RecordingTransportListener listener = new RecordingTransportListener();
710 PutTask task = new PutTask(URI.create("repo/some%20space.txt"))
711 .setListener(listener)
712 .setDataString("OK");
713 transporter.put(task);
714 assertEquals(0L, listener.getDataOffset());
715 assertEquals(2L, listener.getDataLength());
716 assertEquals(1, listener.getStartedCount());
717 assertTrue(listener.getProgressedCount() > 0, "Count: " + listener.getProgressedCount());
718 assertEquals("OK", TestFileUtils.readString(new File(repoDir, "some space.txt")));
719 }
720
721 @Test
722 protected void testPut_Authenticated_ExpectContinue() throws Exception {
723 httpServer.setAuthentication("testuser", "testpass");
724 auth = new AuthenticationBuilder()
725 .addUsername("testuser")
726 .addPassword("testpass")
727 .build();
728 newTransporter(httpServer.getHttpUrl());
729 RecordingTransportListener listener = new RecordingTransportListener();
730 PutTask task =
731 new PutTask(URI.create("repo/file.txt")).setListener(listener).setDataString("upload");
732 transporter.put(task);
733 assertEquals(0L, listener.getDataOffset());
734 assertEquals(6L, listener.getDataLength());
735 assertEquals(1, listener.getStartedCount());
736 assertTrue(listener.getProgressedCount() > 0, "Count: " + listener.getProgressedCount());
737 assertEquals("upload", TestFileUtils.readString(new File(repoDir, "file.txt")));
738 }
739
740 @Test
741 protected void testPut_Authenticated_ExpectContinueBroken() throws Exception {
742
743 session.setConfigProperty(ConfigurationProperties.HTTP_SUPPORT_WEBDAV, true);
744 httpServer.setAuthentication("testuser", "testpass");
745 httpServer.setExpectSupport(HttpServer.ExpectContinue.BROKEN);
746 auth = new AuthenticationBuilder()
747 .addUsername("testuser")
748 .addPassword("testpass")
749 .build();
750 newTransporter(httpServer.getHttpUrl());
751 RecordingTransportListener listener = new RecordingTransportListener();
752 PutTask task =
753 new PutTask(URI.create("repo/file.txt")).setListener(listener).setDataString("upload");
754 transporter.put(task);
755 assertEquals(0L, listener.getDataOffset());
756 assertEquals(6L, listener.getDataLength());
757 assertEquals(1, listener.getStartedCount());
758 assertTrue(listener.getProgressedCount() > 0, "Count: " + listener.getProgressedCount());
759 assertEquals("upload", TestFileUtils.readString(new File(repoDir, "file.txt")));
760 }
761
762 @Test
763 protected void testPut_Authenticated_ExpectContinueRejected() throws Exception {
764 httpServer.setAuthentication("testuser", "testpass");
765 httpServer.setExpectSupport(HttpServer.ExpectContinue.FAIL);
766 auth = new AuthenticationBuilder()
767 .addUsername("testuser")
768 .addPassword("testpass")
769 .build();
770 newTransporter(httpServer.getHttpUrl());
771 RecordingTransportListener listener = new RecordingTransportListener();
772 PutTask task =
773 new PutTask(URI.create("repo/file.txt")).setListener(listener).setDataString("upload");
774 transporter.put(task);
775 assertEquals(0L, listener.getDataOffset());
776 assertEquals(6L, listener.getDataLength());
777 assertEquals(1, listener.getStartedCount());
778 assertTrue(listener.getProgressedCount() > 0, "Count: " + listener.getProgressedCount());
779 assertEquals("upload", TestFileUtils.readString(new File(repoDir, "file.txt")));
780 }
781
782 @Test
783 protected void testPut_Authenticated_ExpectContinueDisabled() throws Exception {
784 session.setConfigProperty(ConfigurationProperties.HTTP_EXPECT_CONTINUE, false);
785 httpServer.setAuthentication("testuser", "testpass");
786 httpServer.setExpectSupport(HttpServer.ExpectContinue.FAIL);
787 auth = new AuthenticationBuilder()
788 .addUsername("testuser")
789 .addPassword("testpass")
790 .build();
791 newTransporter(httpServer.getHttpUrl());
792 RecordingTransportListener listener = new RecordingTransportListener();
793 PutTask task =
794 new PutTask(URI.create("repo/file.txt")).setListener(listener).setDataString("upload");
795 transporter.put(task);
796 assertEquals(0L, listener.getDataOffset());
797 assertEquals(6L, listener.getDataLength());
798 assertEquals(1, listener.getStartedCount());
799 assertTrue(listener.getProgressedCount() > 0, "Count: " + listener.getProgressedCount());
800 assertEquals("upload", TestFileUtils.readString(new File(repoDir, "file.txt")));
801 }
802
803 @Test
804 protected void testPut_Authenticated_ExpectContinueRejected_ExplicitlyConfiguredHeader() throws Exception {
805 Map<String, String> headers = new HashMap<>();
806 headers.put("Expect", "100-continue");
807 session.setConfigProperty(ConfigurationProperties.HTTP_HEADERS + ".test", headers);
808 httpServer.setAuthentication("testuser", "testpass");
809 httpServer.setExpectSupport(HttpServer.ExpectContinue.FAIL);
810 auth = new AuthenticationBuilder()
811 .addUsername("testuser")
812 .addPassword("testpass")
813 .build();
814 newTransporter(httpServer.getHttpUrl());
815 RecordingTransportListener listener = new RecordingTransportListener();
816 PutTask task =
817 new PutTask(URI.create("repo/file.txt")).setListener(listener).setDataString("upload");
818 transporter.put(task);
819 assertEquals(0L, listener.getDataOffset());
820 assertEquals(6L, listener.getDataLength());
821 assertEquals(1, listener.getStartedCount());
822 assertTrue(listener.getProgressedCount() > 0, "Count: " + listener.getProgressedCount());
823 assertEquals("upload", TestFileUtils.readString(new File(repoDir, "file.txt")));
824 }
825
826 @Test
827 protected void testPut_Unauthenticated() throws Exception {
828 httpServer.setAuthentication("testuser", "testpass");
829 RecordingTransportListener listener = new RecordingTransportListener();
830 PutTask task =
831 new PutTask(URI.create("repo/file.txt")).setListener(listener).setDataString("upload");
832 try {
833 transporter.put(task);
834 fail("Expected error");
835 } catch (HttpTransporterException e) {
836 assertEquals(401, e.getStatusCode());
837 assertEquals(Transporter.ERROR_OTHER, transporter.classify(e));
838 }
839 assertEquals(0, listener.getStartedCount());
840 assertEquals(0, listener.getProgressedCount());
841 }
842
843 @Test
844 protected void testPut_ProxyAuthenticated() throws Exception {
845 httpServer.setProxyAuthentication("testuser", "testpass");
846 Authentication auth = new AuthenticationBuilder()
847 .addUsername("testuser")
848 .addPassword("testpass")
849 .build();
850 proxy = new Proxy(Proxy.TYPE_HTTP, httpServer.getHost(), httpServer.getHttpPort(), auth);
851 newTransporter("http://bad.localhost:1/");
852 RecordingTransportListener listener = new RecordingTransportListener();
853 PutTask task =
854 new PutTask(URI.create("repo/file.txt")).setListener(listener).setDataString("upload");
855 transporter.put(task);
856 assertEquals(0L, listener.getDataOffset());
857 assertEquals(6L, listener.getDataLength());
858 assertEquals(1, listener.getStartedCount());
859 assertTrue(listener.getProgressedCount() > 0, "Count: " + listener.getProgressedCount());
860 assertEquals("upload", TestFileUtils.readString(new File(repoDir, "file.txt")));
861 }
862
863 @Test
864 protected void testPut_ProxyUnauthenticated() throws Exception {
865 httpServer.setProxyAuthentication("testuser", "testpass");
866 proxy = new Proxy(Proxy.TYPE_HTTP, httpServer.getHost(), httpServer.getHttpPort());
867 newTransporter("http://bad.localhost:1/");
868 RecordingTransportListener listener = new RecordingTransportListener();
869 PutTask task =
870 new PutTask(URI.create("repo/file.txt")).setListener(listener).setDataString("upload");
871 try {
872 transporter.put(task);
873 fail("Expected error");
874 } catch (HttpTransporterException e) {
875 assertEquals(407, e.getStatusCode());
876 assertEquals(Transporter.ERROR_OTHER, transporter.classify(e));
877 }
878 assertEquals(0, listener.getStartedCount());
879 assertEquals(0, listener.getProgressedCount());
880 }
881
882 @Test
883 protected void testPut_SSL() throws Exception {
884 httpServer.addSslConnector();
885 httpServer.setAuthentication("testuser", "testpass");
886 auth = new AuthenticationBuilder()
887 .addUsername("testuser")
888 .addPassword("testpass")
889 .build();
890 newTransporter(httpServer.getHttpsUrl());
891 RecordingTransportListener listener = new RecordingTransportListener();
892 PutTask task =
893 new PutTask(URI.create("repo/file.txt")).setListener(listener).setDataString("upload");
894 transporter.put(task);
895 assertEquals(0L, listener.getDataOffset());
896 assertEquals(6L, listener.getDataLength());
897 assertEquals(1, listener.getStartedCount());
898 assertTrue(listener.getProgressedCount() > 0, "Count: " + listener.getProgressedCount());
899 assertEquals("upload", TestFileUtils.readString(new File(repoDir, "file.txt")));
900 }
901
902 @Test
903 protected void testPut_FileHandleLeak() throws Exception {
904 for (int i = 0; i < 100; i++) {
905 File src = TestFileUtils.createTempFile("upload");
906 File dst = new File(repoDir, "file.txt");
907 transporter.put(new PutTask(URI.create("repo/file.txt")).setDataFile(src));
908 assertTrue(src.delete(), i + ", " + src.getAbsolutePath());
909 assertTrue(dst.delete(), i + ", " + dst.getAbsolutePath());
910 }
911 }
912
913 @Test
914 protected void testPut_Closed() throws Exception {
915 transporter.close();
916 try {
917 transporter.put(new PutTask(URI.create("repo/missing.txt")));
918 fail("Expected error");
919 } catch (IllegalStateException e) {
920 assertEquals(Transporter.ERROR_OTHER, transporter.classify(e));
921 }
922 }
923
924 @Test
925 protected void testPut_StartCancelled() throws Exception {
926 RecordingTransportListener listener = new RecordingTransportListener();
927 listener.cancelStart();
928 PutTask task =
929 new PutTask(URI.create("repo/file.txt")).setListener(listener).setDataString("upload");
930 try {
931 transporter.put(task);
932 fail("Expected error");
933 } catch (TransferCancelledException e) {
934 assertEquals(Transporter.ERROR_OTHER, transporter.classify(e));
935 }
936 assertEquals(0L, listener.getDataOffset());
937 assertEquals(6L, listener.getDataLength());
938 assertEquals(1, listener.getStartedCount());
939 assertEquals(0, listener.getProgressedCount());
940 }
941
942 @Test
943 protected void testPut_ProgressCancelled() throws Exception {
944 RecordingTransportListener listener = new RecordingTransportListener();
945 listener.cancelProgress();
946 PutTask task =
947 new PutTask(URI.create("repo/file.txt")).setListener(listener).setDataString("upload");
948 try {
949 transporter.put(task);
950 fail("Expected error");
951 } catch (TransferCancelledException e) {
952 assertEquals(Transporter.ERROR_OTHER, transporter.classify(e));
953 }
954 assertEquals(0L, listener.getDataOffset());
955 assertEquals(6L, listener.getDataLength());
956 assertEquals(1, listener.getStartedCount());
957 assertEquals(1, listener.getProgressedCount());
958 }
959
960 @Test
961 protected void testGetPut_AuthCache() throws Exception {
962 httpServer.setAuthentication("testuser", "testpass");
963 auth = new AuthenticationBuilder()
964 .addUsername("testuser")
965 .addPassword("testpass")
966 .build();
967 newTransporter(httpServer.getHttpUrl());
968 GetTask get = new GetTask(URI.create("repo/file.txt"));
969 transporter.get(get);
970 RecordingTransportListener listener = new RecordingTransportListener();
971 PutTask task =
972 new PutTask(URI.create("repo/file.txt")).setListener(listener).setDataString("upload");
973 transporter.put(task);
974 assertEquals(1, listener.getStartedCount());
975 }
976
977 @Test
978 protected void testPut_PreemptiveIsDefault() throws Exception {
979 httpServer.setAuthentication("testuser", "testpass");
980 auth = new AuthenticationBuilder()
981 .addUsername("testuser")
982 .addPassword("testpass")
983 .build();
984 newTransporter(httpServer.getHttpUrl());
985 PutTask task = new PutTask(URI.create("repo/file.txt")).setDataString("upload");
986 transporter.put(task);
987 assertEquals(1, httpServer.getLogEntries().size());
988 }
989
990 @Test
991 protected void testPut_AuthCache() throws Exception {
992 session.setConfigProperty(ConfigurationProperties.HTTP_PREEMPTIVE_PUT_AUTH, false);
993 httpServer.setAuthentication("testuser", "testpass");
994 auth = new AuthenticationBuilder()
995 .addUsername("testuser")
996 .addPassword("testpass")
997 .build();
998 newTransporter(httpServer.getHttpUrl());
999 PutTask task = new PutTask(URI.create("repo/file.txt")).setDataString("upload");
1000 transporter.put(task);
1001 assertEquals(2, httpServer.getLogEntries().size());
1002 httpServer.getLogEntries().clear();
1003 task = new PutTask(URI.create("repo/file.txt")).setDataString("upload");
1004 transporter.put(task);
1005 assertEquals(1, httpServer.getLogEntries().size());
1006 }
1007
1008 @Test
1009 protected void testPut_AuthCache_Preemptive() throws Exception {
1010 httpServer.setAuthentication("testuser", "testpass");
1011 auth = new AuthenticationBuilder()
1012 .addUsername("testuser")
1013 .addPassword("testpass")
1014 .build();
1015 session.setConfigProperty(ConfigurationProperties.HTTP_PREEMPTIVE_AUTH, true);
1016 newTransporter(httpServer.getHttpUrl());
1017 PutTask task = new PutTask(URI.create("repo/file.txt")).setDataString("upload");
1018 transporter.put(task);
1019 assertEquals(1, httpServer.getLogEntries().size());
1020 httpServer.getLogEntries().clear();
1021 task = new PutTask(URI.create("repo/file.txt")).setDataString("upload");
1022 transporter.put(task);
1023 assertEquals(1, httpServer.getLogEntries().size());
1024 }
1025
1026 @Test
1027 @Timeout(20)
1028 protected void testConcurrency() throws Exception {
1029 httpServer.setAuthentication("testuser", "testpass");
1030 auth = new AuthenticationBuilder()
1031 .addUsername("testuser")
1032 .addPassword("testpass")
1033 .build();
1034 newTransporter(httpServer.getHttpUrl());
1035 final AtomicReference<Throwable> error = new AtomicReference<>();
1036 Thread[] threads = new Thread[20];
1037 for (int i = 0; i < threads.length; i++) {
1038 final String path = "repo/file.txt?i=" + i;
1039 threads[i] = new Thread(() -> {
1040 try {
1041 for (int j = 0; j < 100; j++) {
1042 GetTask task = new GetTask(URI.create(path));
1043 transporter.get(task);
1044 assertEquals("test", task.getDataString());
1045 }
1046 } catch (Throwable t) {
1047 error.compareAndSet(null, t);
1048 System.err.println(path);
1049 t.printStackTrace();
1050 }
1051 });
1052 threads[i].setName("Task-" + i);
1053 }
1054 for (Thread thread : threads) {
1055 thread.start();
1056 }
1057 for (Thread thread : threads) {
1058 thread.join();
1059 }
1060 assertNull(error.get(), String.valueOf(error.get()));
1061 }
1062
1063 @Test
1064 @Timeout(10)
1065 protected void testConnectTimeout() throws Exception {
1066 session.setConfigProperty(ConfigurationProperties.CONNECT_TIMEOUT, 100);
1067 int port = 1;
1068 newTransporter("http://localhost:" + port);
1069 try {
1070 transporter.get(new GetTask(URI.create("repo/file.txt")));
1071 fail("Expected error");
1072 } catch (Exception e) {
1073
1074 assertEquals(Transporter.ERROR_OTHER, transporter.classify(e));
1075 }
1076 }
1077
1078 @Test
1079 @Timeout(10)
1080 protected void testRequestTimeout() throws Exception {
1081 session.setConfigProperty(ConfigurationProperties.REQUEST_TIMEOUT, 100);
1082 ServerSocket server = new ServerSocket(0);
1083 try (server) {
1084 newTransporter("http://localhost:" + server.getLocalPort());
1085 try {
1086 transporter.get(new GetTask(URI.create("repo/file.txt")));
1087 fail("Expected error");
1088 } catch (Exception e) {
1089 assertTrue(e.getClass().getSimpleName().contains("Timeout"));
1090 assertEquals(Transporter.ERROR_OTHER, transporter.classify(e));
1091 }
1092 }
1093 }
1094
1095 @Test
1096 protected void testUserAgent() throws Exception {
1097 session.setConfigProperty(ConfigurationProperties.USER_AGENT, "SomeTest/1.0");
1098 newTransporter(httpServer.getHttpUrl());
1099 transporter.get(new GetTask(URI.create("repo/file.txt")));
1100 assertEquals(1, httpServer.getLogEntries().size());
1101 for (HttpServer.LogEntry log : httpServer.getLogEntries()) {
1102 assertEquals("SomeTest/1.0", log.getHeaders().get("User-Agent"));
1103 }
1104 }
1105
1106 @Test
1107 protected void testCustomHeaders() throws Exception {
1108 Map<String, String> headers = new HashMap<>();
1109 headers.put("User-Agent", "Custom/1.0");
1110 headers.put("X-CustomHeader", "Custom-Value");
1111 session.setConfigProperty(ConfigurationProperties.USER_AGENT, "SomeTest/1.0");
1112 session.setConfigProperty(ConfigurationProperties.HTTP_HEADERS + ".test", headers);
1113 newTransporter(httpServer.getHttpUrl());
1114 transporter.get(new GetTask(URI.create("repo/file.txt")));
1115 assertEquals(1, httpServer.getLogEntries().size());
1116 for (HttpServer.LogEntry log : httpServer.getLogEntries()) {
1117 for (Map.Entry<String, String> entry : headers.entrySet()) {
1118 assertEquals(entry.getValue(), log.getHeaders().get(entry.getKey()), entry.getKey());
1119 }
1120 }
1121 }
1122
1123 @Test
1124 protected void testServerAuthScope_NotUsedForProxy() throws Exception {
1125 String username = "testuser", password = "testpass";
1126 httpServer.setProxyAuthentication(username, password);
1127 auth = new AuthenticationBuilder()
1128 .addUsername(username)
1129 .addPassword(password)
1130 .build();
1131 proxy = new Proxy(Proxy.TYPE_HTTP, httpServer.getHost(), httpServer.getHttpPort());
1132 newTransporter("http://" + httpServer.getHost() + ":12/");
1133 try {
1134 transporter.get(new GetTask(URI.create("repo/file.txt")));
1135 fail("Server auth must not be used as proxy auth");
1136 } catch (HttpTransporterException e) {
1137 assertEquals(407, e.getStatusCode());
1138 } catch (IOException e) {
1139
1140 }
1141 }
1142
1143 @Test
1144 protected void testProxyAuthScope_NotUsedForServer() throws Exception {
1145 String username = "testuser", password = "testpass";
1146 httpServer.setAuthentication(username, password);
1147 Authentication auth = new AuthenticationBuilder()
1148 .addUsername(username)
1149 .addPassword(password)
1150 .build();
1151 proxy = new Proxy(Proxy.TYPE_HTTP, httpServer.getHost(), httpServer.getHttpPort(), auth);
1152 newTransporter("http://" + httpServer.getHost() + ":12/");
1153 try {
1154 transporter.get(new GetTask(URI.create("repo/file.txt")));
1155 fail("Proxy auth must not be used as server auth");
1156 } catch (HttpTransporterException e) {
1157 assertEquals(401, e.getStatusCode());
1158 } catch (IOException e) {
1159
1160 }
1161 }
1162
1163 @Test
1164 protected void testAuthSchemeReuse() throws Exception {
1165 httpServer.setAuthentication("testuser", "testpass");
1166 httpServer.setProxyAuthentication("proxyuser", "proxypass");
1167 session.setCache(new DefaultRepositoryCache());
1168 auth = new AuthenticationBuilder()
1169 .addUsername("testuser")
1170 .addPassword("testpass")
1171 .build();
1172 Authentication auth = new AuthenticationBuilder()
1173 .addUsername("proxyuser")
1174 .addPassword("proxypass")
1175 .build();
1176 proxy = new Proxy(Proxy.TYPE_HTTP, httpServer.getHost(), httpServer.getHttpPort(), auth);
1177 newTransporter("http://bad.localhost:1/");
1178 GetTask task = new GetTask(URI.create("repo/file.txt"));
1179 transporter.get(task);
1180 assertEquals("test", task.getDataString());
1181 assertEquals(3, httpServer.getLogEntries().size());
1182 httpServer.getLogEntries().clear();
1183 newTransporter("http://bad.localhost:1/");
1184 task = new GetTask(URI.create("repo/file.txt"));
1185 transporter.get(task);
1186 assertEquals("test", task.getDataString());
1187 assertEquals(1, httpServer.getLogEntries().size());
1188 assertNotNull(httpServer.getLogEntries().get(0).getHeaders().get("Authorization"));
1189 assertNotNull(httpServer.getLogEntries().get(0).getHeaders().get("Proxy-Authorization"));
1190 }
1191
1192 @Test
1193 protected void testAuthSchemePreemptive() throws Exception {
1194 httpServer.setAuthentication("testuser", "testpass");
1195 session.setCache(new DefaultRepositoryCache());
1196 auth = new AuthenticationBuilder()
1197 .addUsername("testuser")
1198 .addPassword("testpass")
1199 .build();
1200
1201 session.setConfigProperty(ConfigurationProperties.HTTP_PREEMPTIVE_AUTH, false);
1202 newTransporter(httpServer.getHttpUrl());
1203 GetTask task = new GetTask(URI.create("repo/file.txt"));
1204 transporter.get(task);
1205 assertEquals("test", task.getDataString());
1206
1207 assertEquals(2, httpServer.getLogEntries().size());
1208
1209 httpServer.getLogEntries().clear();
1210
1211 session.setConfigProperty(ConfigurationProperties.HTTP_PREEMPTIVE_AUTH, true);
1212 newTransporter(httpServer.getHttpUrl());
1213 task = new GetTask(URI.create("repo/file.txt"));
1214 transporter.get(task);
1215 assertEquals("test", task.getDataString());
1216
1217 assertEquals(1, httpServer.getLogEntries().size());
1218 }
1219
1220 @Test
1221 void testInit_BadProtocol() {
1222 assertThrows(NoTransporterException.class, () -> newTransporter("bad:/void"));
1223 }
1224
1225 @Test
1226 void testInit_BadUrl() {
1227 assertThrows(NoTransporterException.class, () -> newTransporter("http://localhost:NaN"));
1228 }
1229
1230 @Test
1231 void testInit_CaseInsensitiveProtocol() throws Exception {
1232 newTransporter("http://localhost");
1233 newTransporter("HTTP://localhost");
1234 newTransporter("Http://localhost");
1235 newTransporter("https://localhost");
1236 newTransporter("HTTPS://localhost");
1237 newTransporter("HttpS://localhost");
1238 }
1239 }