1 package org.apache.maven.continuum.project.builder;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.commons.io.IOUtils;
23 import org.apache.http.HttpException;
24 import org.apache.http.HttpHost;
25 import org.apache.http.HttpResponse;
26 import org.apache.http.HttpVersion;
27 import org.apache.http.auth.AuthScope;
28 import org.apache.http.auth.UsernamePasswordCredentials;
29 import org.apache.http.client.AuthCache;
30 import org.apache.http.client.methods.HttpGet;
31 import org.apache.http.client.protocol.ClientContext;
32 import org.apache.http.conn.ClientConnectionManager;
33 import org.apache.http.conn.params.ConnManagerPNames;
34 import org.apache.http.conn.params.ConnPerRouteBean;
35 import org.apache.http.conn.scheme.PlainSocketFactory;
36 import org.apache.http.conn.scheme.Scheme;
37 import org.apache.http.conn.scheme.SchemeRegistry;
38 import org.apache.http.impl.auth.BasicScheme;
39 import org.apache.http.impl.client.BasicAuthCache;
40 import org.apache.http.impl.client.DefaultHttpClient;
41 import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
42 import org.apache.http.params.BasicHttpParams;
43 import org.apache.http.params.HttpParams;
44 import org.apache.http.params.HttpProtocolParams;
45 import org.apache.http.protocol.BasicHttpContext;
46 import org.apache.http.util.EntityUtils;
47 import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
48 import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
49 import org.codehaus.plexus.util.FileUtils;
50 import org.codehaus.plexus.util.IOUtil;
51 import org.codehaus.plexus.util.StringUtils;
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
54
55 import java.io.File;
56 import java.io.FileNotFoundException;
57 import java.io.FileWriter;
58 import java.io.IOException;
59 import java.io.InputStream;
60 import java.net.MalformedURLException;
61 import java.net.URI;
62 import java.net.URISyntaxException;
63 import java.net.URL;
64 import java.net.UnknownHostException;
65
66
67
68
69
70
71 public abstract class AbstractContinuumProjectBuilder
72 implements ContinuumProjectBuilder, Initializable
73 {
74 private static final String TMP_DIR = System.getProperty( "java.io.tmpdir" );
75
76 protected final Logger log = LoggerFactory.getLogger( getClass() );
77
78 private HttpParams params;
79
80 private ClientConnectionManager cm;
81
82 public void initialize()
83 throws InitializationException
84 {
85 SchemeRegistry schemeRegistry = new SchemeRegistry();
86
87 schemeRegistry.register( new Scheme( "http", PlainSocketFactory.getSocketFactory(), 80 ) );
88
89 schemeRegistry.register( new Scheme( "https", new EasySSLSocketFactory(), 443 ) );
90
91 params = new BasicHttpParams();
92
93 params.setParameter( ConnManagerPNames.MAX_TOTAL_CONNECTIONS, 30 );
94 params.setParameter( ConnManagerPNames.MAX_CONNECTIONS_PER_ROUTE, new ConnPerRouteBean( 30 ) );
95 HttpProtocolParams.setVersion( params, HttpVersion.HTTP_1_1 );
96
97 cm = new ThreadSafeClientConnManager( params, schemeRegistry );
98 }
99
100 protected File createMetadataFile( URL metadata, String username, String password,
101 ContinuumProjectBuildingResult result )
102 throws IOException, URISyntaxException, HttpException
103 {
104 DefaultHttpClient httpClient = new DefaultHttpClient( cm, params );
105
106 String url = metadata.toExternalForm();
107 if ( metadata.getProtocol().startsWith( "http" ) )
108 {
109 url = hidePasswordInUrl( url );
110 }
111 log.info( "Downloading " + url );
112
113 InputStream is;
114
115 if ( metadata.getProtocol().startsWith( "http" ) )
116 {
117 URI uri = metadata.toURI();
118 HttpGet httpGet = new HttpGet( uri );
119
120 httpClient.getCredentialsProvider().clear();
121
122
123 if ( username != null && password != null )
124 {
125 httpClient.getCredentialsProvider().setCredentials( new AuthScope( uri.getHost(), uri.getPort() ),
126 new UsernamePasswordCredentials( username,
127 password ) );
128 }
129
130
131 HttpResponse httpResponse = httpClient.execute( httpGet );
132
133
134 if ( httpResponse.getStatusLine().getStatusCode() != 200 )
135 {
136 log.debug( "Initial attempt did not return a 200 status code. Trying pre-emptive authentication.." );
137
138 HttpHost targetHost = new HttpHost( uri.getHost(), uri.getPort(), uri.getScheme() );
139
140
141 AuthCache authCache = new BasicAuthCache();
142
143 BasicScheme basicAuth = new BasicScheme();
144 authCache.put( targetHost, basicAuth );
145
146
147 BasicHttpContext localcontext = new BasicHttpContext();
148 localcontext.setAttribute( ClientContext.AUTH_CACHE, authCache );
149
150 httpResponse = httpClient.execute( targetHost, httpGet, localcontext );
151 }
152
153 int res = httpResponse.getStatusLine().getStatusCode();
154
155 switch ( res )
156 {
157 case 200:
158 break;
159 case 401:
160 log.error( "Error adding project: Unauthorized " + url );
161 result.addError( ContinuumProjectBuildingResult.ERROR_UNAUTHORIZED );
162 return null;
163 default:
164 log.warn( "skip non handled http return code " + res );
165 }
166 is = IOUtils.toInputStream( EntityUtils.toString( httpResponse.getEntity(), EntityUtils.getContentCharSet(
167 httpResponse.getEntity() ) ) );
168 }
169 else
170 {
171 is = metadata.openStream();
172 }
173
174 String path = metadata.getPath();
175
176 String baseDirectory;
177
178 String fileName;
179
180 int lastIndex = path.lastIndexOf( "/" );
181
182 if ( lastIndex >= 0 )
183 {
184 baseDirectory = path.substring( 0, lastIndex );
185
186
187 int colonIndex = baseDirectory.indexOf( ":" );
188
189 if ( colonIndex >= 0 )
190 {
191 baseDirectory = baseDirectory.substring( colonIndex + 1 );
192 }
193
194 fileName = path.substring( lastIndex + 1 );
195 }
196 else
197 {
198 baseDirectory = "";
199
200 fileName = path;
201 }
202
203
204 baseDirectory = StringUtils.replace( baseDirectory, "*", "" );
205
206 File continuumTmpDir = new File( TMP_DIR, "continuum" );
207
208
209 File uploadDirectory = new File( continuumTmpDir, baseDirectory );
210
211 uploadDirectory.deleteOnExit();
212
213
214 uploadDirectory = uploadDirectory.getCanonicalFile();
215
216 uploadDirectory.mkdirs();
217
218 FileUtils.forceDeleteOnExit( continuumTmpDir );
219
220 File file = new File( uploadDirectory, fileName );
221
222 file.deleteOnExit();
223
224 FileWriter writer = new FileWriter( file );
225
226 IOUtil.copy( is, writer );
227
228 is.close();
229
230 writer.close();
231
232 return file;
233 }
234
235 private String hidePasswordInUrl( String url )
236 {
237 int indexAt = url.indexOf( "@" );
238
239 if ( indexAt < 0 )
240 {
241 return url;
242 }
243
244 String s = url.substring( 0, indexAt );
245
246 int pos = s.lastIndexOf( ":" );
247
248 return s.substring( 0, pos + 1 ) + "*****" + url.substring( indexAt );
249 }
250
251
252
253
254
255
256
257
258
259
260 protected File createMetadataFile( ContinuumProjectBuildingResult result, URL metadata, String username,
261 String password )
262 {
263 String url = metadata.toExternalForm();
264
265 if ( metadata.getProtocol().startsWith( "http" ) )
266 {
267 url = hidePasswordInUrl( url );
268 }
269
270 try
271 {
272 return createMetadataFile( metadata, username, password, result );
273 }
274 catch ( FileNotFoundException e )
275 {
276 log.info( "URL not found: " + url, e );
277 result.addError( ContinuumProjectBuildingResult.ERROR_POM_NOT_FOUND );
278 }
279 catch ( MalformedURLException e )
280 {
281 log.info( "Malformed URL: " + url, e );
282 result.addError( ContinuumProjectBuildingResult.ERROR_MALFORMED_URL );
283 }
284 catch ( URISyntaxException e )
285 {
286 log.info( "Malformed URL: " + url, e );
287 result.addError( ContinuumProjectBuildingResult.ERROR_MALFORMED_URL );
288 }
289 catch ( UnknownHostException e )
290 {
291 log.info( "Unknown host: " + url, e );
292 result.addError( ContinuumProjectBuildingResult.ERROR_UNKNOWN_HOST );
293 }
294 catch ( IOException e )
295 {
296 log.warn( "Could not download the URL: " + url, e );
297 result.addError( ContinuumProjectBuildingResult.ERROR_UNKNOWN );
298 }
299 catch ( HttpException e )
300 {
301 log.warn( "Could not download the URL: " + url, e );
302 result.addError( ContinuumProjectBuildingResult.ERROR_UNKNOWN );
303 }
304 return null;
305 }
306
307 }