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