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