| package org.apache.maven.wagon.providers.webdav; |
| |
| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| import org.apache.commons.httpclient.Credentials; |
| import org.apache.commons.httpclient.Header; |
| import org.apache.commons.httpclient.HostConfiguration; |
| import org.apache.commons.httpclient.HttpClient; |
| import org.apache.commons.httpclient.HttpConnectionManager; |
| import org.apache.commons.httpclient.HttpMethod; |
| import org.apache.commons.httpclient.HttpStatus; |
| import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager; |
| import org.apache.commons.httpclient.NTCredentials; |
| import org.apache.commons.httpclient.UsernamePasswordCredentials; |
| import org.apache.commons.httpclient.auth.AuthScope; |
| import org.apache.commons.httpclient.cookie.CookiePolicy; |
| import org.apache.commons.httpclient.methods.EntityEnclosingMethod; |
| import org.apache.commons.httpclient.methods.GetMethod; |
| import org.apache.commons.httpclient.methods.HeadMethod; |
| import org.apache.commons.httpclient.methods.PutMethod; |
| import org.apache.commons.httpclient.methods.RequestEntity; |
| import org.apache.commons.httpclient.params.HttpMethodParams; |
| import org.apache.commons.httpclient.util.DateParseException; |
| import org.apache.commons.httpclient.util.DateUtil; |
| import org.apache.commons.io.IOUtils; |
| import org.apache.commons.lang.StringUtils; |
| import org.apache.maven.wagon.InputData; |
| import org.apache.maven.wagon.OutputData; |
| import org.apache.maven.wagon.PathUtils; |
| import org.apache.maven.wagon.ResourceDoesNotExistException; |
| import org.apache.maven.wagon.StreamWagon; |
| import org.apache.maven.wagon.TransferFailedException; |
| import org.apache.maven.wagon.Wagon; |
| import org.apache.maven.wagon.authorization.AuthorizationException; |
| import org.apache.maven.wagon.events.TransferEvent; |
| import org.apache.maven.wagon.proxy.ProxyInfo; |
| import org.apache.maven.wagon.repository.Repository; |
| import org.apache.maven.wagon.resource.Resource; |
| import org.apache.maven.wagon.shared.http.EncodingUtil; |
| import org.codehaus.plexus.util.IOUtil; |
| |
| import java.io.ByteArrayInputStream; |
| import java.io.File; |
| import java.io.FileInputStream; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.OutputStream; |
| import java.nio.ByteBuffer; |
| import java.text.SimpleDateFormat; |
| import java.util.Date; |
| import java.util.Locale; |
| import java.util.Properties; |
| import java.util.TimeZone; |
| import java.util.zip.GZIPInputStream; |
| |
| /** |
| * @author <a href="michal.maczka@dimatics.com">Michal Maczka</a> |
| * @author <a href="mailto:james@atlassian.com">James William Dumay</a> |
| */ |
| public abstract class AbstractHttpClientWagon |
| extends StreamWagon |
| { |
| private final class RequestEntityImplementation |
| implements RequestEntity |
| { |
| private final Resource resource; |
| |
| private final Wagon wagon; |
| |
| private File source; |
| |
| private ByteBuffer byteBuffer; |
| |
| private RequestEntityImplementation( final InputStream stream, final Resource resource, final Wagon wagon, |
| final File source ) |
| throws TransferFailedException |
| { |
| if ( source != null ) |
| { |
| this.source = source; |
| } |
| else |
| { |
| try |
| { |
| byte[] bytes = IOUtils.toByteArray( stream ); |
| this.byteBuffer = ByteBuffer.allocate( bytes.length ); |
| this.byteBuffer.put( bytes ); |
| stream.close(); |
| } |
| catch ( IOException e ) |
| { |
| throw new TransferFailedException( e.getMessage(), e ); |
| } |
| finally |
| { |
| IOUtils.closeQuietly( stream ); |
| } |
| } |
| |
| this.resource = resource; |
| this.wagon = wagon; |
| } |
| |
| public long getContentLength() |
| { |
| return resource.getContentLength(); |
| } |
| |
| public String getContentType() |
| { |
| return null; |
| } |
| |
| public boolean isRepeatable() |
| { |
| return true; |
| } |
| |
| public void writeRequest( OutputStream output ) |
| throws IOException |
| { |
| byte[] buffer = new byte[DEFAULT_BUFFER_SIZE]; |
| |
| TransferEvent transferEvent = |
| new TransferEvent( wagon, resource, TransferEvent.TRANSFER_PROGRESS, TransferEvent.REQUEST_PUT ); |
| transferEvent.setTimestamp( System.currentTimeMillis() ); |
| |
| InputStream fin = null; |
| try |
| { |
| fin = this.source != null |
| ? new FileInputStream( source ) |
| : new ByteArrayInputStream( this.byteBuffer.array() ); |
| int remaining = Integer.MAX_VALUE; |
| while ( remaining > 0 ) |
| { |
| int n = fin.read( buffer, 0, Math.min( buffer.length, remaining ) ); |
| |
| if ( n == -1 ) |
| { |
| break; |
| } |
| |
| fireTransferProgress( transferEvent, buffer, n ); |
| |
| output.write( buffer, 0, n ); |
| |
| remaining -= n; |
| } |
| |
| fin.close(); |
| fin = null; |
| } |
| finally |
| { |
| IOUtils.closeQuietly( fin ); |
| } |
| |
| output.flush(); |
| } |
| } |
| |
| protected static final int SC_NULL = -1; |
| |
| protected static final TimeZone GMT_TIME_ZONE = TimeZone.getTimeZone( "GMT" ); |
| |
| private HttpClient client; |
| |
| protected HttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager(); |
| |
| /** |
| * @deprecated Use httpConfiguration instead. |
| */ |
| private Properties httpHeaders; |
| |
| /** |
| * @since 1.0-beta-6 |
| */ |
| private HttpConfiguration httpConfiguration; |
| |
| private HttpMethod getMethod; |
| |
| public void openConnectionInternal() |
| { |
| repository.setUrl( getURL( repository ) ); |
| client = new HttpClient( connectionManager ); |
| |
| // WAGON-273: default the cookie-policy to browser compatible |
| client.getParams().setCookiePolicy( CookiePolicy.BROWSER_COMPATIBILITY ); |
| |
| String username = null; |
| String password = null; |
| String domain = null; |
| |
| if ( authenticationInfo != null ) |
| { |
| username = authenticationInfo.getUserName(); |
| |
| if ( StringUtils.contains( username, "\\" ) ) |
| { |
| String[] domainAndUsername = username.split( "\\\\" ); |
| domain = domainAndUsername[0]; |
| username = domainAndUsername[1]; |
| } |
| |
| password = authenticationInfo.getPassword(); |
| |
| |
| } |
| |
| String host = getRepository().getHost(); |
| |
| if ( StringUtils.isNotEmpty( username ) && StringUtils.isNotEmpty( password ) ) |
| { |
| Credentials creds; |
| if ( domain != null ) |
| { |
| creds = new NTCredentials( username, password, host, domain ); |
| } |
| else |
| { |
| creds = new UsernamePasswordCredentials( username, password ); |
| } |
| |
| int port = getRepository().getPort() > -1 ? getRepository().getPort() : AuthScope.ANY_PORT; |
| |
| AuthScope scope = new AuthScope( host, port ); |
| client.getState().setCredentials( scope, creds ); |
| } |
| |
| HostConfiguration hc = new HostConfiguration(); |
| |
| ProxyInfo proxyInfo = getProxyInfo( getRepository().getProtocol(), getRepository().getHost() ); |
| if ( proxyInfo != null ) |
| { |
| String proxyUsername = proxyInfo.getUserName(); |
| String proxyPassword = proxyInfo.getPassword(); |
| String proxyHost = proxyInfo.getHost(); |
| int proxyPort = proxyInfo.getPort(); |
| String proxyNtlmHost = proxyInfo.getNtlmHost(); |
| String proxyNtlmDomain = proxyInfo.getNtlmDomain(); |
| if ( proxyHost != null ) |
| { |
| hc.setProxy( proxyHost, proxyPort ); |
| |
| if ( proxyUsername != null && proxyPassword != null ) |
| { |
| Credentials creds; |
| if ( proxyNtlmHost != null || proxyNtlmDomain != null ) |
| { |
| creds = new NTCredentials( proxyUsername, proxyPassword, proxyNtlmHost, proxyNtlmDomain ); |
| } |
| else |
| { |
| creds = new UsernamePasswordCredentials( proxyUsername, proxyPassword ); |
| } |
| |
| int port = proxyInfo.getPort() > -1 ? proxyInfo.getPort() : AuthScope.ANY_PORT; |
| |
| AuthScope scope = new AuthScope( proxyHost, port ); |
| client.getState().setProxyCredentials( scope, creds ); |
| } |
| } |
| } |
| |
| hc.setHost( host ); |
| |
| //start a session with the webserver |
| client.setHostConfiguration( hc ); |
| } |
| |
| public void closeConnection() |
| { |
| if ( connectionManager instanceof MultiThreadedHttpConnectionManager ) |
| { |
| ( (MultiThreadedHttpConnectionManager) connectionManager ).shutdown(); |
| } |
| } |
| |
| public void put( File source, String resourceName ) |
| throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException |
| { |
| Resource resource = new Resource( resourceName ); |
| |
| firePutInitiated( resource, source ); |
| |
| resource.setContentLength( source.length() ); |
| |
| resource.setLastModified( source.lastModified() ); |
| |
| put( null, resource, source ); |
| } |
| |
| public void putFromStream( final InputStream stream, String destination, long contentLength, long lastModified ) |
| throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException |
| { |
| Resource resource = new Resource( destination ); |
| |
| firePutInitiated( resource, null ); |
| |
| resource.setContentLength( contentLength ); |
| |
| resource.setLastModified( lastModified ); |
| |
| put( stream, resource, null ); |
| } |
| |
| private void put( final InputStream stream, Resource resource, File source ) |
| throws TransferFailedException, AuthorizationException, ResourceDoesNotExistException |
| { |
| RequestEntityImplementation requestEntityImplementation = |
| new RequestEntityImplementation( stream, resource, this, source ); |
| |
| put( resource, source, requestEntityImplementation, buildUrl( resource ) ); |
| |
| } |
| |
| /** |
| * Builds a complete URL string from the repository URL and the relative path of the resource passed. |
| * |
| * @param resource the resource to extract the relative path from. |
| * @return the complete URL |
| */ |
| private String buildUrl( Resource resource ) |
| { |
| return EncodingUtil.encodeURLToString( getRepository().getUrl(), resource.getName() ); |
| } |
| |
| private void put( Resource resource, File source, RequestEntityImplementation requestEntityImplementation, |
| String url ) |
| throws TransferFailedException, AuthorizationException, ResourceDoesNotExistException |
| { |
| // preemptive true for put |
| client.getParams().setAuthenticationPreemptive( true ); |
| |
| //Parent directories need to be created before posting |
| try |
| { |
| mkdirs( PathUtils.dirname( resource.getName() ) ); |
| } |
| catch ( IOException e ) |
| { |
| fireTransferError( resource, e, TransferEvent.REQUEST_GET ); |
| } |
| |
| PutMethod putMethod = new PutMethod( url ); |
| |
| firePutStarted( resource, source ); |
| |
| try |
| { |
| putMethod.setRequestEntity( requestEntityImplementation ); |
| |
| int statusCode; |
| try |
| { |
| statusCode = execute( putMethod ); |
| |
| } |
| catch ( IOException e ) |
| { |
| fireTransferError( resource, e, TransferEvent.REQUEST_PUT ); |
| |
| throw new TransferFailedException( e.getMessage(), e ); |
| } |
| |
| fireTransferDebug( url + " - Status code: " + statusCode ); |
| |
| // Check that we didn't run out of retries. |
| // CHECKSTYLE_OFF: AvoidNestedBlocks |
| switch ( statusCode ) |
| { |
| // Success Codes |
| case HttpStatus.SC_OK: // 200 |
| case HttpStatus.SC_CREATED: // 201 |
| case HttpStatus.SC_ACCEPTED: // 202 |
| case HttpStatus.SC_NO_CONTENT: // 204 |
| break; |
| |
| // handle all redirect even if http specs says |
| // " the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user" |
| case HttpStatus.SC_MOVED_PERMANENTLY: // 301 |
| case HttpStatus.SC_MOVED_TEMPORARILY: // 302 |
| case HttpStatus.SC_SEE_OTHER: // 303 |
| String relocatedUrl = calculateRelocatedUrl( putMethod ); |
| fireTransferDebug( "relocate to " + relocatedUrl ); |
| put( resource, source, requestEntityImplementation, relocatedUrl ); |
| return; |
| |
| case SC_NULL: |
| { |
| TransferFailedException e = new TransferFailedException( "Failed to transfer file: " + url ); |
| fireTransferError( resource, e, TransferEvent.REQUEST_PUT ); |
| throw e; |
| } |
| |
| case HttpStatus.SC_FORBIDDEN: |
| fireSessionConnectionRefused(); |
| throw new AuthorizationException( "Access denied to: " + url ); |
| |
| case HttpStatus.SC_NOT_FOUND: |
| throw new ResourceDoesNotExistException( "File: " + url + " does not exist" ); |
| |
| //add more entries here |
| default: |
| { |
| TransferFailedException e = new TransferFailedException( |
| "Failed to transfer file: " + url + ". Return code is: " + statusCode ); |
| fireTransferError( resource, e, TransferEvent.REQUEST_PUT ); |
| throw e; |
| } |
| } |
| // CHECKSTYLE_ON: AvoidNestedBlocks |
| |
| firePutCompleted( resource, source ); |
| } |
| finally |
| { |
| putMethod.releaseConnection(); |
| } |
| } |
| |
| protected String calculateRelocatedUrl( EntityEnclosingMethod method ) |
| { |
| Header locationHeader = method.getResponseHeader( "Location" ); |
| String locationField = locationHeader.getValue(); |
| // is it a relative Location or a full ? |
| return locationField.startsWith( "http" ) ? locationField : getURL( getRepository() ) + '/' + locationField; |
| } |
| |
| protected void mkdirs( String dirname ) |
| throws IOException |
| { |
| // do nothing as default. |
| } |
| |
| public boolean resourceExists( String resourceName ) |
| throws TransferFailedException, AuthorizationException |
| { |
| StringBuilder url = new StringBuilder( getRepository().getUrl() ); |
| if ( !url.toString().endsWith( "/" ) ) |
| { |
| url.append( '/' ); |
| } |
| url.append( resourceName ); |
| HeadMethod headMethod = new HeadMethod( url.toString() ); |
| |
| int statusCode; |
| try |
| { |
| statusCode = execute( headMethod ); |
| } |
| catch ( IOException e ) |
| { |
| throw new TransferFailedException( e.getMessage(), e ); |
| } |
| try |
| { |
| switch ( statusCode ) |
| { |
| case HttpStatus.SC_OK: |
| return true; |
| |
| case HttpStatus.SC_NOT_MODIFIED: |
| return true; |
| |
| case SC_NULL: |
| throw new TransferFailedException( "Failed to transfer file: " + url ); |
| |
| case HttpStatus.SC_FORBIDDEN: |
| throw new AuthorizationException( "Access denied to: " + url ); |
| |
| case HttpStatus.SC_UNAUTHORIZED: |
| throw new AuthorizationException( "Not authorized." ); |
| |
| case HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED: |
| throw new AuthorizationException( "Not authorized by proxy." ); |
| |
| case HttpStatus.SC_NOT_FOUND: |
| return false; |
| |
| //add more entries here |
| default: |
| throw new TransferFailedException( |
| "Failed to transfer file: " + url + ". Return code is: " + statusCode ); |
| } |
| } |
| finally |
| { |
| headMethod.releaseConnection(); |
| } |
| } |
| |
| protected int execute( HttpMethod httpMethod ) |
| throws IOException |
| { |
| int statusCode; |
| |
| setParameters( httpMethod ); |
| setHeaders( httpMethod ); |
| |
| statusCode = client.executeMethod( httpMethod ); |
| return statusCode; |
| } |
| |
| protected void setParameters( HttpMethod method ) |
| { |
| HttpMethodConfiguration config = |
| httpConfiguration == null ? null : httpConfiguration.getMethodConfiguration( method ); |
| if ( config != null ) |
| { |
| HttpMethodParams params = config.asMethodParams( method.getParams() ); |
| if ( params != null ) |
| { |
| method.setParams( params ); |
| } |
| } |
| |
| if ( config == null || config.getConnectionTimeout() == HttpMethodConfiguration.DEFAULT_CONNECTION_TIMEOUT ) |
| { |
| method.getParams().setSoTimeout( getTimeout() ); |
| } |
| } |
| |
| protected void setHeaders( HttpMethod method ) |
| { |
| HttpMethodConfiguration config = |
| httpConfiguration == null ? null : httpConfiguration.getMethodConfiguration( method ); |
| if ( config == null || config.isUseDefaultHeaders() ) |
| { |
| // TODO: merge with the other headers and have some better defaults, unify with lightweight headers |
| method.addRequestHeader( "Cache-control", "no-cache" ); |
| method.addRequestHeader( "Cache-store", "no-store" ); |
| method.addRequestHeader( "Pragma", "no-cache" ); |
| method.addRequestHeader( "Expires", "0" ); |
| method.addRequestHeader( "Accept-Encoding", "gzip" ); |
| method.addRequestHeader( "User-Agent", DEFAULT_USER_AGENT ); |
| } |
| |
| if ( httpHeaders != null ) |
| { |
| for ( Object header : httpHeaders.keySet() ) |
| { |
| if ( "User-Agent".equals( header ) ) |
| { |
| method.setRequestHeader( (String) header, httpHeaders.getProperty( (String) header ) ); |
| } |
| else |
| { |
| method.addRequestHeader( (String) header, httpHeaders.getProperty( (String) header ) ); |
| } |
| } |
| } |
| |
| Header[] headers = config == null ? null : config.asRequestHeaders(); |
| if ( headers != null ) |
| { |
| for ( Header header : headers ) |
| { |
| method.addRequestHeader( header ); |
| } |
| } |
| } |
| |
| private static final String DEFAULT_USER_AGENT = getDefaultUserAgent(); |
| |
| private static String getDefaultUserAgent() |
| { |
| Properties props = new Properties(); |
| |
| InputStream is = AbstractHttpClientWagon.class.getResourceAsStream( |
| "/META-INF/maven/org.apache.maven.wagon/wagon-webdav-jackrabbit/pom.properties" ); |
| if ( is != null ) |
| { |
| try |
| { |
| props.load( is ); |
| is.close(); |
| is = null; |
| } |
| catch ( IOException ignore ) |
| { |
| // ignore |
| } |
| finally |
| { |
| IOUtil.close( is ); |
| } |
| } |
| |
| String ver = props.getProperty( "version", "unknown-version" ); |
| return "Apache-Maven-Wagon/" + ver + " (Java " + System.getProperty( "java.version" ) + "; "; |
| } |
| |
| /** |
| * getUrl |
| * Implementors can override this to remove unwanted parts of the url such as role-hints |
| * |
| * @param repository |
| * @return |
| */ |
| protected String getURL( Repository repository ) |
| { |
| return repository.getUrl(); |
| } |
| |
| protected HttpClient getClient() |
| { |
| return client; |
| } |
| |
| public void setConnectionManager( HttpConnectionManager connectionManager ) |
| { |
| this.connectionManager = connectionManager; |
| } |
| |
| public Properties getHttpHeaders() |
| { |
| return httpHeaders; |
| } |
| |
| public void setHttpHeaders( Properties httpHeaders ) |
| { |
| this.httpHeaders = httpHeaders; |
| } |
| |
| public HttpConfiguration getHttpConfiguration() |
| { |
| return httpConfiguration; |
| } |
| |
| public void setHttpConfiguration( HttpConfiguration httpConfiguration ) |
| { |
| this.httpConfiguration = httpConfiguration; |
| } |
| |
| public void fillInputData( InputData inputData ) |
| throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException |
| { |
| Resource resource = inputData.getResource(); |
| |
| StringBuilder url = new StringBuilder( getRepository().getUrl() ); |
| if ( !url.toString().endsWith( "/" ) ) |
| { |
| url.append( '/' ); |
| } |
| url.append( resource.getName() ); |
| |
| getMethod = new GetMethod( url.toString() ); |
| |
| long timestamp = resource.getLastModified(); |
| if ( timestamp > 0 ) |
| { |
| SimpleDateFormat fmt = new SimpleDateFormat( "EEE, dd-MMM-yy HH:mm:ss zzz", Locale.US ); |
| fmt.setTimeZone( GMT_TIME_ZONE ); |
| Header hdr = new Header( "If-Modified-Since", fmt.format( new Date( timestamp ) ) ); |
| fireTransferDebug( "sending ==> " + hdr + "(" + timestamp + ")" ); |
| getMethod.addRequestHeader( hdr ); |
| } |
| |
| int statusCode; |
| try |
| { |
| statusCode = execute( getMethod ); |
| } |
| catch ( IOException e ) |
| { |
| fireTransferError( resource, e, TransferEvent.REQUEST_GET ); |
| |
| throw new TransferFailedException( e.getMessage(), e ); |
| } |
| |
| fireTransferDebug( url + " - Status code: " + statusCode ); |
| |
| // TODO [BP]: according to httpclient docs, really should swallow the output on error. verify if that is |
| // required |
| // CHECKSTYLE_OFF: AvoidNestedBlocks |
| switch ( statusCode ) |
| { |
| case HttpStatus.SC_OK: |
| break; |
| |
| case HttpStatus.SC_NOT_MODIFIED: |
| // return, leaving last modified set to original value so getIfNewer should return unmodified |
| return; |
| |
| case SC_NULL: |
| { |
| TransferFailedException e = new TransferFailedException( "Failed to transfer file: " + url ); |
| fireTransferError( resource, e, TransferEvent.REQUEST_GET ); |
| throw e; |
| } |
| |
| case HttpStatus.SC_FORBIDDEN: |
| fireSessionConnectionRefused(); |
| throw new AuthorizationException( "Access denied to: " + url ); |
| |
| case HttpStatus.SC_UNAUTHORIZED: |
| fireSessionConnectionRefused(); |
| throw new AuthorizationException( "Not authorized." ); |
| |
| case HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED: |
| fireSessionConnectionRefused(); |
| throw new AuthorizationException( "Not authorized by proxy." ); |
| |
| case HttpStatus.SC_NOT_FOUND: |
| throw new ResourceDoesNotExistException( "File: " + url + " does not exist" ); |
| |
| // add more entries here |
| default: |
| { |
| cleanupGetTransfer( resource ); |
| TransferFailedException e = new TransferFailedException( |
| "Failed to transfer file: " + url + ". Return code is: " + statusCode ); |
| fireTransferError( resource, e, TransferEvent.REQUEST_GET ); |
| throw e; |
| } |
| } |
| // CHECKSTYLE_ON: AvoidNestedBlocks |
| |
| InputStream is = null; |
| |
| Header contentLengthHeader = getMethod.getResponseHeader( "Content-Length" ); |
| |
| if ( contentLengthHeader != null ) |
| { |
| try |
| { |
| long contentLength = Integer.valueOf( contentLengthHeader.getValue() ).intValue(); |
| |
| resource.setContentLength( contentLength ); |
| } |
| catch ( NumberFormatException e ) |
| { |
| fireTransferDebug( |
| "error parsing content length header '" + contentLengthHeader.getValue() + "' " + e ); |
| } |
| } |
| |
| Header lastModifiedHeader = getMethod.getResponseHeader( "Last-Modified" ); |
| |
| long lastModified = 0; |
| |
| if ( lastModifiedHeader != null ) |
| { |
| try |
| { |
| lastModified = DateUtil.parseDate( lastModifiedHeader.getValue() ).getTime(); |
| |
| resource.setLastModified( lastModified ); |
| } |
| catch ( DateParseException e ) |
| { |
| fireTransferDebug( "Unable to parse last modified header" ); |
| } |
| |
| fireTransferDebug( "last-modified = " + lastModifiedHeader.getValue() + " (" + lastModified + ")" ); |
| } |
| |
| Header contentEncoding = getMethod.getResponseHeader( "Content-Encoding" ); |
| boolean isGZipped = contentEncoding != null && "gzip".equalsIgnoreCase( contentEncoding.getValue() ); |
| |
| try |
| { |
| is = getMethod.getResponseBodyAsStream(); |
| if ( isGZipped ) |
| { |
| is = new GZIPInputStream( is ); |
| } |
| } |
| catch ( IOException e ) |
| { |
| fireTransferError( resource, e, TransferEvent.REQUEST_GET ); |
| |
| String msg = |
| "Error occurred while retrieving from remote repository:" + getRepository() + ": " + e.getMessage(); |
| |
| throw new TransferFailedException( msg, e ); |
| } |
| |
| inputData.setInputStream( is ); |
| } |
| |
| protected void cleanupGetTransfer( Resource resource ) |
| { |
| if ( getMethod != null ) |
| { |
| getMethod.releaseConnection(); |
| } |
| } |
| |
| @Override |
| public void putFromStream( InputStream stream, String destination ) |
| throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException |
| { |
| putFromStream( stream, destination, -1, -1 ); |
| } |
| |
| @Override |
| protected void putFromStream( InputStream stream, Resource resource ) |
| throws TransferFailedException, AuthorizationException, ResourceDoesNotExistException |
| { |
| putFromStream( stream, resource.getName(), -1, -1 ); |
| } |
| |
| @Override |
| public void fillOutputData( OutputData outputData ) |
| throws TransferFailedException |
| { |
| // no needed in this implementation but throw an Exception if used |
| throw new IllegalStateException( "this wagon http client must not use fillOutputData" ); |
| } |
| } |