001: /**
002: * Copyright (c) 2000-2008 Liferay, Inc. All rights reserved.
003: *
004: * Permission is hereby granted, free of charge, to any person obtaining a copy
005: * of this software and associated documentation files (the "Software"), to deal
006: * in the Software without restriction, including without limitation the rights
007: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
008: * copies of the Software, and to permit persons to whom the Software is
009: * furnished to do so, subject to the following conditions:
010: *
011: * The above copyright notice and this permission notice shall be included in
012: * all copies or substantial portions of the Software.
013: *
014: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
015: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
016: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
017: * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
018: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
019: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
020: * SOFTWARE.
021: */package com.liferay.util;
022:
023: import com.liferay.portal.kernel.util.ByteArrayMaker;
024: import com.liferay.portal.kernel.util.GetterUtil;
025: import com.liferay.portal.kernel.util.StringMaker;
026: import com.liferay.portal.kernel.util.StringPool;
027: import com.liferay.portal.kernel.util.StringUtil;
028: import com.liferay.portal.kernel.util.Validator;
029:
030: import java.io.IOException;
031: import java.io.InputStream;
032:
033: import java.net.URL;
034: import java.net.URLConnection;
035:
036: import java.util.ArrayList;
037: import java.util.Iterator;
038: import java.util.List;
039: import java.util.Map;
040: import java.util.StringTokenizer;
041: import java.util.regex.Pattern;
042:
043: import javax.portlet.ActionRequest;
044: import javax.portlet.RenderRequest;
045:
046: import javax.servlet.http.HttpServletRequest;
047:
048: import org.apache.commons.httpclient.Cookie;
049: import org.apache.commons.httpclient.Credentials;
050: import org.apache.commons.httpclient.Header;
051: import org.apache.commons.httpclient.HostConfiguration;
052: import org.apache.commons.httpclient.HttpClient;
053: import org.apache.commons.httpclient.HttpMethod;
054: import org.apache.commons.httpclient.HttpState;
055: import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
056: import org.apache.commons.httpclient.NTCredentials;
057: import org.apache.commons.httpclient.NameValuePair;
058: import org.apache.commons.httpclient.URI;
059: import org.apache.commons.httpclient.UsernamePasswordCredentials;
060: import org.apache.commons.httpclient.auth.AuthPolicy;
061: import org.apache.commons.httpclient.auth.AuthScope;
062: import org.apache.commons.httpclient.cookie.CookiePolicy;
063: import org.apache.commons.httpclient.methods.GetMethod;
064: import org.apache.commons.httpclient.methods.PostMethod;
065: import org.apache.commons.httpclient.params.HttpConnectionParams;
066: import org.apache.commons.logging.Log;
067: import org.apache.commons.logging.LogFactory;
068:
069: /**
070: * <a href="Http.java.html"><b><i>View Source</i></b></a>
071: *
072: * @author Brian Wing Shun Chan
073: *
074: */
075: public class Http {
076:
077: public static final String HTTP = "http";
078:
079: public static final String HTTPS = "https";
080:
081: public static final String HTTP_WITH_SLASH = "http://";
082:
083: public static final String HTTPS_WITH_SLASH = "https://";
084:
085: public static final int HTTP_PORT = 80;
086:
087: public static final int HTTPS_PORT = 443;
088:
089: public static final String LIFERAY_PROXY_HOST = GetterUtil
090: .getString(SystemProperties.get(Http.class.getName()
091: + ".proxy.host"));
092:
093: public static final int LIFERAY_PROXY_PORT = GetterUtil
094: .getInteger(SystemProperties.get(Http.class.getName()
095: + ".proxy.port"));
096:
097: private static final int MAX_CONNECTIONS_PER_HOST = GetterUtil
098: .getInteger(SystemProperties.get(Http.class.getName()
099: + ".max.connections.per.host"), 2);
100:
101: private static final int MAX_TOTAL_CONNECTIONS = GetterUtil
102: .getInteger(SystemProperties.get(Http.class.getName()
103: + ".max.total.connections"), 20);
104:
105: public static final String PROXY_HOST = GetterUtil.getString(
106: SystemProperties.get("http.proxyHost"), LIFERAY_PROXY_HOST);
107:
108: public static final int PROXY_PORT = GetterUtil.getInteger(
109: SystemProperties.get("http.proxyPort"), LIFERAY_PROXY_PORT);
110:
111: public static final String NON_PROXY_HOSTS = SystemProperties
112: .get("http.nonProxyHosts");
113:
114: public static final String PROXY_AUTH_TYPE = GetterUtil
115: .getString(SystemProperties.get(Http.class.getName()
116: + ".proxy.auth.type"));
117:
118: public static final String PROXY_USERNAME = GetterUtil
119: .getString(SystemProperties.get(Http.class.getName()
120: + ".proxy.username"));
121:
122: public static final String PROXY_PASSWORD = GetterUtil
123: .getString(SystemProperties.get(Http.class.getName()
124: + ".proxy.password"));
125:
126: public static final String PROXY_NTLM_DOMAIN = GetterUtil
127: .getString(SystemProperties.get(Http.class.getName()
128: + ".proxy.ntlm.domain"));
129:
130: public static final String PROXY_NTLM_HOST = GetterUtil
131: .getString(SystemProperties.get(Http.class.getName()
132: + ".proxy.ntlm.host"));
133:
134: public static final int TIMEOUT = GetterUtil.getInteger(
135: SystemProperties.get(Http.class.getName() + ".timeout"),
136: 5000);
137:
138: public static String addParameter(String url, String name,
139: boolean value) {
140: return addParameter(url, name, String.valueOf(value));
141: }
142:
143: public static String addParameter(String url, String name,
144: double value) {
145: return addParameter(url, name, String.valueOf(value));
146: }
147:
148: public static String addParameter(String url, String name, int value) {
149: return addParameter(url, name, String.valueOf(value));
150: }
151:
152: public static String addParameter(String url, String name,
153: long value) {
154: return addParameter(url, name, String.valueOf(value));
155: }
156:
157: public static String addParameter(String url, String name,
158: short value) {
159: return addParameter(url, name, String.valueOf(value));
160: }
161:
162: public static String addParameter(String url, String name,
163: String value) {
164: if (url == null) {
165: return null;
166: }
167:
168: if (url.indexOf(StringPool.QUESTION) == -1) {
169: url += StringPool.QUESTION;
170: }
171:
172: if (!url.endsWith(StringPool.QUESTION)
173: && !url.endsWith(StringPool.AMPERSAND)) {
174:
175: url += StringPool.AMPERSAND;
176: }
177:
178: return url + name + StringPool.EQUAL
179: + HttpUtil.encodeURL(value);
180: }
181:
182: /**
183: * @deprecated This method has been moved to
184: * <code>com.liferay.util.HttpUtil</code>.
185: */
186: public static String decodeURL(String url) {
187: return HttpUtil.decodeURL(url);
188: }
189:
190: /**
191: * @deprecated This method has been moved to
192: * <code>com.liferay.util.HttpUtil</code>.
193: */
194: public static String encodeURL(String url) {
195: return HttpUtil.encodeURL(url);
196: }
197:
198: public static HttpClient getClient(HostConfiguration hostConfig)
199: throws IOException {
200:
201: return _instance._getClient(hostConfig);
202: }
203:
204: public static String getCompleteURL(HttpServletRequest req) {
205: StringBuffer completeURL = req.getRequestURL();
206:
207: if (completeURL == null) {
208: completeURL = new StringBuffer();
209: }
210:
211: if (req.getQueryString() != null) {
212: completeURL.append(StringPool.QUESTION);
213: completeURL.append(req.getQueryString());
214: }
215:
216: return completeURL.toString();
217: }
218:
219: public static HostConfiguration getHostConfig(String location)
220: throws IOException {
221:
222: if (_log.isDebugEnabled()) {
223: _log.debug("Location is " + location);
224: }
225:
226: HostConfiguration hostConfig = new HostConfiguration();
227:
228: hostConfig.setHost(new URI(location, false));
229:
230: if (isProxyHost(hostConfig.getHost())) {
231: hostConfig.setProxy(PROXY_HOST, PROXY_PORT);
232: }
233:
234: return hostConfig;
235: }
236:
237: public static String getParameter(String url, String name) {
238: return getParameter(url, name, true);
239: }
240:
241: public static String getParameter(String url, String name,
242: boolean escaped) {
243:
244: if (Validator.isNull(url) || Validator.isNull(name)) {
245: return StringPool.BLANK;
246: }
247:
248: String[] parts = StringUtil.split(url, StringPool.QUESTION);
249:
250: if (parts.length == 2) {
251: String[] params = null;
252:
253: if (escaped) {
254: params = StringUtil.split(parts[1], "&");
255: } else {
256: params = StringUtil.split(parts[1],
257: StringPool.AMPERSAND);
258: }
259:
260: for (int i = 0; i < params.length; i++) {
261: String[] kvp = StringUtil.split(params[i],
262: StringPool.EQUAL);
263:
264: if ((kvp.length == 2) && kvp[0].equals(name)) {
265: return kvp[1];
266: }
267: }
268: }
269:
270: return StringPool.BLANK;
271: }
272:
273: /**
274: * @deprecated This method has been moved to
275: * <code>com.liferay.util.HttpUtil</code>.
276: */
277: public static Map getParameterMap(String queryString) {
278: return HttpUtil.parameterMapFromString(queryString);
279: }
280:
281: public static String getProtocol(boolean secure) {
282: if (!secure) {
283: return HTTP;
284: } else {
285: return HTTPS;
286: }
287: }
288:
289: public static String getProtocol(HttpServletRequest req) {
290: return getProtocol(req.isSecure());
291: }
292:
293: public static String getProtocol(ActionRequest req) {
294: return getProtocol(req.isSecure());
295: }
296:
297: public static String getProtocol(RenderRequest req) {
298: return getProtocol(req.isSecure());
299: }
300:
301: /**
302: * @deprecated This method has been moved to
303: * <code>com.liferay.util.HttpUtil</code>.
304: */
305: public static String getQueryString(String url) {
306: return HttpUtil.getQueryString(url);
307: }
308:
309: public static String getRequestURL(HttpServletRequest req) {
310: return req.getRequestURL().toString();
311: }
312:
313: public static boolean hasProxyConfig() {
314: if (Validator.isNotNull(PROXY_HOST) && (PROXY_PORT > 0)) {
315: return true;
316: } else {
317: return false;
318: }
319: }
320:
321: public static boolean isNonProxyHost(String host) {
322: return _instance._isNonProxyHost(host);
323: }
324:
325: public static boolean isProxyHost(String host) {
326: if (hasProxyConfig() && !isNonProxyHost(host)) {
327: return true;
328: } else {
329: return false;
330: }
331: }
332:
333: /**
334: * @deprecated This method has been moved to
335: * <code>com.liferay.util.HttpUtil</code>.
336: */
337: public static String parameterMapToString(Map parameterMap) {
338: return HttpUtil.parameterMapToString(parameterMap);
339: }
340:
341: /**
342: * @deprecated This method has been moved to
343: * <code>com.liferay.util.HttpUtil</code>.
344: */
345: public static String parameterMapToString(Map parameterMap,
346: boolean addQuestion) {
347:
348: return HttpUtil.parameterMapToString(parameterMap, addQuestion);
349: }
350:
351: public static String protocolize(String url, boolean secure) {
352: if (secure) {
353: if (url.startsWith(HTTP_WITH_SLASH)) {
354: return StringUtil.replace(url, HTTP_WITH_SLASH,
355: HTTPS_WITH_SLASH);
356: }
357: } else {
358: if (url.startsWith(HTTPS_WITH_SLASH)) {
359: return StringUtil.replace(url, HTTPS_WITH_SLASH,
360: HTTP_WITH_SLASH);
361: }
362: }
363:
364: return url;
365: }
366:
367: public static String protocolize(String url, HttpServletRequest req) {
368: return protocolize(url, req.isSecure());
369: }
370:
371: public static String protocolize(String url, ActionRequest req) {
372: return protocolize(url, req.isSecure());
373: }
374:
375: public static String protocolize(String url, RenderRequest req) {
376: return protocolize(url, req.isSecure());
377: }
378:
379: public static void proxifyState(HttpState state,
380: HostConfiguration hostConfig) {
381:
382: Credentials proxyCredentials = _instance._proxyCredentials;
383:
384: String host = hostConfig.getHost();
385:
386: if (isProxyHost(host) && (proxyCredentials != null)) {
387: AuthScope scope = new AuthScope(PROXY_HOST, PROXY_PORT,
388: null);
389:
390: state.setProxyCredentials(scope, proxyCredentials);
391: }
392: }
393:
394: public static String removeParameter(String url, String name) {
395: int pos = url.indexOf(StringPool.QUESTION);
396:
397: if (pos == -1) {
398: return url;
399: }
400:
401: StringMaker sm = new StringMaker();
402:
403: sm.append(url.substring(0, pos + 1));
404:
405: StringTokenizer st = new StringTokenizer(url.substring(pos + 1,
406: url.length()), StringPool.AMPERSAND);
407:
408: while (st.hasMoreTokens()) {
409: String token = st.nextToken();
410:
411: if (Validator.isNotNull(token)) {
412: String[] kvp = StringUtil
413: .split(token, StringPool.EQUAL);
414:
415: String key = kvp[0];
416:
417: String value = StringPool.BLANK;
418:
419: if (kvp.length > 1) {
420: value = kvp[1];
421: }
422:
423: if (!key.equals(name)) {
424: sm.append(key);
425: sm.append(StringPool.EQUAL);
426: sm.append(value);
427: sm.append(StringPool.AMPERSAND);
428: }
429: }
430: }
431:
432: url = StringUtil.replace(sm.toString(), StringPool.AMPERSAND
433: + StringPool.AMPERSAND, StringPool.AMPERSAND);
434:
435: return url;
436: }
437:
438: public static String removeProtocol(String url) {
439: if (url.startsWith(HTTP_WITH_SLASH)) {
440: return url
441: .substring(HTTP_WITH_SLASH.length(), url.length());
442: } else if (url.startsWith(HTTPS_WITH_SLASH)) {
443: return url.substring(HTTPS_WITH_SLASH.length(), url
444: .length());
445: } else {
446: return url;
447: }
448: }
449:
450: public static void submit(String location) throws IOException {
451: submit(location, null);
452: }
453:
454: public static void submit(String location, Cookie[] cookies)
455: throws IOException {
456:
457: submit(location, cookies, false);
458: }
459:
460: public static void submit(String location, boolean post)
461: throws IOException {
462:
463: submit(location, null, post);
464: }
465:
466: public static void submit(String location, Cookie[] cookies,
467: boolean post) throws IOException {
468:
469: URLtoByteArray(location, cookies, post);
470: }
471:
472: public static void submit(String location, Cookie[] cookies,
473: Map parts, boolean post) throws IOException {
474:
475: URLtoByteArray(location, cookies, parts, post);
476: }
477:
478: public static byte[] URLtoByteArray(String location)
479: throws IOException {
480:
481: return URLtoByteArray(location, null);
482: }
483:
484: public static byte[] URLtoByteArray(String location,
485: Cookie[] cookies) throws IOException {
486:
487: return URLtoByteArray(location, cookies, false);
488: }
489:
490: public static byte[] URLtoByteArray(String location, boolean post)
491: throws IOException {
492:
493: return URLtoByteArray(location, null, post);
494: }
495:
496: public static byte[] URLtoByteArray(String location,
497: Cookie[] cookies, boolean post) throws IOException {
498:
499: return URLtoByteArray(location, cookies, null, post);
500: }
501:
502: public static byte[] URLtoByteArray(String location,
503: Cookie[] cookies, Map parts, boolean post)
504: throws IOException {
505:
506: byte[] byteArray = null;
507:
508: HttpMethod method = null;
509:
510: try {
511: if (location == null) {
512: return byteArray;
513: } else if (!location.startsWith(HTTP_WITH_SLASH)
514: && !location.startsWith(HTTPS_WITH_SLASH)) {
515:
516: location = HTTP_WITH_SLASH + location;
517: }
518:
519: HostConfiguration hostConfig = getHostConfig(location);
520:
521: HttpClient client = getClient(hostConfig);
522:
523: if (post) {
524: method = new PostMethod(location);
525:
526: if ((parts != null) && (parts.size() > 0)) {
527: List nvpList = new ArrayList();
528:
529: Iterator itr = parts.entrySet().iterator();
530:
531: while (itr.hasNext()) {
532: Map.Entry entry = (Map.Entry) itr.next();
533:
534: String key = (String) entry.getKey();
535: String value = (String) entry.getValue();
536:
537: if (value != null) {
538: nvpList.add(new NameValuePair(key, value));
539: }
540: }
541:
542: NameValuePair[] nvpArray = (NameValuePair[]) nvpList
543: .toArray(new NameValuePair[nvpList.size()]);
544:
545: PostMethod postMethod = (PostMethod) method;
546:
547: postMethod.setRequestBody(nvpArray);
548: }
549: } else {
550: method = new GetMethod(location);
551: }
552:
553: method.addRequestHeader("Content-Type",
554: "application/x-www-form-urlencoded");
555:
556: method
557: .addRequestHeader("User-agent",
558: "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)");
559:
560: //method.setFollowRedirects(true);
561:
562: HttpState state = new HttpState();
563:
564: if ((cookies != null) && (cookies.length > 0)) {
565: state.addCookies(cookies);
566:
567: method.getParams().setCookiePolicy(
568: CookiePolicy.BROWSER_COMPATIBILITY);
569: }
570:
571: proxifyState(state, hostConfig);
572:
573: client.executeMethod(hostConfig, method, state);
574:
575: Header locationHeader = method
576: .getResponseHeader("location");
577:
578: if (locationHeader != null) {
579: return URLtoByteArray(locationHeader.getValue(),
580: cookies, post);
581: }
582:
583: InputStream is = method.getResponseBodyAsStream();
584:
585: if (is != null) {
586: ByteArrayMaker bam = new ByteArrayMaker();
587: byte[] bytes = new byte[512];
588:
589: for (int i = is.read(bytes, 0, 512); i != -1; i = is
590: .read(bytes, 0, 512)) {
591:
592: bam.write(bytes, 0, i);
593: }
594:
595: byteArray = bam.toByteArray();
596:
597: is.close();
598: bam.close();
599: }
600:
601: return byteArray;
602: } finally {
603: try {
604: if (method != null) {
605: method.releaseConnection();
606: }
607: } catch (Exception e) {
608: _log.error(e, e);
609: }
610: }
611: }
612:
613: public static String URLtoString(String location)
614: throws IOException {
615:
616: return URLtoString(location, null);
617: }
618:
619: public static String URLtoString(String location, Cookie[] cookies)
620: throws IOException {
621:
622: return URLtoString(location, cookies, false);
623: }
624:
625: public static String URLtoString(String location, boolean post)
626: throws IOException {
627:
628: return URLtoString(location, null, post);
629: }
630:
631: public static String URLtoString(String location, Cookie[] cookies,
632: boolean post) throws IOException {
633:
634: return new String(URLtoByteArray(location, cookies, post));
635: }
636:
637: public static String URLtoString(String location, Cookie[] cookies,
638: Map parts, boolean post) throws IOException {
639:
640: return new String(
641: URLtoByteArray(location, cookies, parts, post));
642: }
643:
644: /**
645: * This method only uses the default Commons HttpClient implementation when
646: * the URL object represents a HTTP resource. The URL object could also
647: * represent a file or some JNDI resource. In that case, the default Java
648: * implementation is used.
649: *
650: * @param url URL object
651: * @return A string representation of the resource referenced by the
652: * URL object
653: * @throws IOException
654: */
655: public static String URLtoString(URL url) throws IOException {
656: String xml = null;
657:
658: if (url != null) {
659: String protocol = url.getProtocol().toLowerCase();
660:
661: if (protocol.startsWith(HTTP) || protocol.startsWith(HTTPS)) {
662: return URLtoString(url.toString());
663: }
664:
665: URLConnection con = url.openConnection();
666:
667: InputStream is = con.getInputStream();
668:
669: ByteArrayMaker bam = new ByteArrayMaker();
670: byte[] bytes = new byte[512];
671:
672: for (int i = is.read(bytes, 0, 512); i != -1; i = is.read(
673: bytes, 0, 512)) {
674:
675: bam.write(bytes, 0, i);
676: }
677:
678: xml = new String(bam.toByteArray());
679:
680: is.close();
681: bam.close();
682: }
683:
684: return xml;
685: }
686:
687: private Http() {
688:
689: // Mimic behavior found in
690: // http://java.sun.com/j2se/1.5.0/docs/guide/net/properties.html
691:
692: if (Validator.isNotNull(NON_PROXY_HOSTS)) {
693: String nonProxyHostsRegEx = NON_PROXY_HOSTS;
694:
695: nonProxyHostsRegEx = nonProxyHostsRegEx.replaceAll("\\.",
696: "\\\\.");
697: nonProxyHostsRegEx = nonProxyHostsRegEx.replaceAll("\\*",
698: ".*?");
699: nonProxyHostsRegEx = nonProxyHostsRegEx.replaceAll("\\|",
700: ")|(");
701:
702: nonProxyHostsRegEx = "(" + nonProxyHostsRegEx + ")";
703:
704: _nonProxyHostsPattern = Pattern.compile(nonProxyHostsRegEx);
705: }
706:
707: MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
708:
709: HttpConnectionParams params = connectionManager.getParams();
710:
711: params.setParameter("maxConnectionsPerHost", new Integer(
712: MAX_CONNECTIONS_PER_HOST));
713: params.setParameter("maxTotalConnections", new Integer(
714: MAX_TOTAL_CONNECTIONS));
715: params.setConnectionTimeout(TIMEOUT);
716: params.setSoTimeout(TIMEOUT);
717:
718: _client.setHttpConnectionManager(connectionManager);
719: _proxyClient.setHttpConnectionManager(connectionManager);
720:
721: if (hasProxyConfig() && Validator.isNotNull(PROXY_USERNAME)) {
722: if (PROXY_AUTH_TYPE.equals("username-password")) {
723: _proxyCredentials = new UsernamePasswordCredentials(
724: PROXY_USERNAME, PROXY_PASSWORD);
725: } else if (PROXY_AUTH_TYPE.equals("ntlm")) {
726: _proxyCredentials = new NTCredentials(PROXY_USERNAME,
727: PROXY_PASSWORD, PROXY_NTLM_HOST,
728: PROXY_NTLM_DOMAIN);
729:
730: List authPrefs = new ArrayList();
731:
732: authPrefs.add(AuthPolicy.NTLM);
733: authPrefs.add(AuthPolicy.BASIC);
734: authPrefs.add(AuthPolicy.DIGEST);
735:
736: _proxyClient.getParams().setParameter(
737: AuthPolicy.AUTH_SCHEME_PRIORITY, authPrefs);
738: }
739: }
740: }
741:
742: private HttpClient _getClient(HostConfiguration hostConfig)
743: throws IOException {
744:
745: if (isProxyHost(hostConfig.getHost())) {
746: return _proxyClient;
747: } else {
748: return _client;
749: }
750: }
751:
752: private boolean _isNonProxyHost(String host) {
753: if (_nonProxyHostsPattern == null
754: || _nonProxyHostsPattern.matcher(host).matches()) {
755:
756: return true;
757: } else {
758: return false;
759: }
760: }
761:
762: private static Log _log = LogFactory.getLog(Http.class);
763:
764: private static Http _instance = new Http();
765:
766: private HttpClient _client = new HttpClient();
767: private HttpClient _proxyClient = new HttpClient();
768: private Credentials _proxyCredentials;
769: private Pattern _nonProxyHostsPattern;
770:
771: }
|