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