View Javadoc

1   package org.apache.maven.wagon.providers.webdav;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.commons.httpclient.Credentials;
23  import org.apache.commons.httpclient.Header;
24  import org.apache.commons.httpclient.HostConfiguration;
25  import org.apache.commons.httpclient.HttpClient;
26  import org.apache.commons.httpclient.HttpConnectionManager;
27  import org.apache.commons.httpclient.HttpMethod;
28  import org.apache.commons.httpclient.HttpStatus;
29  import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
30  import org.apache.commons.httpclient.NTCredentials;
31  import org.apache.commons.httpclient.UsernamePasswordCredentials;
32  import org.apache.commons.httpclient.auth.AuthScope;
33  import org.apache.commons.httpclient.cookie.CookiePolicy;
34  import org.apache.commons.httpclient.methods.EntityEnclosingMethod;
35  import org.apache.commons.httpclient.methods.GetMethod;
36  import org.apache.commons.httpclient.methods.HeadMethod;
37  import org.apache.commons.httpclient.methods.PutMethod;
38  import org.apache.commons.httpclient.methods.RequestEntity;
39  import org.apache.commons.httpclient.params.HttpMethodParams;
40  import org.apache.commons.httpclient.util.DateParseException;
41  import org.apache.commons.httpclient.util.DateUtil;
42  import org.apache.commons.io.IOUtils;
43  import org.apache.commons.lang.StringUtils;
44  import org.apache.maven.wagon.InputData;
45  import org.apache.maven.wagon.OutputData;
46  import org.apache.maven.wagon.PathUtils;
47  import org.apache.maven.wagon.ResourceDoesNotExistException;
48  import org.apache.maven.wagon.StreamWagon;
49  import org.apache.maven.wagon.TransferFailedException;
50  import org.apache.maven.wagon.Wagon;
51  import org.apache.maven.wagon.authorization.AuthorizationException;
52  import org.apache.maven.wagon.events.TransferEvent;
53  import org.apache.maven.wagon.proxy.ProxyInfo;
54  import org.apache.maven.wagon.repository.Repository;
55  import org.apache.maven.wagon.resource.Resource;
56  
57  import java.io.ByteArrayInputStream;
58  import java.io.File;
59  import java.io.FileInputStream;
60  import java.io.IOException;
61  import java.io.InputStream;
62  import java.io.OutputStream;
63  import java.net.URLEncoder;
64  import java.nio.ByteBuffer;
65  import java.text.SimpleDateFormat;
66  import java.util.Date;
67  import java.util.Locale;
68  import java.util.Properties;
69  import java.util.TimeZone;
70  import java.util.zip.GZIPInputStream;
71  
72  /**
73   * @author <a href="michal.maczka@dimatics.com">Michal Maczka</a>
74   * @author <a href="mailto:james@atlassian.com">James William Dumay</a>
75   */
76  public abstract class AbstractHttpClientWagon
77      extends StreamWagon
78  {
79      private final class RequestEntityImplementation
80          implements RequestEntity
81      {
82          private final Resource resource;
83  
84          private final Wagon wagon;
85  
86          private File source;
87  
88          private ByteBuffer byteBuffer;
89  
90          private RequestEntityImplementation( final InputStream stream, final Resource resource, final Wagon wagon,
91                                               final File source )
92              throws TransferFailedException
93          {
94              if ( source != null )
95              {
96                  this.source = source;
97              }
98              else
99              {
100                 try
101                 {
102                     byte[] bytes = IOUtils.toByteArray( stream );
103                     this.byteBuffer = ByteBuffer.allocate( bytes.length );
104                     this.byteBuffer.put( bytes );
105                 }
106                 catch ( IOException e )
107                 {
108                     throw new TransferFailedException( e.getMessage(), e );
109                 }
110             }
111 
112             this.resource = resource;
113             this.wagon = wagon;
114         }
115 
116         public long getContentLength()
117         {
118             return resource.getContentLength();
119         }
120 
121         public String getContentType()
122         {
123             return null;
124         }
125 
126         public boolean isRepeatable()
127         {
128             return true;
129         }
130 
131         public void writeRequest( OutputStream output )
132             throws IOException
133         {
134             byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
135 
136             TransferEvent transferEvent =
137                 new TransferEvent( wagon, resource, TransferEvent.TRANSFER_PROGRESS, TransferEvent.REQUEST_PUT );
138             transferEvent.setTimestamp( System.currentTimeMillis() );
139 
140             InputStream fin = null;
141             try
142             {
143                 fin = this.source != null
144                     ? new FileInputStream( source )
145                     : new ByteArrayInputStream( this.byteBuffer.array() );
146                 int remaining = Integer.MAX_VALUE;
147                 while ( remaining > 0 )
148                 {
149                     int n = fin.read( buffer, 0, Math.min( buffer.length, remaining ) );
150 
151                     if ( n == -1 )
152                     {
153                         break;
154                     }
155 
156                     fireTransferProgress( transferEvent, buffer, n );
157 
158                     output.write( buffer, 0, n );
159 
160                     remaining -= n;
161                 }
162             }
163             finally
164             {
165                 IOUtils.closeQuietly( fin );
166             }
167 
168             output.flush();
169         }
170     }
171 
172     protected static final int SC_NULL = -1;
173 
174     protected static final TimeZone GMT_TIME_ZONE = TimeZone.getTimeZone( "GMT" );
175 
176     private HttpClient client;
177 
178     protected HttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
179 
180     /**
181      * @deprecated Use httpConfiguration instead.
182      */
183     private Properties httpHeaders;
184 
185     /**
186      * @since 1.0-beta-6
187      */
188     private HttpConfiguration httpConfiguration;
189 
190     private HttpMethod getMethod;
191 
192     public void openConnectionInternal()
193     {
194         repository.setUrl( getURL( repository ) );
195         client = new HttpClient( connectionManager );
196 
197         // WAGON-273: default the cookie-policy to browser compatible
198         client.getParams().setCookiePolicy( CookiePolicy.BROWSER_COMPATIBILITY );
199 
200 
201 
202         String username = null;
203         String password = null;
204         String domain = null;
205 
206         if ( authenticationInfo != null )
207         {
208             username = authenticationInfo.getUserName();
209 
210             if ( StringUtils.contains( username, "\\" ) )
211             {
212                 String[] domainAndUsername = username.split( "\\\\" );
213                 domain = domainAndUsername[0];
214                 username = domainAndUsername[1];
215             }
216 
217             password = authenticationInfo.getPassword();
218 
219 
220         }
221 
222         String host = getRepository().getHost();
223 
224         if ( StringUtils.isNotEmpty( username ) && StringUtils.isNotEmpty( password ) )
225         {
226             Credentials creds;
227             if ( domain != null )
228             {
229                 creds = new NTCredentials( username, password, host, domain );
230             }
231             else
232             {
233                 creds = new UsernamePasswordCredentials( username, password );
234             }
235 
236             int port = getRepository().getPort() > -1 ? getRepository().getPort() : AuthScope.ANY_PORT;
237 
238             AuthScope scope = new AuthScope( host, port );
239             client.getState().setCredentials( scope, creds );
240         }
241 
242         HostConfiguration hc = new HostConfiguration();
243 
244         ProxyInfo proxyInfo = getProxyInfo( getRepository().getProtocol(), getRepository().getHost() );
245         if ( proxyInfo != null )
246         {
247             String proxyUsername = proxyInfo.getUserName();
248             String proxyPassword = proxyInfo.getPassword();
249             String proxyHost = proxyInfo.getHost();
250             int proxyPort = proxyInfo.getPort();
251             String proxyNtlmHost = proxyInfo.getNtlmHost();
252             String proxyNtlmDomain = proxyInfo.getNtlmDomain();
253             if ( proxyHost != null )
254             {
255                 hc.setProxy( proxyHost, proxyPort );
256 
257                 if ( proxyUsername != null && proxyPassword != null )
258                 {
259                     Credentials creds;
260                     if ( proxyNtlmHost != null || proxyNtlmDomain != null )
261                     {
262                         creds = new NTCredentials( proxyUsername, proxyPassword, proxyNtlmHost, proxyNtlmDomain );
263                     }
264                     else
265                     {
266                         creds = new UsernamePasswordCredentials( proxyUsername, proxyPassword );
267                     }
268 
269                     int port = proxyInfo.getPort() > -1 ? proxyInfo.getPort() : AuthScope.ANY_PORT;
270 
271                     AuthScope scope = new AuthScope( proxyHost, port );
272                     client.getState().setProxyCredentials( scope, creds );
273                 }
274             }
275         }
276 
277         hc.setHost( host );
278 
279         //start a session with the webserver
280         client.setHostConfiguration( hc );
281     }
282 
283     public void closeConnection()
284     {
285         if ( connectionManager instanceof MultiThreadedHttpConnectionManager )
286         {
287             ( (MultiThreadedHttpConnectionManager) connectionManager ).shutdown();
288         }
289     }
290 
291     public void put( File source, String resourceName )
292         throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
293     {
294         Resource resource = new Resource( resourceName );
295 
296         firePutInitiated( resource, source );
297 
298         resource.setContentLength( source.length() );
299 
300         resource.setLastModified( source.lastModified() );
301 
302         put( null, resource, source );
303     }
304 
305     public void putFromStream( final InputStream stream, String destination, long contentLength, long lastModified )
306         throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
307     {
308         Resource resource = new Resource( destination );
309 
310         firePutInitiated( resource, null );
311 
312         resource.setContentLength( contentLength );
313 
314         resource.setLastModified( lastModified );
315 
316         put( stream, resource, null );
317     }
318 
319     private void put( final InputStream stream, Resource resource, File source )
320         throws TransferFailedException, AuthorizationException, ResourceDoesNotExistException
321     {
322         StringBuilder url = new StringBuilder( getRepository().getUrl() );
323         String[] parts = StringUtils.split( resource.getName(), "/" );
324         for ( String part : parts )
325         {
326             // TODO: Fix encoding...
327             if ( !url.toString().endsWith( "/" ) )
328             {
329                 url.append( '/' );
330             }
331             url.append( URLEncoder.encode( part ) );
332         }
333         RequestEntityImplementation requestEntityImplementation =
334             new RequestEntityImplementation( stream, resource, this, source );
335         put( resource, source, requestEntityImplementation, url.toString() );
336 
337     }
338 
339     private void put( Resource resource, File source, RequestEntityImplementation requestEntityImplementation,
340                       String url )
341         throws TransferFailedException, AuthorizationException, ResourceDoesNotExistException
342     {
343 
344         // preemptive true for put
345         client.getParams().setAuthenticationPreemptive( true );
346 
347         //Parent directories need to be created before posting
348         try
349         {
350             mkdirs( PathUtils.dirname( resource.getName() ) );
351         }
352         catch ( IOException e )
353         {
354             fireTransferError( resource, e, TransferEvent.REQUEST_GET );
355         }
356 
357         PutMethod putMethod = new PutMethod( url );
358 
359         firePutStarted( resource, source );
360 
361         try
362         {
363             putMethod.setRequestEntity( requestEntityImplementation );
364 
365             int statusCode;
366             try
367             {
368                 statusCode = execute( putMethod );
369 
370             }
371             catch ( IOException e )
372             {
373                 fireTransferError( resource, e, TransferEvent.REQUEST_PUT );
374 
375                 throw new TransferFailedException( e.getMessage(), e );
376             }
377 
378             fireTransferDebug( url + " - Status code: " + statusCode );
379 
380             // Check that we didn't run out of retries.
381             switch ( statusCode )
382             {
383                 // Success Codes
384                 case HttpStatus.SC_OK: // 200
385                 case HttpStatus.SC_CREATED: // 201
386                 case HttpStatus.SC_ACCEPTED: // 202
387                 case HttpStatus.SC_NO_CONTENT:  // 204
388                     break;
389 
390                 // 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"
391                 case HttpStatus.SC_MOVED_PERMANENTLY: // 301
392                 case HttpStatus.SC_MOVED_TEMPORARILY: // 302
393                 case HttpStatus.SC_SEE_OTHER: // 303
394                     String relocatedUrl = calculateRelocatedUrl( putMethod );
395                     fireTransferDebug( "relocate to " + relocatedUrl );
396                     put( resource, source, requestEntityImplementation, relocatedUrl );
397                     return;
398 
399                 case SC_NULL:
400                 {
401                     TransferFailedException e = new TransferFailedException( "Failed to transfer file: " + url );
402                     fireTransferError( resource, e, TransferEvent.REQUEST_PUT );
403                     throw e;
404                 }
405 
406                 case HttpStatus.SC_FORBIDDEN:
407                     fireSessionConnectionRefused();
408                     throw new AuthorizationException( "Access denied to: " + url );
409 
410                 case HttpStatus.SC_NOT_FOUND:
411                     throw new ResourceDoesNotExistException( "File: " + url + " does not exist" );
412 
413                     //add more entries here
414                 default:
415                 {
416                     TransferFailedException e = new TransferFailedException(
417                         "Failed to transfer file: " + url + ". Return code is: " + statusCode );
418                     fireTransferError( resource, e, TransferEvent.REQUEST_PUT );
419                     throw e;
420                 }
421             }
422 
423             firePutCompleted( resource, source );
424         }
425         finally
426         {
427             putMethod.releaseConnection();
428         }
429     }
430 
431     protected String calculateRelocatedUrl( EntityEnclosingMethod method )
432     {
433         Header locationHeader = method.getResponseHeader( "Location" );
434         String locationField = locationHeader.getValue();
435         // is it a relative Location or a full ?
436         return locationField.startsWith( "http" ) ? locationField : getURL( getRepository() ) + '/' + locationField;
437     }
438 
439     protected void mkdirs( String dirname )
440         throws IOException
441     {
442         // do nothing as default.
443     }
444 
445     public boolean resourceExists( String resourceName )
446         throws TransferFailedException, AuthorizationException
447     {
448         StringBuilder url = new StringBuilder( getRepository().getUrl() );
449         if ( !url.toString().endsWith( "/" ) )
450         {
451             url.append( '/' );
452         }
453         url.append( resourceName );
454         HeadMethod headMethod = new HeadMethod( url.toString() );
455 
456         int statusCode;
457         try
458         {
459             statusCode = execute( headMethod );
460         }
461         catch ( IOException e )
462         {
463             throw new TransferFailedException( e.getMessage(), e );
464         }
465         try
466         {
467             switch ( statusCode )
468             {
469                 case HttpStatus.SC_OK:
470                     return true;
471 
472                 case HttpStatus.SC_NOT_MODIFIED:
473                     return true;
474 
475                 case SC_NULL:
476                     throw new TransferFailedException( "Failed to transfer file: " + url );
477 
478                 case HttpStatus.SC_FORBIDDEN:
479                     throw new AuthorizationException( "Access denied to: " + url );
480 
481                 case HttpStatus.SC_UNAUTHORIZED:
482                     throw new AuthorizationException( "Not authorized." );
483 
484                 case HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED:
485                     throw new AuthorizationException( "Not authorized by proxy." );
486 
487                 case HttpStatus.SC_NOT_FOUND:
488                     return false;
489 
490                 //add more entries here
491                 default:
492                     throw new TransferFailedException(
493                         "Failed to transfer file: " + url + ". Return code is: " + statusCode );
494             }
495         }
496         finally
497         {
498             headMethod.releaseConnection();
499         }
500     }
501 
502     protected int execute( HttpMethod httpMethod )
503         throws IOException
504     {
505         int statusCode;
506 
507         setParameters( httpMethod );
508         setHeaders( httpMethod );
509 
510         statusCode = client.executeMethod( httpMethod );
511         return statusCode;
512     }
513 
514     protected void setParameters( HttpMethod method )
515     {
516         HttpMethodConfiguration config =
517             httpConfiguration == null ? null : httpConfiguration.getMethodConfiguration( method );
518         if ( config != null )
519         {
520             HttpMethodParams params = config.asMethodParams( method.getParams() );
521             if ( params != null )
522             {
523                 method.setParams( params );
524             }
525         }
526 
527         if ( config == null || config.getConnectionTimeout() == HttpMethodConfiguration.DEFAULT_CONNECTION_TIMEOUT )
528         {
529             method.getParams().setSoTimeout( getTimeout() );
530         }
531     }
532 
533     protected void setHeaders( HttpMethod method )
534     {
535         HttpMethodConfiguration config =
536             httpConfiguration == null ? null : httpConfiguration.getMethodConfiguration( method );
537         if ( config == null || config.isUseDefaultHeaders() )
538         {
539             // TODO: merge with the other headers and have some better defaults, unify with lightweight headers
540             method.addRequestHeader( "Cache-control", "no-cache" );
541             method.addRequestHeader( "Cache-store", "no-store" );
542             method.addRequestHeader( "Pragma", "no-cache" );
543             method.addRequestHeader( "Expires", "0" );
544             method.addRequestHeader( "Accept-Encoding", "gzip" );
545         }
546 
547         if ( httpHeaders != null )
548         {
549             for ( Object header : httpHeaders.keySet() )
550             {
551                 method.addRequestHeader( (String) header, httpHeaders.getProperty( (String) header ) );
552             }
553         }
554 
555         Header[] headers = config == null ? null : config.asRequestHeaders();
556         if ( headers != null )
557         {
558             for ( Header header : headers )
559             {
560                 method.addRequestHeader( header );
561             }
562         }
563     }
564 
565     /**
566      * getUrl
567      * Implementors can override this to remove unwanted parts of the url such as role-hints
568      *
569      * @param repository
570      * @return
571      */
572     protected String getURL( Repository repository )
573     {
574         return repository.getUrl();
575     }
576 
577     protected HttpClient getClient()
578     {
579         return client;
580     }
581 
582     public void setConnectionManager( HttpConnectionManager connectionManager )
583     {
584         this.connectionManager = connectionManager;
585     }
586 
587     public Properties getHttpHeaders()
588     {
589         return httpHeaders;
590     }
591 
592     public void setHttpHeaders( Properties httpHeaders )
593     {
594         this.httpHeaders = httpHeaders;
595     }
596 
597     public HttpConfiguration getHttpConfiguration()
598     {
599         return httpConfiguration;
600     }
601 
602     public void setHttpConfiguration( HttpConfiguration httpConfiguration )
603     {
604         this.httpConfiguration = httpConfiguration;
605     }
606 
607     public void fillInputData( InputData inputData )
608         throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
609     {
610         Resource resource = inputData.getResource();
611 
612         StringBuilder url = new StringBuilder( getRepository().getUrl() );
613         if ( !url.toString().endsWith( "/" ) )
614         {
615             url.append( '/' );
616         }
617         url.append( resource.getName() );
618 
619         getMethod = new GetMethod( url.toString() );
620 
621         long timestamp = resource.getLastModified();
622         if ( timestamp > 0 )
623         {
624             SimpleDateFormat fmt = new SimpleDateFormat( "EEE, dd-MMM-yy HH:mm:ss zzz", Locale.US );
625             fmt.setTimeZone( GMT_TIME_ZONE );
626             Header hdr = new Header( "If-Modified-Since", fmt.format( new Date( timestamp ) ) );
627             fireTransferDebug( "sending ==> " + hdr + "(" + timestamp + ")" );
628             getMethod.addRequestHeader( hdr );
629         }
630 
631         int statusCode;
632         try
633         {
634             statusCode = execute( getMethod );
635         }
636         catch ( IOException e )
637         {
638             fireTransferError( resource, e, TransferEvent.REQUEST_GET );
639 
640             throw new TransferFailedException( e.getMessage(), e );
641         }
642 
643         fireTransferDebug( url + " - Status code: " + statusCode );
644 
645         // TODO [BP]: according to httpclient docs, really should swallow the output on error. verify if that is
646         // required
647         switch ( statusCode )
648         {
649             case HttpStatus.SC_OK:
650                 break;
651 
652             case HttpStatus.SC_NOT_MODIFIED:
653                 // return, leaving last modified set to original value so getIfNewer should return unmodified
654                 return;
655 
656             case SC_NULL:
657             {
658                 TransferFailedException e = new TransferFailedException( "Failed to transfer file: " + url );
659                 fireTransferError( resource, e, TransferEvent.REQUEST_GET );
660                 throw e;
661             }
662 
663             case HttpStatus.SC_FORBIDDEN:
664                 fireSessionConnectionRefused();
665                 throw new AuthorizationException( "Access denied to: " + url );
666 
667             case HttpStatus.SC_UNAUTHORIZED:
668                 fireSessionConnectionRefused();
669                 throw new AuthorizationException( "Not authorized." );
670 
671             case HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED:
672                 fireSessionConnectionRefused();
673                 throw new AuthorizationException( "Not authorized by proxy." );
674 
675             case HttpStatus.SC_NOT_FOUND:
676                 throw new ResourceDoesNotExistException( "File: " + url + " does not exist" );
677 
678                 // add more entries here
679             default:
680             {
681                 cleanupGetTransfer( resource );
682                 TransferFailedException e = new TransferFailedException(
683                     "Failed to transfer file: " + url + ". Return code is: " + statusCode );
684                 fireTransferError( resource, e, TransferEvent.REQUEST_GET );
685                 throw e;
686             }
687         }
688 
689         InputStream is = null;
690 
691         Header contentLengthHeader = getMethod.getResponseHeader( "Content-Length" );
692 
693         if ( contentLengthHeader != null )
694         {
695             try
696             {
697                 long contentLength = Integer.valueOf( contentLengthHeader.getValue() ).intValue();
698 
699                 resource.setContentLength( contentLength );
700             }
701             catch ( NumberFormatException e )
702             {
703                 fireTransferDebug(
704                     "error parsing content length header '" + contentLengthHeader.getValue() + "' " + e );
705             }
706         }
707 
708         Header lastModifiedHeader = getMethod.getResponseHeader( "Last-Modified" );
709 
710         long lastModified = 0;
711 
712         if ( lastModifiedHeader != null )
713         {
714             try
715             {
716                 lastModified = DateUtil.parseDate( lastModifiedHeader.getValue() ).getTime();
717 
718                 resource.setLastModified( lastModified );
719             }
720             catch ( DateParseException e )
721             {
722                 fireTransferDebug( "Unable to parse last modified header" );
723             }
724 
725             fireTransferDebug( "last-modified = " + lastModifiedHeader.getValue() + " (" + lastModified + ")" );
726         }
727 
728         Header contentEncoding = getMethod.getResponseHeader( "Content-Encoding" );
729         boolean isGZipped = contentEncoding != null && "gzip".equalsIgnoreCase( contentEncoding.getValue() );
730 
731         try
732         {
733             is = getMethod.getResponseBodyAsStream();
734             if ( isGZipped )
735             {
736                 is = new GZIPInputStream( is );
737             }
738         }
739         catch ( IOException e )
740         {
741             fireTransferError( resource, e, TransferEvent.REQUEST_GET );
742 
743             String msg =
744                 "Error occurred while retrieving from remote repository:" + getRepository() + ": " + e.getMessage();
745 
746             throw new TransferFailedException( msg, e );
747         }
748 
749         inputData.setInputStream( is );
750     }
751 
752     protected void cleanupGetTransfer( Resource resource )
753     {
754         if ( getMethod != null )
755         {
756             getMethod.releaseConnection();
757         }
758     }
759 
760     @Override
761     public void putFromStream( InputStream stream, String destination )
762         throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
763     {
764         putFromStream( stream, destination, -1, -1 );
765     }
766 
767     @Override
768     protected void putFromStream( InputStream stream, Resource resource )
769         throws TransferFailedException, AuthorizationException, ResourceDoesNotExistException
770     {
771         putFromStream( stream, resource.getName(), -1, -1 );
772     }
773 
774     @Override
775     public void fillOutputData( OutputData outputData )
776         throws TransferFailedException
777     {
778         // no needed in this implementation but throw an Exception if used
779         throw new IllegalStateException( "this wagon http client must not use fillOutputData" );
780     }
781 }