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