1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package davmail.http;
20
21 import davmail.BundleMessage;
22 import davmail.Settings;
23 import davmail.exception.*;
24 import davmail.exchange.dav.ExchangeDavMethod;
25 import davmail.exchange.dav.ExchangeSearchMethod;
26 import davmail.ui.tray.DavGatewayTray;
27 import org.apache.commons.httpclient.*;
28 import org.apache.commons.httpclient.URI;
29 import org.apache.commons.httpclient.auth.AuthPolicy;
30 import org.apache.commons.httpclient.auth.AuthScope;
31 import org.apache.commons.httpclient.cookie.CookiePolicy;
32 import org.apache.commons.httpclient.methods.DeleteMethod;
33 import org.apache.commons.httpclient.methods.GetMethod;
34 import org.apache.commons.httpclient.params.HttpClientParams;
35 import org.apache.commons.httpclient.params.HttpMethodParams;
36 import org.apache.commons.httpclient.util.IdleConnectionTimeoutThread;
37 import org.apache.http.client.HttpResponseException;
38 import org.apache.jackrabbit.webdav.DavException;
39 import org.apache.jackrabbit.webdav.MultiStatusResponse;
40 import org.apache.jackrabbit.webdav.client.methods.CopyMethod;
41 import org.apache.jackrabbit.webdav.client.methods.DavMethodBase;
42 import org.apache.jackrabbit.webdav.client.methods.MoveMethod;
43 import org.apache.jackrabbit.webdav.client.methods.PropFindMethod;
44 import org.apache.jackrabbit.webdav.property.DavPropertyNameSet;
45 import org.apache.log4j.Logger;
46
47 import java.io.IOException;
48 import java.net.*;
49 import java.security.Security;
50 import java.util.*;
51 import java.util.regex.Matcher;
52 import java.util.regex.Pattern;
53
54
55
56
57 public final class DavGatewayHttpClientFacade {
58 static final Logger LOGGER = Logger.getLogger("davmail.http.DavGatewayHttpClientFacade");
59
60 public static final String IE_USER_AGENT = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; Trident/6.0; Microsoft Outlook 15.0.4420)";
61 static final int MAX_REDIRECTS = 10;
62 static final Object LOCK = new Object();
63 private static boolean needNTLM;
64
65 static final long ONE_MINUTE = 60000;
66
67 static String WORKSTATION_NAME = "UNKNOWN";
68
69 private static IdleConnectionTimeoutThread httpConnectionManagerThread;
70
71 private static Set<MultiThreadedHttpConnectionManager> ALL_CONNECTION_MANAGERS = new HashSet<>();
72
73 static {
74
75 System.setProperty("jdk.tls.rejectClientInitiatedRenegotiation", "true");
76
77 System.setProperty("jdk.tls.ephemeralDHKeySize", "2048");
78
79 Security.setProperty("ssl.SocketFactory.provider", "davmail.http.DavGatewaySSLSocketFactory");
80
81
82 System.setProperty("jdk.http.auth.tunneling.disabledSchemes", "");
83
84 DavGatewayHttpClientFacade.start();
85
86
87 CookiePolicy.registerCookieSpec("DavMailCookieSpec", DavMailCookieSpec.class);
88
89 AuthPolicy.registerAuthScheme(AuthPolicy.BASIC, LenientBasicScheme.class);
90
91 AuthPolicy.registerAuthScheme(AuthPolicy.NTLM, NTLMv2Scheme.class);
92 try {
93 WORKSTATION_NAME = InetAddress.getLocalHost().getHostName();
94 } catch (Throwable t) {
95
96 }
97
98
99 if (Settings.getBooleanProperty("davmail.useSystemProxies", Boolean.FALSE)) {
100 System.setProperty("java.net.useSystemProxies", "true");
101 }
102 ProxySelector.setDefault(new DavGatewayProxySelector(ProxySelector.getDefault()));
103 }
104
105
106 private DavGatewayHttpClientFacade() {
107 }
108
109
110
111
112
113
114 private static HttpClient getBaseInstance() {
115 HttpClient httpClient = new HttpClient();
116 httpClient.getParams().setParameter(HttpMethodParams.USER_AGENT, getUserAgent());
117 httpClient.getParams().setParameter(HttpClientParams.MAX_REDIRECTS, Settings.getIntProperty("davmail.httpMaxRedirects", MAX_REDIRECTS));
118 httpClient.getParams().setCookiePolicy("DavMailCookieSpec");
119 return httpClient;
120 }
121
122
123
124
125
126
127
128
129 public static HttpClient getInstance(String url) throws DavMailException {
130
131 HttpClient httpClient = getBaseInstance();
132 configureClient(httpClient, url);
133 return httpClient;
134 }
135
136
137
138
139
140
141
142
143 public static void setCredentials(HttpClient httpClient, String userName, String password) {
144
145 AuthScope authScope = new AuthScope(null, -1);
146 int backSlashIndex = userName.indexOf('\\');
147 if (needNTLM && backSlashIndex >= 0) {
148
149 String domain = userName.substring(0, backSlashIndex);
150 userName = userName.substring(backSlashIndex + 1);
151 httpClient.getState().setCredentials(authScope, new NTCredentials(userName, password, WORKSTATION_NAME, domain));
152 } else {
153 httpClient.getState().setCredentials(authScope, new NTCredentials(userName, password, WORKSTATION_NAME, ""));
154 }
155 }
156
157
158
159
160
161
162
163
164 public static void setClientHost(HttpClient httpClient, String url) throws DavMailException {
165 try {
166 HostConfiguration hostConfig = httpClient.getHostConfiguration();
167 URI httpURI = new URI(url, true);
168 hostConfig.setHost(httpURI);
169 } catch (URIException e) {
170 throw new DavMailException("LOG_INVALID_URL", url);
171 }
172 }
173
174 protected static boolean isNoProxyFor(java.net.URI uri) {
175 final String noProxyFor = Settings.getProperty("davmail.noProxyFor");
176 if (noProxyFor != null) {
177 final String urihost = uri.getHost().toLowerCase();
178 final String[] domains = noProxyFor.toLowerCase().split(",\\s*");
179 for (String domain : domains) {
180 if (urihost.endsWith(domain)) {
181 return true;
182 }
183 }
184 }
185 return false;
186 }
187
188
189
190
191
192
193
194
195 public static void configureClient(HttpClient httpClient, String url) throws DavMailException {
196 setClientHost(httpClient, url);
197
198
199 if (!needNTLM && url.toLowerCase().endsWith("/ews/exchange.asmx") && !Settings.getBooleanProperty("davmail.disableNTLM", false)) {
200 needNTLM = true;
201 }
202
203 if (Settings.getBooleanProperty("davmail.enableKerberos", false)) {
204 AuthPolicy.registerAuthScheme("Negotiate", SpNegoScheme.class);
205 ArrayList<String> authPrefs = new ArrayList<>();
206 authPrefs.add("Negotiate");
207 httpClient.getParams().setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, authPrefs);
208 } else if (!needNTLM) {
209 ArrayList<String> authPrefs = new ArrayList<>();
210 authPrefs.add(AuthPolicy.DIGEST);
211 authPrefs.add(AuthPolicy.BASIC);
212
213 httpClient.getParams().setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, authPrefs);
214 }
215
216 boolean enableProxy = Settings.getBooleanProperty("davmail.enableProxy");
217 boolean useSystemProxies = Settings.getBooleanProperty("davmail.useSystemProxies", Boolean.FALSE);
218 String proxyHost = null;
219 int proxyPort = 0;
220 String proxyUser = null;
221 String proxyPassword = null;
222
223 try {
224 java.net.URI uri = new java.net.URI(url);
225 if (useSystemProxies) {
226
227 System.setProperty("java.net.useSystemProxies", "true");
228 List<Proxy> proxyList = getProxyForURI(uri);
229 if (!proxyList.isEmpty() && proxyList.get(0).address() != null) {
230 InetSocketAddress inetSocketAddress = (InetSocketAddress) proxyList.get(0).address();
231 proxyHost = inetSocketAddress.getHostName();
232 proxyPort = inetSocketAddress.getPort();
233
234
235 proxyUser = Settings.getProperty("davmail.proxyUser");
236 proxyPassword = Settings.getProperty("davmail.proxyPassword");
237 }
238 } else if (isNoProxyFor(uri)) {
239 LOGGER.debug("no proxy for " + uri.getHost());
240 } else if (enableProxy) {
241 proxyHost = Settings.getProperty("davmail.proxyHost");
242 proxyPort = Settings.getIntProperty("davmail.proxyPort");
243 proxyUser = Settings.getProperty("davmail.proxyUser");
244 proxyPassword = Settings.getProperty("davmail.proxyPassword");
245 }
246 } catch (URISyntaxException e) {
247 throw new DavMailException("LOG_INVALID_URL", url);
248 }
249
250
251 if (proxyHost != null && proxyHost.length() > 0) {
252 httpClient.getHostConfiguration().setProxy(proxyHost, proxyPort);
253 if (proxyUser != null && proxyUser.length() > 0) {
254
255 AuthScope authScope = new AuthScope(proxyHost, proxyPort, AuthScope.ANY_REALM);
256
257
258 int backslashindex = proxyUser.indexOf('\\');
259 if (backslashindex > 0) {
260 httpClient.getState().setProxyCredentials(authScope,
261 new NTCredentials(proxyUser.substring(backslashindex + 1),
262 proxyPassword, WORKSTATION_NAME,
263 proxyUser.substring(0, backslashindex)));
264 } else {
265 httpClient.getState().setProxyCredentials(authScope,
266 new NTCredentials(proxyUser, proxyPassword, WORKSTATION_NAME, ""));
267 }
268 }
269 }
270
271 }
272
273
274
275
276
277
278 public static void close(HttpClient httpClient) {
279 if (httpClient != null) {
280 synchronized (LOCK) {
281 MultiThreadedHttpConnectionManager httpConnectionManager = ((MultiThreadedHttpConnectionManager) httpClient.getHttpConnectionManager());
282 ALL_CONNECTION_MANAGERS.remove(httpConnectionManager);
283 httpConnectionManager.shutdown();
284 }
285 }
286 }
287
288
289
290
291
292
293
294 private static List<Proxy> getProxyForURI(java.net.URI uri) {
295 LOGGER.debug("get Default proxy selector");
296 ProxySelector proxySelector = ProxySelector.getDefault();
297 LOGGER.debug("getProxyForURI(" + uri + ')');
298 List<Proxy> proxies = proxySelector.select(uri);
299 LOGGER.debug("got system proxies:" + proxies);
300 return proxies;
301 }
302
303
304
305
306
307
308
309
310
311 public static int getHttpStatus(HttpClient httpClient, String url) {
312 int status = 0;
313 HttpMethod testMethod = new GetMethod(url);
314 testMethod.setDoAuthentication(false);
315 try {
316 status = httpClient.executeMethod(testMethod);
317 } catch (IOException e) {
318 LOGGER.warn(e.getMessage(), e);
319 } finally {
320 testMethod.releaseConnection();
321 }
322 return status;
323 }
324
325
326
327
328
329
330
331 public static boolean isRedirect(int status) {
332 return status == HttpStatus.SC_MOVED_PERMANENTLY
333 || status == HttpStatus.SC_MOVED_TEMPORARILY
334 || status == HttpStatus.SC_SEE_OTHER
335 || status == HttpStatus.SC_TEMPORARY_REDIRECT;
336 }
337
338
339
340
341
342
343
344
345
346
347 public static HttpMethod executeFollowRedirects(HttpClient httpClient, String url) throws IOException {
348 HttpMethod method = new GetMethod(url);
349 method.setFollowRedirects(false);
350 return executeFollowRedirects(httpClient, method);
351 }
352
353 private static int executeMethod(HttpClient httpClient, HttpMethod currentMethod) throws IOException {
354 httpClient.executeMethod(currentMethod);
355 int status = currentMethod.getStatusCode();
356 if ((status == HttpStatus.SC_UNAUTHORIZED || status == HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED)
357 && acceptsNTLMOnly(currentMethod) && !hasNTLMorNegotiate(httpClient)) {
358 LOGGER.debug("Received " + status + " unauthorized at " + currentMethod.getURI() + ", retrying with NTLM");
359 resetMethod(currentMethod);
360 addNTLM(httpClient);
361 status = httpClient.executeMethod(currentMethod);
362 }
363 return status;
364 }
365
366
367
368
369
370
371
372
373
374
375
376 private static String getJavascriptRedirectUrl(HttpMethod method) throws IOException {
377 String responseBody = method.getResponseBodyAsString();
378 String jsRedirectionUrl = null;
379 if (responseBody.indexOf("javascript:go_url()") > 0) {
380
381 Pattern p = Pattern.compile("go_url\\(\\)[^{]+\\{[^l]+location.replace\\(\"(/[^\"]+)\"\\)");
382 Matcher m = p.matcher(responseBody);
383 if (m.find()) {
384
385 jsRedirectionUrl = m.group(1);
386 }
387 }
388 return jsRedirectionUrl;
389 }
390
391
392 private static String getLocationValue(HttpMethod method) {
393 String locationValue = null;
394 Header location = method.getResponseHeader("Location");
395 if (location != null && isRedirect(method.getStatusCode())) {
396 locationValue = location.getValue();
397
398 if (locationValue.indexOf('"') >= 0) {
399 locationValue = URIUtil.encodePath(locationValue);
400 }
401
402 if (locationValue.startsWith("./")) {
403 locationValue = locationValue.substring(1);
404 }
405 }
406 return locationValue;
407 }
408
409
410
411
412
413
414
415
416
417 public static HttpMethod executeFollowRedirects(HttpClient httpClient, HttpMethod method) throws IOException {
418 HttpMethod currentMethod = method;
419 try {
420 DavGatewayTray.debug(new BundleMessage("LOG_EXECUTE_FOLLOW_REDIRECTS", currentMethod.getURI()));
421 executeMethod(httpClient, currentMethod);
422
423 String locationValue = getLocationValue(currentMethod);
424
425 if (locationValue == null) {
426 locationValue = getJavascriptRedirectUrl(currentMethod);
427 }
428
429 int redirectCount = 0;
430 while (redirectCount++ < Settings.getIntProperty("davmail.httpMaxRedirects", MAX_REDIRECTS)
431 && locationValue != null) {
432 currentMethod.releaseConnection();
433 currentMethod = new GetMethod(locationValue);
434 currentMethod.setFollowRedirects(false);
435 DavGatewayTray.debug(new BundleMessage("LOG_EXECUTE_FOLLOW_REDIRECTS_COUNT", currentMethod.getURI(), redirectCount));
436 executeMethod(httpClient, currentMethod);
437 locationValue = getLocationValue(currentMethod);
438 }
439 if (locationValue != null) {
440 currentMethod.releaseConnection();
441 throw new HttpServerErrorException("Maximum redirections reached");
442 }
443 } catch (IOException e) {
444 currentMethod.releaseConnection();
445 throw e;
446 }
447
448 return currentMethod;
449 }
450
451
452
453
454
455
456
457
458
459 public static int executeNoRedirect(HttpClient httpClient, HttpMethod method) throws IOException {
460 int status;
461 try {
462 status = executeMethod(httpClient, method);
463 } finally {
464 method.releaseConnection();
465 }
466
467 return status;
468 }
469
470
471
472
473
474
475
476
477
478
479
480 public static MultiStatusResponse[] executeSearchMethod(HttpClient httpClient, String path, String searchRequest,
481 int maxCount) throws IOException {
482 ExchangeSearchMethod searchMethod = new ExchangeSearchMethod(path, searchRequest);
483 if (maxCount > 0) {
484 searchMethod.addRequestHeader("Range", "rows=0-" + (maxCount - 1));
485 }
486 return executeMethod(httpClient, searchMethod);
487 }
488
489
490
491
492
493
494
495
496
497
498
499 public static MultiStatusResponse[] executePropFindMethod(HttpClient httpClient, String path, int depth, DavPropertyNameSet properties) throws IOException {
500 PropFindMethod propFindMethod = new PropFindMethod(path, properties, depth);
501 return executeMethod(httpClient, propFindMethod);
502 }
503
504
505
506
507
508
509
510
511
512 public static int executeDeleteMethod(HttpClient httpClient, String path) throws IOException {
513 DeleteMethod deleteMethod = new DeleteMethod(path);
514 deleteMethod.setFollowRedirects(false);
515
516 int status = executeHttpMethod(httpClient, deleteMethod);
517
518 if (status != HttpStatus.SC_OK && status != HttpStatus.SC_NOT_FOUND) {
519 throw DavGatewayHttpClientFacade.buildHttpResponseException(deleteMethod);
520 }
521 return status;
522 }
523
524
525
526
527
528
529
530
531
532 public static MultiStatusResponse[] executeMethod(HttpClient httpClient, DavMethodBase method) throws IOException {
533 MultiStatusResponse[] responses;
534 try {
535 int status = executeMethodFollowRedirectOnce(httpClient, method);
536
537 if (status != HttpStatus.SC_MULTI_STATUS) {
538 throw buildHttpResponseException(method);
539 }
540 responses = method.getResponseBodyAsMultiStatus().getResponses();
541
542 } catch (DavException e) {
543 throw new IOException(e.getMessage());
544 } finally {
545 method.releaseConnection();
546 }
547 return responses;
548 }
549
550
551
552
553
554
555
556
557
558 protected static int executeMethodFollowRedirectOnce(HttpClient httpClient, HttpMethod method) throws IOException {
559 int status = httpClient.executeMethod(method);
560
561
562 if (isRedirect(status)) {
563 method.releaseConnection();
564 URI targetUri = new URI(method.getResponseHeader("Location").getValue(), true);
565 checkExpiredSession(targetUri.getQuery());
566 method.setURI(targetUri);
567 status = httpClient.executeMethod(method);
568 }
569 return status;
570 }
571
572
573
574
575
576
577
578
579
580 public static MultiStatusResponse[] executeMethod(HttpClient httpClient, ExchangeDavMethod method) throws IOException {
581 MultiStatusResponse[] responses;
582 try {
583 int status = executeMethodFollowRedirectOnce(httpClient, method);
584
585 if (status != HttpStatus.SC_MULTI_STATUS) {
586 throw buildHttpResponseException(method);
587 }
588 responses = method.getResponses();
589
590 } finally {
591 method.releaseConnection();
592 }
593 return responses;
594 }
595
596
597
598
599
600
601
602
603
604 public static int executeHttpMethod(HttpClient httpClient, HttpMethod method) throws IOException {
605 int status;
606 try {
607 status = httpClient.executeMethod(method);
608 } finally {
609 method.releaseConnection();
610 }
611 return status;
612 }
613
614
615
616
617
618
619
620 public static boolean hasNTLMorNegotiate(HttpClient httpClient) {
621 Object authPrefs = httpClient.getParams().getParameter(AuthPolicy.AUTH_SCHEME_PRIORITY);
622 return authPrefs == null || (authPrefs instanceof List<?> &&
623 (((Collection) authPrefs).contains(AuthPolicy.NTLM) || ((Collection) authPrefs).contains("Negotiate")));
624 }
625
626
627
628
629
630
631 public static void addNTLM(HttpClient httpClient) {
632
633 httpClient.getParams().setParameter(HttpClientParams.PREEMPTIVE_AUTHENTICATION, false);
634
635 ArrayList<String> authPrefs = new ArrayList<>();
636 authPrefs.add(AuthPolicy.NTLM);
637 authPrefs.add(AuthPolicy.DIGEST);
638 authPrefs.add(AuthPolicy.BASIC);
639 httpClient.getParams().setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, authPrefs);
640
641
642 needNTLM = true;
643
644
645 AuthScope authScope = new AuthScope(null, -1);
646 NTCredentials credentials = (NTCredentials) httpClient.getState().getCredentials(authScope);
647 if (credentials != null && (credentials.getDomain() == null || credentials.getDomain().isEmpty())) {
648 setCredentials(httpClient, credentials.getUserName(), credentials.getPassword());
649 }
650 }
651
652
653
654
655
656
657
658
659 public static boolean acceptsNTLMOnly(HttpMethod getMethod) {
660 Header authenticateHeader = null;
661 if (getMethod.getStatusCode() == HttpStatus.SC_UNAUTHORIZED) {
662 authenticateHeader = getMethod.getResponseHeader("WWW-Authenticate");
663 } else if (getMethod.getStatusCode() == HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED) {
664 authenticateHeader = getMethod.getResponseHeader("Proxy-Authenticate");
665 }
666 if (authenticateHeader == null) {
667 return false;
668 } else {
669 boolean acceptBasic = false;
670 boolean acceptNTLM = false;
671 HeaderElement[] headerElements = authenticateHeader.getElements();
672 for (HeaderElement headerElement : headerElements) {
673 if ("NTLM".equalsIgnoreCase(headerElement.getName())) {
674 acceptNTLM = true;
675 }
676 if ("Basic realm".equalsIgnoreCase(headerElement.getName())) {
677 acceptBasic = true;
678 }
679 }
680 return acceptNTLM && !acceptBasic;
681
682 }
683 }
684
685
686
687
688
689
690
691
692
693 public static int executeTestMethod(HttpClient httpClient, GetMethod method) throws IOException {
694
695 method.setFollowRedirects(false);
696 int status = httpClient.executeMethod(method);
697 if (status == HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED
698 && acceptsNTLMOnly(method) && !hasNTLMorNegotiate(httpClient)) {
699 resetMethod(method);
700 LOGGER.debug("Received " + status + " unauthorized at " + method.getURI() + ", retrying with NTLM");
701 addNTLM(httpClient);
702 status = httpClient.executeMethod(method);
703 }
704
705 return status;
706 }
707
708
709
710
711
712
713
714
715
716 public static void executeGetMethod(HttpClient httpClient, GetMethod method, boolean followRedirects) throws IOException {
717
718 method.setFollowRedirects(followRedirects);
719 int status = httpClient.executeMethod(method);
720 if ((status == HttpStatus.SC_UNAUTHORIZED || status == HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED)
721 && acceptsNTLMOnly(method) && !hasNTLMorNegotiate(httpClient)) {
722 resetMethod(method);
723 LOGGER.debug("Received " + status + " unauthorized at " + method.getURI() + ", retrying with NTLM");
724 addNTLM(httpClient);
725 status = httpClient.executeMethod(method);
726 }
727 if (status != HttpStatus.SC_OK && (followRedirects || !isRedirect(status))) {
728 LOGGER.warn("GET failed with status " + status + " at " + method.getURI());
729 if (status != HttpStatus.SC_NOT_FOUND && status != HttpStatus.SC_FORBIDDEN) {
730 LOGGER.warn(method.getResponseBodyAsString());
731 }
732 throw DavGatewayHttpClientFacade.buildHttpResponseException(method);
733 }
734
735 if (followRedirects) {
736 String queryString = method.getQueryString();
737 checkExpiredSession(queryString);
738 }
739 }
740
741 private static void resetMethod(HttpMethod method) {
742
743 method.releaseConnection();
744 method.getHostAuthState().invalidate();
745 method.getProxyAuthState().invalidate();
746 }
747
748 private static void checkExpiredSession(String queryString) throws DavMailAuthenticationException {
749 if (queryString != null && (queryString.contains("reason=2") || queryString.contains("reason=0"))) {
750 LOGGER.warn("Request failed, session expired");
751 throw new DavMailAuthenticationException("EXCEPTION_SESSION_EXPIRED");
752 }
753 }
754
755
756
757
758
759
760
761 public static HttpResponseException buildHttpResponseException(HttpMethod method) {
762 int status = method.getStatusCode();
763 StringBuilder message = new StringBuilder();
764 message.append(status).append(' ').append(method.getStatusText());
765 try {
766 message.append(" at ").append(method.getURI().getURI());
767 if (method instanceof CopyMethod || method instanceof MoveMethod) {
768 message.append(" to ").append(method.getRequestHeader("Destination"));
769 }
770 } catch (URIException e) {
771 message.append(method.getPath());
772 }
773
774 if (status == 440) {
775 return new LoginTimeoutException(message.toString());
776 } else if (status == HttpStatus.SC_FORBIDDEN) {
777 return new HttpForbiddenException(message.toString());
778 } else if (status == HttpStatus.SC_NOT_FOUND) {
779 return new HttpNotFoundException(message.toString());
780 } else if (status == HttpStatus.SC_PRECONDITION_FAILED) {
781 return new HttpPreconditionFailedException(message.toString());
782 } else if (status == HttpStatus.SC_INTERNAL_SERVER_ERROR) {
783 return new HttpServerErrorException(message.toString());
784 } else {
785 return new HttpResponseException(status, message.toString());
786 }
787 }
788
789
790
791
792
793
794
795 public static boolean isGzipEncoded(HttpMethod method) {
796 Header[] contentEncodingHeaders = method.getResponseHeaders("Content-Encoding");
797 if (contentEncodingHeaders != null) {
798 for (Header header : contentEncodingHeaders) {
799 if ("gzip".equals(header.getValue())) {
800 return true;
801 }
802 }
803 }
804 return false;
805 }
806
807
808
809
810 public static void stop() {
811 synchronized (LOCK) {
812 if (httpConnectionManagerThread != null) {
813 httpConnectionManagerThread.shutdown();
814 httpConnectionManagerThread.interrupt();
815 httpConnectionManagerThread = null;
816 }
817 for (MultiThreadedHttpConnectionManager httpConnectionManager : ALL_CONNECTION_MANAGERS) {
818
819
820
821 synchronized (httpConnectionManager) {
822 httpConnectionManager.shutdown();
823 }
824 }
825 }
826 }
827
828
829
830
831
832
833 public static void createMultiThreadedHttpConnectionManager(HttpClient httpClient) {
834 MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
835 connectionManager.getParams().setDefaultMaxConnectionsPerHost(Settings.getIntProperty("davmail.exchange.maxConnections", 100));
836 connectionManager.getParams().setConnectionTimeout(Settings.getIntProperty("davmail.exchange.connectionTimeout", 10) * 1000);
837 connectionManager.getParams().setSoTimeout(Settings.getIntProperty("davmail.exchange.soTimeout", 120) * 1000);
838 synchronized (LOCK) {
839 ALL_CONNECTION_MANAGERS.add(connectionManager);
840 httpConnectionManagerThread.addConnectionManager(connectionManager);
841 }
842 httpClient.setHttpConnectionManager(connectionManager);
843 }
844
845
846
847
848 public static void start() {
849 synchronized (LOCK) {
850 if (httpConnectionManagerThread == null) {
851 httpConnectionManagerThread = new IdleConnectionTimeoutThread();
852 httpConnectionManagerThread.setName(IdleConnectionTimeoutThread.class.getSimpleName());
853 httpConnectionManagerThread.setConnectionTimeout(ONE_MINUTE);
854 httpConnectionManagerThread.setTimeoutInterval(ONE_MINUTE);
855 httpConnectionManagerThread.start();
856 }
857 }
858 }
859
860 public static String getUserAgent() {
861 return Settings.getProperty("davmail.userAgent", IE_USER_AGENT);
862 }
863 }