1 package org.apache.maven.wagon.shared.http;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.http.Header;
23 import org.apache.http.HttpEntity;
24 import org.apache.http.HttpException;
25 import org.apache.http.HttpHost;
26 import org.apache.http.HttpResponse;
27 import org.apache.http.HttpStatus;
28 import org.apache.http.auth.AuthScope;
29 import org.apache.http.auth.Credentials;
30 import org.apache.http.auth.NTCredentials;
31 import org.apache.http.auth.UsernamePasswordCredentials;
32 import org.apache.http.client.AuthCache;
33 import org.apache.http.client.methods.HttpGet;
34 import org.apache.http.client.methods.HttpHead;
35 import org.apache.http.client.methods.HttpPut;
36 import org.apache.http.client.methods.HttpUriRequest;
37 import org.apache.http.client.params.ClientPNames;
38 import org.apache.http.client.params.CookiePolicy;
39 import org.apache.http.client.protocol.ClientContext;
40 import org.apache.http.conn.ClientConnectionManager;
41 import org.apache.http.conn.params.ConnRoutePNames;
42 import org.apache.http.conn.scheme.Scheme;
43 import org.apache.http.conn.ssl.BrowserCompatHostnameVerifier;
44 import org.apache.http.conn.ssl.SSLSocketFactory;
45 import org.apache.http.conn.ssl.X509HostnameVerifier;
46 import org.apache.http.impl.auth.BasicScheme;
47 import org.apache.http.impl.client.BasicAuthCache;
48 import org.apache.http.impl.client.DefaultHttpClient;
49 import org.apache.http.impl.conn.SingleClientConnManager;
50 import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
51 import org.apache.http.impl.cookie.DateParseException;
52 import org.apache.http.impl.cookie.DateUtils;
53 import org.apache.http.message.BasicHeader;
54 import org.apache.http.params.CoreConnectionPNames;
55 import org.apache.http.params.CoreProtocolPNames;
56 import org.apache.http.params.HttpParams;
57 import org.apache.http.protocol.BasicHttpContext;
58 import org.apache.maven.wagon.InputData;
59 import org.apache.maven.wagon.OutputData;
60 import org.apache.maven.wagon.PathUtils;
61 import org.apache.maven.wagon.ResourceDoesNotExistException;
62 import org.apache.maven.wagon.StreamWagon;
63 import org.apache.maven.wagon.TransferFailedException;
64 import org.apache.maven.wagon.Wagon;
65 import org.apache.maven.wagon.authorization.AuthorizationException;
66 import org.apache.maven.wagon.events.TransferEvent;
67 import org.apache.maven.wagon.proxy.ProxyInfo;
68 import org.apache.maven.wagon.repository.Repository;
69 import org.apache.maven.wagon.resource.Resource;
70 import org.codehaus.plexus.util.IOUtil;
71 import org.codehaus.plexus.util.StringUtils;
72
73 import javax.net.ssl.SSLException;
74 import javax.net.ssl.SSLSession;
75 import javax.net.ssl.SSLSocket;
76 import java.io.File;
77 import java.io.FileInputStream;
78 import java.io.FileOutputStream;
79 import java.io.IOException;
80 import java.io.InputStream;
81 import java.io.OutputStream;
82 import java.net.URLEncoder;
83 import java.security.cert.X509Certificate;
84 import java.text.SimpleDateFormat;
85 import java.util.Date;
86 import java.util.Locale;
87 import java.util.Map;
88 import java.util.Properties;
89 import java.util.TimeZone;
90 import java.util.zip.GZIPInputStream;
91
92
93
94
95
96 public abstract class AbstractHttpClientWagon
97 extends StreamWagon
98 {
99
100 private BasicHttpContext localContext;
101
102 private final class RequestEntityImplementation
103 implements HttpEntity
104 {
105 private final Resource resource;
106
107 private final Wagon wagon;
108
109 private final File source;
110
111 private RequestEntityImplementation( final InputStream stream, final Resource resource, final Wagon wagon,
112 final File source )
113 throws TransferFailedException
114 {
115 if ( source != null )
116 {
117 this.source = source;
118 }
119 else
120 {
121 FileOutputStream fos = null;
122 try
123 {
124 this.source = File.createTempFile( "http-wagon.", ".tmp" );
125 this.source.deleteOnExit();
126
127 fos = new FileOutputStream( this.source );
128 IOUtil.copy( stream, fos );
129 }
130 catch ( IOException e )
131 {
132 fireTransferError( resource, e, TransferEvent.REQUEST_PUT );
133 throw new TransferFailedException( "Failed to buffer stream contents to temp file for upload.", e );
134 }
135 finally
136 {
137 IOUtil.close( fos );
138 }
139 }
140
141 this.resource = resource;
142 this.wagon = wagon;
143 }
144
145 public long getContentLength()
146 {
147 return resource.getContentLength();
148 }
149
150 public Header getContentType()
151 {
152 return null;
153 }
154
155 public Header getContentEncoding()
156 {
157 return null;
158 }
159
160 public InputStream getContent()
161 throws IOException, IllegalStateException
162 {
163 FileInputStream fis = new FileInputStream( source );
164
165 return fis;
166 }
167
168 public boolean isRepeatable()
169 {
170 return true;
171 }
172
173 public boolean isChunked()
174 {
175 return false;
176 }
177
178 public void writeTo( OutputStream output )
179 throws IOException
180 {
181 byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
182
183 TransferEvent transferEvent =
184 new TransferEvent( wagon, resource, TransferEvent.TRANSFER_PROGRESS, TransferEvent.REQUEST_PUT );
185 transferEvent.setTimestamp( System.currentTimeMillis() );
186
187 FileInputStream fin = null;
188 try
189 {
190 fin = new FileInputStream( source );
191 int remaining = Integer.MAX_VALUE;
192 while ( remaining > 0 )
193 {
194 int n = fin.read( buffer, 0, Math.min( buffer.length, remaining ) );
195
196 if ( n == -1 )
197 {
198 break;
199 }
200
201 fireTransferProgress( transferEvent, buffer, n );
202
203 output.write( buffer, 0, n );
204
205 remaining -= n;
206 }
207 }
208 finally
209 {
210 IOUtil.close( fin );
211 }
212
213 output.flush();
214 }
215
216 public boolean isStreaming()
217 {
218 return false;
219 }
220
221 public void consumeContent()
222 throws IOException
223 {
224 }
225 }
226
227 protected static final int SC_NULL = -1;
228
229 protected static final TimeZone GMT_TIME_ZONE = TimeZone.getTimeZone( "GMT" );
230
231 private DefaultHttpClient client;
232
233
234
235
236 protected static ClientConnectionManager connectionManagerPooled;
237
238
239
240
241 protected ClientConnectionManager clientConnectionManager = new SingleClientConnManager();
242
243
244
245
246
247
248
249 protected static boolean useClientManagerPooled =
250 Boolean.valueOf( System.getProperty( "maven.wagon.http.pool", "true" ) );
251
252
253
254
255
256
257
258 protected static boolean sslEasy = Boolean.valueOf( System.getProperty( "maven.wagon.http.ssl.easy", "true" ) );
259
260
261
262
263
264
265
266 protected static boolean sslAllowAll =
267 Boolean.valueOf( System.getProperty( "maven.wagon.http.ssl.allowall", "true" ) );
268
269
270
271
272
273
274
275 protected static boolean IGNORE_SSL_VALIDITY_DATES =
276 Boolean.valueOf( System.getProperty( "maven.wagon.http.ssl.ignore.validity.dates", "true" ) );
277
278 static
279 {
280 if ( !useClientManagerPooled )
281 {
282 System.out.println( "http connection pool disabled in wagon http" );
283 }
284 else
285 {
286
287 ThreadSafeClientConnManager threadSafeClientConnManager = new ThreadSafeClientConnManager();
288 int maxPerRoute =
289 Integer.parseInt( System.getProperty( "maven.wagon.httpconnectionManager.maxPerRoute", "20" ) );
290 threadSafeClientConnManager.setDefaultMaxPerRoute( maxPerRoute );
291 int maxTotal = Integer.parseInt( System.getProperty( "maven.wagon.httpconnectionManager.maxTotal", "40" ) );
292 threadSafeClientConnManager.setDefaultMaxPerRoute( maxPerRoute );
293 threadSafeClientConnManager.setMaxTotal( maxTotal );
294
295 if ( sslEasy )
296 {
297 try
298 {
299 SSLSocketFactory sslSocketFactory =
300 new SSLSocketFactory( EasyX509TrustManager.createEasySSLContext(), sslAllowAll
301 ? new EasyHostNameVerifier()
302 : new BrowserCompatHostnameVerifier() );
303 Scheme httpsScheme = new Scheme( "https", 443, sslSocketFactory );
304
305 threadSafeClientConnManager.getSchemeRegistry().register( httpsScheme );
306 }
307 catch ( IOException e )
308 {
309 throw new RuntimeException( "failed to init SSLSocket Factory " + e.getMessage(), e );
310 }
311 }
312 System.out.println( " wagon http use multi threaded http connection manager maxPerRoute "
313 + threadSafeClientConnManager.getDefaultMaxPerRoute() + ", max total "
314 + threadSafeClientConnManager.getMaxTotal() );
315
316 connectionManagerPooled = threadSafeClientConnManager;
317 }
318 }
319
320
321
322
323
324
325 private static class EasyHostNameVerifier
326 implements X509HostnameVerifier
327 {
328 public void verify( String s, SSLSocket sslSocket )
329 throws IOException
330 {
331
332 }
333
334 public void verify( String s, X509Certificate x509Certificate )
335 throws SSLException
336 {
337
338 }
339
340 public void verify( String s, String[] strings, String[] strings1 )
341 throws SSLException
342 {
343
344 }
345
346 public boolean verify( String s, SSLSession sslSession )
347 {
348 return true;
349 }
350 }
351
352 public ClientConnectionManager getConnectionManager()
353 {
354 if ( !useClientManagerPooled )
355 {
356 return clientConnectionManager;
357 }
358 return connectionManagerPooled;
359 }
360
361 public static void setConnectionManagerPooled( ClientConnectionManager clientConnectionManager )
362 {
363 connectionManagerPooled = clientConnectionManager;
364 }
365
366 public static void setUseClientManagerPooled( boolean pooledClientManager )
367 {
368 useClientManagerPooled = pooledClientManager;
369 }
370
371
372
373
374
375 private Properties httpHeaders;
376
377
378
379
380 private HttpConfiguration httpConfiguration;
381
382 private HttpGet getMethod;
383
384 public void openConnectionInternal()
385 {
386 repository.setUrl( getURL( repository ) );
387 client = new DefaultHttpClient( getConnectionManager() );
388
389
390 client.getParams().setParameter( ClientPNames.COOKIE_POLICY, CookiePolicy.BROWSER_COMPATIBILITY );
391
392 String username = null;
393 String password = null;
394
395 if ( authenticationInfo != null )
396 {
397 username = authenticationInfo.getUserName();
398
399 password = authenticationInfo.getPassword();
400 }
401
402 if ( StringUtils.isNotEmpty( username ) && StringUtils.isNotEmpty( password ) )
403 {
404 Credentials creds = new UsernamePasswordCredentials( username, password );
405
406 String host = getRepository().getHost();
407 int port = getRepository().getPort() > -1 ? getRepository().getPort() : AuthScope.ANY_PORT;
408
409 client.getCredentialsProvider().setCredentials( new AuthScope( host, port ), creds );
410
411 AuthCache authCache = new BasicAuthCache();
412 BasicScheme basicAuth = new BasicScheme();
413 HttpHost targetHost = new HttpHost( repository.getHost(), repository.getPort(), repository.getProtocol() );
414 authCache.put( targetHost, basicAuth );
415
416 localContext = new BasicHttpContext();
417 localContext.setAttribute( ClientContext.AUTH_CACHE, authCache );
418 }
419
420 ProxyInfo proxyInfo = getProxyInfo( getRepository().getProtocol(), getRepository().getHost() );
421 if ( proxyInfo != null )
422 {
423 String proxyUsername = proxyInfo.getUserName();
424 String proxyPassword = proxyInfo.getPassword();
425 String proxyHost = proxyInfo.getHost();
426 int proxyPort = proxyInfo.getPort();
427 String proxyNtlmHost = proxyInfo.getNtlmHost();
428 String proxyNtlmDomain = proxyInfo.getNtlmDomain();
429 if ( proxyHost != null )
430 {
431 HttpHost proxy = new HttpHost( proxyHost, proxyPort );
432
433 if ( proxyUsername != null && proxyPassword != null )
434 {
435 Credentials creds;
436 if ( proxyNtlmHost != null || proxyNtlmDomain != null )
437 {
438 creds = new NTCredentials( proxyUsername, proxyPassword, proxyNtlmHost, proxyNtlmDomain );
439 }
440 else
441 {
442 creds = new UsernamePasswordCredentials( proxyUsername, proxyPassword );
443 }
444
445 int port = proxyInfo.getPort() > -1 ? proxyInfo.getPort() : AuthScope.ANY_PORT;
446
447 AuthScope authScope = new AuthScope( proxyHost, port );
448 client.getCredentialsProvider().setCredentials( authScope, creds );
449 }
450
451 client.getParams().setParameter( ConnRoutePNames.DEFAULT_PROXY, proxy );
452 }
453 }
454 }
455
456 public void closeConnection()
457 {
458 if ( !useClientManagerPooled )
459 {
460 getConnectionManager().shutdown();
461 }
462 }
463
464 public void put( File source, String resourceName )
465 throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
466 {
467 Resource resource = new Resource( resourceName );
468
469 firePutInitiated( resource, source );
470
471 resource.setContentLength( source.length() );
472
473 resource.setLastModified( source.lastModified() );
474
475 put( null, resource, source );
476 }
477
478 public void putFromStream( final InputStream stream, String destination, long contentLength, long lastModified )
479 throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
480 {
481 Resource resource = new Resource( destination );
482
483 firePutInitiated( resource, null );
484
485 resource.setContentLength( contentLength );
486
487 resource.setLastModified( lastModified );
488
489 put( stream, resource, null );
490 }
491
492 private void put( final InputStream stream, Resource resource, File source )
493 throws TransferFailedException, AuthorizationException, ResourceDoesNotExistException
494 {
495 put( resource, source, new RequestEntityImplementation( stream, resource, this, source ) );
496 }
497
498 private void put( Resource resource, File source, HttpEntity httpEntity )
499 throws TransferFailedException, AuthorizationException, ResourceDoesNotExistException
500 {
501 StringBuilder url = new StringBuilder( getRepository().getUrl() );
502 String[] parts = StringUtils.split( resource.getName(), "/" );
503 for ( String part : parts )
504 {
505
506
507 if ( !url.toString().endsWith( "/" ) )
508 {
509 url.append( '/' );
510 }
511 url.append( URLEncoder.encode( part ) );
512 }
513
514
515 try
516 {
517 mkdirs( PathUtils.dirname( resource.getName() ) );
518 }
519 catch ( HttpException he )
520 {
521 fireTransferError( resource, he, TransferEvent.REQUEST_GET );
522 }
523 catch ( IOException e )
524 {
525 fireTransferError( resource, e, TransferEvent.REQUEST_GET );
526 }
527
528 HttpPut putMethod = new HttpPut( url.toString() );
529
530 firePutStarted( resource, source );
531
532 try
533 {
534 putMethod.setEntity( httpEntity );
535
536 HttpResponse response;
537 try
538 {
539 response = execute( putMethod );
540 }
541 catch ( IOException e )
542 {
543 fireTransferError( resource, e, TransferEvent.REQUEST_PUT );
544
545 throw new TransferFailedException( e.getMessage(), e );
546 }
547 catch ( HttpException e )
548 {
549 fireTransferError( resource, e, TransferEvent.REQUEST_PUT );
550
551 throw new TransferFailedException( e.getMessage(), e );
552 }
553
554 int statusCode = response.getStatusLine().getStatusCode();
555 String reasonPhrase = ", ReasonPhrase:" + response.getStatusLine().getReasonPhrase() + ".";
556 fireTransferDebug( url + " - Status code: " + statusCode + reasonPhrase );
557
558
559 switch ( statusCode )
560 {
561
562 case HttpStatus.SC_OK:
563 case HttpStatus.SC_CREATED:
564 case HttpStatus.SC_ACCEPTED:
565 case HttpStatus.SC_NO_CONTENT:
566 break;
567
568 case SC_NULL:
569 {
570 TransferFailedException e =
571 new TransferFailedException( "Failed to transfer file: " + url + reasonPhrase );
572 fireTransferError( resource, e, TransferEvent.REQUEST_PUT );
573 throw e;
574 }
575
576 case HttpStatus.SC_FORBIDDEN:
577 fireSessionConnectionRefused();
578 throw new AuthorizationException( "Access denied to: " + url + reasonPhrase );
579
580 case HttpStatus.SC_NOT_FOUND:
581 throw new ResourceDoesNotExistException( "File: " + url + " does not exist" + reasonPhrase );
582
583
584 default:
585 {
586 TransferFailedException e = new TransferFailedException(
587 "Failed to transfer file: " + url + ". Return code is: " + statusCode + reasonPhrase );
588 fireTransferError( resource, e, TransferEvent.REQUEST_PUT );
589 throw e;
590 }
591 }
592
593 firePutCompleted( resource, source );
594 }
595 finally
596 {
597 putMethod.abort();
598 }
599 }
600
601 protected void mkdirs( String dirname )
602 throws HttpException, IOException
603 {
604
605 }
606
607 public boolean resourceExists( String resourceName )
608 throws TransferFailedException, AuthorizationException
609 {
610 String repositoryUrl = getRepository().getUrl();
611 String url = repositoryUrl + ( repositoryUrl.endsWith( "/" ) ? "" : "/" ) + resourceName;
612 HttpHead headMethod = new HttpHead( url );
613 HttpResponse response = null;
614 int statusCode;
615 try
616 {
617 response = execute( headMethod );
618 }
619 catch ( IOException e )
620 {
621 throw new TransferFailedException( e.getMessage(), e );
622 }
623 catch ( HttpException e )
624 {
625 throw new TransferFailedException( e.getMessage(), e );
626 }
627
628 try
629 {
630 statusCode = response.getStatusLine().getStatusCode();
631 String reasonPhrase = ", ReasonPhrase:" + response.getStatusLine().getReasonPhrase() + ".";
632 switch ( statusCode )
633 {
634 case HttpStatus.SC_OK:
635 return true;
636
637 case HttpStatus.SC_NOT_MODIFIED:
638 return true;
639
640 case SC_NULL:
641 throw new TransferFailedException( "Failed to transfer file: " + url + reasonPhrase );
642
643 case HttpStatus.SC_FORBIDDEN:
644 throw new AuthorizationException( "Access denied to: " + url + reasonPhrase );
645
646 case HttpStatus.SC_UNAUTHORIZED:
647 throw new AuthorizationException( "Not authorized" + reasonPhrase );
648
649 case HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED:
650 throw new AuthorizationException( "Not authorized by proxy" + reasonPhrase );
651
652 case HttpStatus.SC_NOT_FOUND:
653 return false;
654
655
656 default:
657 throw new TransferFailedException(
658 "Failed to transfer file: " + url + ". Return code is: " + statusCode + reasonPhrase );
659 }
660 }
661 finally
662 {
663 headMethod.abort();
664 }
665 }
666
667 protected HttpResponse execute( HttpUriRequest httpMethod )
668 throws HttpException, IOException
669 {
670 setParameters( httpMethod );
671 setHeaders( httpMethod );
672 client.getParams().setParameter( CoreProtocolPNames.USER_AGENT, getUserAgent( httpMethod ) );
673
674 return client.execute( httpMethod, localContext );
675 }
676
677 protected void setParameters( HttpUriRequest method )
678 {
679 HttpMethodConfiguration config =
680 httpConfiguration == null ? null : httpConfiguration.getMethodConfiguration( method );
681 if ( config != null )
682 {
683 HttpParams params = config.asMethodParams( method.getParams() );
684 if ( params != null )
685 {
686 method.setParams( params );
687 }
688 }
689
690 if ( config == null || config.getReadTimeout() == HttpMethodConfiguration.DEFAULT_CONNECTION_TIMEOUT )
691 {
692 method.getParams().setParameter( CoreConnectionPNames.SO_TIMEOUT, getTimeout() );
693 }
694 }
695
696 protected void setHeaders( HttpUriRequest method )
697 {
698 HttpMethodConfiguration config =
699 httpConfiguration == null ? null : httpConfiguration.getMethodConfiguration( method );
700 if ( config == null || config.isUseDefaultHeaders() )
701 {
702
703 method.addHeader( "Cache-control", "no-cache" );
704 method.addHeader( "Cache-store", "no-store" );
705 method.addHeader( "Pragma", "no-cache" );
706 method.addHeader( "Expires", "0" );
707 method.addHeader( "Accept-Encoding", "gzip" );
708 }
709
710 if ( httpHeaders != null )
711 {
712 for ( Map.Entry<Object, Object> entry : httpHeaders.entrySet() )
713 {
714 method.addHeader( (String) entry.getKey(), (String) entry.getValue() );
715 }
716 }
717
718 Header[] headers = config == null ? null : config.asRequestHeaders();
719 if ( headers != null )
720 {
721 for ( int i = 0; i < headers.length; i++ )
722 {
723 method.addHeader( headers[i] );
724 }
725 }
726 }
727
728 protected String getUserAgent( HttpUriRequest method )
729 {
730 if ( httpHeaders != null )
731 {
732 String value = (String) httpHeaders.get( "User-Agent" );
733 if ( value != null )
734 {
735 return value;
736 }
737 }
738 HttpMethodConfiguration config =
739 httpConfiguration == null ? null : httpConfiguration.getMethodConfiguration( method );
740
741 if ( config != null )
742 {
743 return (String) config.getHeaders().get( "User-Agent" );
744 }
745 return null;
746 }
747
748
749
750
751
752
753
754
755 protected String getURL( Repository repository )
756 {
757 return repository.getUrl();
758 }
759
760 public HttpConfiguration getHttpConfiguration()
761 {
762 return httpConfiguration;
763 }
764
765 public void setHttpConfiguration( HttpConfiguration httpConfiguration )
766 {
767 this.httpConfiguration = httpConfiguration;
768 }
769
770 public void fillInputData( InputData inputData )
771 throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
772 {
773 Resource resource = inputData.getResource();
774
775 String repositoryUrl = getRepository().getUrl();
776 String url = repositoryUrl + ( repositoryUrl.endsWith( "/" ) ? "" : "/" ) + resource.getName();
777 getMethod = new HttpGet( url );
778 long timestamp = resource.getLastModified();
779 if ( timestamp > 0 )
780 {
781 SimpleDateFormat fmt = new SimpleDateFormat( "EEE, dd-MMM-yy HH:mm:ss zzz", Locale.US );
782 fmt.setTimeZone( GMT_TIME_ZONE );
783 Header hdr = new BasicHeader( "If-Modified-Since", fmt.format( new Date( timestamp ) ) );
784 fireTransferDebug( "sending ==> " + hdr + "(" + timestamp + ")" );
785 getMethod.addHeader( hdr );
786 }
787
788 HttpResponse response;
789 int statusCode;
790 try
791 {
792 response = execute( getMethod );
793 }
794 catch ( IOException e )
795 {
796 fireTransferError( resource, e, TransferEvent.REQUEST_GET );
797
798 throw new TransferFailedException( e.getMessage(), e );
799 }
800 catch ( HttpException e )
801 {
802 fireTransferError( resource, e, TransferEvent.REQUEST_GET );
803
804 throw new TransferFailedException( e.getMessage(), e );
805 }
806
807 statusCode = response.getStatusLine().getStatusCode();
808
809 String reasonPhrase = ", ReasonPhrase:" + response.getStatusLine().getReasonPhrase() + ".";
810
811 fireTransferDebug( url + " - Status code: " + statusCode + reasonPhrase );
812
813
814
815 switch ( statusCode )
816 {
817 case HttpStatus.SC_OK:
818 break;
819
820 case HttpStatus.SC_NOT_MODIFIED:
821
822 return;
823
824 case SC_NULL:
825 {
826 TransferFailedException e =
827 new TransferFailedException( "Failed to transfer file: " + url + reasonPhrase );
828 fireTransferError( resource, e, TransferEvent.REQUEST_GET );
829 throw e;
830 }
831
832 case HttpStatus.SC_FORBIDDEN:
833 fireSessionConnectionRefused();
834 throw new AuthorizationException( "Access denied to: " + url + reasonPhrase );
835
836 case HttpStatus.SC_UNAUTHORIZED:
837 fireSessionConnectionRefused();
838 throw new AuthorizationException( "Not authorized" + reasonPhrase );
839
840 case HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED:
841 fireSessionConnectionRefused();
842 throw new AuthorizationException( "Not authorized by proxy" + reasonPhrase );
843
844 case HttpStatus.SC_NOT_FOUND:
845 throw new ResourceDoesNotExistException( "File: " + url + reasonPhrase );
846
847
848 default:
849 {
850 cleanupGetTransfer( resource );
851 TransferFailedException e = new TransferFailedException(
852 "Failed to transfer file: " + url + ". Return code is: " + statusCode + reasonPhrase );
853 fireTransferError( resource, e, TransferEvent.REQUEST_GET );
854 throw e;
855 }
856 }
857
858 InputStream is;
859
860 Header contentLengthHeader = response.getFirstHeader( "Content-Length" );
861
862 if ( contentLengthHeader != null )
863 {
864 try
865 {
866 long contentLength = Integer.valueOf( contentLengthHeader.getValue() ).intValue();
867
868 resource.setContentLength( contentLength );
869 }
870 catch ( NumberFormatException e )
871 {
872 fireTransferDebug(
873 "error parsing content length header '" + contentLengthHeader.getValue() + "' " + e );
874 }
875 }
876
877 Header lastModifiedHeader = response.getFirstHeader( "Last-Modified" );
878
879 long lastModified = 0;
880
881 if ( lastModifiedHeader != null )
882 {
883 try
884 {
885 lastModified = DateUtils.parseDate( lastModifiedHeader.getValue() ).getTime();
886
887 resource.setLastModified( lastModified );
888 }
889 catch ( DateParseException e )
890 {
891 fireTransferDebug( "Unable to parse last modified header" );
892 }
893
894 fireTransferDebug( "last-modified = " + lastModifiedHeader.getValue() + " (" + lastModified + ")" );
895 }
896
897 Header contentEncoding = response.getFirstHeader( "Content-Encoding" );
898 boolean isGZipped = contentEncoding == null ? false : "gzip".equalsIgnoreCase( contentEncoding.getValue() );
899
900 try
901 {
902 is = response.getEntity().getContent();
903
904 if ( isGZipped )
905 {
906 is = new GZIPInputStream( is );
907 }
908 }
909 catch ( IOException e )
910 {
911 fireTransferError( resource, e, TransferEvent.REQUEST_GET );
912
913 String msg =
914 "Error occurred while retrieving from remote repository:" + getRepository() + ": " + e.getMessage();
915
916 throw new TransferFailedException( msg, e );
917 }
918
919 inputData.setInputStream( is );
920 }
921
922 protected void cleanupGetTransfer( Resource resource )
923 {
924 if ( getMethod != null )
925 {
926 getMethod.abort();
927 }
928 }
929
930
931 @Override
932 public void putFromStream( InputStream stream, String destination )
933 throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
934 {
935 putFromStream( stream, destination, -1, -1 );
936 }
937
938 @Override
939 protected void putFromStream( InputStream stream, Resource resource )
940 throws TransferFailedException, AuthorizationException, ResourceDoesNotExistException
941 {
942 putFromStream( stream, resource.getName(), -1, -1 );
943 }
944
945 public Properties getHttpHeaders()
946 {
947 return httpHeaders;
948 }
949
950 public void setHttpHeaders( Properties httpHeaders )
951 {
952 this.httpHeaders = httpHeaders;
953 }
954
955 @Override
956 public void fillOutputData( OutputData outputData )
957 throws TransferFailedException
958 {
959
960 throw new IllegalStateException( "this wagon http client must not use fillOutputData" );
961 }
962 }