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