KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > axis > components > net > DefaultSocketFactory


1 /*
2  * Copyright 2001-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.axis.components.net;
17
18 import org.apache.axis.components.logger.LogFactory;
19 import org.apache.axis.encoding.Base64;
20 import org.apache.axis.transport.http.HTTPConstants;
21 import org.apache.axis.utils.Messages;
22 import org.apache.commons.logging.Log;
23
24 import java.net.Socket JavaDoc;
25 import java.util.Hashtable JavaDoc;
26 import java.util.StringTokenizer JavaDoc;
27 import java.lang.reflect.Constructor JavaDoc;
28 import java.lang.reflect.Method JavaDoc;
29
30 /**
31  * Default socket factory.
32  *
33  * @author Davanum Srinivas (dims@yahoo.com)
34  */

35 public class DefaultSocketFactory implements SocketFactory {
36
37     /** Field log */
38     protected static Log log =
39             LogFactory.getLog(DefaultSocketFactory.class.getName());
40
41     /** Field CONNECT_TIMEOUT */
42     public static String JavaDoc CONNECT_TIMEOUT = "axis.client.connect.timeout";
43     
44     /** attributes */
45     protected Hashtable JavaDoc attributes = null;
46
47     private static boolean plain;
48     private static Class JavaDoc inetClass;
49     private static Constructor JavaDoc inetConstructor;
50     private static Constructor JavaDoc socketConstructor;
51     private static Method JavaDoc connect;
52
53     static {
54         try {
55             inetClass = Class.forName("java.net.InetSocketAddress");
56             plain = false;
57             inetConstructor = inetClass.getConstructor(new Class JavaDoc[]{String JavaDoc.class, int.class});
58             socketConstructor = Socket JavaDoc.class.getConstructor(new Class JavaDoc[]{});
59             connect = Socket JavaDoc.class.getMethod("connect", new Class JavaDoc[]{inetClass.getSuperclass(),
60                                                                     int.class});
61         } catch (Exception JavaDoc e) {
62             plain = true;
63         }
64     }
65
66     /**
67      * Constructor is used only by subclasses.
68      *
69      * @param attributes
70      */

71     public DefaultSocketFactory(Hashtable JavaDoc attributes) {
72         this.attributes = attributes;
73     }
74
75     /**
76      * Creates a socket.
77      *
78      * @param host
79      * @param port
80      * @param otherHeaders
81      * @param useFullURL
82      *
83      * @return Socket
84      *
85      * @throws Exception
86      */

87     public Socket JavaDoc create(
88             String JavaDoc host, int port, StringBuffer JavaDoc otherHeaders, BooleanHolder useFullURL)
89             throws Exception JavaDoc {
90
91         int timeout = 0;
92         if (attributes != null) {
93             String JavaDoc value = (String JavaDoc)attributes.get(CONNECT_TIMEOUT);
94             timeout = (value != null) ? Integer.parseInt(value) : 0;
95         }
96
97         TransportClientProperties tcp = TransportClientPropertiesFactory.create("http");
98
99         Socket JavaDoc sock = null;
100         boolean hostInNonProxyList = isHostInNonProxyList(host, tcp.getNonProxyHosts());
101
102         if (tcp.getProxyUser().length() != 0) {
103             StringBuffer JavaDoc tmpBuf = new StringBuffer JavaDoc();
104
105             tmpBuf.append(tcp.getProxyUser())
106                   .append(":")
107                   .append(tcp.getProxyPassword());
108             otherHeaders.append(HTTPConstants.HEADER_PROXY_AUTHORIZATION)
109                         .append(": Basic ")
110                         .append(Base64.encode(tmpBuf.toString().getBytes()))
111                         .append("\r\n");
112         }
113         if (port == -1) {
114             port = 80;
115         }
116         if ((tcp.getProxyHost().length() == 0) ||
117             (tcp.getProxyPort().length() == 0) ||
118             hostInNonProxyList)
119         {
120             sock = create(host, port, timeout);
121             if (log.isDebugEnabled()) {
122                 log.debug(Messages.getMessage("createdHTTP00"));
123             }
124         } else {
125             sock = create(tcp.getProxyHost(),
126                     new Integer JavaDoc(tcp.getProxyPort()).intValue(),
127                     timeout);
128             if (log.isDebugEnabled()) {
129                 log.debug(Messages.getMessage("createdHTTP01", tcp.getProxyHost(),
130                           tcp.getProxyPort()));
131             }
132             useFullURL.value = true;
133         }
134         return sock;
135     }
136
137     /**
138      * Creates a socket with connect timeout using reflection API
139      *
140      * @param host
141      * @param port
142      * @param timeout
143      * @return
144      * @throws Exception
145      */

146     private static Socket JavaDoc create(String JavaDoc host, int port, int timeout) throws Exception JavaDoc {
147         Socket JavaDoc sock = null;
148         if (plain || timeout == 0) {
149             sock = new Socket JavaDoc(host, port);
150         } else {
151             Object JavaDoc address = inetConstructor.newInstance(new Object JavaDoc[]{host, new Integer JavaDoc(port)});
152             sock = (Socket JavaDoc)socketConstructor.newInstance(new Object JavaDoc[]{});
153             connect.invoke(sock, new Object JavaDoc[]{address, new Integer JavaDoc(timeout)});
154         }
155         return sock;
156     }
157
158     /**
159      * Check if the specified host is in the list of non proxy hosts.
160      *
161      * @param host host name
162      * @param nonProxyHosts string containing the list of non proxy hosts
163      *
164      * @return true/false
165      */

166     protected boolean isHostInNonProxyList(String JavaDoc host, String JavaDoc nonProxyHosts) {
167
168         if ((nonProxyHosts == null) || (host == null)) {
169             return false;
170         }
171
172         /*
173          * The http.nonProxyHosts system property is a list enclosed in
174          * double quotes with items separated by a vertical bar.
175          */

176         StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(nonProxyHosts, "|\"");
177
178         while (tokenizer.hasMoreTokens()) {
179             String JavaDoc pattern = tokenizer.nextToken();
180
181             if (log.isDebugEnabled()) {
182                 log.debug(Messages.getMessage("match00",
183                         new String JavaDoc[]{"HTTPSender",
184                                      host,
185                                      pattern}));
186             }
187             if (match(pattern, host, false)) {
188                 return true;
189             }
190         }
191         return false;
192     }
193
194     /**
195      * Matches a string against a pattern. The pattern contains two special
196      * characters:
197      * '*' which means zero or more characters,
198      *
199      * @param pattern the (non-null) pattern to match against
200      * @param str the (non-null) string that must be matched against the
201      * pattern
202      * @param isCaseSensitive
203      *
204      * @return <code>true</code> when the string matches against the pattern,
205      * <code>false</code> otherwise.
206      */

207     protected static boolean match(String JavaDoc pattern, String JavaDoc str,
208                                    boolean isCaseSensitive) {
209
210         char[] patArr = pattern.toCharArray();
211         char[] strArr = str.toCharArray();
212         int patIdxStart = 0;
213         int patIdxEnd = patArr.length - 1;
214         int strIdxStart = 0;
215         int strIdxEnd = strArr.length - 1;
216         char ch;
217         boolean containsStar = false;
218
219         for (int i = 0; i < patArr.length; i++) {
220             if (patArr[i] == '*') {
221                 containsStar = true;
222                 break;
223             }
224         }
225         if (!containsStar) {
226
227             // No '*'s, so we make a shortcut
228
if (patIdxEnd != strIdxEnd) {
229                 return false; // Pattern and string do not have the same size
230
}
231             for (int i = 0; i <= patIdxEnd; i++) {
232                 ch = patArr[i];
233                 if (isCaseSensitive && (ch != strArr[i])) {
234                     return false; // Character mismatch
235
}
236                 if (!isCaseSensitive
237                         && (Character.toUpperCase(ch)
238                         != Character.toUpperCase(strArr[i]))) {
239                     return false; // Character mismatch
240
}
241             }
242             return true; // String matches against pattern
243
}
244         if (patIdxEnd == 0) {
245             return true; // Pattern contains only '*', which matches anything
246
}
247
248         // Process characters before first star
249
while ((ch = patArr[patIdxStart]) != '*'
250                 && (strIdxStart <= strIdxEnd)) {
251             if (isCaseSensitive && (ch != strArr[strIdxStart])) {
252                 return false; // Character mismatch
253
}
254             if (!isCaseSensitive
255                     && (Character.toUpperCase(ch)
256                     != Character.toUpperCase(strArr[strIdxStart]))) {
257                 return false; // Character mismatch
258
}
259             patIdxStart++;
260             strIdxStart++;
261         }
262         if (strIdxStart > strIdxEnd) {
263
264             // All characters in the string are used. Check if only '*'s are
265
// left in the pattern. If so, we succeeded. Otherwise failure.
266
for (int i = patIdxStart; i <= patIdxEnd; i++) {
267                 if (patArr[i] != '*') {
268                     return false;
269                 }
270             }
271             return true;
272         }
273
274         // Process characters after last star
275
while ((ch = patArr[patIdxEnd]) != '*' && (strIdxStart <= strIdxEnd)) {
276             if (isCaseSensitive && (ch != strArr[strIdxEnd])) {
277                 return false; // Character mismatch
278
}
279             if (!isCaseSensitive
280                     && (Character.toUpperCase(ch)
281                     != Character.toUpperCase(strArr[strIdxEnd]))) {
282                 return false; // Character mismatch
283
}
284             patIdxEnd--;
285             strIdxEnd--;
286         }
287         if (strIdxStart > strIdxEnd) {
288
289             // All characters in the string are used. Check if only '*'s are
290
// left in the pattern. If so, we succeeded. Otherwise failure.
291
for (int i = patIdxStart; i <= patIdxEnd; i++) {
292                 if (patArr[i] != '*') {
293                     return false;
294                 }
295             }
296             return true;
297         }
298
299         // process pattern between stars. padIdxStart and patIdxEnd point
300
// always to a '*'.
301
while ((patIdxStart != patIdxEnd) && (strIdxStart <= strIdxEnd)) {
302             int patIdxTmp = -1;
303
304             for (int i = patIdxStart + 1; i <= patIdxEnd; i++) {
305                 if (patArr[i] == '*') {
306                     patIdxTmp = i;
307                     break;
308                 }
309             }
310             if (patIdxTmp == patIdxStart + 1) {
311
312                 // Two stars next to each other, skip the first one.
313
patIdxStart++;
314                 continue;
315             }
316
317             // Find the pattern between padIdxStart & padIdxTmp in str between
318
// strIdxStart & strIdxEnd
319
int patLength = (patIdxTmp - patIdxStart - 1);
320             int strLength = (strIdxEnd - strIdxStart + 1);
321             int foundIdx = -1;
322
323             strLoop:
324             for (int i = 0; i <= strLength - patLength; i++) {
325                 for (int j = 0; j < patLength; j++) {
326                     ch = patArr[patIdxStart + j + 1];
327                     if (isCaseSensitive
328                             && (ch != strArr[strIdxStart + i + j])) {
329                         continue strLoop;
330                     }
331                     if (!isCaseSensitive && (Character
332                             .toUpperCase(ch) != Character
333                             .toUpperCase(strArr[strIdxStart + i + j]))) {
334                         continue strLoop;
335                     }
336                 }
337                 foundIdx = strIdxStart + i;
338                 break;
339             }
340             if (foundIdx == -1) {
341                 return false;
342             }
343             patIdxStart = patIdxTmp;
344             strIdxStart = foundIdx + patLength;
345         }
346
347         // All characters in the string are used. Check if only '*'s are left
348
// in the pattern. If so, we succeeded. Otherwise failure.
349
for (int i = patIdxStart; i <= patIdxEnd; i++) {
350             if (patArr[i] != '*') {
351                 return false;
352             }
353         }
354         return true;
355     }
356 }
357
Popular Tags