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