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                                            value = decodeURL(kvp[1]);
739                                    }
740    
741                                    List<String> values = tempParameterMap.get(key);
742    
743                                    if (values == null) {
744                                            values = new ArrayList<String>();
745    
746                                            tempParameterMap.put(key, values);
747                                    }
748    
749                                    values.add(value);
750                            }
751                    }
752    
753                    for (Map.Entry<String, List<String>> entry :
754                                    tempParameterMap.entrySet()) {
755    
756                            String key = entry.getKey();
757                            List<String> values = entry.getValue();
758    
759                            parameterMap.put(key, values.toArray(new String[values.size()]));
760                    }
761    
762                    return parameterMap;
763            }
764    
765            @Override
766            public String parameterMapToString(Map<String, String[]> parameterMap) {
767                    return parameterMapToString(parameterMap, true);
768            }
769    
770            @Override
771            public String parameterMapToString(
772                    Map<String, String[]> parameterMap, boolean addQuestion) {
773    
774                    if (parameterMap.isEmpty()) {
775                            return StringPool.BLANK;
776                    }
777    
778                    StringBundler sb = new StringBundler();
779    
780                    if (addQuestion) {
781                            sb.append(StringPool.QUESTION);
782                    }
783    
784                    for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
785                            String name = entry.getKey();
786                            String[] values = entry.getValue();
787    
788                            for (String value : values) {
789                                    sb.append(name);
790                                    sb.append(StringPool.EQUAL);
791                                    sb.append(encodeURL(value));
792                                    sb.append(StringPool.AMPERSAND);
793                            }
794                    }
795    
796                    if (sb.index() > 1) {
797                            sb.setIndex(sb.index() - 1);
798                    }
799    
800                    return sb.toString();
801            }
802    
803            @Override
804            public String protocolize(String url, ActionRequest actionRequest) {
805                    return protocolize(url, actionRequest.isSecure());
806            }
807    
808            @Override
809            public String protocolize(String url, boolean secure) {
810                    return protocolize(url, -1, secure);
811            }
812    
813            @Override
814            public String protocolize(String url, HttpServletRequest request) {
815                    return protocolize(url, request.isSecure());
816            }
817    
818            @Override
819            public String protocolize(String url, int port, boolean secure) {
820                    if (Validator.isNull(url)) {
821                            return url;
822                    }
823    
824                    try {
825                            URL urlObj = new URL(url);
826    
827                            String protocol = Http.HTTP;
828    
829                            if (secure) {
830                                    protocol = Http.HTTPS;
831                            }
832    
833                            urlObj = new URL(
834                                    protocol, urlObj.getHost(), port, urlObj.getFile());
835    
836                            return urlObj.toString();
837                    }
838                    catch (Exception e) {
839                            return url;
840                    }
841            }
842    
843            @Override
844            public String protocolize(String url, RenderRequest renderRequest) {
845                    return protocolize(url, renderRequest.isSecure());
846            }
847    
848            public void proxifyState(
849                    HttpState httpState, HostConfiguration hostConfiguration) {
850    
851                    Credentials proxyCredentials = _proxyCredentials;
852    
853                    String host = hostConfiguration.getHost();
854    
855                    if (isProxyHost(host) && (proxyCredentials != null)) {
856                            AuthScope scope = new AuthScope(_PROXY_HOST, _PROXY_PORT, null);
857    
858                            httpState.setProxyCredentials(scope, proxyCredentials);
859                    }
860            }
861    
862            @Override
863            public String removeDomain(String url) {
864                    if (Validator.isNull(url)) {
865                            return url;
866                    }
867    
868                    url = removeProtocol(url);
869    
870                    int pos = url.indexOf(CharPool.SLASH);
871    
872                    if (pos > 0) {
873                            return url.substring(pos);
874                    }
875    
876                    return url;
877            }
878    
879            @Override
880            public String removeParameter(String url, String name) {
881                    if (Validator.isNull(url) || Validator.isNull(name)) {
882                            return url;
883                    }
884    
885                    int pos = url.indexOf(CharPool.QUESTION);
886    
887                    if (pos == -1) {
888                            return url;
889                    }
890    
891                    String[] array = PortalUtil.stripURLAnchor(url, StringPool.POUND);
892    
893                    url = array[0];
894    
895                    String anchor = array[1];
896    
897                    StringBundler sb = new StringBundler();
898    
899                    sb.append(url.substring(0, pos + 1));
900    
901                    String[] parameters = StringUtil.split(
902                            url.substring(pos + 1, url.length()), CharPool.AMPERSAND);
903    
904                    for (String parameter : parameters) {
905                            if (parameter.length() > 0) {
906                                    String[] kvp = StringUtil.split(parameter, CharPool.EQUAL);
907    
908                                    String key = kvp[0];
909    
910                                    String value = StringPool.BLANK;
911    
912                                    if (kvp.length > 1) {
913                                            value = kvp[1];
914                                    }
915    
916                                    if (!key.equals(name)) {
917                                            sb.append(key);
918                                            sb.append(StringPool.EQUAL);
919                                            sb.append(value);
920                                            sb.append(StringPool.AMPERSAND);
921                                    }
922                            }
923                    }
924    
925                    url = StringUtil.replace(
926                            sb.toString(), StringPool.AMPERSAND + StringPool.AMPERSAND,
927                            StringPool.AMPERSAND);
928    
929                    if (url.endsWith(StringPool.AMPERSAND)) {
930                            url = url.substring(0, url.length() - 1);
931                    }
932    
933                    if (url.endsWith(StringPool.QUESTION)) {
934                            url = url.substring(0, url.length() - 1);
935                    }
936    
937                    return url + anchor;
938            }
939    
940            @Override
941            public String removeProtocol(String url) {
942                    if (Validator.isNull(url)) {
943                            return url;
944                    }
945    
946                    if (url.startsWith(Http.HTTP_WITH_SLASH)) {
947                            return url.substring(Http.HTTP_WITH_SLASH.length());
948                    }
949                    else if (url.startsWith(Http.HTTPS_WITH_SLASH)) {
950                            return url.substring(Http.HTTPS_WITH_SLASH.length());
951                    }
952                    else {
953                            return url;
954                    }
955            }
956    
957            @Override
958            public String sanitizeHeader(String header) {
959                    if (header == null) {
960                            return null;
961                    }
962    
963                    StringBuilder sb = null;
964    
965                    for (int i = 0; i < header.length(); i++) {
966                            char c = header.charAt(i);
967    
968                            if (((c <= 31) && (c != 9)) || (c == 127) || (c > 255)) {
969                                    if (sb == null) {
970                                            sb = new StringBuilder(header);
971                                    }
972    
973                                    sb.setCharAt(i, CharPool.SPACE);
974                            }
975                    }
976    
977                    if (sb != null) {
978                            header = sb.toString();
979                    }
980    
981                    return header;
982            }
983    
984            @Override
985            public String setParameter(String url, String name, boolean value) {
986                    return setParameter(url, name, String.valueOf(value));
987            }
988    
989            @Override
990            public String setParameter(String url, String name, double value) {
991                    return setParameter(url, name, String.valueOf(value));
992            }
993    
994            @Override
995            public String setParameter(String url, String name, int value) {
996                    return setParameter(url, name, String.valueOf(value));
997            }
998    
999            @Override
1000            public String setParameter(String url, String name, long value) {
1001                    return setParameter(url, name, String.valueOf(value));
1002            }
1003    
1004            @Override
1005            public String setParameter(String url, String name, short value) {
1006                    return setParameter(url, name, String.valueOf(value));
1007            }
1008    
1009            @Override
1010            public String setParameter(String url, String name, String value) {
1011                    if (Validator.isNull(url) || Validator.isNull(name)) {
1012                            return url;
1013                    }
1014    
1015                    url = removeParameter(url, name);
1016    
1017                    return addParameter(url, name, value);
1018            }
1019    
1020            @Override
1021            public byte[] URLtoByteArray(Http.Options options) throws IOException {
1022                    return URLtoByteArray(
1023                            options.getLocation(), options.getMethod(), options.getHeaders(),
1024                            options.getCookies(), options.getAuth(), options.getBody(),
1025                            options.getFileParts(), options.getParts(), options.getResponse(),
1026                            options.isFollowRedirects(), options.getProgressId(),
1027                            options.getPortletRequest());
1028            }
1029    
1030            @Override
1031            public byte[] URLtoByteArray(String location) throws IOException {
1032                    Http.Options options = new Http.Options();
1033    
1034                    options.setLocation(location);
1035    
1036                    return URLtoByteArray(options);
1037            }
1038    
1039            @Override
1040            public byte[] URLtoByteArray(String location, boolean post)
1041                    throws IOException {
1042    
1043                    Http.Options options = new Http.Options();
1044    
1045                    options.setLocation(location);
1046                    options.setPost(post);
1047    
1048                    return URLtoByteArray(options);
1049            }
1050    
1051            @Override
1052            public String URLtoString(Http.Options options) throws IOException {
1053                    return new String(URLtoByteArray(options));
1054            }
1055    
1056            @Override
1057            public String URLtoString(String location) throws IOException {
1058                    return new String(URLtoByteArray(location));
1059            }
1060    
1061            @Override
1062            public String URLtoString(String location, boolean post)
1063                    throws IOException {
1064    
1065                    return new String(URLtoByteArray(location, post));
1066            }
1067    
1068            /**
1069             * This method only uses the default Commons HttpClient implementation when
1070             * the URL object represents a HTTP resource. The URL object could also
1071             * represent a file or some JNDI resource. In that case, the default Java
1072             * implementation is used.
1073             *
1074             * @param  url the URL
1075             * @return A string representation of the resource referenced by the URL
1076             *         object
1077             * @throws IOException if an IO exception occurred
1078             */
1079            @Override
1080            public String URLtoString(URL url) throws IOException {
1081                    String xml = null;
1082    
1083                    if (url == null) {
1084                            return null;
1085                    }
1086    
1087                    String protocol = StringUtil.toLowerCase(url.getProtocol());
1088    
1089                    if (protocol.startsWith(Http.HTTP) || protocol.startsWith(Http.HTTPS)) {
1090                            return URLtoString(url.toString());
1091                    }
1092    
1093                    URLConnection urlConnection = url.openConnection();
1094    
1095                    InputStream inputStream = urlConnection.getInputStream();
1096    
1097                    UnsyncByteArrayOutputStream unsyncByteArrayOutputStream =
1098                            new UnsyncByteArrayOutputStream();
1099    
1100                    byte[] bytes = new byte[512];
1101    
1102                    for (int i = inputStream.read(bytes, 0, 512); i != -1;
1103                                    i = inputStream.read(bytes, 0, 512)) {
1104    
1105                            unsyncByteArrayOutputStream.write(bytes, 0, i);
1106                    }
1107    
1108                    xml = new String(
1109                            unsyncByteArrayOutputStream.unsafeGetByteArray(), 0,
1110                            unsyncByteArrayOutputStream.size());
1111    
1112                    inputStream.close();
1113    
1114                    unsyncByteArrayOutputStream.close();
1115    
1116                    return xml;
1117            }
1118    
1119            protected boolean hasRequestHeader(HttpMethod httpMethod, String name) {
1120                    Header[] headers = httpMethod.getRequestHeaders(name);
1121    
1122                    if (headers.length == 0) {
1123                            return false;
1124                    }
1125    
1126                    return true;
1127            }
1128    
1129            protected void processPostMethod(
1130                    PostMethod postMethod, List<Http.FilePart> fileParts,
1131                    Map<String, String> parts) {
1132    
1133                    if ((fileParts == null) || fileParts.isEmpty()) {
1134                            if (parts != null) {
1135                                    for (Map.Entry<String, String> entry : parts.entrySet()) {
1136                                            String value = entry.getValue();
1137    
1138                                            if (value != null) {
1139                                                    postMethod.addParameter(entry.getKey(), value);
1140                                            }
1141                                    }
1142                            }
1143                    }
1144                    else {
1145                            List<Part> partsList = new ArrayList<Part>();
1146    
1147                            if (parts != null) {
1148                                    for (Map.Entry<String, String> entry : parts.entrySet()) {
1149                                            String value = entry.getValue();
1150    
1151                                            if (value != null) {
1152                                                    StringPart stringPart = new StringPart(
1153                                                            entry.getKey(), value);
1154    
1155                                                    partsList.add(stringPart);
1156                                            }
1157                                    }
1158                            }
1159    
1160                            for (Http.FilePart filePart : fileParts) {
1161                                    partsList.add(toCommonsFilePart(filePart));
1162                            }
1163    
1164                            MultipartRequestEntity multipartRequestEntity =
1165                                    new MultipartRequestEntity(
1166                                            partsList.toArray(new Part[partsList.size()]),
1167                                            postMethod.getParams());
1168    
1169                            postMethod.setRequestEntity(multipartRequestEntity);
1170                    }
1171            }
1172    
1173            protected org.apache.commons.httpclient.Cookie toCommonsCookie(
1174                    Cookie cookie) {
1175    
1176                    org.apache.commons.httpclient.Cookie commonsCookie =
1177                            new org.apache.commons.httpclient.Cookie(
1178                                    cookie.getDomain(), cookie.getName(), cookie.getValue(),
1179                                    cookie.getPath(), cookie.getMaxAge(), cookie.getSecure());
1180    
1181                    commonsCookie.setVersion(cookie.getVersion());
1182    
1183                    return commonsCookie;
1184            }
1185    
1186            protected org.apache.commons.httpclient.Cookie[] toCommonsCookies(
1187                    Cookie[] cookies) {
1188    
1189                    if (cookies == null) {
1190                            return null;
1191                    }
1192    
1193                    org.apache.commons.httpclient.Cookie[] commonCookies =
1194                            new org.apache.commons.httpclient.Cookie[cookies.length];
1195    
1196                    for (int i = 0; i < cookies.length; i++) {
1197                            commonCookies[i] = toCommonsCookie(cookies[i]);
1198                    }
1199    
1200                    return commonCookies;
1201            }
1202    
1203            protected org.apache.commons.httpclient.methods.multipart.FilePart
1204                    toCommonsFilePart(Http.FilePart filePart) {
1205    
1206                    return new org.apache.commons.httpclient.methods.multipart.FilePart(
1207                            filePart.getName(),
1208                            new ByteArrayPartSource(
1209                                    filePart.getFileName(), filePart.getValue()),
1210                            filePart.getContentType(), filePart.getCharSet());
1211            }
1212    
1213            protected Cookie toServletCookie(
1214                    org.apache.commons.httpclient.Cookie commonsCookie) {
1215    
1216                    Cookie cookie = new Cookie(
1217                            commonsCookie.getName(), commonsCookie.getValue());
1218    
1219                    if (!PropsValues.SESSION_COOKIE_USE_FULL_HOSTNAME) {
1220                            String domain = commonsCookie.getDomain();
1221    
1222                            if (Validator.isNotNull(domain)) {
1223                                    cookie.setDomain(domain);
1224                            }
1225                    }
1226    
1227                    Date expiryDate = commonsCookie.getExpiryDate();
1228    
1229                    if (expiryDate != null) {
1230                            int maxAge =
1231                                    (int)(expiryDate.getTime() - System.currentTimeMillis());
1232    
1233                            maxAge = maxAge / 1000;
1234    
1235                            if (maxAge > -1) {
1236                                    cookie.setMaxAge(maxAge);
1237                            }
1238                    }
1239    
1240                    String path = commonsCookie.getPath();
1241    
1242                    if (Validator.isNotNull(path)) {
1243                            cookie.setPath(path);
1244                    }
1245    
1246                    cookie.setSecure(commonsCookie.getSecure());
1247                    cookie.setVersion(commonsCookie.getVersion());
1248    
1249                    return cookie;
1250            }
1251    
1252            protected Cookie[] toServletCookies(
1253                    org.apache.commons.httpclient.Cookie[] commonsCookies) {
1254    
1255                    if (commonsCookies == null) {
1256                            return null;
1257                    }
1258    
1259                    Cookie[] cookies = new Cookie[commonsCookies.length];
1260    
1261                    for (int i = 0; i < commonsCookies.length; i++) {
1262                            cookies[i] = toServletCookie(commonsCookies[i]);
1263                    }
1264    
1265                    return cookies;
1266            }
1267    
1268            protected byte[] URLtoByteArray(
1269                            String location, Http.Method method, Map<String, String> headers,
1270                            Cookie[] cookies, Http.Auth auth, Http.Body body,
1271                            List<Http.FilePart> fileParts, Map<String, String> parts,
1272                            Http.Response response, boolean followRedirects, String progressId,
1273                            PortletRequest portletRequest)
1274                    throws IOException {
1275    
1276                    byte[] bytes = null;
1277    
1278                    HttpMethod httpMethod = null;
1279                    HttpState httpState = null;
1280    
1281                    try {
1282                            _cookies.set(null);
1283    
1284                            if (location == null) {
1285                                    return null;
1286                            }
1287                            else if (!location.startsWith(Http.HTTP_WITH_SLASH) &&
1288                                             !location.startsWith(Http.HTTPS_WITH_SLASH)) {
1289    
1290                                    location = Http.HTTP_WITH_SLASH + location;
1291                            }
1292    
1293                            HostConfiguration hostConfiguration = getHostConfiguration(
1294                                    location);
1295    
1296                            HttpClient httpClient = getClient(hostConfiguration);
1297    
1298                            if (method.equals(Http.Method.POST) ||
1299                                    method.equals(Http.Method.PUT)) {
1300    
1301                                    if (method.equals(Http.Method.POST)) {
1302                                            httpMethod = new PostMethod(location);
1303                                    }
1304                                    else {
1305                                            httpMethod = new PutMethod(location);
1306                                    }
1307    
1308                                    if (body != null) {
1309                                            RequestEntity requestEntity = new StringRequestEntity(
1310                                                    body.getContent(), body.getContentType(),
1311                                                    body.getCharset());
1312    
1313                                            EntityEnclosingMethod entityEnclosingMethod =
1314                                                    (EntityEnclosingMethod)httpMethod;
1315    
1316                                            entityEnclosingMethod.setRequestEntity(requestEntity);
1317                                    }
1318                                    else if (method.equals(Http.Method.POST)) {
1319                                            PostMethod postMethod = (PostMethod)httpMethod;
1320    
1321                                            if (!hasRequestHeader(
1322                                                            postMethod, HttpHeaders.CONTENT_TYPE)) {
1323    
1324                                                    HttpClientParams httpClientParams =
1325                                                            httpClient.getParams();
1326    
1327                                                    httpClientParams.setParameter(
1328                                                            HttpMethodParams.HTTP_CONTENT_CHARSET,
1329                                                            StringPool.UTF8);
1330                                            }
1331    
1332                                            processPostMethod(postMethod, fileParts, parts);
1333                                    }
1334                            }
1335                            else if (method.equals(Http.Method.DELETE)) {
1336                                    httpMethod = new DeleteMethod(location);
1337                            }
1338                            else if (method.equals(Http.Method.HEAD)) {
1339                                    httpMethod = new HeadMethod(location);
1340                            }
1341                            else {
1342                                    httpMethod = new GetMethod(location);
1343                            }
1344    
1345                            if (headers != null) {
1346                                    for (Map.Entry<String, String> header : headers.entrySet()) {
1347                                            httpMethod.addRequestHeader(
1348                                                    header.getKey(), header.getValue());
1349                                    }
1350                            }
1351    
1352                            if ((method.equals(Http.Method.POST) ||
1353                                     method.equals(Http.Method.PUT)) &&
1354                                    ((body != null) ||
1355                                     ((fileParts != null) && !fileParts.isEmpty()) ||
1356                                     ((parts != null) && !parts.isEmpty()))) {
1357                            }
1358                            else if (!hasRequestHeader(httpMethod, HttpHeaders.CONTENT_TYPE)) {
1359                                    httpMethod.addRequestHeader(
1360                                            HttpHeaders.CONTENT_TYPE,
1361                                            ContentTypes.APPLICATION_X_WWW_FORM_URLENCODED_UTF8);
1362                            }
1363    
1364                            if (!hasRequestHeader(httpMethod, HttpHeaders.USER_AGENT)) {
1365                                    httpMethod.addRequestHeader(
1366                                            HttpHeaders.USER_AGENT, _DEFAULT_USER_AGENT);
1367                            }
1368    
1369                            httpState = new HttpState();
1370    
1371                            if (ArrayUtil.isNotEmpty(cookies)) {
1372                                    org.apache.commons.httpclient.Cookie[] commonsCookies =
1373                                            toCommonsCookies(cookies);
1374    
1375                                    httpState.addCookies(commonsCookies);
1376    
1377                                    HttpMethodParams httpMethodParams = httpMethod.getParams();
1378    
1379                                    httpMethodParams.setCookiePolicy(
1380                                            CookiePolicy.BROWSER_COMPATIBILITY);
1381                            }
1382    
1383                            if (auth != null) {
1384                                    httpMethod.setDoAuthentication(true);
1385    
1386                                    httpState.setCredentials(
1387                                            new AuthScope(
1388                                                    auth.getHost(), auth.getPort(), auth.getRealm()),
1389                                            new UsernamePasswordCredentials(
1390                                                    auth.getUsername(), auth.getPassword()));
1391                            }
1392    
1393                            proxifyState(httpState, hostConfiguration);
1394    
1395                            int responseCode = httpClient.executeMethod(
1396                                    hostConfiguration, httpMethod, httpState);
1397    
1398                            response.setResponseCode(responseCode);
1399    
1400                            Header locationHeader = httpMethod.getResponseHeader("location");
1401    
1402                            if ((locationHeader != null) && !locationHeader.equals(location)) {
1403                                    String redirect = locationHeader.getValue();
1404    
1405                                    if (followRedirects) {
1406                                            return URLtoByteArray(
1407                                                    redirect, Http.Method.GET, headers, cookies, auth, body,
1408                                                    fileParts, parts, response, followRedirects, progressId,
1409                                                    portletRequest);
1410                                    }
1411                                    else {
1412                                            response.setRedirect(redirect);
1413                                    }
1414                            }
1415    
1416                            InputStream inputStream = httpMethod.getResponseBodyAsStream();
1417    
1418                            if (inputStream != null) {
1419                                    int contentLength = 0;
1420    
1421                                    Header contentLengthHeader = httpMethod.getResponseHeader(
1422                                            HttpHeaders.CONTENT_LENGTH);
1423    
1424                                    if (contentLengthHeader != null) {
1425                                            contentLength = GetterUtil.getInteger(
1426                                                    contentLengthHeader.getValue());
1427    
1428                                            response.setContentLength(contentLength);
1429                                    }
1430    
1431                                    Header contentType = httpMethod.getResponseHeader(
1432                                            HttpHeaders.CONTENT_TYPE);
1433    
1434                                    if (contentType != null) {
1435                                            response.setContentType(contentType.getValue());
1436                                    }
1437    
1438                                    if (Validator.isNotNull(progressId) &&
1439                                            (portletRequest != null)) {
1440    
1441                                            ProgressInputStream progressInputStream =
1442                                                    new ProgressInputStream(
1443                                                            portletRequest, inputStream, contentLength,
1444                                                            progressId);
1445    
1446                                            UnsyncByteArrayOutputStream unsyncByteArrayOutputStream =
1447                                                    new UnsyncByteArrayOutputStream(contentLength);
1448    
1449                                            try {
1450                                                    progressInputStream.readAll(
1451                                                    unsyncByteArrayOutputStream);
1452                                            }
1453                                            finally {
1454                                                    progressInputStream.clearProgress();
1455                                            }
1456    
1457                                            bytes = unsyncByteArrayOutputStream.unsafeGetByteArray();
1458    
1459                                            unsyncByteArrayOutputStream.close();
1460                                    }
1461                                    else {
1462                                            bytes = FileUtil.getBytes(inputStream);
1463                                    }
1464                            }
1465    
1466                            for (Header header : httpMethod.getResponseHeaders()) {
1467                                    response.addHeader(header.getName(), header.getValue());
1468                            }
1469    
1470                            return bytes;
1471                    }
1472                    finally {
1473                            try {
1474                                    if (httpState != null) {
1475                                            _cookies.set(toServletCookies(httpState.getCookies()));
1476                                    }
1477                            }
1478                            catch (Exception e) {
1479                                    _log.error(e, e);
1480                            }
1481    
1482                            try {
1483                                    if (httpMethod != null) {
1484                                            httpMethod.releaseConnection();
1485                                    }
1486                            }
1487                            catch (Exception e) {
1488                                    _log.error(e, e);
1489                            }
1490                    }
1491            }
1492    
1493            private static final String _DEFAULT_USER_AGENT =
1494                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)";
1495    
1496            private static final int _MAX_CONNECTIONS_PER_HOST = GetterUtil.getInteger(
1497                    PropsUtil.get(HttpImpl.class.getName() + ".max.connections.per.host"),
1498                    2);
1499    
1500            private static final int _MAX_TOTAL_CONNECTIONS = GetterUtil.getInteger(
1501                    PropsUtil.get(HttpImpl.class.getName() + ".max.total.connections"), 20);
1502    
1503            private static final String _NON_PROXY_HOSTS = SystemProperties.get(
1504                    "http.nonProxyHosts");
1505    
1506            private static final String _PROXY_AUTH_TYPE = GetterUtil.getString(
1507                    PropsUtil.get(HttpImpl.class.getName() + ".proxy.auth.type"));
1508    
1509            private static final String _PROXY_HOST = GetterUtil.getString(
1510                    SystemProperties.get("http.proxyHost"));
1511    
1512            private static final String _PROXY_NTLM_DOMAIN = GetterUtil.getString(
1513                    PropsUtil.get(HttpImpl.class.getName() + ".proxy.ntlm.domain"));
1514    
1515            private static final String _PROXY_NTLM_HOST = GetterUtil.getString(
1516                    PropsUtil.get(HttpImpl.class.getName() + ".proxy.ntlm.host"));
1517    
1518            private static final String _PROXY_PASSWORD = GetterUtil.getString(
1519                    PropsUtil.get(HttpImpl.class.getName() + ".proxy.password"));
1520    
1521            private static final int _PROXY_PORT = GetterUtil.getInteger(
1522                    SystemProperties.get("http.proxyPort"));
1523    
1524            private static final String _PROXY_USERNAME = GetterUtil.getString(
1525                    PropsUtil.get(HttpImpl.class.getName() + ".proxy.username"));
1526    
1527            private static final String _TEMP_SLASH = "_LIFERAY_TEMP_SLASH_";
1528    
1529            private static final int _TIMEOUT = GetterUtil.getInteger(
1530                    PropsUtil.get(HttpImpl.class.getName() + ".timeout"), 5000);
1531    
1532            private static Log _log = LogFactoryUtil.getLog(HttpImpl.class);
1533    
1534            private static ThreadLocal<Cookie[]> _cookies = new ThreadLocal<Cookie[]>();
1535    
1536            private HttpClient _httpClient = new HttpClient();
1537            private Pattern _nonProxyHostsPattern;
1538            private Credentials _proxyCredentials;
1539            private HttpClient _proxyHttpClient = new HttpClient();
1540    
1541            private class FastProtocolSocketFactory
1542                    extends DefaultProtocolSocketFactory {
1543    
1544                    @Override
1545                    public Socket createSocket(
1546                                    final String host, final int port,
1547                                    final InetAddress localInetAddress, final int localPort,
1548                                    final HttpConnectionParams httpConnectionParams)
1549                            throws ConnectTimeoutException, IOException, UnknownHostException {
1550    
1551                            int connectionTimeout = httpConnectionParams.getConnectionTimeout();
1552    
1553                            if (connectionTimeout == 0) {
1554                                    return createSocket(host, port, localInetAddress, localPort);
1555                            }
1556    
1557                            SocketFactory socketFactory = SocketFactory.getDefault();
1558    
1559                            Socket socket = socketFactory.createSocket();
1560    
1561                            SocketAddress localSocketAddress = new InetSocketAddress(
1562                                    localInetAddress, localPort);
1563    
1564                            SocketAddress remoteSocketAddress = new InetSocketAddress(
1565                                    host, port);
1566    
1567                            socket.bind(localSocketAddress);
1568    
1569                            socket.connect(remoteSocketAddress, connectionTimeout);
1570    
1571                            return socket;
1572                    }
1573    
1574            }
1575    
1576    }