1 package org.apache.maven.wagon.providers.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.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
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 }