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