001    /**
002     * Copyright (c) 2000-2013 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.configuration.Filter;
018    import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayOutputStream;
019    import com.liferay.portal.kernel.log.Log;
020    import com.liferay.portal.kernel.log.LogFactoryUtil;
021    import com.liferay.portal.kernel.security.pacl.DoPrivileged;
022    import com.liferay.portal.kernel.servlet.HttpHeaders;
023    import com.liferay.portal.kernel.upload.ProgressInputStream;
024    import com.liferay.portal.kernel.util.ArrayUtil;
025    import com.liferay.portal.kernel.util.CharPool;
026    import com.liferay.portal.kernel.util.ContentTypes;
027    import com.liferay.portal.kernel.util.FileUtil;
028    import com.liferay.portal.kernel.util.GetterUtil;
029    import com.liferay.portal.kernel.util.Http;
030    import com.liferay.portal.kernel.util.StringBundler;
031    import com.liferay.portal.kernel.util.StringPool;
032    import com.liferay.portal.kernel.util.StringUtil;
033    import com.liferay.portal.kernel.util.SystemProperties;
034    import com.liferay.portal.kernel.util.URLCodec;
035    import com.liferay.portal.kernel.util.Validator;
036    
037    import java.io.IOException;
038    import java.io.InputStream;
039    
040    import java.net.InetAddress;
041    import java.net.InetSocketAddress;
042    import java.net.Socket;
043    import java.net.SocketAddress;
044    import java.net.URL;
045    import java.net.URLConnection;
046    import java.net.UnknownHostException;
047    
048    import java.util.ArrayList;
049    import java.util.Date;
050    import java.util.LinkedHashMap;
051    import java.util.List;
052    import java.util.Map;
053    import java.util.regex.Matcher;
054    import java.util.regex.Pattern;
055    
056    import javax.net.SocketFactory;
057    
058    import javax.portlet.ActionRequest;
059    import javax.portlet.PortletRequest;
060    import javax.portlet.RenderRequest;
061    
062    import javax.servlet.http.Cookie;
063    import javax.servlet.http.HttpServletRequest;
064    import javax.servlet.http.HttpSession;
065    
066    import org.apache.commons.httpclient.ConnectTimeoutException;
067    import org.apache.commons.httpclient.Credentials;
068    import org.apache.commons.httpclient.Header;
069    import org.apache.commons.httpclient.HostConfiguration;
070    import org.apache.commons.httpclient.HttpClient;
071    import org.apache.commons.httpclient.HttpConnectionManager;
072    import org.apache.commons.httpclient.HttpMethod;
073    import org.apache.commons.httpclient.HttpState;
074    import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
075    import org.apache.commons.httpclient.NTCredentials;
076    import org.apache.commons.httpclient.URI;
077    import org.apache.commons.httpclient.UsernamePasswordCredentials;
078    import org.apache.commons.httpclient.auth.AuthPolicy;
079    import org.apache.commons.httpclient.auth.AuthScope;
080    import org.apache.commons.httpclient.cookie.CookiePolicy;
081    import org.apache.commons.httpclient.methods.DeleteMethod;
082    import org.apache.commons.httpclient.methods.EntityEnclosingMethod;
083    import org.apache.commons.httpclient.methods.GetMethod;
084    import org.apache.commons.httpclient.methods.HeadMethod;
085    import org.apache.commons.httpclient.methods.PostMethod;
086    import org.apache.commons.httpclient.methods.PutMethod;
087    import org.apache.commons.httpclient.methods.RequestEntity;
088    import org.apache.commons.httpclient.methods.StringRequestEntity;
089    import org.apache.commons.httpclient.methods.multipart.ByteArrayPartSource;
090    import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
091    import org.apache.commons.httpclient.methods.multipart.Part;
092    import org.apache.commons.httpclient.methods.multipart.StringPart;
093    import org.apache.commons.httpclient.params.HostParams;
094    import org.apache.commons.httpclient.params.HttpClientParams;
095    import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
096    import org.apache.commons.httpclient.params.HttpConnectionParams;
097    import org.apache.commons.httpclient.params.HttpMethodParams;
098    import org.apache.commons.httpclient.protocol.DefaultProtocolSocketFactory;
099    import org.apache.commons.httpclient.protocol.Protocol;
100    
101    /**
102     * @author Brian Wing Shun Chan
103     * @author Hugo Huijser
104     * @author Shuyang Zhou
105     */
106    @DoPrivileged
107    public class HttpImpl implements Http {
108    
109            public HttpImpl() {
110    
111                    // Override the default protocol socket factory because it uses
112                    // reflection for JDK 1.4 compatibility, which we do not need. It also
113                    // attemps to create a new socket in a different thread so that we
114                    // cannot track which class loader initiated the call.
115    
116                    Protocol protocol = new Protocol(
117                            "http", new FastProtocolSocketFactory(), 80);
118    
119                    Protocol.registerProtocol("http", protocol);
120    
121                    // Mimic behavior found in
122                    // http://java.sun.com/j2se/1.5.0/docs/guide/net/properties.html
123    
124                    if (Validator.isNotNull(_NON_PROXY_HOSTS)) {
125                            String nonProxyHostsRegEx = _NON_PROXY_HOSTS;
126    
127                            nonProxyHostsRegEx = nonProxyHostsRegEx.replaceAll("\\.", "\\\\.");
128                            nonProxyHostsRegEx = nonProxyHostsRegEx.replaceAll("\\*", ".*?");
129                            nonProxyHostsRegEx = nonProxyHostsRegEx.replaceAll("\\|", ")|(");
130    
131                            nonProxyHostsRegEx = "(" + nonProxyHostsRegEx + ")";
132    
133                            _nonProxyHostsPattern = Pattern.compile(nonProxyHostsRegEx);
134                    }
135    
136                    MultiThreadedHttpConnectionManager httpConnectionManager =
137                            new MultiThreadedHttpConnectionManager();
138    
139                    HttpConnectionManagerParams httpConnectionManagerParams =
140                            httpConnectionManager.getParams();
141    
142                    httpConnectionManagerParams.setConnectionTimeout(_TIMEOUT);
143                    httpConnectionManagerParams.setDefaultMaxConnectionsPerHost(
144                            new Integer(_MAX_CONNECTIONS_PER_HOST));
145                    httpConnectionManagerParams.setMaxTotalConnections(
146                            new Integer(_MAX_TOTAL_CONNECTIONS));
147                    httpConnectionManagerParams.setSoTimeout(_TIMEOUT);
148    
149                    _httpClient.setHttpConnectionManager(httpConnectionManager);
150                    _proxyHttpClient.setHttpConnectionManager(httpConnectionManager);
151    
152                    if (!hasProxyConfig() || Validator.isNull(_PROXY_USERNAME)) {
153                            return;
154                    }
155    
156                    List<String> authPrefs = new ArrayList<String>();
157    
158                    if (_PROXY_AUTH_TYPE.equals("username-password")) {
159                            _proxyCredentials = new UsernamePasswordCredentials(
160                                    _PROXY_USERNAME, _PROXY_PASSWORD);
161    
162                            authPrefs.add(AuthPolicy.BASIC);
163                            authPrefs.add(AuthPolicy.DIGEST);
164                            authPrefs.add(AuthPolicy.NTLM);
165                    }
166                    else if (_PROXY_AUTH_TYPE.equals("ntlm")) {
167                            _proxyCredentials = new NTCredentials(
168                                    _PROXY_USERNAME, _PROXY_PASSWORD, _PROXY_NTLM_HOST,
169                                    _PROXY_NTLM_DOMAIN);
170    
171                            authPrefs.add(AuthPolicy.NTLM);
172                            authPrefs.add(AuthPolicy.BASIC);
173                            authPrefs.add(AuthPolicy.DIGEST);
174                    }
175    
176                    HttpClientParams httpClientParams = _proxyHttpClient.getParams();
177    
178                    httpClientParams.setParameter(
179                            AuthPolicy.AUTH_SCHEME_PRIORITY, authPrefs);
180            }
181    
182            @Override
183            public String addParameter(String url, String name, boolean value) {
184                    return addParameter(url, name, String.valueOf(value));
185            }
186    
187            @Override
188            public String addParameter(String url, String name, double value) {
189                    return addParameter(url, name, String.valueOf(value));
190            }
191    
192            @Override
193            public String addParameter(String url, String name, int value) {
194                    return addParameter(url, name, String.valueOf(value));
195            }
196    
197            @Override
198            public String addParameter(String url, String name, long value) {
199                    return addParameter(url, name, String.valueOf(value));
200            }
201    
202            @Override
203            public String addParameter(String url, String name, short value) {
204                    return addParameter(url, name, String.valueOf(value));
205            }
206    
207            @Override
208            public String addParameter(String url, String name, String value) {
209                    if (url == null) {
210                            return null;
211                    }
212    
213                    String[] urlArray = PortalUtil.stripURLAnchor(url, StringPool.POUND);
214    
215                    url = urlArray[0];
216    
217                    String anchor = urlArray[1];
218    
219                    StringBundler sb = new StringBundler(7);
220    
221                    sb.append(url);
222    
223                    if (url.indexOf(CharPool.QUESTION) == -1) {
224                            sb.append(StringPool.QUESTION);
225                    }
226                    else if (!url.endsWith(StringPool.QUESTION) &&
227                                     !url.endsWith(StringPool.AMPERSAND)) {
228    
229                            sb.append(StringPool.AMPERSAND);
230                    }
231    
232                    sb.append(name);
233                    sb.append(StringPool.EQUAL);
234                    sb.append(encodeURL(value));
235                    sb.append(anchor);
236    
237                    return sb.toString();
238            }
239    
240            @Override
241            public String decodePath(String path) {
242                    if (Validator.isNull(path)) {
243                            return path;
244                    }
245    
246                    path = StringUtil.replace(path, StringPool.SLASH, _TEMP_SLASH);
247                    path = decodeURL(path, true);
248                    path = StringUtil.replace(path, _TEMP_SLASH, StringPool.SLASH);
249    
250                    return path;
251            }
252    
253            @Override
254            public String decodeURL(String url) {
255                    return decodeURL(url, false);
256            }
257    
258            @Override
259            public String decodeURL(String url, boolean unescapeSpaces) {
260                    if (Validator.isNull(url)) {
261                            return url;
262                    }
263    
264                    return URLCodec.decodeURL(url, StringPool.UTF8, unescapeSpaces);
265            }
266    
267            public void destroy() {
268                    MultiThreadedHttpConnectionManager.shutdownAll();
269            }
270    
271            @Override
272            public String encodeParameters(String url) {
273                    if (Validator.isNull(url)) {
274                            return url;
275                    }
276    
277                    String queryString = getQueryString(url);
278    
279                    if (Validator.isNull(queryString)) {
280                            return url;
281                    }
282    
283                    String encodedQueryString = parameterMapToString(
284                            parameterMapFromString(queryString), false);
285    
286                    return StringUtil.replace(url, queryString, encodedQueryString);
287            }
288    
289            @Override
290            public String encodePath(String path) {
291                    if (Validator.isNull(path)) {
292                            return path;
293                    }
294    
295                    path = StringUtil.replace(path, StringPool.SLASH, _TEMP_SLASH);
296                    path = encodeURL(path, true);
297                    path = StringUtil.replace(path, _TEMP_SLASH, StringPool.SLASH);
298    
299                    return path;
300            }
301    
302            @Override
303            public String encodeURL(String url) {
304                    return encodeURL(url, false);
305            }
306    
307            @Override
308            public String encodeURL(String url, boolean escapeSpaces) {
309                    if (Validator.isNull(url)) {
310                            return url;
311                    }
312    
313                    return URLCodec.encodeURL(url, StringPool.UTF8, escapeSpaces);
314            }
315    
316            @Override
317            public String fixPath(String path) {
318                    return fixPath(path, true, true);
319            }
320    
321            @Override
322            public String fixPath(String path, boolean leading, boolean trailing) {
323                    if (path == null) {
324                            return StringPool.BLANK;
325                    }
326    
327                    int leadingSlashCount = 0;
328                    int trailingSlashCount = 0;
329    
330                    if (leading) {
331                            for (int i = 0; i < path.length(); i++) {
332                                    if (path.charAt(i) == CharPool.SLASH) {
333                                            leadingSlashCount++;
334                                    }
335                                    else {
336                                            break;
337                                    }
338                            }
339                    }
340    
341                    if (trailing) {
342                            for (int i = path.length() - 1; i >= 0; i--) {
343                                    if (path.charAt(i) == CharPool.SLASH) {
344                                            trailingSlashCount++;
345                                    }
346                                    else {
347                                            break;
348                                    }
349                            }
350                    }
351    
352                    int slashCount = leadingSlashCount + trailingSlashCount;
353    
354                    if (slashCount > path.length()) {
355                            return StringPool.BLANK;
356                    }
357    
358                    if (slashCount > 0) {
359                            path = path.substring(
360                                    leadingSlashCount, path.length() - trailingSlashCount);
361                    }
362    
363                    return path;
364            }
365    
366            public HttpClient getClient(HostConfiguration hostConfiguration) {
367                    if (isProxyHost(hostConfiguration.getHost())) {
368                            return _proxyHttpClient;
369                    }
370    
371                    return _httpClient;
372            }
373    
374            @Override
375            public String getCompleteURL(HttpServletRequest request) {
376                    StringBuffer sb = request.getRequestURL();
377    
378                    if (sb == null) {
379                            sb = new StringBuffer();
380                    }
381    
382                    if (request.getQueryString() != null) {
383                            sb.append(StringPool.QUESTION);
384                            sb.append(request.getQueryString());
385                    }
386    
387                    String proxyPath = PortalUtil.getPathProxy();
388    
389                    if (Validator.isNotNull(proxyPath)) {
390                            int x =
391                                    sb.indexOf(Http.PROTOCOL_DELIMITER) +
392                                            Http.PROTOCOL_DELIMITER.length();
393                            int y = sb.indexOf(StringPool.SLASH, x);
394    
395                            sb.insert(y, proxyPath);
396                    }
397    
398                    String completeURL = sb.toString();
399    
400                    if (request.isRequestedSessionIdFromURL()) {
401                            HttpSession session = request.getSession();
402    
403                            String sessionId = session.getId();
404    
405                            completeURL = PortalUtil.getURLWithSessionId(
406                                    completeURL, sessionId);
407                    }
408    
409                    if (_log.isWarnEnabled()) {
410                            if (completeURL.contains("?&")) {
411                                    _log.warn("Invalid url " + completeURL);
412                            }
413                    }
414    
415                    return completeURL;
416            }
417    
418            @Override
419            public Cookie[] getCookies() {
420                    return _cookies.get();
421            }
422    
423            @Override
424            public String getDomain(String url) {
425                    if (Validator.isNull(url)) {
426                            return url;
427                    }
428    
429                    url = removeProtocol(url);
430    
431                    int pos = url.indexOf(CharPool.SLASH);
432    
433                    if (pos != -1) {
434                            return url.substring(0, pos);
435                    }
436    
437                    return url;
438            }
439    
440            /**
441             * @deprecated As of 6.1.0, replaced by {@link
442             *             #getHostConfiguration(String)}
443             */
444            public HostConfiguration getHostConfig(String location) throws IOException {
445                    return getHostConfiguration(location);
446            }
447    
448            public HostConfiguration getHostConfiguration(String location)
449                    throws IOException {
450    
451                    if (_log.isDebugEnabled()) {
452                            _log.debug("Location is " + location);
453                    }
454    
455                    HostConfiguration hostConfiguration = new HostConfiguration();
456    
457                    hostConfiguration.setHost(new URI(location, false));
458    
459                    if (isProxyHost(hostConfiguration.getHost())) {
460                            hostConfiguration.setProxy(_PROXY_HOST, _PROXY_PORT);
461                    }
462    
463                    HttpConnectionManager httpConnectionManager =
464                            _httpClient.getHttpConnectionManager();
465    
466                    HttpConnectionManagerParams httpConnectionManagerParams =
467                            httpConnectionManager.getParams();
468    
469                    int defaultMaxConnectionsPerHost =
470                            httpConnectionManagerParams.getMaxConnectionsPerHost(
471                                    hostConfiguration);
472    
473                    int maxConnectionsPerHost = GetterUtil.getInteger(
474                            PropsUtil.get(
475                                    HttpImpl.class.getName() + ".max.connections.per.host",
476                                    new Filter(hostConfiguration.getHost())));
477    
478                    if ((maxConnectionsPerHost > 0) &&
479                            (maxConnectionsPerHost != defaultMaxConnectionsPerHost)) {
480    
481                            httpConnectionManagerParams.setMaxConnectionsPerHost(
482                                    hostConfiguration, maxConnectionsPerHost);
483                    }
484    
485                    int timeout = GetterUtil.getInteger(
486                            PropsUtil.get(
487                                    HttpImpl.class.getName() + ".timeout",
488                                    new Filter(hostConfiguration.getHost())));
489    
490                    if (timeout > 0) {
491                            HostParams hostParams = hostConfiguration.getParams();
492    
493                            hostParams.setIntParameter(
494                                    HttpConnectionParams.CONNECTION_TIMEOUT, timeout);
495                            hostParams.setIntParameter(
496                                    HttpConnectionParams.SO_TIMEOUT, timeout);
497                    }
498    
499                    return hostConfiguration;
500            }
501    
502            @Override
503            public String getIpAddress(String url) {
504                    if (Validator.isNull(url)) {
505                            return url;
506                    }
507    
508                    try {
509                            URL urlObj = new URL(url);
510    
511                            InetAddress address = InetAddress.getByName(urlObj.getHost());
512    
513                            return address.getHostAddress();
514                    }
515                    catch (Exception e) {
516                            return url;
517                    }
518            }
519    
520            @Override
521            public String getParameter(String url, String name) {
522                    return getParameter(url, name, true);
523            }
524    
525            @Override
526            public String getParameter(String url, String name, boolean escaped) {
527                    if (Validator.isNull(url) || Validator.isNull(name)) {
528                            return StringPool.BLANK;
529                    }
530    
531                    String[] parts = StringUtil.split(url, CharPool.QUESTION);
532    
533                    if (parts.length == 2) {
534                            String[] params = null;
535    
536                            if (escaped) {
537                                    params = StringUtil.split(parts[1], "&amp;");
538                            }
539                            else {
540                                    params = StringUtil.split(parts[1], CharPool.AMPERSAND);
541                            }
542    
543                            for (String param : params) {
544                                    String[] kvp = StringUtil.split(param, CharPool.EQUAL);
545    
546                                    if ((kvp.length == 2) && kvp[0].equals(name)) {
547                                            return kvp[1];
548                                    }
549                            }
550                    }
551    
552                    return StringPool.BLANK;
553            }
554    
555            @Override
556            public Map<String, String[]> getParameterMap(String queryString) {
557                    return parameterMapFromString(queryString);
558            }
559    
560            @Override
561            public String getPath(String url) {
562                    if (Validator.isNull(url)) {
563                            return url;
564                    }
565    
566                    if (url.startsWith(Http.HTTP)) {
567                            int pos = url.indexOf(
568                                    StringPool.SLASH, Http.HTTPS_WITH_SLASH.length());
569    
570                            url = url.substring(pos);
571                    }
572    
573                    int pos = url.indexOf(CharPool.QUESTION);
574    
575                    if (pos == -1) {
576                            return url;
577                    }
578    
579                    return url.substring(0, pos);
580            }
581    
582            @Override
583            public String getProtocol(ActionRequest actionRequest) {
584                    return getProtocol(actionRequest.isSecure());
585            }
586    
587            @Override
588            public String getProtocol(boolean secure) {
589                    if (!secure) {
590                            return Http.HTTP;
591                    }
592    
593                    return Http.HTTPS;
594            }
595    
596            @Override
597            public String getProtocol(HttpServletRequest request) {
598                    return getProtocol(request.isSecure());
599            }
600    
601            @Override
602            public String getProtocol(RenderRequest renderRequest) {
603                    return getProtocol(renderRequest.isSecure());
604            }
605    
606            @Override
607            public String getProtocol(String url) {
608                    if (Validator.isNull(url)) {
609                            return url;
610                    }
611    
612                    int pos = url.indexOf(Http.PROTOCOL_DELIMITER);
613    
614                    if (pos != -1) {
615                            return url.substring(0, pos);
616                    }
617    
618                    return Http.HTTP;
619            }
620    
621            @Override
622            public String getQueryString(String url) {
623                    if (Validator.isNull(url)) {
624                            return url;
625                    }
626    
627                    int pos = url.indexOf(CharPool.QUESTION);
628    
629                    if (pos == -1) {
630                            return StringPool.BLANK;
631                    }
632    
633                    return url.substring(pos + 1);
634            }
635    
636            @Override
637            public String getRequestURL(HttpServletRequest request) {
638                    return String.valueOf(request.getRequestURL());
639            }
640    
641            @Override
642            public boolean hasDomain(String url) {
643                    if (Validator.isNull(url)) {
644                            return false;
645                    }
646    
647                    return Validator.isNotNull(getDomain(url));
648            }
649    
650            @Override
651            public boolean hasProtocol(String url) {
652                    if (Validator.isNull(url)) {
653                            return false;
654                    }
655    
656                    int pos = url.indexOf(Http.PROTOCOL_DELIMITER);
657    
658                    if (pos != -1) {
659                            return true;
660                    }
661    
662                    return false;
663            }
664    
665            @Override
666            public boolean hasProxyConfig() {
667                    if (Validator.isNotNull(_PROXY_HOST) && (_PROXY_PORT > 0)) {
668                            return true;
669                    }
670    
671                    return false;
672            }
673    
674            @Override
675            public boolean isNonProxyHost(String host) {
676                    if (Validator.isNull(host)) {
677                            return false;
678                    }
679    
680                    if (_nonProxyHostsPattern != null) {
681                            Matcher matcher = _nonProxyHostsPattern.matcher(host);
682    
683                            if (matcher.matches()) {
684                                    return true;
685                            }
686                    }
687    
688                    return false;
689            }
690    
691            @Override
692            public boolean isProxyHost(String host) {
693                    if (Validator.isNull(host)) {
694                            return false;
695                    }
696    
697                    if (hasProxyConfig() && !isNonProxyHost(host)) {
698                            return true;
699                    }
700    
701                    return false;
702            }
703    
704            @Override
705            public boolean isSecure(String url) {
706                    String protocol = getProtocol(url);
707    
708                    return StringUtil.equalsIgnoreCase(protocol, Http.HTTPS);
709            }
710    
711            @Override
712            public Map<String, String[]> parameterMapFromString(String queryString) {
713                    Map<String, String[]> parameterMap =
714                            new LinkedHashMap<String, String[]>();
715    
716                    if (Validator.isNull(queryString)) {
717                            return parameterMap;
718                    }
719    
720                    Map<String, List<String>> tempParameterMap =
721                            new LinkedHashMap<String, List<String>>();
722    
723                    String[] parameters = StringUtil.split(queryString, CharPool.AMPERSAND);
724    
725                    for (String parameter : parameters) {
726                            if (parameter.length() > 0) {
727                                    String[] kvp = StringUtil.split(parameter, CharPool.EQUAL);
728    
729                                    if (kvp.length == 0) {
730                                            continue;
731                                    }
732    
733                                    String key = kvp[0];
734    
735                                    String value = StringPool.BLANK;
736    
737                                    if (kvp.length > 1) {
738                                            try {
739                                                    value = decodeURL(kvp[1]);
740                                            }
741                                            catch (IllegalArgumentException iae) {
742                                                    if (_log.isInfoEnabled()) {
743                                                            _log.info(
744                                                                    "Skipping parameter with key " + key +
745                                                                            " because of invalid value " + kvp[1],
746                                                                    iae);
747                                                    }
748    
749                                                    continue;
750                                            }
751                                    }
752    
753                                    List<String> values = tempParameterMap.get(key);
754    
755                                    if (values == null) {
756                                            values = new ArrayList<String>();
757    
758                                            tempParameterMap.put(key, values);
759                                    }
760    
761                                    values.add(value);
762                            }
763                    }
764    
765                    for (Map.Entry<String, List<String>> entry :
766                                    tempParameterMap.entrySet()) {
767    
768                            String key = entry.getKey();
769                            List<String> values = entry.getValue();
770    
771                            parameterMap.put(key, values.toArray(new String[values.size()]));
772                    }
773    
774                    return parameterMap;
775            }
776    
777            @Override
778            public String parameterMapToString(Map<String, String[]> parameterMap) {
779                    return parameterMapToString(parameterMap, true);
780            }
781    
782            @Override
783            public String parameterMapToString(
784                    Map<String, String[]> parameterMap, boolean addQuestion) {
785    
786                    if (parameterMap.isEmpty()) {
787                            return StringPool.BLANK;
788                    }
789    
790                    StringBundler sb = new StringBundler();
791    
792                    if (addQuestion) {
793                            sb.append(StringPool.QUESTION);
794                    }
795    
796                    for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
797                            String name = entry.getKey();
798                            String[] values = entry.getValue();
799    
800                            for (String value : values) {
801                                    sb.append(name);
802                                    sb.append(StringPool.EQUAL);
803                                    sb.append(encodeURL(value));
804                                    sb.append(StringPool.AMPERSAND);
805                            }
806                    }
807    
808                    if (sb.index() > 1) {
809                            sb.setIndex(sb.index() - 1);
810                    }
811    
812                    return sb.toString();
813            }
814    
815            @Override
816            public String protocolize(String url, ActionRequest actionRequest) {
817                    return protocolize(url, actionRequest.isSecure());
818            }
819    
820            @Override
821            public String protocolize(String url, boolean secure) {
822                    return protocolize(url, -1, secure);
823            }
824    
825            @Override
826            public String protocolize(String url, HttpServletRequest request) {
827                    return protocolize(url, request.isSecure());
828            }
829    
830            @Override
831            public String protocolize(String url, int port, boolean secure) {
832                    if (Validator.isNull(url)) {
833                            return url;
834                    }
835    
836                    try {
837                            URL urlObj = new URL(url);
838    
839                            String protocol = Http.HTTP;
840    
841                            if (secure) {
842                                    protocol = Http.HTTPS;
843                            }
844    
845                            if (port == -1) {
846                                    port = urlObj.getPort();
847                            }
848    
849                            urlObj = new URL(
850                                    protocol, urlObj.getHost(), port, urlObj.getFile());
851    
852                            return urlObj.toString();
853                    }
854                    catch (Exception e) {
855                            return url;
856                    }
857            }
858    
859            @Override
860            public String protocolize(String url, RenderRequest renderRequest) {
861                    return protocolize(url, renderRequest.isSecure());
862            }
863    
864            public void proxifyState(
865                    HttpState httpState, HostConfiguration hostConfiguration) {
866    
867                    Credentials proxyCredentials = _proxyCredentials;
868    
869                    String host = hostConfiguration.getHost();
870    
871                    if (isProxyHost(host) && (proxyCredentials != null)) {
872                            AuthScope scope = new AuthScope(_PROXY_HOST, _PROXY_PORT, null);
873    
874                            httpState.setProxyCredentials(scope, proxyCredentials);
875                    }
876            }
877    
878            @Override
879            public String removeDomain(String url) {
880                    if (Validator.isNull(url)) {
881                            return url;
882                    }
883    
884                    url = removeProtocol(url);
885    
886                    int pos = url.indexOf(CharPool.SLASH);
887    
888                    if (pos > 0) {
889                            return url.substring(pos);
890                    }
891    
892                    return url;
893            }
894    
895            @Override
896            public String removeParameter(String url, String name) {
897                    if (Validator.isNull(url) || Validator.isNull(name)) {
898                            return url;
899                    }
900    
901                    int pos = url.indexOf(CharPool.QUESTION);
902    
903                    if (pos == -1) {
904                            return url;
905                    }
906    
907                    String[] array = PortalUtil.stripURLAnchor(url, StringPool.POUND);
908    
909                    url = array[0];
910    
911                    String anchor = array[1];
912    
913                    StringBundler sb = new StringBundler();
914    
915                    sb.append(url.substring(0, pos + 1));
916    
917                    String[] parameters = StringUtil.split(
918                            url.substring(pos + 1, url.length()), CharPool.AMPERSAND);
919    
920                    for (String parameter : parameters) {
921                            if (parameter.length() > 0) {
922                                    String[] kvp = StringUtil.split(parameter, CharPool.EQUAL);
923    
924                                    String key = kvp[0];
925    
926                                    String value = StringPool.BLANK;
927    
928                                    if (kvp.length > 1) {
929                                            value = kvp[1];
930                                    }
931    
932                                    if (!key.equals(name)) {
933                                            sb.append(key);
934                                            sb.append(StringPool.EQUAL);
935                                            sb.append(value);
936                                            sb.append(StringPool.AMPERSAND);
937                                    }
938                            }
939                    }
940    
941                    url = StringUtil.replace(
942                            sb.toString(), StringPool.AMPERSAND + StringPool.AMPERSAND,
943                            StringPool.AMPERSAND);
944    
945                    if (url.endsWith(StringPool.AMPERSAND)) {
946                            url = url.substring(0, url.length() - 1);
947                    }
948    
949                    if (url.endsWith(StringPool.QUESTION)) {
950                            url = url.substring(0, url.length() - 1);
951                    }
952    
953                    return url + anchor;
954            }
955    
956            @Override
957            public String removeProtocol(String url) {
958                    if (Validator.isNull(url)) {
959                            return url;
960                    }
961    
962                    if (url.startsWith(Http.HTTP_WITH_SLASH)) {
963                            return url.substring(Http.HTTP_WITH_SLASH.length());
964                    }
965                    else if (url.startsWith(Http.HTTPS_WITH_SLASH)) {
966                            return url.substring(Http.HTTPS_WITH_SLASH.length());
967                    }
968                    else {
969                            return url;
970                    }
971            }
972    
973            @Override
974            public String sanitizeHeader(String header) {
975                    if (header == null) {
976                            return null;
977                    }
978    
979                    StringBuilder sb = null;
980    
981                    for (int i = 0; i < header.length(); i++) {
982                            char c = header.charAt(i);
983    
984                            if (((c <= 31) && (c != 9)) || (c == 127) || (c > 255)) {
985                                    if (sb == null) {
986                                            sb = new StringBuilder(header);
987                                    }
988    
989                                    sb.setCharAt(i, CharPool.SPACE);
990                            }
991                    }
992    
993                    if (sb != null) {
994                            header = sb.toString();
995                    }
996    
997                    return header;
998            }
999    
1000            @Override
1001            public String setParameter(String url, String name, boolean value) {
1002                    return setParameter(url, name, String.valueOf(value));
1003            }
1004    
1005            @Override
1006            public String setParameter(String url, String name, double value) {
1007                    return setParameter(url, name, String.valueOf(value));
1008            }
1009    
1010            @Override
1011            public String setParameter(String url, String name, int value) {
1012                    return setParameter(url, name, String.valueOf(value));
1013            }
1014    
1015            @Override
1016            public String setParameter(String url, String name, long value) {
1017                    return setParameter(url, name, String.valueOf(value));
1018            }
1019    
1020            @Override
1021            public String setParameter(String url, String name, short value) {
1022                    return setParameter(url, name, String.valueOf(value));
1023            }
1024    
1025            @Override
1026            public String setParameter(String url, String name, String value) {
1027                    if (Validator.isNull(url) || Validator.isNull(name)) {
1028                            return url;
1029                    }
1030    
1031                    url = removeParameter(url, name);
1032    
1033                    return addParameter(url, name, value);
1034            }
1035    
1036            @Override
1037            public byte[] URLtoByteArray(Http.Options options) throws IOException {
1038                    return URLtoByteArray(
1039                            options.getLocation(), options.getMethod(), options.getHeaders(),
1040                            options.getCookies(), options.getAuth(), options.getBody(),
1041                            options.getFileParts(), options.getParts(), options.getResponse(),
1042                            options.isFollowRedirects(), options.getProgressId(),
1043                            options.getPortletRequest());
1044            }
1045    
1046            @Override
1047            public byte[] URLtoByteArray(String location) throws IOException {
1048                    Http.Options options = new Http.Options();
1049    
1050                    options.setLocation(location);
1051    
1052                    return URLtoByteArray(options);
1053            }
1054    
1055            @Override
1056            public byte[] URLtoByteArray(String location, boolean post)
1057                    throws IOException {
1058    
1059                    Http.Options options = new Http.Options();
1060    
1061                    options.setLocation(location);
1062                    options.setPost(post);
1063    
1064                    return URLtoByteArray(options);
1065            }
1066    
1067            @Override
1068            public String URLtoString(Http.Options options) throws IOException {
1069                    return new String(URLtoByteArray(options));
1070            }
1071    
1072            @Override
1073            public String URLtoString(String location) throws IOException {
1074                    return new String(URLtoByteArray(location));
1075            }
1076    
1077            @Override
1078            public String URLtoString(String location, boolean post)
1079                    throws IOException {
1080    
1081                    return new String(URLtoByteArray(location, post));
1082            }
1083    
1084            /**
1085             * This method only uses the default Commons HttpClient implementation when
1086             * the URL object represents a HTTP resource. The URL object could also
1087             * represent a file or some JNDI resource. In that case, the default Java
1088             * implementation is used.
1089             *
1090             * @param  url the URL
1091             * @return A string representation of the resource referenced by the URL
1092             *         object
1093             * @throws IOException if an IO exception occurred
1094             */
1095            @Override
1096            public String URLtoString(URL url) throws IOException {
1097                    String xml = null;
1098    
1099                    if (url == null) {
1100                            return null;
1101                    }
1102    
1103                    String protocol = StringUtil.toLowerCase(url.getProtocol());
1104    
1105                    if (protocol.startsWith(Http.HTTP) || protocol.startsWith(Http.HTTPS)) {
1106                            return URLtoString(url.toString());
1107                    }
1108    
1109                    URLConnection urlConnection = url.openConnection();
1110    
1111                    InputStream inputStream = urlConnection.getInputStream();
1112    
1113                    UnsyncByteArrayOutputStream unsyncByteArrayOutputStream =
1114                            new UnsyncByteArrayOutputStream();
1115    
1116                    byte[] bytes = new byte[512];
1117    
1118                    for (int i = inputStream.read(bytes, 0, 512); i != -1;
1119                                    i = inputStream.read(bytes, 0, 512)) {
1120    
1121                            unsyncByteArrayOutputStream.write(bytes, 0, i);
1122                    }
1123    
1124                    xml = new String(
1125                            unsyncByteArrayOutputStream.unsafeGetByteArray(), 0,
1126                            unsyncByteArrayOutputStream.size());
1127    
1128                    inputStream.close();
1129    
1130                    unsyncByteArrayOutputStream.close();
1131    
1132                    return xml;
1133            }
1134    
1135            protected boolean hasRequestHeader(HttpMethod httpMethod, String name) {
1136                    Header[] headers = httpMethod.getRequestHeaders(name);
1137    
1138                    if (headers.length == 0) {
1139                            return false;
1140                    }
1141    
1142                    return true;
1143            }
1144    
1145            protected void processPostMethod(
1146                    PostMethod postMethod, List<Http.FilePart> fileParts,
1147                    Map<String, String> parts) {
1148    
1149                    if ((fileParts == null) || fileParts.isEmpty()) {
1150                            if (parts != null) {
1151                                    for (Map.Entry<String, String> entry : parts.entrySet()) {
1152                                            String value = entry.getValue();
1153    
1154                                            if (value != null) {
1155                                                    postMethod.addParameter(entry.getKey(), value);
1156                                            }
1157                                    }
1158                            }
1159                    }
1160                    else {
1161                            List<Part> partsList = new ArrayList<Part>();
1162    
1163                            if (parts != null) {
1164                                    for (Map.Entry<String, String> entry : parts.entrySet()) {
1165                                            String value = entry.getValue();
1166    
1167                                            if (value != null) {
1168                                                    StringPart stringPart = new StringPart(
1169                                                            entry.getKey(), value);
1170    
1171                                                    partsList.add(stringPart);
1172                                            }
1173                                    }
1174                            }
1175    
1176                            for (Http.FilePart filePart : fileParts) {
1177                                    partsList.add(toCommonsFilePart(filePart));
1178                            }
1179    
1180                            MultipartRequestEntity multipartRequestEntity =
1181                                    new MultipartRequestEntity(
1182                                            partsList.toArray(new Part[partsList.size()]),
1183                                            postMethod.getParams());
1184    
1185                            postMethod.setRequestEntity(multipartRequestEntity);
1186                    }
1187            }
1188    
1189            protected org.apache.commons.httpclient.Cookie toCommonsCookie(
1190                    Cookie cookie) {
1191    
1192                    org.apache.commons.httpclient.Cookie commonsCookie =
1193                            new org.apache.commons.httpclient.Cookie(
1194                                    cookie.getDomain(), cookie.getName(), cookie.getValue(),
1195                                    cookie.getPath(), cookie.getMaxAge(), cookie.getSecure());
1196    
1197                    commonsCookie.setVersion(cookie.getVersion());
1198    
1199                    return commonsCookie;
1200            }
1201    
1202            protected org.apache.commons.httpclient.Cookie[] toCommonsCookies(
1203                    Cookie[] cookies) {
1204    
1205                    if (cookies == null) {
1206                            return null;
1207                    }
1208    
1209                    org.apache.commons.httpclient.Cookie[] commonCookies =
1210                            new org.apache.commons.httpclient.Cookie[cookies.length];
1211    
1212                    for (int i = 0; i < cookies.length; i++) {
1213                            commonCookies[i] = toCommonsCookie(cookies[i]);
1214                    }
1215    
1216                    return commonCookies;
1217            }
1218    
1219            protected org.apache.commons.httpclient.methods.multipart.FilePart
1220                    toCommonsFilePart(Http.FilePart filePart) {
1221    
1222                    return new org.apache.commons.httpclient.methods.multipart.FilePart(
1223                            filePart.getName(),
1224                            new ByteArrayPartSource(
1225                                    filePart.getFileName(), filePart.getValue()),
1226                            filePart.getContentType(), filePart.getCharSet());
1227            }
1228    
1229            protected Cookie toServletCookie(
1230                    org.apache.commons.httpclient.Cookie commonsCookie) {
1231    
1232                    Cookie cookie = new Cookie(
1233                            commonsCookie.getName(), commonsCookie.getValue());
1234    
1235                    if (!PropsValues.SESSION_COOKIE_USE_FULL_HOSTNAME) {
1236                            String domain = commonsCookie.getDomain();
1237    
1238                            if (Validator.isNotNull(domain)) {
1239                                    cookie.setDomain(domain);
1240                            }
1241                    }
1242    
1243                    Date expiryDate = commonsCookie.getExpiryDate();
1244    
1245                    if (expiryDate != null) {
1246                            int maxAge =
1247                                    (int)(expiryDate.getTime() - System.currentTimeMillis());
1248    
1249                            maxAge = maxAge / 1000;
1250    
1251                            if (maxAge > -1) {
1252                                    cookie.setMaxAge(maxAge);
1253                            }
1254                    }
1255    
1256                    String path = commonsCookie.getPath();
1257    
1258                    if (Validator.isNotNull(path)) {
1259                            cookie.setPath(path);
1260                    }
1261    
1262                    cookie.setSecure(commonsCookie.getSecure());
1263                    cookie.setVersion(commonsCookie.getVersion());
1264    
1265                    return cookie;
1266            }
1267    
1268            protected Cookie[] toServletCookies(
1269                    org.apache.commons.httpclient.Cookie[] commonsCookies) {
1270    
1271                    if (commonsCookies == null) {
1272                            return null;
1273                    }
1274    
1275                    Cookie[] cookies = new Cookie[commonsCookies.length];
1276    
1277                    for (int i = 0; i < commonsCookies.length; i++) {
1278                            cookies[i] = toServletCookie(commonsCookies[i]);
1279                    }
1280    
1281                    return cookies;
1282            }
1283    
1284            protected byte[] URLtoByteArray(
1285                            String location, Http.Method method, Map<String, String> headers,
1286                            Cookie[] cookies, Http.Auth auth, Http.Body body,
1287                            List<Http.FilePart> fileParts, Map<String, String> parts,
1288                            Http.Response response, boolean followRedirects, String progressId,
1289                            PortletRequest portletRequest)
1290                    throws IOException {
1291    
1292                    byte[] bytes = null;
1293    
1294                    HttpMethod httpMethod = null;
1295                    HttpState httpState = null;
1296    
1297                    try {
1298                            _cookies.set(null);
1299    
1300                            if (location == null) {
1301                                    return null;
1302                            }
1303                            else if (!location.startsWith(Http.HTTP_WITH_SLASH) &&
1304                                             !location.startsWith(Http.HTTPS_WITH_SLASH)) {
1305    
1306                                    location = Http.HTTP_WITH_SLASH + location;
1307                            }
1308    
1309                            HostConfiguration hostConfiguration = getHostConfiguration(
1310                                    location);
1311    
1312                            HttpClient httpClient = getClient(hostConfiguration);
1313    
1314                            if (method.equals(Http.Method.POST) ||
1315                                    method.equals(Http.Method.PUT)) {
1316    
1317                                    if (method.equals(Http.Method.POST)) {
1318                                            httpMethod = new PostMethod(location);
1319                                    }
1320                                    else {
1321                                            httpMethod = new PutMethod(location);
1322                                    }
1323    
1324                                    if (body != null) {
1325                                            RequestEntity requestEntity = new StringRequestEntity(
1326                                                    body.getContent(), body.getContentType(),
1327                                                    body.getCharset());
1328    
1329                                            EntityEnclosingMethod entityEnclosingMethod =
1330                                                    (EntityEnclosingMethod)httpMethod;
1331    
1332                                            entityEnclosingMethod.setRequestEntity(requestEntity);
1333                                    }
1334                                    else if (method.equals(Http.Method.POST)) {
1335                                            PostMethod postMethod = (PostMethod)httpMethod;
1336    
1337                                            if (!hasRequestHeader(
1338                                                            postMethod, HttpHeaders.CONTENT_TYPE)) {
1339    
1340                                                    HttpClientParams httpClientParams =
1341                                                            httpClient.getParams();
1342    
1343                                                    httpClientParams.setParameter(
1344                                                            HttpMethodParams.HTTP_CONTENT_CHARSET,
1345                                                            StringPool.UTF8);
1346                                            }
1347    
1348                                            processPostMethod(postMethod, fileParts, parts);
1349                                    }
1350                            }
1351                            else if (method.equals(Http.Method.DELETE)) {
1352                                    httpMethod = new DeleteMethod(location);
1353                            }
1354                            else if (method.equals(Http.Method.HEAD)) {
1355                                    httpMethod = new HeadMethod(location);
1356                            }
1357                            else {
1358                                    httpMethod = new GetMethod(location);
1359                            }
1360    
1361                            if (headers != null) {
1362                                    for (Map.Entry<String, String> header : headers.entrySet()) {
1363                                            httpMethod.addRequestHeader(
1364                                                    header.getKey(), header.getValue());
1365                                    }
1366                            }
1367    
1368                            if ((method.equals(Http.Method.POST) ||
1369                                     method.equals(Http.Method.PUT)) &&
1370                                    ((body != null) ||
1371                                     ((fileParts != null) && !fileParts.isEmpty()) ||
1372                                     ((parts != null) && !parts.isEmpty()))) {
1373                            }
1374                            else if (!hasRequestHeader(httpMethod, HttpHeaders.CONTENT_TYPE)) {
1375                                    httpMethod.addRequestHeader(
1376                                            HttpHeaders.CONTENT_TYPE,
1377                                            ContentTypes.APPLICATION_X_WWW_FORM_URLENCODED_UTF8);
1378                            }
1379    
1380                            if (!hasRequestHeader(httpMethod, HttpHeaders.USER_AGENT)) {
1381                                    httpMethod.addRequestHeader(
1382                                            HttpHeaders.USER_AGENT, _DEFAULT_USER_AGENT);
1383                            }
1384    
1385                            httpState = new HttpState();
1386    
1387                            if (ArrayUtil.isNotEmpty(cookies)) {
1388                                    org.apache.commons.httpclient.Cookie[] commonsCookies =
1389                                            toCommonsCookies(cookies);
1390    
1391                                    httpState.addCookies(commonsCookies);
1392    
1393                                    HttpMethodParams httpMethodParams = httpMethod.getParams();
1394    
1395                                    httpMethodParams.setCookiePolicy(
1396                                            CookiePolicy.BROWSER_COMPATIBILITY);
1397                            }
1398    
1399                            if (auth != null) {
1400                                    httpMethod.setDoAuthentication(true);
1401    
1402                                    httpState.setCredentials(
1403                                            new AuthScope(
1404                                                    auth.getHost(), auth.getPort(), auth.getRealm()),
1405                                            new UsernamePasswordCredentials(
1406                                                    auth.getUsername(), auth.getPassword()));
1407                            }
1408    
1409                            proxifyState(httpState, hostConfiguration);
1410    
1411                            int responseCode = httpClient.executeMethod(
1412                                    hostConfiguration, httpMethod, httpState);
1413    
1414                            response.setResponseCode(responseCode);
1415    
1416                            Header locationHeader = httpMethod.getResponseHeader("location");
1417    
1418                            if ((locationHeader != null) && !locationHeader.equals(location)) {
1419                                    String redirect = locationHeader.getValue();
1420    
1421                                    if (followRedirects) {
1422                                            return URLtoByteArray(
1423                                                    redirect, Http.Method.GET, headers, cookies, auth, body,
1424                                                    fileParts, parts, response, followRedirects, progressId,
1425                                                    portletRequest);
1426                                    }
1427                                    else {
1428                                            response.setRedirect(redirect);
1429                                    }
1430                            }
1431    
1432                            InputStream inputStream = httpMethod.getResponseBodyAsStream();
1433    
1434                            if (inputStream != null) {
1435                                    int contentLength = 0;
1436    
1437                                    Header contentLengthHeader = httpMethod.getResponseHeader(
1438                                            HttpHeaders.CONTENT_LENGTH);
1439    
1440                                    if (contentLengthHeader != null) {
1441                                            contentLength = GetterUtil.getInteger(
1442                                                    contentLengthHeader.getValue());
1443    
1444                                            response.setContentLength(contentLength);
1445                                    }
1446    
1447                                    Header contentType = httpMethod.getResponseHeader(
1448                                            HttpHeaders.CONTENT_TYPE);
1449    
1450                                    if (contentType != null) {
1451                                            response.setContentType(contentType.getValue());
1452                                    }
1453    
1454                                    if (Validator.isNotNull(progressId) &&
1455                                            (portletRequest != null)) {
1456    
1457                                            ProgressInputStream progressInputStream =
1458                                                    new ProgressInputStream(
1459                                                            portletRequest, inputStream, contentLength,
1460                                                            progressId);
1461    
1462                                            UnsyncByteArrayOutputStream unsyncByteArrayOutputStream =
1463                                                    new UnsyncByteArrayOutputStream(contentLength);
1464    
1465                                            try {
1466                                                    progressInputStream.readAll(
1467                                                    unsyncByteArrayOutputStream);
1468                                            }
1469                                            finally {
1470                                                    progressInputStream.clearProgress();
1471                                            }
1472    
1473                                            bytes = unsyncByteArrayOutputStream.unsafeGetByteArray();
1474    
1475                                            unsyncByteArrayOutputStream.close();
1476                                    }
1477                                    else {
1478                                            bytes = FileUtil.getBytes(inputStream);
1479                                    }
1480                            }
1481    
1482                            for (Header header : httpMethod.getResponseHeaders()) {
1483                                    response.addHeader(header.getName(), header.getValue());
1484                            }
1485    
1486                            return bytes;
1487                    }
1488                    finally {
1489                            try {
1490                                    if (httpState != null) {
1491                                            _cookies.set(toServletCookies(httpState.getCookies()));
1492                                    }
1493                            }
1494                            catch (Exception e) {
1495                                    _log.error(e, e);
1496                            }
1497    
1498                            try {
1499                                    if (httpMethod != null) {
1500                                            httpMethod.releaseConnection();
1501                                    }
1502                            }
1503                            catch (Exception e) {
1504                                    _log.error(e, e);
1505                            }
1506                    }
1507            }
1508    
1509            private static final String _DEFAULT_USER_AGENT =
1510                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)";
1511    
1512            private static final int _MAX_CONNECTIONS_PER_HOST = GetterUtil.getInteger(
1513                    PropsUtil.get(HttpImpl.class.getName() + ".max.connections.per.host"),
1514                    2);
1515    
1516            private static final int _MAX_TOTAL_CONNECTIONS = GetterUtil.getInteger(
1517                    PropsUtil.get(HttpImpl.class.getName() + ".max.total.connections"), 20);
1518    
1519            private static final String _NON_PROXY_HOSTS = SystemProperties.get(
1520                    "http.nonProxyHosts");
1521    
1522            private static final String _PROXY_AUTH_TYPE = GetterUtil.getString(
1523                    PropsUtil.get(HttpImpl.class.getName() + ".proxy.auth.type"));
1524    
1525            private static final String _PROXY_HOST = GetterUtil.getString(
1526                    SystemProperties.get("http.proxyHost"));
1527    
1528            private static final String _PROXY_NTLM_DOMAIN = GetterUtil.getString(
1529                    PropsUtil.get(HttpImpl.class.getName() + ".proxy.ntlm.domain"));
1530    
1531            private static final String _PROXY_NTLM_HOST = GetterUtil.getString(
1532                    PropsUtil.get(HttpImpl.class.getName() + ".proxy.ntlm.host"));
1533    
1534            private static final String _PROXY_PASSWORD = GetterUtil.getString(
1535                    PropsUtil.get(HttpImpl.class.getName() + ".proxy.password"));
1536    
1537            private static final int _PROXY_PORT = GetterUtil.getInteger(
1538                    SystemProperties.get("http.proxyPort"));
1539    
1540            private static final String _PROXY_USERNAME = GetterUtil.getString(
1541                    PropsUtil.get(HttpImpl.class.getName() + ".proxy.username"));
1542    
1543            private static final String _TEMP_SLASH = "_LIFERAY_TEMP_SLASH_";
1544    
1545            private static final int _TIMEOUT = GetterUtil.getInteger(
1546                    PropsUtil.get(HttpImpl.class.getName() + ".timeout"), 5000);
1547    
1548            private static Log _log = LogFactoryUtil.getLog(HttpImpl.class);
1549    
1550            private static ThreadLocal<Cookie[]> _cookies = new ThreadLocal<Cookie[]>();
1551    
1552            private HttpClient _httpClient = new HttpClient();
1553            private Pattern _nonProxyHostsPattern;
1554            private Credentials _proxyCredentials;
1555            private HttpClient _proxyHttpClient = new HttpClient();
1556    
1557            private class FastProtocolSocketFactory
1558                    extends DefaultProtocolSocketFactory {
1559    
1560                    @Override
1561                    public Socket createSocket(
1562                                    final String host, final int port,
1563                                    final InetAddress localInetAddress, final int localPort,
1564                                    final HttpConnectionParams httpConnectionParams)
1565                            throws ConnectTimeoutException, IOException, UnknownHostException {
1566    
1567                            int connectionTimeout = httpConnectionParams.getConnectionTimeout();
1568    
1569                            if (connectionTimeout == 0) {
1570                                    return createSocket(host, port, localInetAddress, localPort);
1571                            }
1572    
1573                            SocketFactory socketFactory = SocketFactory.getDefault();
1574    
1575                            Socket socket = socketFactory.createSocket();
1576    
1577                            SocketAddress localSocketAddress = new InetSocketAddress(
1578                                    localInetAddress, localPort);
1579    
1580                            SocketAddress remoteSocketAddress = new InetSocketAddress(
1581                                    host, port);
1582    
1583                            socket.bind(localSocketAddress);
1584    
1585                            socket.connect(remoteSocketAddress, connectionTimeout);
1586    
1587                            return socket;
1588                    }
1589    
1590            }
1591    
1592    }