1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package fr.paris.lutece.plugins.webappcontainer.util;
35
36 import java.io.IOException;
37 import java.net.HttpURLConnection;
38 import java.util.Iterator;
39 import java.util.Map;
40 import java.util.Set;
41
42 import org.apache.commons.fileupload.FileItem;
43 import org.apache.commons.httpclient.Cookie;
44 import org.apache.commons.httpclient.Credentials;
45 import org.apache.commons.httpclient.Header;
46 import org.apache.commons.httpclient.HttpClient;
47 import org.apache.commons.httpclient.HttpException;
48 import org.apache.commons.httpclient.HttpMethodBase;
49 import org.apache.commons.httpclient.HttpState;
50 import org.apache.commons.httpclient.NTCredentials;
51 import org.apache.commons.httpclient.UsernamePasswordCredentials;
52 import org.apache.commons.httpclient.auth.AuthScope;
53 import org.apache.commons.httpclient.cookie.CookiePolicy;
54 import org.apache.commons.httpclient.methods.GetMethod;
55 import org.apache.commons.httpclient.methods.PostMethod;
56 import org.apache.commons.httpclient.methods.multipart.ByteArrayPartSource;
57 import org.apache.commons.httpclient.methods.multipart.FilePart;
58 import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
59 import org.apache.commons.httpclient.methods.multipart.Part;
60 import org.apache.commons.httpclient.methods.multipart.PartSource;
61 import org.apache.commons.httpclient.methods.multipart.StringPart;
62 import org.apache.commons.httpclient.params.HttpMethodParams;
63 import org.apache.commons.lang.StringUtils;
64
65 import fr.paris.lutece.plugins.webappcontainer.business.Site;
66 import fr.paris.lutece.plugins.webappcontainer.business.WebappResponse;
67 import fr.paris.lutece.portal.service.util.AppLogService;
68 import fr.paris.lutece.portal.service.util.AppPropertiesService;
69
70
71
72
73 public class HttpAccess
74 {
75
76 private static final String PROPERTY_PROXY_HOST = "webappcontainer.httpAccess.proxyHost";
77
78 private static final String PROPERTY_PROXY_PORT = "webappcontainer.httpAccess.proxyPort";
79
80 private static final String PROPERTY_PROXY_USERNAME = "webappcontainer.httpAccess.proxyUserName";
81
82 private static final String PROPERTY_PROXY_PASSWORD = "webappcontainer.httpAccess.proxyPassword";
83
84 private static final String PROPERTY_HOST_NAME = "webappcontainer.httpAccess.hostName";
85
86 private static final String PROPERTY_DOMAIN_NAME = "webappcontainer.httpAccess.domainName";
87
88 private static final String PROPERTY_REALM = "webappcontainer.httpAccess.realm";
89
90 private static final String PROPERTY_TIMEOUT_SOCKET = "webappcontainer.httpAccess.timeoutSocket";
91
92 private static final String PROPERTY_TIMEOUT_CONNECTION = "webappcontainer.httpAccess.timeoutConnection";
93
94 private static final String PROPERTY_PROTOCOL_CONTENT_CHARSET = "webappcontainer.site.default.encoding";
95
96 private static final String HTTP_SOCKET_TIMEOUT = "http.socket.timeout";
97
98 private static final String HTTP_CONNECTION_TIMEOUT = "http.connection.timeout";
99
100 private static final String HTTP_PROTOCOL_CONTENT_CHARSET = "http.protocol.content-charset";
101
102 private static final String RESPONSE_HEADER_LOCATION = "location";
103
104 private static final String REGEX_INT = "^[\\d]+$";
105
106 private static final int DEFAULT_TIMEOUT_SOCKET = 10000;
107
108 private static final int DEFAULT_TIMEOUT_CONNECTION = 10000;
109
110 private static final boolean FOLLOW_REDIRECT = true;
111
112 private Map<String, String[]> _parametersMap;
113
114 private Map<String, FileItem> _filesMap;
115
116 private HttpClient _client;
117
118 private Cookie[] _cookies = new Cookie[]
119 {};
120
121 private Site _site = new Site();
122
123
124
125
126
127
128
129 public void initializeState( Cookie[] cookies, Site site )
130 {
131
132 if ( cookies != null )
133 {
134 _cookies = cookies.clone();
135 }
136
137 _site = site;
138 }
139
140
141
142
143
144
145
146
147 public WebappResponse doGet( String strUrl ) throws HttpAccessException
148 {
149 WebappResponse webappResponse = null;
150
151 try
152 {
153 AppLogService.debug( "HttpAccess.goGet( strUrl = " + strUrl + ")" );
154
155 HttpMethodBase method = new GetMethod( strUrl );
156
157 method.setFollowRedirects( FOLLOW_REDIRECT );
158
159 webappResponse = doRequest( method );
160 }
161 catch ( Exception e )
162 {
163 AppLogService.error( e.getMessage(), e );
164 throw new HttpAccessException( e.getMessage(), e );
165 }
166
167 return webappResponse;
168 }
169
170
171
172
173
174
175
176
177
178
179 public WebappResponse doPost( String strUrl, Map<String, String[]> parametersMap, Map<String, FileItem> fileMap ) throws HttpAccessException
180 {
181 WebappResponse webappResponse = null;
182 _parametersMap = parametersMap;
183 _filesMap = fileMap;
184
185 try
186 {
187 AppLogService.debug( "HttpAccess.goPost( strUrl = " + strUrl + ")" );
188
189 PostMethod method = new PostMethod( strUrl );
190
191
192 if ( fileMap != null )
193 {
194 setMultipartRequest( method, parametersMap, fileMap );
195 }
196 else
197 {
198 Set<String> setParametersString = parametersMap.keySet();
199 Iterator<String> iteratorParametersString = setParametersString.iterator();
200
201 while (iteratorParametersString.hasNext())
202 {
203 String strKey = ( String ) iteratorParametersString.next();
204 for ( String strValue : parametersMap.get( strKey ) )
205 {
206 method.addParameter( strKey, strValue );
207 }
208
209 }
210 }
211
212 webappResponse = doRequest( method );
213 }
214 catch ( Exception e )
215 {
216 AppLogService.error( e.getMessage(), e );
217 throw new HttpAccessException( e.getMessage(), e );
218 }
219
220 return webappResponse;
221 }
222
223
224
225
226
227
228
229 private void setMultipartRequest( PostMethod method, Map<String, String[]> parametersMap, Map<String, FileItem> fileMap )
230 {
231 Set<String> setParametersString = parametersMap.keySet();
232 Iterator<String> iteratorParametersString = setParametersString.iterator();
233 Set<String> setParametersFile = fileMap.keySet();
234 Part[] parts = new Part[setParametersString.size() + setParametersFile.size()];
235 int i = 0;
236
237
238 while (iteratorParametersString.hasNext())
239 {
240 String strKey = ( String ) iteratorParametersString.next();
241 parts[i++] = new StringPart( strKey, ( String ) parametersMap.get( strKey )[0] );
242 }
243
244 method.getParams().setBooleanParameter( HttpMethodParams.USE_EXPECT_CONTINUE, true );
245
246 Iterator<String> iteratorParemetersFile = setParametersFile.iterator();
247
248
249 while (iteratorParemetersFile.hasNext())
250 {
251 String strKey = ( String ) iteratorParemetersFile.next();
252 FileItem fileItem = fileMap.get( strKey );
253 PartSource partSource = new ByteArrayPartSource( fileItem.getName(), fileItem.get() );
254 parts[i++] = new FilePart( strKey, partSource, fileItem.getContentType(), method.getRequestCharSet() );
255 }
256
257 method.setRequestEntity( new MultipartRequestEntity( parts, method.getParams() ) );
258 }
259
260
261
262
263
264
265
266
267 private WebappResponse doRequest( HttpMethodBase method ) throws HttpAccessException
268 {
269 WebappResponse webappResponse = null;
270 String strUrl = null;
271
272 try
273 {
274 strUrl = method.getURI().toString();
275
276
277 HttpState state = new HttpState();
278
279 state.addCookies( _cookies );
280
281 HttpClient client = getHttpClient( method );
282
283 client.setState( state );
284
285 int nResponse = client.executeMethod( method );
286
287
288 if ( AppLogService.isDebugEnabled() )
289 {
290 showRequestDebugLogs( state );
291
292 AppLogService.debug( "[doRequest] Get content from " + strUrl );
293 AppLogService.debug( "[doRequest] HTTP code : " + nResponse );
294 }
295
296
297 if ( ( nResponse >= HttpURLConnection.HTTP_MULT_CHOICE ) && ( nResponse < HttpURLConnection.HTTP_BAD_REQUEST ) )
298 {
299 String strNewLocation = method.getResponseHeader( RESPONSE_HEADER_LOCATION ).getValue();
300 AppLogService.debug( "[doRequest] Redirection -> " + strNewLocation );
301
302
303 return doPost( strNewLocation, _parametersMap, _filesMap );
304 }
305
306
307 if ( nResponse != HttpURLConnection.HTTP_OK )
308 {
309 String strError = "HttpAccess - Error getting URL : " + strUrl + " - return code : " + nResponse;
310 throw new HttpAccessException( strError, null );
311 }
312
313
314 int nResponseBodyLength = method.getResponseBody().length;
315
316 if ( nResponseBodyLength <= 0 )
317 {
318 String strError = "HttpAccess - Error getting URL : No content received (" + nResponseBodyLength + " byte)";
319 throw new HttpAccessException( strError, null );
320 }
321
322
323 webappResponse = new WebappResponse();
324
325
326 webappResponse.setContent( method.getResponseBody() );
327
328
329 webappResponse.setContentCharset( _site.getEncoding() );
330
331
332 if ( client.getState().getCookies().length > 0 )
333 {
334 webappResponse.setCookies( client.getState().getCookies() );
335 }
336
337
338 if ( method.getURI() != null )
339 {
340 webappResponse.setLocation( method.getURI().getURI() );
341 }
342 else
343 {
344 webappResponse.setLocation( strUrl );
345 }
346
347
348 if ( AppLogService.isDebugEnabled() )
349 {
350 showResponseDebugLogs( client, method );
351 }
352 }
353 catch ( HttpException e )
354 {
355 String strError = "HttpAccess - Error connecting to '" + strUrl + "' : ";
356 AppLogService.error( strError + e.getMessage(), e );
357 throw new HttpAccessException( strError + e.getMessage(), e );
358 }
359 catch ( IOException e )
360 {
361 String strError = "HttpAccess - Error downloading '" + strUrl + "' : ";
362 AppLogService.error( strError + e.getMessage(), e );
363 throw new HttpAccessException( strError + e.getMessage(), e );
364 }
365 finally
366 {
367
368 method.releaseConnection();
369 }
370
371 return webappResponse;
372 }
373
374
375
376
377
378
379
380
381 private HttpClient getHttpClient( HttpMethodBase method ) throws HttpAccessException
382 {
383 String strProxyHost = AppPropertiesService.getProperty( PROPERTY_PROXY_HOST );
384 String strProxyPort = AppPropertiesService.getProperty( PROPERTY_PROXY_PORT );
385 String strProxyUserName = AppPropertiesService.getProperty( PROPERTY_PROXY_USERNAME );
386 String strProxyPassword = AppPropertiesService.getProperty( PROPERTY_PROXY_PASSWORD );
387 String strHostName = AppPropertiesService.getProperty( PROPERTY_HOST_NAME );
388 String strDomainName = AppPropertiesService.getProperty( PROPERTY_DOMAIN_NAME );
389 String strRealm = AppPropertiesService.getProperty( PROPERTY_REALM );
390 String strContentCharset = _site.getEncoding();
391 int nTimeoutSocket = getPropertyInt( PROPERTY_TIMEOUT_SOCKET, DEFAULT_TIMEOUT_SOCKET );
392 int nTimeoutConnection = getPropertyInt( PROPERTY_TIMEOUT_CONNECTION, DEFAULT_TIMEOUT_CONNECTION );
393
394 if ( _client != null )
395 {
396 return _client;
397 }
398
399
400 HttpClient client = new HttpClient();
401
402
403 client.getParams().setParameter( HTTP_SOCKET_TIMEOUT, nTimeoutSocket );
404 client.getParams().setParameter( HTTP_CONNECTION_TIMEOUT, nTimeoutConnection );
405
406
407 if ( StringUtils.isBlank( strContentCharset ) )
408 {
409 strContentCharset = AppPropertiesService.getProperty( PROPERTY_PROTOCOL_CONTENT_CHARSET );
410 }
411 client.getParams().setParameter( HTTP_PROTOCOL_CONTENT_CHARSET, strContentCharset );
412
413
414 if ( ( strProxyHost != null ) && ( !strProxyHost.equals( "" ) ) && ( strProxyPort != null ) && ( !strProxyPort.equals( "" ) ) && _site.isUseProxy() )
415 {
416 client.getHostConfiguration().setProxy( strProxyHost, Integer.parseInt( strProxyPort ) );
417 }
418
419 Credentials cred = null;
420
421
422
423 if ( ( strHostName != null ) && ( strDomainName != null ) )
424 {
425 cred = new NTCredentials( strProxyUserName, strProxyPassword, strHostName, strDomainName );
426 }
427 else if ( ( strProxyUserName != null ) && ( strProxyPassword != null ) )
428 {
429 cred = new UsernamePasswordCredentials( strProxyUserName, strProxyPassword );
430 }
431
432 if ( cred != null )
433 {
434 AuthScope authScope = new AuthScope( null, -1, strRealm, null );
435 client.getState().setProxyCredentials( authScope, cred );
436
437 client.getParams().setAuthenticationPreemptive( true );
438
439 method.setDoAuthentication( true );
440 }
441
442 client.getParams().setCookiePolicy( CookiePolicy.BROWSER_COMPATIBILITY );
443 _client = client;
444
445 return client;
446 }
447
448
449
450
451
452
453 private void showRequestDebugLogs( HttpState state )
454 {
455
456 for ( Cookie c : state.getCookies() )
457 {
458 AppLogService.debug( "[doRequest] setCookie = " + c.getName() + "=" + c.getValue() + " - domain : " + c.getDomain() );
459 }
460 }
461
462
463
464
465
466
467
468
469 private void showResponseDebugLogs( HttpClient client, HttpMethodBase method ) throws IOException
470 {
471
472 for ( Cookie cookie : client.getState().getCookies() )
473 {
474 AppLogService.debug( "[doRequest][response] getCookie = " + cookie.getName() + " " + cookie.getValue() + " - domain : " + cookie.getDomain() );
475 }
476
477 AppLogService.debug( "[doRequest] Received : " + method.getResponseBody().length + " bytes" );
478
479
480 for ( Header header : method.getResponseHeaders() )
481 {
482 AppLogService.debug( "Method Header" + header.getName() + " -> " + header.getValue() );
483 }
484 }
485
486
487
488
489
490
491
492
493
494 private int getPropertyInt( String strPropertyName, int nDefault ) throws HttpAccessException
495 {
496 String strPropertyValue = AppPropertiesService.getProperty( strPropertyName );
497 int nPropertyValue = nDefault;
498
499 try
500 {
501 if ( ( strPropertyValue != null ) && strPropertyValue.matches( REGEX_INT ) )
502 {
503 nPropertyValue = Integer.parseInt( strPropertyValue );
504 }
505 }
506 catch ( NumberFormatException e )
507 {
508 String strError = "HttpAccess - Error retrieving property '" + strPropertyName + "' : ";
509 AppLogService.error( strError + e.getMessage(), e );
510 throw new HttpAccessException( strError + e.getMessage(), e );
511 }
512
513 return nPropertyValue;
514 }
515 }