View Javadoc
1   package org.apache.maven.wagon.providers.http;
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.maven.wagon.Wagon;
23  import org.apache.maven.wagon.observers.Debug;
24  import org.apache.maven.wagon.repository.Repository;
25  import org.codehaus.plexus.PlexusTestCase;
26  import org.codehaus.plexus.util.IOUtil;
27  import org.eclipse.jetty.server.HttpConfiguration;
28  import org.eclipse.jetty.server.HttpConnectionFactory;
29  import org.eclipse.jetty.server.Server;
30  import org.eclipse.jetty.server.ServerConnector;
31  import org.eclipse.jetty.servlet.ServletContextHandler;
32  import org.eclipse.jetty.servlet.ServletHolder;
33  import org.slf4j.Logger;
34  import org.slf4j.LoggerFactory;
35  
36  import javax.servlet.ServletException;
37  import javax.servlet.http.HttpServlet;
38  import javax.servlet.http.HttpServletRequest;
39  import javax.servlet.http.HttpServletResponse;
40  import java.io.File;
41  import java.io.FileInputStream;
42  import java.io.IOException;
43  import java.nio.ByteBuffer;
44  import java.nio.channels.SeekableByteChannel;
45  import java.nio.file.Files;
46  import java.nio.file.OpenOption;
47  import java.nio.file.StandardOpenOption;
48  
49  /**
50   * @author Olivier Lamy
51   */
52  public class HugeFileDownloadTest
53      extends PlexusTestCase
54  {
55  
56      private static final Logger LOGGER = LoggerFactory.getLogger( HugeFileDownloadTest.class );
57  
58      private static long HUGE_FILE_SIZE =
59          Integer.valueOf( Integer.MAX_VALUE ).longValue() + Integer.valueOf( Integer.MAX_VALUE ).longValue();
60  
61      private Server server;
62      private ServerConnector connector;
63  
64      public void testDownloadHugeFileWithContentLength()
65          throws Exception
66      {
67          final File hugeFile = new File( getBasedir(), "target/hugefile.txt" );
68          if ( !hugeFile.exists() || hugeFile.length() < HUGE_FILE_SIZE )
69          {
70              makeHugeFile( hugeFile );
71          }
72  
73          server = new Server(  );
74          connector = new ServerConnector( server, new HttpConnectionFactory( new HttpConfiguration() ) );
75          server.addConnector( connector );
76  
77          ServletContextHandler root = new ServletContextHandler( ServletContextHandler.SESSIONS );
78          root.setResourceBase( new File( getBasedir(), "target" ).getAbsolutePath() );
79          ServletHolder servletHolder = new ServletHolder( new HttpServlet()
80          {
81              @Override
82              protected void doGet( HttpServletRequest req, HttpServletResponse resp )
83                  throws ServletException, IOException
84              {
85                  FileInputStream fis = new FileInputStream( hugeFile );
86  
87                  resp.addHeader( "Content-Length", String.valueOf( hugeFile.length() ) );
88                  IOUtil.copy( fis, resp.getOutputStream() );
89                  fis.close();
90              }
91          } );
92          root.addServlet( servletHolder, "/*" );
93          server.setHandler( root );
94  
95          server.start();
96  
97          File dest = null;
98          try
99          {
100             Wagon wagon = getWagon();
101             wagon.connect( new Repository( "id", "http://localhost:" + connector.getLocalPort() ) );
102 
103             dest = File.createTempFile( "huge", "txt" );
104 
105             LOGGER.info( "Fetching 'hugefile.txt' with content length" );
106             wagon.get( "hugefile.txt", dest );
107 
108             assertTrue( dest.length() >= HUGE_FILE_SIZE );
109             LOGGER.info( "The file was successfully fetched" );
110 
111             wagon.disconnect();
112         }
113         finally
114         {
115             server.stop();
116             dest.delete();
117             hugeFile.delete();
118         }
119 
120     }
121 
122     public void testDownloadHugeFileWithChunked()
123         throws Exception
124     {
125         final File hugeFile = new File( getBasedir(), "target/hugefile.txt" );
126         if ( !hugeFile.exists() || hugeFile.length() < HUGE_FILE_SIZE )
127         {
128             makeHugeFile( hugeFile );
129         }
130 
131         server = new Server(  );
132         connector = new ServerConnector( server, new HttpConnectionFactory( new HttpConfiguration() ) );
133         server.addConnector( connector );
134 
135         ServletContextHandler root = new ServletContextHandler( ServletContextHandler.SESSIONS );
136         root.setResourceBase( new File( getBasedir(), "target" ).getAbsolutePath() );
137         ServletHolder servletHolder = new ServletHolder( new HttpServlet()
138         {
139             @Override
140             protected void doGet( HttpServletRequest req, HttpServletResponse resp )
141                 throws ServletException, IOException
142             {
143                 FileInputStream fis = new FileInputStream( hugeFile );
144 
145                 IOUtil.copy( fis, resp.getOutputStream() );
146                 fis.close();
147             }
148         } );
149         root.addServlet( servletHolder, "/*" );
150         server.setHandler( root );
151 
152         server.start();
153 
154         File dest = null;
155         try
156         {
157             Wagon wagon = getWagon();
158             wagon.connect( new Repository( "id", "http://localhost:" + connector.getLocalPort() ) );
159 
160             dest = File.createTempFile( "huge", "txt" );
161 
162             LOGGER.info( "Fetching 'hugefile.txt' in chunks" );
163             wagon.get( "hugefile.txt", dest );
164 
165             assertTrue( dest.length() >= HUGE_FILE_SIZE );
166             LOGGER.info( "The file was successfully fetched" );
167 
168             wagon.disconnect();
169         }
170         finally
171         {
172             server.stop();
173             dest.delete();
174             hugeFile.delete();
175         }
176 
177     }
178 
179     protected Wagon getWagon()
180         throws Exception
181     {
182         Wagon wagon = (Wagon) lookup( Wagon.ROLE, "http" );
183 
184         Debug debug = new Debug();
185 
186         wagon.addSessionListener( debug );
187 
188         return wagon;
189     }
190 
191     private void makeHugeFile( File hugeFile )
192         throws Exception
193     {
194         LOGGER.info( "Creating test file" );
195         final ByteBuffer buf = ByteBuffer.allocate( 4 ).putInt( 2 );
196         buf.rewind();
197 
198         final OpenOption[] options = { StandardOpenOption.WRITE, StandardOpenOption.CREATE_NEW,
199                                        StandardOpenOption.SPARSE };
200 
201         try ( final SeekableByteChannel channel = Files.newByteChannel( hugeFile.toPath(), options ) )
202         {
203             channel.position( HUGE_FILE_SIZE );
204             channel.write( buf );
205         }
206         LOGGER.info( "Test file created" );
207     }
208 
209 }