KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > micronova > util > NetUtil


1 /*
2
3 Copyright 2003-2007 MicroNova (R)
4 All rights reserved.
5
6 Redistribution and use in source and binary forms, with or
7 without modification, are permitted provided that the following
8 conditions are met:
9
10     * Redistributions of source code must retain the above copyright
11     notice, this list of conditions and the following disclaimer.
12
13     * Redistributions in binary form must reproduce the above copyright
14     notice, this list of conditions and the following disclaimer in the
15     documentation and/or other materials provided with the distribution.
16
17     * Neither the name of MicroNova nor the names of its contributors
18     may be used to endorse or promote products derived from this
19     software without specific prior written permission.
20
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 POSSIBILITY OF SUCH DAMAGE.
32
33 */

34
35 package com.micronova.util;
36
37 import java.net.*;
38 import javax.net.ssl.*;
39 import java.util.*;
40 import java.io.*;
41 import java.security.*;
42 import java.util.regex.*;
43
44 /** network utilities */
45
46 public class NetUtil implements Runnable JavaDoc
47 {
48     /** HTML META Content Type Pattern */
49
50     public static final Pattern htmlMetaPattern = Pattern.compile("(?i)<[ ]*META[ ]*HTTP-EQUIV[ ]*=[ ]*\"?CONTENT-TYPE\"?[ ]*CONTENT[ ]*=[ ]*\"([^\"]+)\"[ ]*/?>");
51
52     /** NestedMap for threaded request */
53
54     private NestedMap _map;
55
56     /** protocol handler package property */
57
58     private final static String JavaDoc HANDLERPKGS = "java.protocol.handler.pkgs";
59
60     /** sun's protocol handler package */
61
62     private final static String JavaDoc SUNNETSSL = "sun.net.ssl.internal.www.protocol";
63     /** customizable version of url.openConnection(). Given trustManager or hostnameVerifier are used if not null. */
64
65     public static URLConnection openConnection(URL url, TrustManager trustManager, HostnameVerifier hostnameVerifier) throws Exception JavaDoc
66     {
67         URLConnection c = null;
68
69         System.setProperty(HANDLERPKGS, SUNNETSSL);
70             
71         c = url.openConnection();
72             
73         if (c instanceof HttpsURLConnection)
74         {
75             HttpsURLConnection sc = (HttpsURLConnection)c;
76             
77             SSLContext sslContext = SSLContext.getInstance("TLS");
78             
79             if (trustManager != null)
80             {
81                 TrustManager[] tm = new TrustManager[] {trustManager};
82                 sslContext.init(null, tm, null);
83                 
84                 SSLSocketFactory factory = sslContext.getSocketFactory();
85                 
86                 sc.setSSLSocketFactory(factory);
87             }
88             
89             if (hostnameVerifier != null)
90             {
91                 sc.setHostnameVerifier(hostnameVerifier);
92             }
93         }
94
95         return c;
96     }
97
98     /** simpler version, selectively disables TrustManager/HostnameVerifier */
99
100     public static URLConnection openConnection(URL url, boolean usesTrustManager, boolean usesHostnameVerifier) throws Exception JavaDoc
101     {
102         TrustManager trustManager = null;
103
104         if (!usesTrustManager)
105         {
106             trustManager = new DefaultTrustManager();
107         }
108
109         HostnameVerifier hostnameVerifier = null;
110
111         if (!usesHostnameVerifier)
112         {
113             hostnameVerifier = new DefaultHostnameVerifier();
114         }
115
116         return openConnection(url, trustManager, hostnameVerifier);
117     }
118
119     /** mime map properties */
120
121     public final static String JavaDoc MIMETYPE = com.micronova.util.cc.mime.Parser.TYPE;
122     public final static String JavaDoc MIMESUBTYPE = com.micronova.util.cc.mime.Parser.SUBTYPE;
123     public final static String JavaDoc MIMEPARAMETER = com.micronova.util.cc.mime.Parser.PARAMETER;
124
125     /** parses MIME into type/subType/parameters */
126     
127     public final static Map parseMime(String JavaDoc mime)
128     {
129         return com.micronova.util.cc.mime.Parser.parse(mime);
130     }
131
132     /** converts parsed MIME to string */
133
134     public final static String JavaDoc encodeMime(Map mimeMap)
135     {
136         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
137
138         buffer.append(mimeMap.get(MIMETYPE));
139
140         Object JavaDoc subType = mimeMap.get(MIMESUBTYPE);
141
142         if (subType != null)
143         {
144             buffer.append("/");
145             buffer.append(subType);
146         }
147
148         Map map = (Map)mimeMap.get(MIMEPARAMETER);
149
150         if (map != null)
151         {
152             Iterator iterator = map.entrySet().iterator();
153
154             while (iterator.hasNext())
155             {
156                 Map.Entry entry = (Map.Entry)iterator.next();
157
158                 buffer.append(";");
159                 buffer.append(entry.getKey());
160                 buffer.append("=\"");
161                 buffer.append(entry.getValue());
162                 buffer.append("\"");
163             }
164         }
165
166         return buffer.toString();
167     }
168
169     /** Map-based HTTP request */
170
171     public static final String JavaDoc USESTRUSTMANAGER = "usesTrustManager";
172     public static final String JavaDoc USESHOSTNAMEVERIFIER = "usesHostnameVerifier";
173     public static final String JavaDoc URL = "url";
174     public static final String JavaDoc METHOD = "method";
175     public static final String JavaDoc THROWSEXCEPTION = "throwsException";
176     public static final String JavaDoc FOLLOWSREDIRECTS = "followsRedirects";
177     public static final String JavaDoc ALLOWSFILE = "allowsFile";
178
179     public static final String JavaDoc REQUEST = "request";
180     public static final String JavaDoc RESPONSE = "response";
181
182     public static final String JavaDoc HEADER = "header";
183     public static final String JavaDoc ENCODING = "encoding";
184     public static final String JavaDoc DEFAULTENCODING = "defaultEncoding";
185     public static final String JavaDoc CONTENT = "content";
186     public static final String JavaDoc TYPE = "type";
187     public static final String JavaDoc PARAMETER = "parameter";
188     public static final String JavaDoc AUTHORIZATION = "authorization";
189     public static final String JavaDoc USER = "user";
190     public static final String JavaDoc PASSWORD = "password";
191     public static final String JavaDoc STATUS = "status";
192     public static final String JavaDoc MESSAGE = "message";
193     public static final String JavaDoc BINARYENCODING = "iso-8859-1";
194     public static final String JavaDoc CONNECTTIMEOUT = "connectTimeout";
195     public static final String JavaDoc READTIMEOUT = "readTimeout";
196
197     /** makes an HTTP request */
198
199     public static NestedMap request(NestedMap map) throws Exception JavaDoc
200     {
201         OutputStream out = null;
202         InputStream in = null;
203
204         try
205         {
206             String JavaDoc urlString = map.getString(URL);
207             String JavaDoc method = map.getString(METHOD, "post");
208
209             boolean isGet = ("get".equalsIgnoreCase(method));
210
211             boolean usesTrustManager = (TypeUtil.isTrue(map.get(USESTRUSTMANAGER)));
212             boolean usesHostnameVerifier = (TypeUtil.isTrue(map.get(USESHOSTNAMEVERIFIER)));
213             Map request = (Map)map.get(REQUEST);
214
215             String JavaDoc requestContent = null;
216             String JavaDoc encoding = null;
217
218             if (request != null)
219             {
220                 encoding = (String JavaDoc)request.get(ENCODING);
221
222                 if (encoding == null)
223                 {
224                     encoding = BINARYENCODING;
225                 }
226
227                 requestContent = (String JavaDoc)request.get(CONTENT);
228
229                 if (requestContent == null)
230                 {
231                     Map requestParameters = (Map)request.get(PARAMETER);
232
233                     if ((requestParameters != null) && (!requestParameters.isEmpty()))
234                     {
235                         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
236
237                         boolean isAppended = false;
238
239                         Iterator iterator = requestParameters.entrySet().iterator();
240
241                         while (iterator.hasNext())
242                         {
243                             Map.Entry entry = (Map.Entry)iterator.next();
244
245                             Object JavaDoc key = entry.getKey();
246                             Object JavaDoc value = entry.getValue();
247                             
248                             String JavaDoc keyString = NestedMap.encodeString((key != null) ? key.toString() : "", encoding);
249
250                             List valueList = TypeUtil.isList(value);
251
252                             if (valueList != null)
253                             {
254                                 Iterator listIterator = valueList.iterator();
255
256                                 while (listIterator.hasNext())
257                                 {
258                                     if (isAppended)
259                                     {
260                                         buffer.append("&");
261                                     }
262                             
263                                     buffer.append(keyString);
264                                     buffer.append("=");
265                                     buffer.append(NestedMap.encodeString(listIterator.next().toString(), encoding));
266                                     isAppended = true;
267                                 }
268                             }
269                             else
270                             {
271                                 String JavaDoc valueString = (value != null) ? value.toString() : "";
272                             
273                                 if (isAppended)
274                                 {
275                                     buffer.append("&");
276                                 }
277                                 
278                                 buffer.append(keyString);
279                                 buffer.append("=");
280                                 buffer.append(NestedMap.encodeString(valueString, encoding));
281                                 isAppended = true;
282                             }
283                         }
284
285                         requestContent = buffer.toString();
286                     }
287                 }
288
289                 if (isGet)
290                 {
291                     if (requestContent != null)
292                     {
293                         urlString += ("?" + requestContent);
294                     }
295                 }
296             }
297
298             URL url = new URL(urlString);
299
300             if (!TypeUtil.isTrue(map.get(ALLOWSFILE)))
301             {
302                 if ("file".equalsIgnoreCase(url.getProtocol()))
303                 {
304                     return null;
305                 }
306             }
307
308             URLConnection c = NetUtil.openConnection(url, usesTrustManager, usesHostnameVerifier);
309
310             HttpURLConnection hc = null;
311
312             if (c instanceof HttpURLConnection)
313             {
314                 hc = (HttpURLConnection)c;
315             }
316
317             // try to call setConnectTimeout() and setReadTimeout()
318
// only available in JDK 1.5 using reflection
319

320             try
321             {
322                 Integer JavaDoc connectTimeoutInteger = TypeUtil.isInteger(map.get(CONNECTTIMEOUT));
323                 
324                 if (connectTimeoutInteger != null)
325                 {
326                     TypeUtil.invoke(hc, null, "setConnectTimeout", new Class JavaDoc[]{Integer.TYPE}, new Object JavaDoc[]{connectTimeoutInteger});
327                 }
328             }
329             catch (Exception JavaDoc e)
330             {
331                 // ignored
332
}
333
334             try
335             {
336                 Integer JavaDoc readTimeoutInteger = TypeUtil.isInteger(map.getString(READTIMEOUT));
337
338                 if (readTimeoutInteger != null)
339                 {
340                     TypeUtil.invoke(hc, null, "setReadTimeout", new Class JavaDoc[]{Integer.TYPE}, new Object JavaDoc[]{readTimeoutInteger});
341                 }
342             }
343             catch (Exception JavaDoc e)
344             {
345                 // ignored
346
}
347
348             c.setAllowUserInteraction(false);
349             c.setDoInput(true);
350             c.setDoOutput(true);
351
352             if (TypeUtil.isTrue(map.get(FOLLOWSREDIRECTS)))
353             {
354                 if (hc != null)
355                 {
356                     hc.setInstanceFollowRedirects(true);
357                 }
358             }
359
360             if (request != null)
361             {
362                 Map requestHeaders = (Map)request.get(HEADER);
363
364                 if (requestHeaders != null)
365                 {
366                     Iterator iterator = requestHeaders.entrySet().iterator();
367                 
368                     while (iterator.hasNext())
369                     {
370                         Map.Entry entry = (Map.Entry)iterator.next();
371
372                         String JavaDoc headerName = entry.getKey().toString();
373
374                         Object JavaDoc headerValue = entry.getValue();
375
376                         if (headerValue instanceof List)
377                         {
378                             List list = (List)headerValue;
379
380                             Iterator valueIterator = list.iterator();
381
382                             while (valueIterator.hasNext())
383                             {
384                                 c.addRequestProperty(headerName, valueIterator.next().toString());
385                             }
386                             
387                         }
388                         else
389                         {
390                             c.addRequestProperty(headerName, headerValue.toString());
391                         }
392                     }
393                 }
394
395                 String JavaDoc authorization = (String JavaDoc)request.get(AUTHORIZATION);
396                 
397                 if ("basic".equals(authorization))
398                 {
399                     String JavaDoc user = (String JavaDoc)request.get(USER);
400                     String JavaDoc password = (String JavaDoc)request.get(PASSWORD);
401                     
402                     if ((user != null) && (password != null))
403                     {
404                         String JavaDoc credential = user + ":" + password;
405                     
406                         String JavaDoc encoded = (new sun.misc.BASE64Encoder()).encode(credential.getBytes());
407                         c.addRequestProperty("Authorization", "Basic " + encoded);
408                     }
409                 }
410             }
411
412             c.connect();
413
414             if (!isGet)
415             {
416                 if (requestContent != null)
417                 {
418                     out = c.getOutputStream();
419
420                     byte[] data = requestContent.getBytes(encoding);
421             
422                     out.write(data, 0, data.length);
423             
424                     out.close();
425                     
426                     out = null;
427                 }
428             }
429
430             NestedMap response = map.getSubMap(RESPONSE);
431             
432             String JavaDoc responseEncoding = response.getString(ENCODING);
433             String JavaDoc responseDefaultEncoding = response.getString(DEFAULTENCODING, BINARYENCODING);
434
435             Map responseHeaders = c.getHeaderFields();
436
437             if (responseHeaders != null)
438             {
439                 Map responseHeaderMap = new NestedMap();
440
441                 response.put(HEADER, responseHeaderMap);
442                 
443                 Iterator iterator = responseHeaders.entrySet().iterator();
444                 
445                 while (iterator.hasNext())
446                 {
447                     Map.Entry entry = (Map.Entry)iterator.next();
448                         
449                     Object JavaDoc headerKey = entry.getKey();
450                     Object JavaDoc headerValue= entry.getValue();
451                         
452                     if (headerKey != null)
453                     {
454                         headerKey = headerKey.toString().toLowerCase();
455                     }
456                         
457                     responseHeaderMap.put(headerKey, headerValue);
458                 }
459             }
460
461             ByteArrayOutputStream buffer = new ByteArrayOutputStream();
462                 
463             try
464             {
465                 in = c.getInputStream();
466                     
467                 IOUtil.copy(in, buffer);
468             }
469             catch (Exception JavaDoc ee)
470             {
471                 IOUtil.tryClose(in);
472                     
473                 buffer.reset();
474                     
475                 if (hc != null)
476                 {
477                     in = hc.getErrorStream();
478                         
479                     if (in != null)
480                     {
481                         IOUtil.copy(in, buffer);
482                             
483                         IOUtil.tryClose(in);
484                     }
485                 }
486                     
487                 if (TypeUtil.isTrue(map.get(THROWSEXCEPTION)))
488                 {
489                     throw ee;
490                 }
491             }
492                 
493             if (hc != null)
494             {
495                 response.put(STATUS, new Integer JavaDoc(hc.getResponseCode()));
496                 response.put(MESSAGE, hc.getResponseMessage());
497             }
498                 
499             byte[] responseData = buffer.toByteArray();
500                 
501             String JavaDoc contentEncoding = c.getContentEncoding();
502                 
503             if (contentEncoding != null)
504             {
505                 contentEncoding = contentEncoding.toLowerCase();
506                     
507                 if (contentEncoding.indexOf("gzip") >= 0)
508                 {
509                     responseData = StringUtil.decompressGZIP(responseData);
510                 }
511                 else if (contentEncoding.indexOf("zip") >= 0)
512                 {
513                     responseData = StringUtil.decompressZip(responseData);
514                 }
515             }
516                 
517             boolean isText = false;
518                 
519             Map mimeType = NetUtil.parseMime(c.getContentType());
520                 
521             response.put(TYPE, mimeType);
522                 
523             String JavaDoc contentString = null;
524                 
525             if (responseEncoding != null)
526             {
527                 encoding = responseEncoding;
528             }
529             else
530             {
531                 encoding = null;
532
533                 if (mimeType != null)
534                 {
535                     String JavaDoc type = (String JavaDoc)mimeType.get(NetUtil.MIMETYPE);
536                     
537                     if ("text".equals(type))
538                     {
539                         isText = true;
540                         
541                         String JavaDoc mimeCharset = (String JavaDoc)((Map)mimeType.get(NetUtil.MIMEPARAMETER)).get("charset");
542                         
543                         if (mimeCharset != null)
544                         {
545                             encoding = mimeCharset;
546                         }
547                     }
548                 }
549
550                 if (encoding == null)
551                 {
552                     String JavaDoc subType = (String JavaDoc)mimeType.get(NetUtil.MIMESUBTYPE);
553
554                     if ("html".equals(subType))
555                     {
556                         contentString = new String JavaDoc(responseData, BINARYENCODING);
557
558                         Matcher metaMatcher = htmlMetaPattern.matcher(contentString);
559
560                         if (metaMatcher.find())
561                         {
562                             Map metaType = NetUtil.parseMime(metaMatcher.group(1));
563
564                             String JavaDoc metaCharset = (String JavaDoc)((Map)metaType.get(NetUtil.MIMEPARAMETER)).get("charset");
565
566                             if (metaCharset != null)
567                             {
568                                 encoding = metaCharset;
569                             }
570                         }
571                     }
572                 }
573
574
575                 if (encoding == null)
576                 {
577                     encoding = responseDefaultEncoding;
578                 }
579                 
580                 response.put(ENCODING, encoding);
581             }
582
583             if ((!BINARYENCODING.equals(encoding)) || (contentString == null))
584             {
585                 contentString = new String JavaDoc(responseData, encoding);
586             }
587
588             response.put(CONTENT, contentString);
589         }
590         catch (Exception JavaDoc e)
591         {
592             throw e;
593         }
594         finally
595         {
596             IOUtil.tryClose(out);
597             IOUtil.tryClose(in);
598         }
599
600         return map;
601     }
602
603     /** runnable for threaded request */
604
605     public void run()
606     {
607         try
608         {
609             request(_map);
610         }
611         catch (Exception JavaDoc e)
612         {
613         }
614     }
615
616     /** constructor for threaded request */
617
618     public NetUtil(NestedMap map)
619     {
620         _map = map;
621     }
622 }
623
Popular Tags