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