001package org.apache.maven.wagon.tck.http; 002 003/* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022import org.apache.maven.wagon.ConnectionException; 023import org.apache.maven.wagon.ResourceDoesNotExistException; 024import org.apache.maven.wagon.StreamWagon; 025import org.apache.maven.wagon.TransferFailedException; 026import org.apache.maven.wagon.authentication.AuthenticationException; 027import org.apache.maven.wagon.authentication.AuthenticationInfo; 028import org.apache.maven.wagon.authorization.AuthorizationException; 029import org.apache.maven.wagon.proxy.ProxyInfo; 030import org.apache.maven.wagon.tck.http.fixture.ErrorCodeServlet; 031import org.apache.maven.wagon.tck.http.fixture.LatencyServlet; 032import org.apache.maven.wagon.tck.http.fixture.ProxyConnectionVerifierFilter; 033import org.apache.maven.wagon.tck.http.fixture.RedirectionServlet; 034import org.apache.maven.wagon.tck.http.fixture.ServerFixture; 035import org.apache.maven.wagon.tck.http.fixture.ServletExceptionServlet; 036import org.apache.maven.wagon.tck.http.util.ValueHolder; 037import org.codehaus.plexus.component.configurator.ComponentConfigurationException; 038import org.junit.Ignore; 039import org.junit.Test; 040 041import javax.servlet.Servlet; 042import javax.servlet.http.HttpServletResponse; 043import java.io.File; 044import java.io.IOException; 045 046import static junit.framework.Assert.assertTrue; 047import static junit.framework.Assert.fail; 048import static org.apache.maven.wagon.tck.http.Assertions.NO_RESPONSE_STATUS_CODE; 049import static org.apache.maven.wagon.tck.http.Assertions.assertFileContentsFromResource; 050import static org.apache.maven.wagon.tck.http.Assertions.assertWagonExceptionMessage; 051 052/** 053 * 054 */ 055public class GetWagonTests 056 extends HttpWagonTests 057{ 058 private static final int TWO_SECONDS = 2000; 059 private static final int ONE_MINUTE = 60000; 060 061 @Test 062 public void basic() 063 throws ConnectionException, AuthenticationException, ComponentConfigurationException, IOException, 064 TransferFailedException, ResourceDoesNotExistException, AuthorizationException 065 { 066 testSuccessfulGet( "base.txt" ); 067 } 068 069 @Test 070 @Ignore( "FIX ME!" ) 071 public void proxied() 072 throws ConnectionException, AuthenticationException, ComponentConfigurationException, IOException, 073 TransferFailedException, ResourceDoesNotExistException, AuthorizationException 074 { 075 getServerFixture().addFilter( "*", new ProxyConnectionVerifierFilter() ); 076 077 ProxyInfo info = newProxyInfo(); 078 if ( !initTest( null, info ) ) 079 { 080 return; 081 } 082 083 File target = newTempFile(); 084 getWagon().get( "base.txt", target ); 085 086 assertFileContentsFromResource( ServerFixture.SERVER_ROOT_RESOURCE_PATH, "base.txt", target, 087 "Downloaded file doesn't match original." ); 088 } 089 090 @Test 091 public void highLatencyHighTimeout() 092 throws ConnectionException, AuthenticationException, ComponentConfigurationException, IOException, 093 TransferFailedException, ResourceDoesNotExistException, AuthorizationException 094 { 095 getServerFixture().addServlet( "/slow/*", new LatencyServlet( TWO_SECONDS ) ); 096 testSuccessfulGet( "slow/large.txt", "large.txt" ); 097 } 098 099 @Test 100 public void highLatencyLowTimeout() 101 throws ConnectionException, AuthenticationException, ComponentConfigurationException, IOException, 102 TransferFailedException, ResourceDoesNotExistException, AuthorizationException 103 { 104 Servlet servlet = new LatencyServlet( TWO_SECONDS ); 105 getServerFixture().addServlet( "/slow/*", servlet ); 106 testSuccessfulGet( "slow/large.txt", "large.txt" ); 107 } 108 109 @Test 110 public void inifiniteLatencyTimeout() 111 throws ConnectionException, AuthenticationException, ComponentConfigurationException, IOException, 112 TransferFailedException, ResourceDoesNotExistException, AuthorizationException 113 { 114 if ( !isSupported() ) 115 { 116 return; 117 } 118 119 final ValueHolder<TransferFailedException> holder = new ValueHolder<>( null ); 120 121 Runnable r = new Runnable() 122 { 123 public void run() 124 { 125 Servlet servlet = new LatencyServlet( -1 ); 126 addNotificationTarget( servlet ); 127 128 getServerFixture().addServlet( "/infinite/*", servlet ); 129 try 130 { 131 if ( !initTest( null, null ) ) 132 { 133 return; 134 } 135 136 if ( getWagon() instanceof StreamWagon ) 137 { 138 logger.info( "Connection timeout is: " + getWagon().getTimeout() ); 139 } 140 141 File target = newTempFile(); 142 getWagon().get( "infinite/", target ); 143 144 fail( "Should have failed to transfer due to transaction timeout." ); 145 } 146 catch ( ConnectionException | AuthenticationException | ResourceDoesNotExistException 147 | AuthorizationException | ComponentConfigurationException | IOException e ) 148 { 149 throw new IllegalStateException( e ); 150 } 151 catch ( TransferFailedException e ) 152 { 153 // expected 154 holder.setValue( e ); 155 } 156 } 157 }; 158 159 Thread t = new Thread( r ); 160 t.start(); 161 162 try 163 { 164 logger.info( "Waiting 60 seconds for wagon timeout." ); 165 t.join( ONE_MINUTE ); 166 } 167 catch ( InterruptedException e ) 168 { 169 e.printStackTrace(); 170 } 171 172 logger.info( "Interrupting thread." ); 173 t.interrupt(); 174 175 assertTrue( "TransferFailedException should have been thrown.", holder.getValue() != null ); 176 assertWagonExceptionMessage( holder.getValue(), NO_RESPONSE_STATUS_CODE, getBaseUrl() + "infinite/", 177 "", null ); 178 } 179 180 @Test 181 public void nonExistentHost() 182 throws ConnectionException, AuthenticationException, ComponentConfigurationException, IOException, 183 ResourceDoesNotExistException, AuthorizationException 184 { 185 // we use a invalid localhost URL since some Internet Service Providers lately 186 // use funny 'search-DNS' which don't handle explicitly marked testing DNS properly. 187 // According to RFC-2606 .test, .invalid TLDs etc should work, but in practice it doesn't :( 188 if ( !initTest( "http://localhost:65520", null, null ) ) 189 { 190 return; 191 } 192 193 File target = newTempFile(); 194 try 195 { 196 getWagon().get( "base.txt", target ); 197 fail( "Expected error related to host lookup failure." ); 198 } 199 catch ( TransferFailedException e ) 200 { 201 // expected 202 assertWagonExceptionMessage( e, NO_RESPONSE_STATUS_CODE, "http://localhost:65520/base.txt", 203 null, null ); 204 } 205 } 206 207 @Test 208 public void oneLevelPermanentMove() 209 throws ConnectionException, AuthenticationException, ComponentConfigurationException, IOException, 210 TransferFailedException, ResourceDoesNotExistException, AuthorizationException 211 { 212 getServerFixture().addServlet( "/moved.txt", 213 new RedirectionServlet( HttpServletResponse.SC_MOVED_PERMANENTLY, 214 "/base.txt" ) ); 215 216 testSuccessfulGet( "moved.txt" ); 217 } 218 219 @Test 220 public void oneLevelTemporaryMove() 221 throws ConnectionException, AuthenticationException, ComponentConfigurationException, IOException, 222 TransferFailedException, ResourceDoesNotExistException, AuthorizationException 223 { 224 getServerFixture().addServlet( "/moved.txt", 225 new RedirectionServlet( HttpServletResponse.SC_MOVED_TEMPORARILY, 226 "/base.txt" ) ); 227 228 testSuccessfulGet( "moved.txt" ); 229 } 230 231 @Test 232 public void sixLevelPermanentMove() 233 throws ConnectionException, AuthenticationException, ComponentConfigurationException, IOException, 234 TransferFailedException, ResourceDoesNotExistException, AuthorizationException 235 { 236 String myPath = "moved.txt"; 237 String targetPath = "/base.txt"; 238 239 getServerFixture().addServlet( "/" + myPath + "/*", 240 new RedirectionServlet( HttpServletResponse.SC_MOVED_PERMANENTLY, myPath, 241 targetPath, 6 ) ); 242 243 testSuccessfulGet( myPath ); 244 } 245 246 @Test 247 public void sixLevelTemporaryMove() 248 throws ConnectionException, AuthenticationException, ComponentConfigurationException, IOException, 249 TransferFailedException, ResourceDoesNotExistException, AuthorizationException 250 { 251 String myPath = "moved.txt"; 252 String targetPath = "/base.txt"; 253 254 getServerFixture().addServlet( "/" + myPath + "/*", 255 new RedirectionServlet( HttpServletResponse.SC_MOVED_TEMPORARILY, myPath, 256 targetPath, 6 ) ); 257 258 testSuccessfulGet( myPath ); 259 } 260 261 @Test 262 public void infinitePermanentMove() 263 throws ConnectionException, AuthenticationException, ComponentConfigurationException, IOException, 264 TransferFailedException, ResourceDoesNotExistException, AuthorizationException 265 { 266 String myPath = "moved.txt"; 267 String targetPath = "/base.txt"; 268 269 getServerFixture().addServlet( 270 "/" + myPath, 271 new RedirectionServlet( HttpServletResponse.SC_MOVED_PERMANENTLY, myPath, 272 targetPath, -1 ) ); 273 274 try 275 { 276 testSuccessfulGet( myPath ); 277 fail( "Expected failure as a result of too many redirects." ); 278 } 279 catch ( TransferFailedException e ) 280 { 281 // expected 282 } 283 } 284 285 @Test 286 public void infiniteTemporaryMove() 287 throws ConnectionException, AuthenticationException, ComponentConfigurationException, IOException, 288 ResourceDoesNotExistException, AuthorizationException 289 { 290 String myPath = "moved.txt"; 291 String targetPath = "/base.txt"; 292 293 getServerFixture().addServlet( 294 "/" + myPath, 295 new RedirectionServlet( HttpServletResponse.SC_MOVED_TEMPORARILY, myPath, 296 targetPath, -1 ) ); 297 298 try 299 { 300 testSuccessfulGet( myPath ); 301 fail( "Expected failure as a result of too many redirects." ); 302 } 303 catch ( TransferFailedException e ) 304 { 305 // expected 306 } 307 } 308 309 /** 310 * NOTE: This test depends on a {@link WagonTestCaseConfigurator} configuration to limit redirects to 20. In the 311 * case of the Sun HTTP implementation, this is the default limit. 312 */ 313 @Test 314 @SuppressWarnings( "checkstyle:methodname" ) 315 public void permanentMove_TooManyRedirects_limit20() 316 throws ConnectionException, AuthenticationException, ComponentConfigurationException, IOException, 317 TransferFailedException, ResourceDoesNotExistException, AuthorizationException 318 { 319 String myPath = "moved.txt"; 320 String targetPath = "/base.txt"; 321 322 getServerFixture().addServlet( 323 "/" + myPath, 324 new RedirectionServlet( HttpServletResponse.SC_MOVED_PERMANENTLY, myPath, 325 targetPath, -1 ) ); 326 327 try 328 { 329 testSuccessfulGet( myPath ); 330 fail( "Expected failure as a result of too many redirects." ); 331 } 332 catch ( TransferFailedException e ) 333 { 334 // expected 335 } 336 } 337 338 /** 339 * NOTE: This test depends on a {@link WagonTestCaseConfigurator} configuration to limit redirects to 20. In the 340 * case of the Sun HTTP implementation, this is the default limit. 341 */ 342 @Test 343 @SuppressWarnings( "checkstyle:methodname" ) 344 public void temporaryMove_TooManyRedirects_limit20() 345 throws ConnectionException, AuthenticationException, ComponentConfigurationException, IOException, 346 ResourceDoesNotExistException, AuthorizationException 347 { 348 String myPath = "moved.txt"; 349 String targetPath = "/base.txt"; 350 351 getServerFixture().addServlet( 352 "/" + myPath, 353 new RedirectionServlet( HttpServletResponse.SC_MOVED_TEMPORARILY, myPath, 354 targetPath, -1 ) ); 355 356 try 357 { 358 testSuccessfulGet( myPath ); 359 fail( "Expected failure as a result of too many redirects." ); 360 } 361 catch ( TransferFailedException e ) 362 { 363 // expected 364 } 365 } 366 367 @Test 368 public void missing() 369 throws ConnectionException, AuthenticationException, ComponentConfigurationException, IOException, 370 TransferFailedException, AuthorizationException 371 { 372 if ( !initTest( null, null ) ) 373 { 374 return; 375 } 376 377 File target = newTempFile(); 378 try 379 { 380 getWagon().get( "404.txt", target ); 381 fail( "should have received a 404, meaning the resource doesn't exist." ); 382 } 383 catch ( ResourceDoesNotExistException e ) 384 { 385 // expected 386 } 387 } 388 389 @Test 390 public void error() 391 throws ConnectionException, AuthenticationException, ComponentConfigurationException, IOException, 392 AuthorizationException, ResourceDoesNotExistException 393 { 394 testErrorHandling( HttpServletResponse.SC_INTERNAL_SERVER_ERROR ); 395 } 396 397 @Test 398 public void proxyTimeout() 399 throws ConnectionException, AuthenticationException, ComponentConfigurationException, IOException, 400 AuthorizationException, ResourceDoesNotExistException 401 { 402 testErrorHandling( HttpServletResponse.SC_GATEWAY_TIMEOUT ); 403 } 404 405 @Test 406 public void forbidden() 407 throws ConnectionException, ComponentConfigurationException, IOException, ResourceDoesNotExistException, 408 TransferFailedException 409 { 410 AuthenticationInfo info = new AuthenticationInfo(); 411 info.setUserName( "user" ); 412 info.setPassword( "password" ); 413 414 getServerFixture().addUser( info.getUserName(), "password" ); 415 416 getServerFixture().addServlet( "/403.txt", 417 new ErrorCodeServlet( HttpServletResponse.SC_FORBIDDEN, "Expected 403" ) ); 418 419 testAuthFailure( "403.txt", info ); 420 } 421 422 @Test 423 public void successfulAuthentication() 424 throws ConnectionException, AuthenticationException, ComponentConfigurationException, IOException, 425 TransferFailedException, ResourceDoesNotExistException, AuthorizationException 426 { 427 AuthenticationInfo info = new AuthenticationInfo(); 428 info.setUserName( "user" ); 429 info.setPassword( "password" ); 430 431 getServerFixture().addUser( info.getUserName(), info.getPassword() ); 432 433 if ( !initTest( info, null ) ) 434 { 435 return; 436 } 437 438 File target = newTempFile(); 439 getWagon().get( "protected/base.txt", target ); 440 441 assertFileContentsFromResource( ServerFixture.SERVER_ROOT_RESOURCE_PATH, "base.txt", target, 442 "Downloaded file doesn't match original." ); 443 } 444 445 @Test 446 public void unsuccessfulAuthentication() 447 throws ConnectionException, ComponentConfigurationException, IOException, TransferFailedException, 448 ResourceDoesNotExistException 449 { 450 AuthenticationInfo info = new AuthenticationInfo(); 451 info.setUserName( "user" ); 452 info.setPassword( "password" ); 453 454 getServerFixture().addUser( info.getUserName(), "anotherPassword" ); 455 456 testAuthFailure( "protected/base.txt", info ); 457 } 458 459 protected void testAuthFailure( final String path, final AuthenticationInfo info ) 460 throws ConnectionException, ComponentConfigurationException, IOException, TransferFailedException, 461 ResourceDoesNotExistException 462 { 463 boolean authFailure = false; 464 try 465 { 466 if ( !initTest( info, null ) ) 467 { 468 return; 469 } 470 } 471 catch ( AuthenticationException e ) 472 { 473 // expected 474 authFailure = true; 475 } 476 477 File target = newTempFile(); 478 try 479 { 480 getWagon().get( path, target ); 481 } 482 catch ( AuthorizationException e ) 483 { 484 // expected 485 authFailure = true; 486 } 487 488 assertTrue( "Authentication/Authorization should have failed.", authFailure ); 489 } 490 491 protected void testSuccessfulGet( final String path ) 492 throws ConnectionException, AuthenticationException, ComponentConfigurationException, IOException, 493 TransferFailedException, ResourceDoesNotExistException, AuthorizationException 494 { 495 testSuccessfulGet( path, "base.txt" ); 496 } 497 498 protected void testSuccessfulGet( final String path, final String checkPath ) 499 throws ConnectionException, AuthenticationException, ComponentConfigurationException, IOException, 500 TransferFailedException, ResourceDoesNotExistException, AuthorizationException 501 { 502 if ( !initTest( null, null ) ) 503 { 504 return; 505 } 506 507 if ( getWagon() instanceof StreamWagon ) 508 { 509 logger.info( "Connection timeout is: " + getWagon().getTimeout() ); 510 } 511 512 File target = newTempFile(); 513 getWagon().get( path, target ); 514 515 assertFileContentsFromResource( ServerFixture.SERVER_ROOT_RESOURCE_PATH, checkPath, target, 516 "Downloaded file doesn't match original." ); 517 } 518 519 protected void testErrorHandling( final int code ) 520 throws ConnectionException, AuthenticationException, ComponentConfigurationException, IOException, 521 AuthorizationException, ResourceDoesNotExistException 522 { 523 if ( code == HttpServletResponse.SC_INTERNAL_SERVER_ERROR ) 524 { 525 getServerFixture().addServlet( "/" + code + ".txt", new ServletExceptionServlet( "Expected " + code ) ); 526 } 527 else 528 { 529 getServerFixture().addServlet( "/" + code + ".txt", new ErrorCodeServlet( code, "Expected " + code ) ); 530 } 531 532 if ( !initTest( null, null ) ) 533 { 534 return; 535 } 536 537 File target = newTempFile(); 538 try 539 { 540 getWagon().get( code + ".txt", target ); 541 fail( "should have received a " + code + " error code, meaning the resource doesn't exist." ); 542 } 543 catch ( TransferFailedException e ) 544 { 545 // expected 546 } 547 } 548}