001package org.apache.maven.wagon.providers.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.ResourceDoesNotExistException; 023import org.apache.maven.wagon.StreamingWagon; 024import org.apache.maven.wagon.TransferFailedException; 025import org.apache.maven.wagon.WagonException; 026import org.apache.maven.wagon.authorization.AuthorizationException; 027import org.apache.maven.wagon.http.HttpWagonTestCase; 028import org.codehaus.plexus.util.StringUtils; 029 030import javax.servlet.http.HttpServletResponse; 031import java.io.FileNotFoundException; 032import java.io.IOException; 033import java.util.Properties; 034 035/** 036 * @author <a href="michal.maczka@dimatics.com">Michal Maczka</a> 037 * 038 */ 039public class LightweightHttpWagonTest 040 extends HttpWagonTestCase 041{ 042 protected String getProtocol() 043 { 044 return "http"; 045 } 046 047 protected String getTestRepositoryUrl() 048 { 049 return getProtocol() + "://localhost:" + getTestRepositoryPort() + "/"; 050 } 051 052 protected void setHttpConfiguration( StreamingWagon wagon, Properties headers, Properties params ) 053 { 054 ( (LightweightHttpWagon) wagon ).setHttpHeaders( headers ); 055 } 056 057 @Override 058 protected boolean supportPreemptiveAuthenticationGet() 059 { 060 return false; 061 } 062 063 @Override 064 protected boolean supportPreemptiveAuthenticationPut() 065 { 066 return false; 067 } 068 069 @Override 070 protected boolean supportProxyPreemptiveAuthentication() 071 { 072 return false; 073 } 074 075 @Override 076 protected void verifyWagonExceptionMessage( Exception e, int forStatusCode, String forUrl, String forReasonPhrase ) 077 { 078 079 // HttpUrlConnection prevents direct API access to the response code or reasonPhrase for any 080 // status code >= 400. So all we can do is check WagonException wraps the HttpUrlConnection 081 // thrown IOException / FileNotFoundException as a cause, if cause is not null 082 083 assertNotNull( e ); 084 try 085 { 086 assertTrue( "only verify instances of WagonException", e instanceof WagonException ); 087 088 String assertMessageForBadMessage = "exception message not described properly: "; 089 switch ( forStatusCode ) 090 { 091 case HttpServletResponse.SC_GONE: 092 case HttpServletResponse.SC_NOT_FOUND: 093 assertTrue( "404 or 410 should throw ResourceDoesNotExistException", 094 e instanceof ResourceDoesNotExistException ); 095 096 if ( e.getCause() != null ) 097 { 098 assertTrue( "ResourceDoesNotExistException should have the expected cause", 099 e.getCause() instanceof FileNotFoundException ); 100 // the status code and reason phrase cannot always be learned due to implementation limitations 101 // which means the message may not include them 102 assertEquals( assertMessageForBadMessage, "resource missing at " + forUrl, e.getMessage() ); 103 } 104 else 105 { 106 assertEquals( assertMessageForBadMessage, "resource missing at " + forUrl 107 + ", status: " + forStatusCode + " " + forReasonPhrase, e.getMessage() ); 108 } 109 110 break; 111 112 case HttpServletResponse.SC_FORBIDDEN: 113 assertTrue( "403 Forbidden throws AuthorizationException", 114 e instanceof AuthorizationException ); 115 116 assertEquals( assertMessageForBadMessage, "authorization failed for " + forUrl + ", status: 403" 117 + ( StringUtils.isEmpty( forReasonPhrase ) ? " Forbidden" : ( " " + forReasonPhrase ) ), 118 e.getMessage() ); 119 break; 120 121 case HttpServletResponse.SC_UNAUTHORIZED: 122 assertTrue( "401 Unauthorized throws AuthorizationException", 123 e instanceof AuthorizationException ); 124 125 assertEquals( assertMessageForBadMessage, "authentication failed for " + forUrl + ", status: 401" 126 + ( StringUtils.isEmpty( forReasonPhrase ) ? " Unauthorized" : 127 ( " " + forReasonPhrase ) ), 128 e.getMessage() ); 129 break; 130 131 default: 132 assertTrue( "general exception must be TransferFailedException", 133 e instanceof TransferFailedException ); 134 assertTrue( "expected status code for transfer failures should be >= 400, but none of " 135 + " the already handled codes", 136 forStatusCode >= HttpServletResponse.SC_BAD_REQUEST ); 137 138 if ( e.getCause() != null ) 139 { 140 assertTrue( "TransferFailedException should have the original cause for diagnosis", 141 e.getCause() instanceof IOException ); 142 } 143 144 // the status code and reason phrase cannot always be learned due to implementation limitations 145 // so the message may not include them, but the implementation should use a consistent format 146 assertTrue( "message should always include url", 147 e.getMessage().startsWith( "transfer failed for " + forUrl ) ); 148 149 if ( e.getMessage().length() > ( "transfer failed for " + forUrl ).length() ) 150 { 151 assertTrue( "message should include url and status code", 152 e.getMessage().startsWith( "transfer failed for " + forUrl + ", status: " + forStatusCode ) ); 153 } 154 155 if ( e.getMessage().length() > ( "transfer failed for " + forUrl + ", status: " + forStatusCode ).length() ) 156 { 157 assertEquals( "message should include url and status code and reason phrase", 158 "transfer failed for " + forUrl + ", status: " + forStatusCode + " " + forReasonPhrase, 159 e.getMessage() ); 160 } 161 162 break; 163 } 164 165 } 166 catch ( AssertionError assertionError ) 167 { 168 logger.error( "Exception which failed assertions: ", e ); 169 throw assertionError; 170 } 171 } 172 173}