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