001    /**
002     * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.util;
016    
017    import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayOutputStream;
018    import com.liferay.portal.kernel.log.Log;
019    import com.liferay.portal.kernel.log.LogFactoryUtil;
020    import com.liferay.portal.kernel.servlet.HttpHeaders;
021    import com.liferay.portal.kernel.util.ContentTypes;
022    import com.liferay.portal.kernel.util.FileUtil;
023    import com.liferay.portal.kernel.util.GetterUtil;
024    import com.liferay.portal.kernel.util.Http;
025    import com.liferay.portal.kernel.util.StringBundler;
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    import com.liferay.util.SystemProperties;
030    
031    import java.io.IOException;
032    import java.io.InputStream;
033    import java.io.UnsupportedEncodingException;
034    
035    import java.net.InetAddress;
036    import java.net.URL;
037    import java.net.URLConnection;
038    import java.net.URLDecoder;
039    import java.net.URLEncoder;
040    
041    import java.util.ArrayList;
042    import java.util.Date;
043    import java.util.LinkedHashMap;
044    import java.util.List;
045    import java.util.Map;
046    import java.util.StringTokenizer;
047    import java.util.regex.Pattern;
048    
049    import javax.portlet.ActionRequest;
050    import javax.portlet.RenderRequest;
051    
052    import javax.servlet.http.Cookie;
053    import javax.servlet.http.HttpServletRequest;
054    
055    import org.apache.commons.httpclient.Credentials;
056    import org.apache.commons.httpclient.Header;
057    import org.apache.commons.httpclient.HostConfiguration;
058    import org.apache.commons.httpclient.HttpClient;
059    import org.apache.commons.httpclient.HttpMethod;
060    import org.apache.commons.httpclient.HttpState;
061    import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
062    import org.apache.commons.httpclient.NTCredentials;
063    import org.apache.commons.httpclient.NameValuePair;
064    import org.apache.commons.httpclient.URI;
065    import org.apache.commons.httpclient.UsernamePasswordCredentials;
066    import org.apache.commons.httpclient.auth.AuthPolicy;
067    import org.apache.commons.httpclient.auth.AuthScope;
068    import org.apache.commons.httpclient.cookie.CookiePolicy;
069    import org.apache.commons.httpclient.methods.DeleteMethod;
070    import org.apache.commons.httpclient.methods.EntityEnclosingMethod;
071    import org.apache.commons.httpclient.methods.GetMethod;
072    import org.apache.commons.httpclient.methods.HeadMethod;
073    import org.apache.commons.httpclient.methods.PostMethod;
074    import org.apache.commons.httpclient.methods.PutMethod;
075    import org.apache.commons.httpclient.methods.RequestEntity;
076    import org.apache.commons.httpclient.methods.StringRequestEntity;
077    import org.apache.commons.httpclient.params.HttpClientParams;
078    import org.apache.commons.httpclient.params.HttpConnectionParams;
079    
080    /**
081     * @author Brian Wing Shun Chan
082     */
083    public class HttpImpl implements Http {
084    
085            public HttpImpl() {
086    
087                    // Mimic behavior found in
088                    // http://java.sun.com/j2se/1.5.0/docs/guide/net/properties.html
089    
090                    if (Validator.isNotNull(_NON_PROXY_HOSTS)) {
091                            String nonProxyHostsRegEx = _NON_PROXY_HOSTS;
092    
093                            nonProxyHostsRegEx = nonProxyHostsRegEx.replaceAll(
094                                    "\\.", "\\\\.");
095                            nonProxyHostsRegEx = nonProxyHostsRegEx.replaceAll(
096                                    "\\*", ".*?");
097                            nonProxyHostsRegEx = nonProxyHostsRegEx.replaceAll(
098                                    "\\|", ")|(");
099    
100                            nonProxyHostsRegEx = "(" + nonProxyHostsRegEx + ")";
101    
102                            _nonProxyHostsPattern = Pattern.compile(nonProxyHostsRegEx);
103                    }
104    
105                    MultiThreadedHttpConnectionManager httpConnectionManager =
106                            new MultiThreadedHttpConnectionManager();
107    
108                    HttpConnectionParams params = httpConnectionManager.getParams();
109    
110                    params.setParameter(
111                            "maxConnectionsPerHost", new Integer(_MAX_CONNECTIONS_PER_HOST));
112                    params.setParameter(
113                            "maxTotalConnections", new Integer(_MAX_TOTAL_CONNECTIONS));
114                    params.setConnectionTimeout(_TIMEOUT);
115                    params.setSoTimeout(_TIMEOUT);
116    
117                    _client.setHttpConnectionManager(httpConnectionManager);
118                    _proxyClient.setHttpConnectionManager(httpConnectionManager);
119    
120                    if (hasProxyConfig() && Validator.isNotNull(_PROXY_USERNAME)) {
121                            if (_PROXY_AUTH_TYPE.equals("username-password")) {
122                                    _proxyCredentials = new UsernamePasswordCredentials(
123                                            _PROXY_USERNAME, _PROXY_PASSWORD);
124                            }
125                            else if (_PROXY_AUTH_TYPE.equals("ntlm")) {
126                                    _proxyCredentials = new NTCredentials(
127                                            _PROXY_USERNAME, _PROXY_PASSWORD, _PROXY_NTLM_HOST,
128                                            _PROXY_NTLM_DOMAIN);
129    
130                                    List<String> authPrefs = new ArrayList<String>();
131    
132                                    authPrefs.add(AuthPolicy.NTLM);
133                                    authPrefs.add(AuthPolicy.BASIC);
134                                    authPrefs.add(AuthPolicy.DIGEST);
135    
136                                    _proxyClient.getParams().setParameter(
137                                            AuthPolicy.AUTH_SCHEME_PRIORITY, authPrefs);
138                            }
139                    }
140            }
141    
142            public String addParameter(String url, String name, boolean value) {
143                    return addParameter(url, name, String.valueOf(value));
144            }
145    
146            public String addParameter(String url, String name, double value) {
147                    return addParameter(url, name, String.valueOf(value));
148            }
149    
150            public String addParameter(String url, String name, int value) {
151                    return addParameter(url, name, String.valueOf(value));
152            }
153    
154            public String addParameter(String url, String name, long value) {
155                    return addParameter(url, name, String.valueOf(value));
156            }
157    
158            public String addParameter(String url, String name, short value) {
159                    return addParameter(url, name, String.valueOf(value));
160            }
161    
162            public String addParameter(String url, String name, String value) {
163                    if (url == null) {
164                            return null;
165                    }
166    
167                    String anchor = StringPool.BLANK;
168    
169                    int pos = url.indexOf(StringPool.POUND);
170    
171                    if (pos != -1) {
172                            anchor = url.substring(pos);
173                            url = url.substring(0, pos);
174                    }
175    
176                    if (url.indexOf(StringPool.QUESTION) == -1) {
177                            url += StringPool.QUESTION;
178                    }
179    
180                    if (!url.endsWith(StringPool.QUESTION) &&
181                            !url.endsWith(StringPool.AMPERSAND)) {
182    
183                            url += StringPool.AMPERSAND;
184                    }
185    
186                    return url + name + StringPool.EQUAL + encodeURL(value) + anchor;
187            }
188    
189            public String decodePath(String path) {
190                    path =  StringUtil.replace(path, StringPool.SLASH, _TEMP_SLASH);
191                    path = decodeURL(path, true);
192                    path =  StringUtil.replace(path, _TEMP_SLASH, StringPool.SLASH);
193    
194                    return path;
195            }
196    
197            public String decodeURL(String url) {
198                    return decodeURL(url, false);
199            }
200    
201            public String decodeURL(String url, boolean unescapeSpace) {
202                    if (url == null) {
203                            return null;
204                    }
205    
206                    if (url.length() == 0) {
207                            return StringPool.BLANK;
208                    }
209    
210                    try {
211                            url = URLDecoder.decode(url, StringPool.UTF8);
212    
213                            if (unescapeSpace) {
214                                    url = StringUtil.replace(url, "%20", StringPool.PLUS);
215                            }
216    
217                            return url;
218                    }
219                    catch (UnsupportedEncodingException uee) {
220                            _log.error(uee, uee);
221    
222                            return StringPool.BLANK;
223                    }
224            }
225    
226            public void destroy() {
227                    MultiThreadedHttpConnectionManager.shutdownAll();
228            }
229    
230            public String encodePath(String path) {
231                    path = StringUtil.replace(path, StringPool.SLASH, _TEMP_SLASH);
232                    path = encodeURL(path, true);
233                    path = StringUtil.replace(path, _TEMP_SLASH, StringPool.SLASH);
234    
235                    return path;
236            }
237    
238            public String encodeURL(String url) {
239                    return encodeURL(url, false);
240            }
241    
242            public String encodeURL(String url, boolean escapeSpaces) {
243                    if (url == null) {
244                            return null;
245                    }
246    
247                    if (url.length() == 0) {
248                            return StringPool.BLANK;
249                    }
250    
251                    try {
252                            url = URLEncoder.encode(url, StringPool.UTF8);
253    
254                            if (escapeSpaces) {
255                                    url = StringUtil.replace(url, StringPool.PLUS, "%20");
256                            }
257    
258                            return url;
259                    }
260                    catch (UnsupportedEncodingException uee) {
261                            _log.error(uee, uee);
262    
263                            return StringPool.BLANK;
264                    }
265            }
266    
267            public String fixPath(String path) {
268                    return fixPath(path, true, true);
269            }
270    
271            public String fixPath(String path, boolean leading, boolean trailing) {
272                    if (path == null) {
273                            return StringPool.BLANK;
274                    }
275    
276                    if (leading) {
277                            path = path.replaceAll("^/+", StringPool.BLANK);
278                    }
279    
280                    if (trailing) {
281                            path = path.replaceAll("/+$", StringPool.BLANK);
282                    }
283    
284                    return path;
285            }
286    
287            public HttpClient getClient(HostConfiguration hostConfig) {
288                    if (isProxyHost(hostConfig.getHost())) {
289                            return _proxyClient;
290                    }
291                    else {
292                            return _client;
293                    }
294            }
295    
296            public String getCompleteURL(HttpServletRequest request) {
297                    StringBuffer sb = request.getRequestURL();
298    
299                    if (sb == null) {
300                            sb = new StringBuffer();
301                    }
302    
303                    if (request.getQueryString() != null) {
304                            sb.append(StringPool.QUESTION);
305                            sb.append(request.getQueryString());
306                    }
307    
308                    String completeURL = sb.toString();
309    
310                    if (_log.isWarnEnabled()) {
311                            if (completeURL.contains("?&")) {
312                                    _log.warn("Invalid url " + completeURL);
313                            }
314                    }
315    
316                    return completeURL;
317            }
318    
319            public Cookie[] getCookies() {
320                    return _cookies.get();
321            }
322    
323            public String getDomain(String url) {
324                    url = removeProtocol(url);
325    
326                    int pos = url.indexOf(StringPool.SLASH);
327    
328                    if (pos != -1) {
329                            return url.substring(0, pos);
330                    }
331                    else {
332                            return url;
333                    }
334            }
335    
336            public HostConfiguration getHostConfig(String location) throws IOException {
337                    if (_log.isDebugEnabled()) {
338                            _log.debug("Location is " + location);
339                    }
340    
341                    HostConfiguration hostConfig = new HostConfiguration();
342    
343                    hostConfig.setHost(new URI(location, false));
344    
345                    if (isProxyHost(hostConfig.getHost())) {
346                            hostConfig.setProxy(_PROXY_HOST, _PROXY_PORT);
347                    }
348    
349                    return hostConfig;
350            }
351    
352            public String getIpAddress(String url) {
353                    try {
354                            URL urlObj = new URL(url);
355    
356                            InetAddress address = InetAddress.getByName(urlObj.getHost());
357    
358                            return address.getHostAddress();
359                    }
360                    catch (Exception e) {
361                            return url;
362                    }
363            }
364    
365            public String getParameter(String url, String name) {
366                    return getParameter(url, name, true);
367            }
368    
369            public String getParameter(String url, String name, boolean escaped) {
370                    if (Validator.isNull(url) || Validator.isNull(name)) {
371                            return StringPool.BLANK;
372                    }
373    
374                    String[] parts = StringUtil.split(url, StringPool.QUESTION);
375    
376                    if (parts.length == 2) {
377                            String[] params = null;
378    
379                            if (escaped) {
380                                    params = StringUtil.split(parts[1], "&amp;");
381                            }
382                            else {
383                                    params = StringUtil.split(parts[1], StringPool.AMPERSAND);
384                            }
385    
386                            for (int i = 0; i < params.length; i++) {
387                                    String[] kvp = StringUtil.split(params[i], StringPool.EQUAL);
388    
389                                    if ((kvp.length == 2) && kvp[0].equals(name)) {
390                                            return kvp[1];
391                                    }
392                            }
393                    }
394    
395                    return StringPool.BLANK;
396            }
397    
398            public Map<String, String[]> getParameterMap(String queryString) {
399                    return parameterMapFromString(queryString);
400            }
401    
402            public String getProtocol(ActionRequest actionRequest) {
403                    return getProtocol(actionRequest.isSecure());
404            }
405    
406            public String getProtocol(boolean secure) {
407                    if (!secure) {
408                            return Http.HTTP;
409                    }
410                    else {
411                            return Http.HTTPS;
412                    }
413            }
414    
415            public String getProtocol(HttpServletRequest request) {
416                    return getProtocol(request.isSecure());
417            }
418    
419            public String getProtocol(RenderRequest renderRequest) {
420                    return getProtocol(renderRequest.isSecure());
421            }
422    
423            public String getProtocol(String url) {
424                    int pos = url.indexOf(Http.PROTOCOL_DELIMITER);
425    
426                    if (pos != -1) {
427                            return url.substring(0, pos);
428                    }
429                    else {
430                            return Http.HTTP;
431                    }
432            }
433    
434            public String getQueryString(String url) {
435                    if (Validator.isNull(url)) {
436                            return url;
437                    }
438    
439                    int pos = url.indexOf(StringPool.QUESTION);
440    
441                    if (pos == -1) {
442                            return StringPool.BLANK;
443                    }
444                    else {
445                            return url.substring(pos + 1, url.length());
446                    }
447            }
448    
449            public String getRequestURL(HttpServletRequest request) {
450                    return request.getRequestURL().toString();
451            }
452    
453            public boolean hasDomain(String url) {
454                    return Validator.isNotNull(getDomain(url));
455            }
456    
457            public boolean hasProtocol(String url) {
458                    int pos = url.indexOf(Http.PROTOCOL_DELIMITER);
459    
460                    if (pos != -1) {
461                            return true;
462                    }
463                    else {
464                            return false;
465                    }
466            }
467    
468            public boolean hasProxyConfig() {
469                    if (Validator.isNotNull(_PROXY_HOST) && (_PROXY_PORT > 0)) {
470                            return true;
471                    }
472                    else {
473                            return false;
474                    }
475            }
476    
477            public boolean isNonProxyHost(String host) {
478                    if (_nonProxyHostsPattern == null ||
479                            _nonProxyHostsPattern.matcher(host).matches()) {
480    
481                            return true;
482                    }
483                    else {
484                            return false;
485                    }
486            }
487    
488            public boolean isProxyHost(String host) {
489                    if (hasProxyConfig() && !isNonProxyHost(host)) {
490                            return true;
491                    }
492                    else {
493                            return false;
494                    }
495            }
496    
497            public Map<String, String[]> parameterMapFromString(String queryString) {
498                    Map<String, String[]> parameterMap =
499                            new LinkedHashMap<String, String[]>();
500    
501                    if (Validator.isNull(queryString)) {
502                            return parameterMap;
503                    }
504    
505                    Map<String, List<String>> tempParameterMap =
506                            new LinkedHashMap<String, List<String>>();
507    
508                    StringTokenizer st = new StringTokenizer(
509                            queryString, StringPool.AMPERSAND);
510    
511                    while (st.hasMoreTokens()) {
512                            String token = st.nextToken();
513    
514                            if (Validator.isNotNull(token)) {
515                                    String[] kvp = StringUtil.split(token, StringPool.EQUAL);
516    
517                                    String key = kvp[0];
518    
519                                    String value = StringPool.BLANK;
520    
521                                    if (kvp.length > 1) {
522                                            value = kvp[1];
523                                    }
524    
525                                    List<String> values = tempParameterMap.get(key);
526    
527                                    if (values == null) {
528                                            values = new ArrayList<String>();
529    
530                                            tempParameterMap.put(key, values);
531                                    }
532    
533                                    values.add(value);
534                            }
535                    }
536    
537                    for (Map.Entry<String, List<String>> entry :
538                                    tempParameterMap.entrySet()) {
539    
540                            String key = entry.getKey();
541                            List<String> values = entry.getValue();
542    
543                            parameterMap.put(key, values.toArray(new String[values.size()]));
544                    }
545    
546                    return parameterMap;
547            }
548    
549            public String parameterMapToString(Map<String, String[]> parameterMap) {
550                    return parameterMapToString(parameterMap, true);
551            }
552    
553            public String parameterMapToString(
554                    Map<String, String[]> parameterMap, boolean addQuestion) {
555    
556                    StringBundler sb = new StringBundler();
557    
558                    if (parameterMap.size() > 0) {
559                            if (addQuestion) {
560                                    sb.append(StringPool.QUESTION);
561                            }
562    
563                            for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
564                                    String name = entry.getKey();
565                                    String[] values = entry.getValue();
566    
567                                    for (String value : values) {
568                                            sb.append(name);
569                                            sb.append(StringPool.EQUAL);
570                                            sb.append(encodeURL(value));
571                                            sb.append(StringPool.AMPERSAND);
572                                    }
573                            }
574    
575                            if (sb.index() > 1) {
576                                    sb.setIndex(sb.index() - 1);
577                            }
578                    }
579    
580                    return sb.toString();
581            }
582    
583            public String protocolize(String url, ActionRequest actionRequest) {
584                    return protocolize(url, actionRequest.isSecure());
585            }
586    
587            public String protocolize(String url, boolean secure) {
588                    if (secure) {
589                            if (url.startsWith(Http.HTTP_WITH_SLASH)) {
590                                    return StringUtil.replace(
591                                            url, Http.HTTP_WITH_SLASH, Http.HTTPS_WITH_SLASH);
592                            }
593                    }
594                    else {
595                            if (url.startsWith(Http.HTTPS_WITH_SLASH)) {
596                                    return StringUtil.replace(
597                                            url, Http.HTTPS_WITH_SLASH, Http.HTTP_WITH_SLASH);
598                            }
599                    }
600    
601                    return url;
602            }
603    
604            public String protocolize(String url, HttpServletRequest request) {
605                    return protocolize(url, request.isSecure());
606            }
607    
608            public String protocolize(String url, RenderRequest renderRequest) {
609                    return protocolize(url, renderRequest.isSecure());
610            }
611    
612            public String removeDomain(String url) {
613                    url = removeProtocol(url);
614    
615                    int pos = url.indexOf(StringPool.SLASH);
616    
617                    if (pos > 0) {
618                            return url.substring(pos);
619                    }
620                    else {
621                            return url;
622                    }
623            }
624    
625            public String removeParameter(String url, String name) {
626                    int pos = url.indexOf(StringPool.QUESTION);
627    
628                    if (pos == -1) {
629                            return url;
630                    }
631    
632                    String anchor = StringPool.BLANK;
633    
634                    int anchorPos = url.indexOf(StringPool.POUND);
635    
636                    if (anchorPos != -1) {
637                            anchor = url.substring(anchorPos);
638                            url = url.substring(0, anchorPos);
639                    }
640    
641                    StringBundler sb = new StringBundler();
642    
643                    sb.append(url.substring(0, pos + 1));
644    
645                    StringTokenizer st = new StringTokenizer(
646                            url.substring(pos + 1, url.length()), StringPool.AMPERSAND);
647    
648                    while (st.hasMoreTokens()) {
649                            String token = st.nextToken();
650    
651                            if (Validator.isNotNull(token)) {
652                                    String[] kvp = StringUtil.split(token, StringPool.EQUAL);
653    
654                                    String key = kvp[0];
655    
656                                    String value = StringPool.BLANK;
657    
658                                    if (kvp.length > 1) {
659                                            value = kvp[1];
660                                    }
661    
662                                    if (!key.equals(name)) {
663                                            sb.append(key);
664                                            sb.append(StringPool.EQUAL);
665                                            sb.append(value);
666                                            sb.append(StringPool.AMPERSAND);
667                                    }
668                            }
669                    }
670    
671                    url = StringUtil.replace(
672                            sb.toString(), StringPool.AMPERSAND + StringPool.AMPERSAND,
673                            StringPool.AMPERSAND);
674    
675                    if (url.endsWith(StringPool.AMPERSAND)) {
676                            url = url.substring(0, url.length() - 1);
677                    }
678    
679                    if (url.endsWith(StringPool.QUESTION)) {
680                            url = url.substring(0, url.length() - 1);
681                    }
682    
683                    return url + anchor;
684            }
685    
686            public String removeProtocol(String url) {
687                    if (url.startsWith(Http.HTTP_WITH_SLASH)) {
688                            return url.substring(Http.HTTP_WITH_SLASH.length() , url.length());
689                    }
690                    else if (url.startsWith(Http.HTTPS_WITH_SLASH)) {
691                            return url.substring(Http.HTTPS_WITH_SLASH.length() , url.length());
692                    }
693                    else {
694                            return url;
695                    }
696            }
697    
698            public String setParameter(String url, String name, boolean value) {
699                    return setParameter(url, name, String.valueOf(value));
700            }
701    
702            public String setParameter(String url, String name, double value) {
703                    return setParameter(url, name, String.valueOf(value));
704            }
705    
706            public String setParameter(String url, String name, int value) {
707                    return setParameter(url, name, String.valueOf(value));
708            }
709    
710            public String setParameter(String url, String name, long value) {
711                    return setParameter(url, name, String.valueOf(value));
712            }
713    
714            public String setParameter(String url, String name, short value) {
715                    return setParameter(url, name, String.valueOf(value));
716            }
717    
718            public String setParameter(String url, String name, String value) {
719                    if (url == null) {
720                            return null;
721                    }
722    
723                    url = removeParameter(url, name);
724    
725                    return addParameter(url, name, value);
726            }
727    
728            public byte[] URLtoByteArray(Http.Options options) throws IOException {
729                    return URLtoByteArray(
730                            options.getLocation(), options.getMethod(), options.getHeaders(),
731                            options.getCookies(), options.getAuth(), options.getBody(),
732                            options.getParts(), options.getResponse(),
733                            options.isFollowRedirects());
734            }
735    
736            public byte[] URLtoByteArray(String location) throws IOException {
737                    Http.Options options = new Http.Options();
738    
739                    options.setLocation(location);
740    
741                    return URLtoByteArray(options);
742            }
743    
744            public byte[] URLtoByteArray(String location, boolean post)
745                    throws IOException {
746    
747                    Http.Options options = new Http.Options();
748    
749                    options.setLocation(location);
750                    options.setPost(post);
751    
752                    return URLtoByteArray(options);
753            }
754    
755            public String URLtoString(Http.Options options) throws IOException {
756                    return new String(URLtoByteArray(options));
757            }
758    
759            public String URLtoString(String location) throws IOException {
760                    return new String(URLtoByteArray(location));
761            }
762    
763            public String URLtoString(String location, boolean post)
764                    throws IOException {
765    
766                    return new String(URLtoByteArray(location, post));
767            }
768    
769            /**
770             * This method only uses the default Commons HttpClient implementation when
771             * the URL object represents a HTTP resource. The URL object could also
772             * represent a file or some JNDI resource. In that case, the default Java
773             * implementation is used.
774             *
775             * @return A string representation of the resource referenced by the URL
776             *                 object
777             */
778            public String URLtoString(URL url) throws IOException {
779                    String xml = null;
780    
781                    if (url != null) {
782                            String protocol = url.getProtocol().toLowerCase();
783    
784                            if (protocol.startsWith(Http.HTTP) ||
785                                    protocol.startsWith(Http.HTTPS)) {
786    
787                                    return URLtoString(url.toString());
788                            }
789    
790                            URLConnection con = url.openConnection();
791    
792                            InputStream is = con.getInputStream();
793    
794                            UnsyncByteArrayOutputStream ubaos =
795                                    new UnsyncByteArrayOutputStream();
796                            byte[] bytes = new byte[512];
797    
798                            for (int i = is.read(bytes, 0, 512); i != -1;
799                                            i = is.read(bytes, 0, 512)) {
800    
801                                    ubaos.write(bytes, 0, i);
802                            }
803    
804                            xml = new String(ubaos.unsafeGetByteArray(), 0, ubaos.size());
805    
806                            is.close();
807                            ubaos.close();
808                    }
809    
810                    return xml;
811            }
812    
813            protected void proxifyState(HttpState state, HostConfiguration hostConfig) {
814                    Credentials proxyCredentials = _proxyCredentials;
815    
816                    String host = hostConfig.getHost();
817    
818                    if (isProxyHost(host) && (proxyCredentials != null)) {
819                            AuthScope scope = new AuthScope(_PROXY_HOST, _PROXY_PORT, null);
820    
821                            state.setProxyCredentials(scope, proxyCredentials);
822                    }
823            }
824    
825            protected org.apache.commons.httpclient.Cookie toCommonsCookie(
826                    Cookie cookie) {
827    
828                    org.apache.commons.httpclient.Cookie commonsCookie =
829                            new org.apache.commons.httpclient.Cookie(
830                            cookie.getDomain(), cookie.getName(), cookie.getValue(),
831                            cookie.getPath(), cookie.getMaxAge(), cookie.getSecure());
832    
833                    commonsCookie.setVersion(cookie.getVersion());
834    
835                    return commonsCookie;
836            }
837    
838            protected org.apache.commons.httpclient.Cookie[] toCommonsCookies(
839                    Cookie[] cookies) {
840    
841                    if (cookies == null) {
842                            return null;
843                    }
844    
845                    org.apache.commons.httpclient.Cookie[] commonCookies =
846                            new org.apache.commons.httpclient.Cookie[cookies.length];
847    
848                    for (int i = 0; i < cookies.length; i++) {
849                            commonCookies[i] = toCommonsCookie(cookies[i]);
850                    }
851    
852                    return commonCookies;
853            }
854    
855            protected Cookie toServletCookie(
856                    org.apache.commons.httpclient.Cookie commonsCookie) {
857    
858                    Cookie cookie = new Cookie(
859                            commonsCookie.getName(), commonsCookie.getValue());
860    
861                    cookie.setDomain(commonsCookie.getDomain());
862    
863                    Date expiryDate = commonsCookie.getExpiryDate();
864    
865                    if (expiryDate != null) {
866                            int maxAge =
867                                    (int)(expiryDate.getTime() - System.currentTimeMillis());
868    
869                            maxAge = maxAge / 1000;
870    
871                            if (maxAge > -1) {
872                                    cookie.setMaxAge(maxAge);
873                            }
874                    }
875    
876                    cookie.setPath(commonsCookie.getPath());
877                    cookie.setSecure(commonsCookie.getSecure());
878                    cookie.setVersion(commonsCookie.getVersion());
879    
880                    return cookie;
881            }
882    
883            protected Cookie[] toServletCookies(
884                    org.apache.commons.httpclient.Cookie[] commonsCookies) {
885    
886                    if (commonsCookies == null) {
887                            return null;
888                    }
889    
890                    Cookie[] cookies = new Cookie[commonsCookies.length];
891    
892                    for (int i = 0; i < commonsCookies.length; i++) {
893                            cookies[i] = toServletCookie(commonsCookies[i]);
894                    }
895    
896                    return cookies;
897            }
898    
899            protected byte[] URLtoByteArray(
900                            String location, Http.Method method, Map<String, String> headers,
901                            Cookie[] cookies, Http.Auth auth, Http.Body body, Map<String,
902                            String> parts, Http.Response response, boolean followRedirects)
903                    throws IOException {
904    
905                    byte[] bytes = null;
906    
907                    HttpMethod httpMethod = null;
908                    HttpState httpState = null;
909    
910                    try {
911                            _cookies.set(null);
912    
913                            if (location == null) {
914                                    return bytes;
915                            }
916                            else if (!location.startsWith(Http.HTTP_WITH_SLASH) &&
917                                             !location.startsWith(Http.HTTPS_WITH_SLASH)) {
918    
919                                    location = Http.HTTP_WITH_SLASH + location;
920                            }
921    
922                            HostConfiguration hostConfig = getHostConfig(location);
923    
924                            HttpClient httpClient = getClient(hostConfig);
925    
926                            if ((method == Http.Method.POST) ||
927                                    (method == Http.Method.PUT)) {
928    
929                                    if (method == Http.Method.POST) {
930                                            httpMethod = new PostMethod(location);
931                                    }
932                                    else {
933                                            httpMethod = new PutMethod(location);
934                                    }
935    
936                                    if (body != null) {
937                                            RequestEntity requestEntity = new StringRequestEntity(
938                                                    body.getContent(), body.getContentType(),
939                                                    body.getCharset());
940    
941                                            EntityEnclosingMethod entityEnclosingMethod =
942                                                    (EntityEnclosingMethod)httpMethod;
943    
944                                            entityEnclosingMethod.setRequestEntity(requestEntity);
945                                    }
946                                    else if ((parts != null) && (parts.size() > 0) &&
947                                                     (method == Http.Method.POST)) {
948    
949                                            List<NameValuePair> nvpList =
950                                                    new ArrayList<NameValuePair>();
951    
952                                            for (Map.Entry<String, String> entry : parts.entrySet()) {
953                                                    String key = entry.getKey();
954                                                    String value = entry.getValue();
955    
956                                                    if (value != null) {
957                                                            nvpList.add(new NameValuePair(key, value));
958                                                    }
959                                            }
960    
961                                            NameValuePair[] nvpArray = nvpList.toArray(
962                                                    new NameValuePair[nvpList.size()]);
963    
964                                            PostMethod postMethod = (PostMethod)httpMethod;
965    
966                                            postMethod.setRequestBody(nvpArray);
967                                    }
968                            }
969                            else if (method == Http.Method.DELETE) {
970                                    httpMethod = new DeleteMethod(location);
971                            }
972                            else if (method == Http.Method.HEAD) {
973                                    httpMethod = new HeadMethod(location);
974                            }
975                            else {
976                                    httpMethod = new GetMethod(location);
977                            }
978    
979                            if (headers != null) {
980                                    for (Map.Entry<String, String> header : headers.entrySet()) {
981                                            httpMethod.addRequestHeader(
982                                                    header.getKey(), header.getValue());
983                                    }
984                            }
985    
986                            if ((method == Http.Method.POST) || (method == Http.Method.PUT) &&
987                                    (body != null)) {
988                            }
989                            else if (!_hasRequestHeader(httpMethod, HttpHeaders.CONTENT_TYPE)) {
990                                    httpMethod.addRequestHeader(
991                                            HttpHeaders.CONTENT_TYPE,
992                                            ContentTypes.APPLICATION_X_WWW_FORM_URLENCODED);
993                            }
994    
995                            if (!_hasRequestHeader(httpMethod, HttpHeaders.USER_AGENT)) {
996                                    httpMethod.addRequestHeader(
997                                            HttpHeaders.USER_AGENT, _DEFAULT_USER_AGENT);
998                            }
999    
1000                            httpMethod.getParams().setIntParameter(
1001                                    HttpClientParams.SO_TIMEOUT, 0);
1002    
1003                            httpState = new HttpState();
1004    
1005                            if ((cookies != null) && (cookies.length > 0)) {
1006                                    org.apache.commons.httpclient.Cookie[] commonsCookies =
1007                                            toCommonsCookies(cookies);
1008    
1009                                    httpState.addCookies(commonsCookies);
1010    
1011                                    httpMethod.getParams().setCookiePolicy(
1012                                            CookiePolicy.BROWSER_COMPATIBILITY);
1013                            }
1014    
1015                            if (auth != null) {
1016                                    httpMethod.setDoAuthentication(true);
1017    
1018                                    httpState.setCredentials(
1019                                            new AuthScope(
1020                                                    auth.getHost(), auth.getPort(), auth.getRealm()),
1021                                            new UsernamePasswordCredentials(
1022                                                    auth.getUsername(), auth.getPassword()));
1023                            }
1024    
1025                            proxifyState(httpState, hostConfig);
1026    
1027                            httpClient.executeMethod(hostConfig, httpMethod, httpState);
1028    
1029                            Header locationHeader = httpMethod.getResponseHeader("location");
1030    
1031                            if ((locationHeader != null) && !locationHeader.equals(location)) {
1032                                    String redirect = locationHeader.getValue();
1033    
1034                                    if (followRedirects) {
1035                                            return URLtoByteArray(
1036                                                    redirect, Http.Method.GET, headers,
1037                                                    cookies, auth, body, parts, response, followRedirects);
1038                                    }
1039                                    else {
1040                                            response.setRedirect(redirect);
1041                                    }
1042                            }
1043    
1044                            InputStream is = httpMethod.getResponseBodyAsStream();
1045    
1046                            if (is != null) {
1047                                    Header contentLength = httpMethod.getResponseHeader(
1048                                            HttpHeaders.CONTENT_LENGTH);
1049    
1050                                    if (contentLength != null) {
1051                                            response.setContentLength(
1052                                                    GetterUtil.getInteger(contentLength.getValue()));
1053                                    }
1054    
1055                                    Header contentType = httpMethod.getResponseHeader(
1056                                            HttpHeaders.CONTENT_TYPE);
1057    
1058                                    if (contentType != null) {
1059                                            response.setContentType(contentType.getValue());
1060                                    }
1061    
1062                                    bytes = FileUtil.getBytes(is);
1063    
1064                                    is.close();
1065                            }
1066    
1067                            for (Header header : httpMethod.getResponseHeaders()) {
1068                                    response.addHeader(header.getName(), header.getValue());
1069                            }
1070    
1071                            return bytes;
1072                    }
1073                    finally {
1074                            try {
1075                                    if (httpState != null) {
1076                                            _cookies.set(toServletCookies(httpState.getCookies()));
1077                                    }
1078                            }
1079                            catch (Exception e) {
1080                                    _log.error(e, e);
1081                            }
1082    
1083                            try {
1084                                    if (httpMethod != null) {
1085                                            httpMethod.releaseConnection();
1086                                    }
1087                            }
1088                            catch (Exception e) {
1089                                    _log.error(e, e);
1090                            }
1091                    }
1092            }
1093    
1094            private boolean _hasRequestHeader(HttpMethod httpMethod, String name) {
1095                    if (httpMethod.getRequestHeaders(name).length == 0) {
1096                            return false;
1097                    }
1098                    else {
1099                            return true;
1100                    }
1101            }
1102    
1103            private static final String _DEFAULT_USER_AGENT =
1104                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)";
1105    
1106            private static final int _MAX_CONNECTIONS_PER_HOST = GetterUtil.getInteger(
1107                    PropsUtil.get(HttpImpl.class.getName() + ".max.connections.per.host"),
1108                    2);
1109    
1110            private static final int _MAX_TOTAL_CONNECTIONS = GetterUtil.getInteger(
1111                    PropsUtil.get(HttpImpl.class.getName() + ".max.total.connections"),
1112                    20);
1113    
1114            private static final String _NON_PROXY_HOSTS =
1115                    SystemProperties.get("http.nonProxyHosts");
1116    
1117            private static final String _PROXY_AUTH_TYPE = GetterUtil.getString(
1118                    PropsUtil.get(HttpImpl.class.getName() + ".proxy.auth.type"));
1119    
1120            private static final String _PROXY_HOST = GetterUtil.getString(
1121                    SystemProperties.get("http.proxyHost"));
1122    
1123            private static final String _PROXY_NTLM_DOMAIN = GetterUtil.getString(
1124                    PropsUtil.get(HttpImpl.class.getName() + ".proxy.ntlm.domain"));
1125    
1126            private static final String _PROXY_NTLM_HOST = GetterUtil.getString(
1127                    PropsUtil.get(HttpImpl.class.getName() + ".proxy.ntlm.host"));
1128    
1129            private static final String _PROXY_PASSWORD = GetterUtil.getString(
1130                    PropsUtil.get(HttpImpl.class.getName() + ".proxy.password"));
1131    
1132            private static final int _PROXY_PORT = GetterUtil.getInteger(
1133                    SystemProperties.get("http.proxyPort"));
1134    
1135            private static final String _PROXY_USERNAME = GetterUtil.getString(
1136                    PropsUtil.get(HttpImpl.class.getName() + ".proxy.username"));
1137    
1138            private static final String _TEMP_SLASH = "_LIFERAY_TEMP_SLASH_";
1139    
1140            private static final int _TIMEOUT = GetterUtil.getInteger(
1141                    PropsUtil.get(HttpImpl.class.getName() + ".timeout"), 5000);
1142    
1143            private static Log _log = LogFactoryUtil.getLog(HttpImpl.class);
1144    
1145            private static ThreadLocal<Cookie[]> _cookies = new ThreadLocal<Cookie[]>();
1146    
1147            private HttpClient _client = new HttpClient();
1148            private Pattern _nonProxyHostsPattern;
1149            private HttpClient _proxyClient = new HttpClient();
1150            private Credentials _proxyCredentials;
1151    
1152    }