001package org.apache.maven.wagon.shared.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 java.net.URI; 023 024import org.apache.http.HttpEntityEnclosingRequest; 025import org.apache.http.HttpRequest; 026import org.apache.http.HttpResponse; 027import org.apache.http.HttpStatus; 028import org.apache.http.ProtocolException; 029import org.apache.http.client.methods.HttpGet; 030import org.apache.http.client.methods.HttpHead; 031import org.apache.http.client.methods.HttpPut; 032import org.apache.http.client.methods.HttpUriRequest; 033import org.apache.http.client.methods.RequestBuilder; 034import org.apache.http.impl.client.DefaultRedirectStrategy; 035import org.apache.http.protocol.HttpContext; 036import org.apache.http.util.Args; 037import org.apache.maven.wagon.events.TransferEvent; 038import org.apache.maven.wagon.shared.http.AbstractHttpClientWagon.WagonHttpEntity; 039import org.slf4j.Logger; 040import org.slf4j.LoggerFactory; 041 042/** 043 * A custom redirect strategy for Apache Maven Wagon HttpClient. 044 * 045 * @since 3.4.0 046 * 047 */ 048public class WagonRedirectStrategy extends DefaultRedirectStrategy 049{ 050 051 private static final Logger LOGGER = LoggerFactory.getLogger( WagonRedirectStrategy.class ); 052 053 private static final int SC_PERMANENT_REDIRECT = 308; 054 055 public WagonRedirectStrategy() 056 { 057 super( new String[] { 058 HttpGet.METHOD_NAME, 059 HttpHead.METHOD_NAME, 060 HttpPut.METHOD_NAME, 061 /** 062 * This covers the most basic case where the redirection relocates to another 063 * collection which has an existing parent collection. 064 */ 065 "MKCOL" } ); 066 } 067 068 @Override 069 public boolean isRedirected( final HttpRequest request, final HttpResponse response, 070 final HttpContext context ) throws ProtocolException 071 { 072 Args.notNull( request, "HTTP request" ); 073 Args.notNull( response, "HTTP response" ); 074 075 final int statusCode = response.getStatusLine().getStatusCode(); 076 final String method = request.getRequestLine().getMethod(); 077 switch ( statusCode ) 078 { 079 case HttpStatus.SC_MOVED_TEMPORARILY: 080 case HttpStatus.SC_MOVED_PERMANENTLY: 081 case HttpStatus.SC_SEE_OTHER: 082 case HttpStatus.SC_TEMPORARY_REDIRECT: 083 case SC_PERMANENT_REDIRECT: 084 return isRedirectable( method ); 085 default: 086 return false; 087 } 088 } 089 090 @Override 091 public HttpUriRequest getRedirect( final HttpRequest request, final HttpResponse response, 092 final HttpContext context ) throws ProtocolException 093 { 094 final URI uri = getLocationURI( request, response, context ); 095 if ( request instanceof HttpEntityEnclosingRequest ) 096 { 097 HttpEntityEnclosingRequest encRequest = (HttpEntityEnclosingRequest) request; 098 if ( encRequest.getEntity() instanceof AbstractHttpClientWagon.WagonHttpEntity ) 099 { 100 AbstractHttpClientWagon.WagonHttpEntity whe = (WagonHttpEntity) encRequest.getEntity(); 101 if ( whe.getWagon() instanceof AbstractHttpClientWagon ) 102 { 103 // Re-execute AbstractWagon#firePutStarted(Resource, File) 104 AbstractHttpClientWagon httpWagon = (AbstractHttpClientWagon) whe.getWagon(); 105 TransferEvent transferEvent = 106 new TransferEvent( httpWagon, whe.getResource(), 107 TransferEvent.TRANSFER_STARTED, TransferEvent.REQUEST_PUT ); 108 transferEvent.setTimestamp( System.currentTimeMillis() ); 109 transferEvent.setLocalFile( whe.getSource() ); 110 httpWagon.getTransferEventSupport().fireDebug( 111 String.format( "Following redirect from '%s' to '%s'", 112 request.getRequestLine().getUri(), uri.toASCIIString() ) ); 113 httpWagon.getTransferEventSupport().fireTransferStarted( transferEvent ); 114 } 115 else 116 { 117 LOGGER.warn( "Cannot properly handle redirect transfer event, wagon has unexpected class: {}", 118 whe.getWagon().getClass() ); 119 } 120 } 121 } 122 123 return RequestBuilder.copy( request ).setUri( uri ).build(); 124 } 125 126}