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