001 //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_testing/src/org/deegree/framework/util/HttpUtils.java $
002 /*---------------- FILE HEADER ------------------------------------------
003 This file is part of deegree.
004 Copyright (C) 2001-2008 by:
005 Department of Geography, University of Bonn
006 http://www.giub.uni-bonn.de/deegree/
007 lat/lon GmbH
008 http://www.lat-lon.de
009
010 This library is free software; you can redistribute it and/or
011 modify it under the terms of the GNU Lesser General Public
012 License as published by the Free Software Foundation; either
013 version 2.1 of the License, or (at your option) any later version.
014 This library is distributed in the hope that it will be useful,
015 but WITHOUT ANY WARRANTY; without even the implied warranty of
016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
017 Lesser General Public License for more details.
018 You should have received a copy of the GNU Lesser General Public
019 License along with this library; if not, write to the Free Software
020 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
021 Contact:
022
023 Andreas Poth
024 lat/lon GmbH
025 Aennchenstr. 19
026 53177 Bonn
027 Germany
028 E-Mail: poth@lat-lon.de
029
030 Prof. Dr. Klaus Greve
031 Department of Geography
032 University of Bonn
033 Meckenheimer Allee 166
034 53115 Bonn
035 Germany
036 E-Mail: greve@giub.uni-bonn.de
037 ---------------------------------------------------------------------------*/
038
039 package org.deegree.framework.util;
040
041 import java.io.ByteArrayOutputStream;
042 import java.io.IOException;
043 import java.io.InputStream;
044 import java.net.HttpURLConnection;
045 import java.net.InetAddress;
046 import java.net.MalformedURLException;
047 import java.net.URISyntaxException;
048 import java.net.URL;
049 import java.util.Iterator;
050 import java.util.Map;
051 import java.util.Properties;
052
053 import javax.xml.transform.OutputKeys;
054
055 import org.apache.commons.codec.binary.Base64;
056 import org.apache.commons.httpclient.Header;
057 import org.apache.commons.httpclient.HttpClient;
058 import org.apache.commons.httpclient.HttpException;
059 import org.apache.commons.httpclient.HttpMethod;
060 import org.apache.commons.httpclient.methods.ByteArrayRequestEntity;
061 import org.apache.commons.httpclient.methods.GetMethod;
062 import org.apache.commons.httpclient.methods.HeadMethod;
063 import org.apache.commons.httpclient.methods.InputStreamRequestEntity;
064 import org.apache.commons.httpclient.methods.PostMethod;
065 import org.apache.commons.httpclient.methods.StringRequestEntity;
066 import org.deegree.enterprise.WebUtils;
067 import org.deegree.framework.log.ILogger;
068 import org.deegree.framework.log.LoggerFactory;
069 import org.deegree.framework.xml.XMLFragment;
070
071 /**
072 * utility class for performing HTTP requests
073 *
074 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
075 * @author last edited by: $Author: apoth $
076 *
077 * @version. $Revision: 27357 $, $Date: 2010-10-18 18:06:09 +0200 (Mo, 18 Okt 2010) $
078 */
079 public class HttpUtils {
080
081 private static final ILogger LOG = LoggerFactory.getLogger( HttpUtils.class );
082
083 /**
084 * validates passed URL. If it is not a valid URL or a client can not connect to it an exception will be thrown
085 *
086 * @param url
087 * @throws IOException
088 */
089 public static int validateURL( String url )
090 throws IOException {
091 return validateURL( url, null, null );
092 }
093
094 /**
095 * validates passed URL. If it is not a valid URL or a client can not connect to it an exception will be thrown
096 *
097 * @param url
098 * @param user
099 * @param password
100 * @throws IOException
101 */
102 public static int validateURL( String url, String user, String password )
103 throws IOException {
104 if ( url.startsWith( "http:" ) ) {
105 URL tmp = new URL( url );
106 HeadMethod hm = new HeadMethod( url );
107 setHTTPCredentials( hm, user, password );
108 InetAddress.getByName( tmp.getHost() );
109 HttpClient client = new HttpClient();
110 client.executeMethod( hm );
111 if ( hm.getStatusCode() != HttpURLConnection.HTTP_OK ) {
112 if ( hm.getStatusCode() != HttpURLConnection.HTTP_UNAUTHORIZED && hm.getStatusCode() != 401 ) {
113 // this method just evaluates if a URL/host is valid; it does not takes care
114 // if authorization is available/valid
115 throw new IOException( "Host " + tmp.getHost() + " of URL + " + url + " does not exists" );
116 }
117 }
118 return hm.getStatusCode();
119 } else if ( url.startsWith( "file:" ) ) {
120 URL tmp = new URL( url );
121 InputStream is = tmp.openStream();
122 is.close();
123 return 200;
124 }
125 return HttpURLConnection.HTTP_UNAVAILABLE;
126 }
127
128 /**
129 *
130 * @param url
131 * @param content
132 * @param timeout
133 * timeout in milliseconds
134 * @param user
135 * (can be <code>null</code>)
136 * @param password
137 * (can be <code>null</code>)
138 * @param contentType
139 * request content mime type (can be <code>null</code>)
140 * @param encoding
141 * request encoding (can be <code>null</code>)
142 * @param header
143 *
144 * @return result of http post request
145 * @throws HttpException
146 * @throws IOException
147 */
148 public static HttpMethod performHttpPost( String url, InputStream content, int timeout, String user,
149 String password, String contentType, String encoding,
150 Map<String, String> header )
151 throws HttpException, IOException {
152 HttpClient client = new HttpClient();
153 URL tmp = new URL( url );
154 WebUtils.enableProxyUsage( client, tmp );
155 url = tmp.toExternalForm();
156 client.getHttpConnectionManager().getParams().setSoTimeout( timeout );
157 client.getHttpConnectionManager().getParams().setConnectionTimeout( timeout );
158
159 PostMethod pm = new PostMethod( url );
160 String ct = contentType;
161 if ( ct != null && encoding != null ) {
162 ct += ( "; " + encoding );
163 }
164 if ( ct != null ) {
165 pm.setRequestEntity( new InputStreamRequestEntity( content, ct ) );
166 } else {
167 pm.setRequestEntity( new InputStreamRequestEntity( content ) );
168 }
169 if ( header != null ) {
170 Iterator<String> iter = header.keySet().iterator();
171 while ( iter.hasNext() ) {
172 String key = (String) iter.next();
173 if ( !"content-length".equalsIgnoreCase( key ) ) {
174 pm.addRequestHeader( new Header( key, header.get( key ) ) );
175 }
176 }
177 }
178
179 setHTTPCredentials( pm, user, password );
180 client.executeMethod( pm );
181 if ( LOG.getLevel() == ILogger.LOG_DEBUG ) {
182 LOG.logDebug( pm.getResponseBodyAsString() );
183 }
184 if ( pm.getStatusCode() != 200 ) {
185 throw new HttpException( "status code: " + pm.getStatusCode() );
186 }
187 return pm;
188 }
189
190 /**
191 *
192 * @param url
193 * @param content
194 * @param timeout
195 * timeout in milliseconds
196 * @param user
197 * (can <code>null</code>)
198 * @param password
199 * (can <code>null</code>)
200 * @param contentType
201 * request content mime type (can be <code>null</code>)
202 * @param encoding
203 * request encoding (can be <code>null</code>)
204 * @param header
205 * @return result of http post request
206 * @throws HttpException
207 * @throws IOException
208 */
209 public static HttpMethod performHttpPost( String url, String content, int timeout, String user, String password,
210 String contentType, String encoding, Map<String, String> header )
211 throws HttpException, IOException {
212 HttpClient client = new HttpClient();
213 URL tmp = new URL( url );
214 WebUtils.enableProxyUsage( client, tmp );
215 url = tmp.toExternalForm();
216 client.getHttpConnectionManager().getParams().setSoTimeout( timeout );
217 client.getHttpConnectionManager().getParams().setConnectionTimeout( timeout );
218 PostMethod pm = new PostMethod( url );
219
220 pm.setRequestEntity( new StringRequestEntity( content, contentType, encoding ) );
221
222 if ( header != null ) {
223 Iterator<String> iter = header.keySet().iterator();
224 while ( iter.hasNext() ) {
225 String key = (String) iter.next();
226 if ( !"content-length".equalsIgnoreCase( key ) ) {
227 pm.addRequestHeader( new Header( key, header.get( key ) ) );
228 }
229 }
230 }
231 pm.addRequestHeader( new Header( "content-length", Integer.toString( content.getBytes().length ) ) );
232
233 setHTTPCredentials( pm, user, password );
234 client.executeMethod( pm );
235 if ( LOG.getLevel() == ILogger.LOG_DEBUG ) {
236 LOG.logDebug( pm.getResponseBodyAsString() );
237 }
238 if ( pm.getStatusCode() != 200 ) {
239 throw new HttpException( "status code: " + pm.getStatusCode() );
240 }
241 return pm;
242 }
243
244 /**
245 *
246 * @param url
247 * @param content
248 * @param timeout
249 * timeout in milliseconds
250 * @param user
251 * (can <code>null</code>)
252 * @param password
253 * (can <code>null</code>)
254 * @param header
255 * @return result of http post request
256 * @throws HttpException
257 * @throws IOException
258 */
259 public static HttpMethod performHttpPost( String url, XMLFragment content, int timeout, String user,
260 String password, Map<String, String> header )
261 throws HttpException, IOException {
262 HttpClient client = new HttpClient();
263 URL tmp = new URL( url );
264 WebUtils.enableProxyUsage( client, tmp );
265 url = tmp.toExternalForm();
266 client.getHttpConnectionManager().getParams().setSoTimeout( timeout );
267 client.getHttpConnectionManager().getParams().setConnectionTimeout( timeout );
268 PostMethod pm = new PostMethod( url );
269
270 ByteArrayOutputStream bos = new ByteArrayOutputStream( 1000000 );
271 Properties props = new Properties();
272 props.put( OutputKeys.ENCODING, "UTF-8" );
273 content.write( bos, props );
274
275 pm.setRequestEntity( new ByteArrayRequestEntity( bos.toByteArray(), "text/xml" ) );
276
277 if ( header != null ) {
278 Iterator<String> iter = header.keySet().iterator();
279 while ( iter.hasNext() ) {
280 String key = (String) iter.next();
281 if ( !"content-length".equalsIgnoreCase( key ) ) {
282 pm.addRequestHeader( new Header( key, header.get( key ) ) );
283 }
284 }
285 }
286 pm.addRequestHeader( new Header( "content-length", Integer.toString( bos.toByteArray().length ) ) );
287 bos.close();
288
289 setHTTPCredentials( pm, user, password );
290 client.executeMethod( pm );
291 if ( LOG.getLevel() == ILogger.LOG_DEBUG ) {
292 LOG.logDebug( pm.getResponseBodyAsString() );
293 }
294 if ( pm.getStatusCode() != 200 ) {
295 throw new HttpException( "status code: " + pm.getStatusCode() );
296 }
297 return pm;
298 }
299
300 /**
301 *
302 * @param url
303 * e.g. http://localhost:8080/deegree/services
304 * @param request
305 * e.g. service=WMS&request=GetCapabilities
306 * @param timeout
307 * timeout in milliseconds
308 * @param user
309 * (can be <code>null</code>)
310 * @param password
311 * (can be <code>null</code>)
312 * @param header
313 * @return result of http get request
314 * @throws HttpException
315 * @throws IOException
316 */
317 public static HttpMethod performHttpGet( String url, String request, int timeout, String user, String password,
318 Map<String, String> header )
319 throws HttpException, IOException {
320 if ( request != null && request.startsWith( "&" ) ) {
321 request = request.substring( 1 );
322 }
323 if ( url != null && url.endsWith( "?" ) ) {
324 url = url.substring( 0, url.length() - 1 );
325 }
326 LOG.logDebug( "HTTP GET URL: ", url );
327 LOG.logDebug( "HTTP GET request: ", request );
328 GetMethod gm = null;
329 if ( url.indexOf( '?' ) > -1 && request != null ) {
330 gm = new GetMethod( StringTools.concat( 500, url, '&', request ) );
331 } else if ( request != null && !request.startsWith( "http://" ) ) {
332 gm = new GetMethod( StringTools.concat( 500, url, '?', request ) );
333 } else if ( request != null && request.startsWith( "http://" ) ) {
334 gm = new GetMethod( request );
335 } else {
336 gm = new GetMethod( url );
337 }
338
339 if ( header != null ) {
340 Iterator<String> iter = header.keySet().iterator();
341 while ( iter.hasNext() ) {
342 String key = (String) iter.next();
343 if ( !"content-length".equalsIgnoreCase( key ) ) {
344 gm.addRequestHeader( new Header( key, header.get( key ) ) );
345 }
346
347 }
348 }
349
350 setHTTPCredentials( gm, user, password );
351
352 HttpClient client = new HttpClient();
353 client.getHttpConnectionManager().getParams().setSoTimeout( timeout );
354 client.getHttpConnectionManager().getParams().setConnectionTimeout( timeout );
355 WebUtils.enableProxyUsage( client, new URL( url ) );
356 client.executeMethod( gm );
357 if ( LOG.getLevel() == ILogger.LOG_DEBUG ) {
358 LOG.logDebug( gm.getResponseBodyAsString() );
359 }
360 if ( gm.getStatusCode() != 200 ) {
361 throw new HttpException( "status code: " + gm.getStatusCode() );
362 }
363 return gm;
364 }
365
366 /**
367 *
368 * @param url
369 * @param user
370 * @param password
371 * @param sessionID
372 * @return URL with attached authentication information (if not null)
373 */
374 public static String addAuthenticationForKVP( String url, String user, String password, String sessionID ) {
375 if ( sessionID != null && sessionID.trim().length() > 0 ) {
376 url = url + "&sessionID=" + sessionID;
377 } else if ( user != null ) {
378 url = url + "&user=" + user;
379 if ( password == null ) {
380 password = "";
381 }
382 url = url + "&password=" + password;
383 }
384 return url;
385 }
386
387 /**
388 *
389 * @param xml
390 * @param user
391 * @param password
392 * @param sessionID
393 * @return XML document with authentication information (if not null) as attributes of the root element
394 */
395 public static XMLFragment addAuthenticationForXML( XMLFragment xml, String user, String password, String sessionID ) {
396 if ( sessionID != null ) {
397 xml.getRootElement().setAttribute( "sessionID", sessionID );
398 } else if ( user != null ) {
399 xml.getRootElement().setAttribute( "user", user );
400 if ( password != null ) {
401 xml.getRootElement().setAttribute( "password", password );
402 }
403 }
404 return xml;
405 }
406
407 /**
408 *
409 * @param url
410 * @return URL as String with protocol and path but without request params
411 * @throws URISyntaxException
412 */
413 public static String normalizeURL( URL url ) {
414 String pr = url.getProtocol();
415 String ho = url.getHost();
416 int po = url.getPort();
417 String pa = url.getPath();
418 String s = pr + "://" + ho + ':' + po;
419 if ( pa != null && pa.length() > 0 ) {
420 s += pa;
421 }
422 return s;
423 }
424
425 /**
426 *
427 * @param url
428 * @return URL as String with protocol and path but without request params
429 * @throws URISyntaxException
430 */
431 public static String normalizeURL( String url ) {
432 try {
433 return normalizeURL( new URL( url ) );
434 } catch ( MalformedURLException e ) {
435 LOG.logWarning( e.getMessage(), e );
436 }
437 return url;
438 }
439
440 private static void setHTTPCredentials( HttpMethod m, String user, String password ) {
441 if ( user != null ) {
442 if ( password == null ) {
443 password = "";
444 }
445 String s = new String( Base64.encodeBase64( ( user + ":" + password ).getBytes() ) );
446 m.setRequestHeader( "authorization", "Basic " + s );
447 }
448 }
449
450 }