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