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