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