001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.util;
016    
017    import com.liferay.portal.kernel.configuration.Filter;
018    import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayOutputStream;
019    import com.liferay.portal.kernel.log.Log;
020    import com.liferay.portal.kernel.log.LogFactoryUtil;
021    import com.liferay.portal.kernel.security.pacl.DoPrivileged;
022    import com.liferay.portal.kernel.servlet.HttpHeaders;
023    import com.liferay.portal.kernel.upload.ProgressInputStream;
024    import com.liferay.portal.kernel.util.ArrayUtil;
025    import com.liferay.portal.kernel.util.CharPool;
026    import com.liferay.portal.kernel.util.ContentTypes;
027    import com.liferay.portal.kernel.util.FileUtil;
028    import com.liferay.portal.kernel.util.GetterUtil;
029    import com.liferay.portal.kernel.util.Http;
030    import com.liferay.portal.kernel.util.StringBundler;
031    import com.liferay.portal.kernel.util.StringPool;
032    import com.liferay.portal.kernel.util.StringUtil;
033    import com.liferay.portal.kernel.util.SystemProperties;
034    import com.liferay.portal.kernel.util.URLCodec;
035    import com.liferay.portal.kernel.util.Validator;
036    
037    import java.io.IOException;
038    import java.io.InputStream;
039    
040    import java.net.InetAddress;
041    import java.net.InetSocketAddress;
042    import java.net.Socket;
043    import java.net.SocketAddress;
044    import java.net.URL;
045    import java.net.URLConnection;
046    import java.net.UnknownHostException;
047    
048    import java.util.ArrayList;
049    import java.util.Date;
050    import java.util.LinkedHashMap;
051    import java.util.List;
052    import java.util.Map;
053    import java.util.regex.Matcher;
054    import java.util.regex.Pattern;
055    
056    import javax.net.SocketFactory;
057    
058    import javax.portlet.ActionRequest;
059    import javax.portlet.PortletRequest;
060    import javax.portlet.RenderRequest;
061    
062    import javax.servlet.http.Cookie;
063    import javax.servlet.http.HttpServletRequest;
064    import javax.servlet.http.HttpSession;
065    
066    import org.apache.commons.httpclient.ConnectTimeoutException;
067    import org.apache.commons.httpclient.Credentials;
068    import org.apache.commons.httpclient.Header;
069    import org.apache.commons.httpclient.HostConfiguration;
070    import org.apache.commons.httpclient.HttpClient;
071    import org.apache.commons.httpclient.HttpConnectionManager;
072    import org.apache.commons.httpclient.HttpMethod;
073    import org.apache.commons.httpclient.HttpState;
074    import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
075    import org.apache.commons.httpclient.NTCredentials;
076    import org.apache.commons.httpclient.URI;
077    import org.apache.commons.httpclient.UsernamePasswordCredentials;
078    import org.apache.commons.httpclient.auth.AuthPolicy;
079    import org.apache.commons.httpclient.auth.AuthScope;
080    import org.apache.commons.httpclient.cookie.CookiePolicy;
081    import org.apache.commons.httpclient.methods.DeleteMethod;
082    import org.apache.commons.httpclient.methods.EntityEnclosingMethod;
083    import org.apache.commons.httpclient.methods.GetMethod;
084    import org.apache.commons.httpclient.methods.HeadMethod;
085    import org.apache.commons.httpclient.methods.PostMethod;
086    import org.apache.commons.httpclient.methods.PutMethod;
087    import org.apache.commons.httpclient.methods.RequestEntity;
088    import org.apache.commons.httpclient.methods.StringRequestEntity;
089    import org.apache.commons.httpclient.methods.multipart.ByteArrayPartSource;
090    import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
091    import org.apache.commons.httpclient.methods.multipart.Part;
092    import org.apache.commons.httpclient.methods.multipart.StringPart;
093    import org.apache.commons.httpclient.params.HostParams;
094    import org.apache.commons.httpclient.params.HttpClientParams;
095    import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
096    import org.apache.commons.httpclient.params.HttpConnectionParams;
097    import org.apache.commons.httpclient.params.HttpMethodParams;
098    import org.apache.commons.httpclient.protocol.DefaultProtocolSocketFactory;
099    import org.apache.commons.httpclient.protocol.Protocol;
100    
101    /**
102     * @author Brian Wing Shun Chan
103     * @author Hugo Huijser
104     * @author Shuyang Zhou
105     */
106    @DoPrivileged
107    public class HttpImpl implements Http {
108    
109            public HttpImpl() {
110    
111                    // Override the default protocol socket factory because it uses
112                    // reflection for JDK 1.4 compatibility, which we do not need. It also
113                    // attemps to create a new socket in a different thread so that we
114                    // cannot track which class loader initiated the call.
115    
116                    Protocol protocol = new Protocol(
117                            "http", new FastProtocolSocketFactory(), 80);
118    
119                    Protocol.registerProtocol("http", protocol);
120    
121                    // Mimic behavior found in
122                    // http://java.sun.com/j2se/1.5.0/docs/guide/net/properties.html
123    
124                    if (Validator.isNotNull(_NON_PROXY_HOSTS)) {
125                            String nonProxyHostsRegEx = _NON_PROXY_HOSTS;
126    
127                            nonProxyHostsRegEx = nonProxyHostsRegEx.replaceAll("\\.", "\\\\.");
128                            nonProxyHostsRegEx = nonProxyHostsRegEx.replaceAll("\\*", ".*?");
129                            nonProxyHostsRegEx = nonProxyHostsRegEx.replaceAll("\\|", ")|(");
130    
131                            nonProxyHostsRegEx = "(" + nonProxyHostsRegEx + ")";
132    
133                            _nonProxyHostsPattern = Pattern.compile(nonProxyHostsRegEx);
134                    }
135    
136                    MultiThreadedHttpConnectionManager httpConnectionManager =
137                            new MultiThreadedHttpConnectionManager();
138    
139                    HttpConnectionManagerParams httpConnectionManagerParams =
140                            httpConnectionManager.getParams();
141    
142                    httpConnectionManagerParams.setConnectionTimeout(_TIMEOUT);
143                    httpConnectionManagerParams.setDefaultMaxConnectionsPerHost(
144                            new Integer(_MAX_CONNECTIONS_PER_HOST));
145                    httpConnectionManagerParams.setMaxTotalConnections(
146                            new Integer(_MAX_TOTAL_CONNECTIONS));
147                    httpConnectionManagerParams.setSoTimeout(_TIMEOUT);
148    
149                    _httpClient.setHttpConnectionManager(httpConnectionManager);
150                    _proxyHttpClient.setHttpConnectionManager(httpConnectionManager);
151    
152                    if (!hasProxyConfig() || Validator.isNull(_PROXY_USERNAME)) {
153                            return;
154                    }
155    
156                    List<String> authPrefs = new ArrayList<String>();
157    
158                    if (_PROXY_AUTH_TYPE.equals("username-password")) {
159                            _proxyCredentials = new UsernamePasswordCredentials(
160                                    _PROXY_USERNAME, _PROXY_PASSWORD);
161    
162                            authPrefs.add(AuthPolicy.BASIC);
163                            authPrefs.add(AuthPolicy.DIGEST);
164                            authPrefs.add(AuthPolicy.NTLM);
165                    }
166                    else if (_PROXY_AUTH_TYPE.equals("ntlm")) {
167                            _proxyCredentials = new NTCredentials(
168                                    _PROXY_USERNAME, _PROXY_PASSWORD, _PROXY_NTLM_HOST,
169                                    _PROXY_NTLM_DOMAIN);
170    
171                            authPrefs.add(AuthPolicy.NTLM);
172                            authPrefs.add(AuthPolicy.BASIC);
173                            authPrefs.add(AuthPolicy.DIGEST);
174                    }
175    
176                    HttpClientParams httpClientParams = _proxyHttpClient.getParams();
177    
178                    httpClientParams.setParameter(
179                            AuthPolicy.AUTH_SCHEME_PRIORITY, authPrefs);
180            }
181    
182            @Override
183            public String addParameter(String url, String name, boolean value) {
184                    return addParameter(url, name, String.valueOf(value));
185            }
186    
187            @Override
188            public String addParameter(String url, String name, double value) {
189                    return addParameter(url, name, String.valueOf(value));
190            }
191    
192            @Override
193            public String addParameter(String url, String name, int value) {
194                    return addParameter(url, name, String.valueOf(value));
195            }
196    
197            @Override
198            public String addParameter(String url, String name, long value) {
199                    return addParameter(url, name, String.valueOf(value));
200            }
201    
202            @Override
203            public String addParameter(String url, String name, short value) {
204                    return addParameter(url, name, String.valueOf(value));
205            }
206    
207            @Override
208            public String addParameter(String url, String name, String value) {
209                    if (url == null) {
210                            return null;
211                    }
212    
213                    String[] urlArray = PortalUtil.stripURLAnchor(url, StringPool.POUND);
214    
215                    url = urlArray[0];
216    
217                    String anchor = urlArray[1];
218    
219                    StringBundler sb = new StringBundler(7);
220    
221                    sb.append(url);
222    
223                    if (url.indexOf(CharPool.QUESTION) == -1) {
224                            sb.append(StringPool.QUESTION);
225                    }
226                    else if (!url.endsWith(StringPool.QUESTION) &&
227                                     !url.endsWith(StringPool.AMPERSAND)) {
228    
229                            sb.append(StringPool.AMPERSAND);
230                    }
231    
232                    sb.append(name);
233                    sb.append(StringPool.EQUAL);
234                    sb.append(encodeURL(value));
235                    sb.append(anchor);
236    
237                    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                    if (url.startsWith(Http.HTTP_WITH_SLASH)) {
969                            return url.substring(Http.HTTP_WITH_SLASH.length());
970                    }
971                    else if (url.startsWith(Http.HTTPS_WITH_SLASH)) {
972                            return url.substring(Http.HTTPS_WITH_SLASH.length());
973                    }
974                    else {
975                            return url;
976                    }
977            }
978    
979            @Override
980            public String sanitizeHeader(String header) {
981                    if (header == null) {
982                            return null;
983                    }
984    
985                    StringBuilder sb = null;
986    
987                    for (int i = 0; i < header.length(); i++) {
988                            char c = header.charAt(i);
989    
990                            if (((c <= 31) && (c != 9)) || (c == 127) || (c > 255)) {
991                                    if (sb == null) {
992                                            sb = new StringBuilder(header);
993                                    }
994    
995                                    sb.setCharAt(i, CharPool.SPACE);
996                            }
997                    }
998    
999                    if (sb != null) {
1000                            header = sb.toString();
1001                    }
1002    
1003                    return header;
1004            }
1005    
1006            @Override
1007            public String setParameter(String url, String name, boolean value) {
1008                    return setParameter(url, name, String.valueOf(value));
1009            }
1010    
1011            @Override
1012            public String setParameter(String url, String name, double value) {
1013                    return setParameter(url, name, String.valueOf(value));
1014            }
1015    
1016            @Override
1017            public String setParameter(String url, String name, int value) {
1018                    return setParameter(url, name, String.valueOf(value));
1019            }
1020    
1021            @Override
1022            public String setParameter(String url, String name, long value) {
1023                    return setParameter(url, name, String.valueOf(value));
1024            }
1025    
1026            @Override
1027            public String setParameter(String url, String name, short value) {
1028                    return setParameter(url, name, String.valueOf(value));
1029            }
1030    
1031            @Override
1032            public String setParameter(String url, String name, String value) {
1033                    if (Validator.isNull(url) || Validator.isNull(name)) {
1034                            return url;
1035                    }
1036    
1037                    url = removeParameter(url, name);
1038    
1039                    return addParameter(url, name, value);
1040            }
1041    
1042            @Override
1043            public String shortenURL(String url, int count) {
1044                    if (count == 0) {
1045                            return null;
1046                    }
1047    
1048                    StringBundler sb = new StringBundler();
1049    
1050                    String[] params = url.split(StringPool.AMPERSAND);
1051    
1052                    for (int i = 0; i < params.length; i++) {
1053                            String param = params[i];
1054    
1055                            if (param.contains("_backURL=") || param.contains("_redirect=") ||
1056                                    param.contains("_returnToFullPageURL=") ||
1057                                    param.startsWith("redirect")) {
1058    
1059                                    int pos = param.indexOf(StringPool.EQUAL);
1060    
1061                                    String qName = param.substring(0, pos);
1062    
1063                                    String redirect = param.substring(pos + 1);
1064    
1065                                    redirect = decodeURL(redirect);
1066    
1067                                    String newURL = shortenURL(redirect, count - 1);
1068    
1069                                    if (newURL != null) {
1070                                            newURL = encodeURL(newURL);
1071    
1072                                            sb.append(qName);
1073                                            sb.append(StringPool.EQUAL);
1074                                            sb.append(newURL);
1075    
1076                                            if (i < (params.length - 1)) {
1077                                                    sb.append(StringPool.AMPERSAND);
1078                                            }
1079                                    }
1080                            }
1081                            else {
1082                                    sb.append(param);
1083    
1084                                    if (i < (params.length - 1)) {
1085                                            sb.append(StringPool.AMPERSAND);
1086                                    }
1087                            }
1088                    }
1089    
1090                    return sb.toString();
1091            }
1092    
1093            @Override
1094            public byte[] URLtoByteArray(Http.Options options) throws IOException {
1095                    return URLtoByteArray(
1096                            options.getLocation(), options.getMethod(), options.getHeaders(),
1097                            options.getCookies(), options.getAuth(), options.getBody(),
1098                            options.getFileParts(), options.getParts(), options.getResponse(),
1099                            options.isFollowRedirects(), options.getProgressId(),
1100                            options.getPortletRequest());
1101            }
1102    
1103            @Override
1104            public byte[] URLtoByteArray(String location) throws IOException {
1105                    Http.Options options = new Http.Options();
1106    
1107                    options.setLocation(location);
1108    
1109                    return URLtoByteArray(options);
1110            }
1111    
1112            @Override
1113            public byte[] URLtoByteArray(String location, boolean post)
1114                    throws IOException {
1115    
1116                    Http.Options options = new Http.Options();
1117    
1118                    options.setLocation(location);
1119                    options.setPost(post);
1120    
1121                    return URLtoByteArray(options);
1122            }
1123    
1124            @Override
1125            public String URLtoString(Http.Options options) throws IOException {
1126                    return new String(URLtoByteArray(options));
1127            }
1128    
1129            @Override
1130            public String URLtoString(String location) throws IOException {
1131                    return new String(URLtoByteArray(location));
1132            }
1133    
1134            @Override
1135            public String URLtoString(String location, boolean post)
1136                    throws IOException {
1137    
1138                    return new String(URLtoByteArray(location, post));
1139            }
1140    
1141            /**
1142             * This method only uses the default Commons HttpClient implementation when
1143             * the URL object represents a HTTP resource. The URL object could also
1144             * represent a file or some JNDI resource. In that case, the default Java
1145             * implementation is used.
1146             *
1147             * @param  url the URL
1148             * @return A string representation of the resource referenced by the URL
1149             *         object
1150             * @throws IOException if an IO exception occurred
1151             */
1152            @Override
1153            public String URLtoString(URL url) throws IOException {
1154                    String xml = null;
1155    
1156                    if (url == null) {
1157                            return null;
1158                    }
1159    
1160                    String protocol = StringUtil.toLowerCase(url.getProtocol());
1161    
1162                    if (protocol.startsWith(Http.HTTP) || protocol.startsWith(Http.HTTPS)) {
1163                            return URLtoString(url.toString());
1164                    }
1165    
1166                    URLConnection urlConnection = url.openConnection();
1167    
1168                    if (urlConnection == null) {
1169                            if (_log.isDebugEnabled()) {
1170                                    _log.debug("Unable to open a connection to " + url);
1171                            }
1172    
1173                            return null;
1174                    }
1175    
1176                    InputStream inputStream = urlConnection.getInputStream();
1177    
1178                    UnsyncByteArrayOutputStream unsyncByteArrayOutputStream =
1179                            new UnsyncByteArrayOutputStream();
1180    
1181                    byte[] bytes = new byte[512];
1182    
1183                    for (int i = inputStream.read(bytes, 0, 512); i != -1;
1184                                    i = inputStream.read(bytes, 0, 512)) {
1185    
1186                            unsyncByteArrayOutputStream.write(bytes, 0, i);
1187                    }
1188    
1189                    xml = new String(
1190                            unsyncByteArrayOutputStream.unsafeGetByteArray(), 0,
1191                            unsyncByteArrayOutputStream.size());
1192    
1193                    inputStream.close();
1194    
1195                    unsyncByteArrayOutputStream.close();
1196    
1197                    return xml;
1198            }
1199    
1200            protected boolean hasRequestHeader(HttpMethod httpMethod, String name) {
1201                    Header[] headers = httpMethod.getRequestHeaders(name);
1202    
1203                    if (headers.length == 0) {
1204                            return false;
1205                    }
1206    
1207                    return true;
1208            }
1209    
1210            protected void processPostMethod(
1211                    PostMethod postMethod, List<Http.FilePart> fileParts,
1212                    Map<String, String> parts) {
1213    
1214                    if ((fileParts == null) || fileParts.isEmpty()) {
1215                            if (parts != null) {
1216                                    for (Map.Entry<String, String> entry : parts.entrySet()) {
1217                                            String value = entry.getValue();
1218    
1219                                            if (value != null) {
1220                                                    postMethod.addParameter(entry.getKey(), value);
1221                                            }
1222                                    }
1223                            }
1224                    }
1225                    else {
1226                            List<Part> partsList = new ArrayList<Part>();
1227    
1228                            if (parts != null) {
1229                                    for (Map.Entry<String, String> entry : parts.entrySet()) {
1230                                            String value = entry.getValue();
1231    
1232                                            if (value != null) {
1233                                                    StringPart stringPart = new StringPart(
1234                                                            entry.getKey(), value);
1235    
1236                                                    partsList.add(stringPart);
1237                                            }
1238                                    }
1239                            }
1240    
1241                            for (Http.FilePart filePart : fileParts) {
1242                                    partsList.add(toCommonsFilePart(filePart));
1243                            }
1244    
1245                            MultipartRequestEntity multipartRequestEntity =
1246                                    new MultipartRequestEntity(
1247                                            partsList.toArray(new Part[partsList.size()]),
1248                                            postMethod.getParams());
1249    
1250                            postMethod.setRequestEntity(multipartRequestEntity);
1251                    }
1252            }
1253    
1254            protected org.apache.commons.httpclient.Cookie toCommonsCookie(
1255                    Cookie cookie) {
1256    
1257                    org.apache.commons.httpclient.Cookie commonsCookie =
1258                            new org.apache.commons.httpclient.Cookie(
1259                                    cookie.getDomain(), cookie.getName(), cookie.getValue(),
1260                                    cookie.getPath(), cookie.getMaxAge(), cookie.getSecure());
1261    
1262                    commonsCookie.setVersion(cookie.getVersion());
1263    
1264                    return commonsCookie;
1265            }
1266    
1267            protected org.apache.commons.httpclient.Cookie[] toCommonsCookies(
1268                    Cookie[] cookies) {
1269    
1270                    if (cookies == null) {
1271                            return null;
1272                    }
1273    
1274                    org.apache.commons.httpclient.Cookie[] commonCookies =
1275                            new org.apache.commons.httpclient.Cookie[cookies.length];
1276    
1277                    for (int i = 0; i < cookies.length; i++) {
1278                            commonCookies[i] = toCommonsCookie(cookies[i]);
1279                    }
1280    
1281                    return commonCookies;
1282            }
1283    
1284            protected org.apache.commons.httpclient.methods.multipart.FilePart
1285                    toCommonsFilePart(Http.FilePart filePart) {
1286    
1287                    return new org.apache.commons.httpclient.methods.multipart.FilePart(
1288                            filePart.getName(),
1289                            new ByteArrayPartSource(
1290                                    filePart.getFileName(), filePart.getValue()),
1291                            filePart.getContentType(), filePart.getCharSet());
1292            }
1293    
1294            protected Cookie toServletCookie(
1295                    org.apache.commons.httpclient.Cookie commonsCookie) {
1296    
1297                    Cookie cookie = new Cookie(
1298                            commonsCookie.getName(), commonsCookie.getValue());
1299    
1300                    if (!PropsValues.SESSION_COOKIE_USE_FULL_HOSTNAME) {
1301                            String domain = commonsCookie.getDomain();
1302    
1303                            if (Validator.isNotNull(domain)) {
1304                                    cookie.setDomain(domain);
1305                            }
1306                    }
1307    
1308                    Date expiryDate = commonsCookie.getExpiryDate();
1309    
1310                    if (expiryDate != null) {
1311                            int maxAge =
1312                                    (int)(expiryDate.getTime() - System.currentTimeMillis());
1313    
1314                            maxAge = maxAge / 1000;
1315    
1316                            if (maxAge > -1) {
1317                                    cookie.setMaxAge(maxAge);
1318                            }
1319                    }
1320    
1321                    String path = commonsCookie.getPath();
1322    
1323                    if (Validator.isNotNull(path)) {
1324                            cookie.setPath(path);
1325                    }
1326    
1327                    cookie.setSecure(commonsCookie.getSecure());
1328                    cookie.setVersion(commonsCookie.getVersion());
1329    
1330                    return cookie;
1331            }
1332    
1333            protected Cookie[] toServletCookies(
1334                    org.apache.commons.httpclient.Cookie[] commonsCookies) {
1335    
1336                    if (commonsCookies == null) {
1337                            return null;
1338                    }
1339    
1340                    Cookie[] cookies = new Cookie[commonsCookies.length];
1341    
1342                    for (int i = 0; i < commonsCookies.length; i++) {
1343                            cookies[i] = toServletCookie(commonsCookies[i]);
1344                    }
1345    
1346                    return cookies;
1347            }
1348    
1349            protected byte[] URLtoByteArray(
1350                            String location, Http.Method method, Map<String, String> headers,
1351                            Cookie[] cookies, Http.Auth auth, Http.Body body,
1352                            List<Http.FilePart> fileParts, Map<String, String> parts,
1353                            Http.Response response, boolean followRedirects, String progressId,
1354                            PortletRequest portletRequest)
1355                    throws IOException {
1356    
1357                    byte[] bytes = null;
1358    
1359                    HttpMethod httpMethod = null;
1360                    HttpState httpState = null;
1361    
1362                    try {
1363                            _cookies.set(null);
1364    
1365                            if (location == null) {
1366                                    return null;
1367                            }
1368                            else if (!location.startsWith(Http.HTTP_WITH_SLASH) &&
1369                                             !location.startsWith(Http.HTTPS_WITH_SLASH)) {
1370    
1371                                    location = Http.HTTP_WITH_SLASH + location;
1372                            }
1373    
1374                            HostConfiguration hostConfiguration = getHostConfiguration(
1375                                    location);
1376    
1377                            HttpClient httpClient = getClient(hostConfiguration);
1378    
1379                            if (method.equals(Http.Method.POST) ||
1380                                    method.equals(Http.Method.PUT)) {
1381    
1382                                    if (method.equals(Http.Method.POST)) {
1383                                            httpMethod = new PostMethod(location);
1384                                    }
1385                                    else {
1386                                            httpMethod = new PutMethod(location);
1387                                    }
1388    
1389                                    if (body != null) {
1390                                            RequestEntity requestEntity = new StringRequestEntity(
1391                                                    body.getContent(), body.getContentType(),
1392                                                    body.getCharset());
1393    
1394                                            EntityEnclosingMethod entityEnclosingMethod =
1395                                                    (EntityEnclosingMethod)httpMethod;
1396    
1397                                            entityEnclosingMethod.setRequestEntity(requestEntity);
1398                                    }
1399                                    else if (method.equals(Http.Method.POST)) {
1400                                            PostMethod postMethod = (PostMethod)httpMethod;
1401    
1402                                            if (!hasRequestHeader(
1403                                                            postMethod, HttpHeaders.CONTENT_TYPE)) {
1404    
1405                                                    HttpClientParams httpClientParams =
1406                                                            httpClient.getParams();
1407    
1408                                                    httpClientParams.setParameter(
1409                                                            HttpMethodParams.HTTP_CONTENT_CHARSET,
1410                                                            StringPool.UTF8);
1411                                            }
1412    
1413                                            processPostMethod(postMethod, fileParts, parts);
1414                                    }
1415                            }
1416                            else if (method.equals(Http.Method.DELETE)) {
1417                                    httpMethod = new DeleteMethod(location);
1418                            }
1419                            else if (method.equals(Http.Method.HEAD)) {
1420                                    httpMethod = new HeadMethod(location);
1421                            }
1422                            else {
1423                                    httpMethod = new GetMethod(location);
1424                            }
1425    
1426                            if (headers != null) {
1427                                    for (Map.Entry<String, String> header : headers.entrySet()) {
1428                                            httpMethod.addRequestHeader(
1429                                                    header.getKey(), header.getValue());
1430                                    }
1431                            }
1432    
1433                            if ((method.equals(Http.Method.POST) ||
1434                                     method.equals(Http.Method.PUT)) &&
1435                                    ((body != null) ||
1436                                     ((fileParts != null) && !fileParts.isEmpty()) ||
1437                                     ((parts != null) && !parts.isEmpty()))) {
1438                            }
1439                            else if (!hasRequestHeader(httpMethod, HttpHeaders.CONTENT_TYPE)) {
1440                                    httpMethod.addRequestHeader(
1441                                            HttpHeaders.CONTENT_TYPE,
1442                                            ContentTypes.APPLICATION_X_WWW_FORM_URLENCODED_UTF8);
1443                            }
1444    
1445                            if (!hasRequestHeader(httpMethod, HttpHeaders.USER_AGENT)) {
1446                                    httpMethod.addRequestHeader(
1447                                            HttpHeaders.USER_AGENT, _DEFAULT_USER_AGENT);
1448                            }
1449    
1450                            httpState = new HttpState();
1451    
1452                            if (ArrayUtil.isNotEmpty(cookies)) {
1453                                    org.apache.commons.httpclient.Cookie[] commonsCookies =
1454                                            toCommonsCookies(cookies);
1455    
1456                                    httpState.addCookies(commonsCookies);
1457    
1458                                    HttpMethodParams httpMethodParams = httpMethod.getParams();
1459    
1460                                    httpMethodParams.setCookiePolicy(
1461                                            CookiePolicy.BROWSER_COMPATIBILITY);
1462                            }
1463    
1464                            if (auth != null) {
1465                                    httpMethod.setDoAuthentication(true);
1466    
1467                                    httpState.setCredentials(
1468                                            new AuthScope(
1469                                                    auth.getHost(), auth.getPort(), auth.getRealm()),
1470                                            new UsernamePasswordCredentials(
1471                                                    auth.getUsername(), auth.getPassword()));
1472                            }
1473    
1474                            proxifyState(httpState, hostConfiguration);
1475    
1476                            int responseCode = httpClient.executeMethod(
1477                                    hostConfiguration, httpMethod, httpState);
1478    
1479                            response.setResponseCode(responseCode);
1480    
1481                            Header locationHeader = httpMethod.getResponseHeader("location");
1482    
1483                            if ((locationHeader != null) && !locationHeader.equals(location)) {
1484                                    String redirect = locationHeader.getValue();
1485    
1486                                    if (followRedirects) {
1487                                            return URLtoByteArray(
1488                                                    redirect, Http.Method.GET, headers, cookies, auth, body,
1489                                                    fileParts, parts, response, followRedirects, progressId,
1490                                                    portletRequest);
1491                                    }
1492                                    else {
1493                                            response.setRedirect(redirect);
1494                                    }
1495                            }
1496    
1497                            InputStream inputStream = httpMethod.getResponseBodyAsStream();
1498    
1499                            if (inputStream != null) {
1500                                    int contentLength = 0;
1501    
1502                                    Header contentLengthHeader = httpMethod.getResponseHeader(
1503                                            HttpHeaders.CONTENT_LENGTH);
1504    
1505                                    if (contentLengthHeader != null) {
1506                                            contentLength = GetterUtil.getInteger(
1507                                                    contentLengthHeader.getValue());
1508    
1509                                            response.setContentLength(contentLength);
1510                                    }
1511    
1512                                    Header contentType = httpMethod.getResponseHeader(
1513                                            HttpHeaders.CONTENT_TYPE);
1514    
1515                                    if (contentType != null) {
1516                                            response.setContentType(contentType.getValue());
1517                                    }
1518    
1519                                    if (Validator.isNotNull(progressId) &&
1520                                            (portletRequest != null)) {
1521    
1522                                            ProgressInputStream progressInputStream =
1523                                                    new ProgressInputStream(
1524                                                            portletRequest, inputStream, contentLength,
1525                                                            progressId);
1526    
1527                                            UnsyncByteArrayOutputStream unsyncByteArrayOutputStream =
1528                                                    new UnsyncByteArrayOutputStream(contentLength);
1529    
1530                                            try {
1531                                                    progressInputStream.readAll(
1532                                                    unsyncByteArrayOutputStream);
1533                                            }
1534                                            finally {
1535                                                    progressInputStream.clearProgress();
1536                                            }
1537    
1538                                            bytes = unsyncByteArrayOutputStream.unsafeGetByteArray();
1539    
1540                                            unsyncByteArrayOutputStream.close();
1541                                    }
1542                                    else {
1543                                            bytes = FileUtil.getBytes(inputStream);
1544                                    }
1545                            }
1546    
1547                            for (Header header : httpMethod.getResponseHeaders()) {
1548                                    response.addHeader(header.getName(), header.getValue());
1549                            }
1550    
1551                            return bytes;
1552                    }
1553                    finally {
1554                            try {
1555                                    if (httpState != null) {
1556                                            _cookies.set(toServletCookies(httpState.getCookies()));
1557                                    }
1558                            }
1559                            catch (Exception e) {
1560                                    _log.error(e, e);
1561                            }
1562    
1563                            try {
1564                                    if (httpMethod != null) {
1565                                            httpMethod.releaseConnection();
1566                                    }
1567                            }
1568                            catch (Exception e) {
1569                                    _log.error(e, e);
1570                            }
1571                    }
1572            }
1573    
1574            private static final String _DEFAULT_USER_AGENT =
1575                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)";
1576    
1577            private static final int _MAX_CONNECTIONS_PER_HOST = GetterUtil.getInteger(
1578                    PropsUtil.get(HttpImpl.class.getName() + ".max.connections.per.host"),
1579                    2);
1580    
1581            private static final int _MAX_TOTAL_CONNECTIONS = GetterUtil.getInteger(
1582                    PropsUtil.get(HttpImpl.class.getName() + ".max.total.connections"), 20);
1583    
1584            private static final String _NON_PROXY_HOSTS = SystemProperties.get(
1585                    "http.nonProxyHosts");
1586    
1587            private static final String _PROXY_AUTH_TYPE = GetterUtil.getString(
1588                    PropsUtil.get(HttpImpl.class.getName() + ".proxy.auth.type"));
1589    
1590            private static final String _PROXY_HOST = GetterUtil.getString(
1591                    SystemProperties.get("http.proxyHost"));
1592    
1593            private static final String _PROXY_NTLM_DOMAIN = GetterUtil.getString(
1594                    PropsUtil.get(HttpImpl.class.getName() + ".proxy.ntlm.domain"));
1595    
1596            private static final String _PROXY_NTLM_HOST = GetterUtil.getString(
1597                    PropsUtil.get(HttpImpl.class.getName() + ".proxy.ntlm.host"));
1598    
1599            private static final String _PROXY_PASSWORD = GetterUtil.getString(
1600                    PropsUtil.get(HttpImpl.class.getName() + ".proxy.password"));
1601    
1602            private static final int _PROXY_PORT = GetterUtil.getInteger(
1603                    SystemProperties.get("http.proxyPort"));
1604    
1605            private static final String _PROXY_USERNAME = GetterUtil.getString(
1606                    PropsUtil.get(HttpImpl.class.getName() + ".proxy.username"));
1607    
1608            private static final String _TEMP_SLASH = "_LIFERAY_TEMP_SLASH_";
1609    
1610            private static final int _TIMEOUT = GetterUtil.getInteger(
1611                    PropsUtil.get(HttpImpl.class.getName() + ".timeout"), 5000);
1612    
1613            private static Log _log = LogFactoryUtil.getLog(HttpImpl.class);
1614    
1615            private static ThreadLocal<Cookie[]> _cookies = new ThreadLocal<Cookie[]>();
1616    
1617            private HttpClient _httpClient = new HttpClient();
1618            private Pattern _nonProxyHostsPattern;
1619            private Credentials _proxyCredentials;
1620            private HttpClient _proxyHttpClient = new HttpClient();
1621    
1622            private class FastProtocolSocketFactory
1623                    extends DefaultProtocolSocketFactory {
1624    
1625                    @Override
1626                    public Socket createSocket(
1627                                    final String host, final int port,
1628                                    final InetAddress localInetAddress, final int localPort,
1629                                    final HttpConnectionParams httpConnectionParams)
1630                            throws ConnectTimeoutException, IOException, UnknownHostException {
1631    
1632                            int connectionTimeout = httpConnectionParams.getConnectionTimeout();
1633    
1634                            if (connectionTimeout == 0) {
1635                                    return createSocket(host, port, localInetAddress, localPort);
1636                            }
1637    
1638                            SocketFactory socketFactory = SocketFactory.getDefault();
1639    
1640                            Socket socket = socketFactory.createSocket();
1641    
1642                            SocketAddress localSocketAddress = new InetSocketAddress(
1643                                    localInetAddress, localPort);
1644    
1645                            SocketAddress remoteSocketAddress = new InetSocketAddress(
1646                                    host, port);
1647    
1648                            socket.bind(localSocketAddress);
1649    
1650                            socket.connect(remoteSocketAddress, connectionTimeout);
1651    
1652                            return socket;
1653                    }
1654    
1655            }
1656    
1657    }