001 //$HeadURL: http://svn.wald.intevation.org/svn/deegree/base/trunk/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: 30454 $, $Date: 2011-04-14 14:03:42 +0200 (Thu, 14 Apr 2011) $
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
263 HttpClient client = new HttpClient();
264 URL tmp = new URL( url );
265 WebUtils.enableProxyUsage( client, tmp );
266 url = tmp.toExternalForm();
267 client.getHttpConnectionManager().getParams().setSoTimeout( timeout );
268 client.getHttpConnectionManager().getParams().setConnectionTimeout( timeout );
269 PostMethod pm = new PostMethod( url );
270
271 ByteArrayOutputStream bos = new ByteArrayOutputStream( 1000000 );
272 Properties props = new Properties();
273 props.put( OutputKeys.ENCODING, "UTF-8" );
274 content.write( bos, props );
275
276 pm.setRequestEntity( new ByteArrayRequestEntity( bos.toByteArray(), "text/xml" ) );
277
278 if ( header != null ) {
279 Iterator<String> iter = header.keySet().iterator();
280 while ( iter.hasNext() ) {
281 String key = (String) iter.next();
282 if ( !"content-length".equalsIgnoreCase( key ) ) {
283 pm.addRequestHeader( new Header( key, header.get( key ) ) );
284 }
285 }
286 }
287 pm.addRequestHeader( new Header( "content-length", Integer.toString( bos.toByteArray().length ) ) );
288 bos.close();
289
290 setHTTPCredentials( pm, user, password );
291 client.executeMethod( pm );
292 if ( LOG.getLevel() == ILogger.LOG_DEBUG ) {
293 LOG.logDebug( pm.getResponseBodyAsString() );
294 }
295 if ( pm.getStatusCode() != 200 ) {
296 throw new HttpException( "status code: " + pm.getStatusCode() );
297 }
298 return pm;
299 }
300
301 /**
302 *
303 * @param url
304 * e.g. http://localhost:8080/deegree/services
305 * @param request
306 * e.g. service=WMS&request=GetCapabilities
307 * @param timeout
308 * timeout in milliseconds
309 * @param user
310 * (can be <code>null</code>)
311 * @param password
312 * (can be <code>null</code>)
313 * @param header
314 * @return result of http get request
315 * @throws HttpException
316 * @throws IOException
317 */
318 public static HttpMethod performHttpGet( String url, String request, int timeout, String user, String password,
319 Map<String, String> header )
320 throws HttpException, IOException {
321 if ( request != null && request.startsWith( "&" ) ) {
322 request = request.substring( 1 );
323 }
324 if ( url != null && url.endsWith( "?" ) ) {
325 url = url.substring( 0, url.length() - 1 );
326 }
327 LOG.logDebug( "HTTP GET URL: ", url );
328 LOG.logDebug( "HTTP GET request: ", request );
329 GetMethod gm = null;
330 if ( url.indexOf( '?' ) > -1 && request != null ) {
331 gm = new GetMethod( StringTools.concat( 500, url, '&', request ) );
332 } else if ( request != null && !request.startsWith( "http://" ) ) {
333 gm = new GetMethod( StringTools.concat( 500, url, '?', request ) );
334 } else if ( request != null && request.startsWith( "http://" ) ) {
335 gm = new GetMethod( request );
336 } else {
337 gm = new GetMethod( url );
338 }
339
340 if ( header != null ) {
341 Iterator<String> iter = header.keySet().iterator();
342 while ( iter.hasNext() ) {
343 String key = (String) iter.next();
344 if ( !"content-length".equalsIgnoreCase( key ) ) {
345 gm.addRequestHeader( new Header( key, header.get( key ) ) );
346 }
347
348 }
349 }
350
351 setHTTPCredentials( gm, user, password );
352
353 HttpClient client = new HttpClient();
354 client.getHttpConnectionManager().getParams().setSoTimeout( timeout );
355 client.getHttpConnectionManager().getParams().setConnectionTimeout( timeout );
356 WebUtils.enableProxyUsage( client, new URL( url ) );
357 client.executeMethod( gm );
358 if ( LOG.getLevel() == ILogger.LOG_DEBUG ) {
359 LOG.logDebug( gm.getResponseBodyAsString() );
360 }
361 if ( gm.getStatusCode() != 200 ) {
362 throw new HttpException( "status code: " + gm.getStatusCode() );
363 }
364 return gm;
365 }
366
367 /**
368 *
369 * @param url
370 * @param user
371 * @param password
372 * @param sessionID
373 * @return URL with attached authentication information (if not null)
374 */
375 public static String addAuthenticationForKVP( String url, String user, String password, String sessionID ) {
376 if ( sessionID != null && sessionID.trim().length() > 0 ) {
377 url = url + "&sessionID=" + sessionID;
378 } else if ( user != null ) {
379 url = url + "&user=" + user;
380 if ( password == null ) {
381 password = "";
382 }
383 url = url + "&password=" + password;
384 }
385 return url;
386 }
387
388 /**
389 *
390 * @param xml
391 * @param user
392 * @param password
393 * @param sessionID
394 * @return XML document with authentication information (if not null) as attributes of the root element
395 */
396 public static XMLFragment addAuthenticationForXML( XMLFragment xml, String user, String password, String sessionID ) {
397 if ( sessionID != null ) {
398 xml.getRootElement().setAttribute( "sessionID", sessionID );
399 } else if ( user != null ) {
400 xml.getRootElement().setAttribute( "user", user );
401 if ( password != null ) {
402 xml.getRootElement().setAttribute( "password", password );
403 }
404 }
405 return xml;
406 }
407
408 /**
409 *
410 * @param url
411 * @return URL as String with protocol and path but without request params
412 * @throws URISyntaxException
413 */
414 public static String normalizeURL( URL url ) {
415 String pr = url.getProtocol();
416 String ho = url.getHost();
417 int po = url.getPort();
418 String pa = url.getPath();
419 String s = pr + "://" + ho + ':' + po;
420 if ( pa != null && pa.length() > 0 ) {
421 s += pa;
422 }
423 return s;
424 }
425
426 /**
427 *
428 * @param url
429 * @return URL as String with protocol and path but without request params
430 * @throws URISyntaxException
431 */
432 public static String normalizeURL( String url ) {
433 try {
434 return normalizeURL( new URL( url ) );
435 } catch ( MalformedURLException e ) {
436 LOG.logWarning( e.getMessage(), e );
437 }
438 return url;
439 }
440
441 private static void setHTTPCredentials( HttpMethod m, String user, String password ) {
442 if ( user != null ) {
443 if ( password == null ) {
444 password = "";
445 }
446 String s = new String( Base64.encodeBase64( ( user + ":" + password ).getBytes() ) );
447 m.setRequestHeader( "authorization", "Basic " + s );
448 }
449 }
450
451 }