2009-07-21 04:39:18 -04:00
|
|
|
/*
|
|
|
|
* DavMail POP/IMAP/SMTP/CalDav/LDAP Exchange Gateway
|
|
|
|
* Copyright (C) 2009 Mickael Guessant
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
2008-11-03 20:47:10 -05:00
|
|
|
package davmail.http;
|
|
|
|
|
2009-04-23 10:54:06 -04:00
|
|
|
import davmail.BundleMessage;
|
2009-08-21 05:58:19 -04:00
|
|
|
import davmail.Settings;
|
2009-12-09 16:13:43 -05:00
|
|
|
import davmail.exception.*;
|
2012-01-06 06:56:55 -05:00
|
|
|
import davmail.exchange.dav.ExchangeDavMethod;
|
|
|
|
import davmail.exchange.dav.ExchangeSearchMethod;
|
2009-04-03 03:34:45 -04:00
|
|
|
import davmail.ui.tray.DavGatewayTray;
|
2008-12-08 07:59:47 -05:00
|
|
|
import org.apache.commons.httpclient.*;
|
2009-11-24 19:39:08 -05:00
|
|
|
import org.apache.commons.httpclient.auth.AuthPolicy;
|
2009-04-01 11:51:12 -04:00
|
|
|
import org.apache.commons.httpclient.auth.AuthScope;
|
2010-08-13 15:58:51 -04:00
|
|
|
import org.apache.commons.httpclient.cookie.CookiePolicy;
|
2009-03-18 13:26:33 -04:00
|
|
|
import org.apache.commons.httpclient.methods.DeleteMethod;
|
2009-04-01 11:51:12 -04:00
|
|
|
import org.apache.commons.httpclient.methods.GetMethod;
|
2009-04-07 08:46:26 -04:00
|
|
|
import org.apache.commons.httpclient.params.HttpClientParams;
|
2009-08-21 05:58:19 -04:00
|
|
|
import org.apache.commons.httpclient.params.HttpMethodParams;
|
2010-07-23 10:54:24 -04:00
|
|
|
import org.apache.commons.httpclient.util.IdleConnectionTimeoutThread;
|
2010-09-30 19:18:24 -04:00
|
|
|
import org.apache.commons.httpclient.util.URIUtil;
|
2009-04-01 11:51:12 -04:00
|
|
|
import org.apache.jackrabbit.webdav.DavException;
|
|
|
|
import org.apache.jackrabbit.webdav.MultiStatusResponse;
|
2010-10-27 04:52:27 -04:00
|
|
|
import org.apache.jackrabbit.webdav.client.methods.CopyMethod;
|
2009-04-01 11:51:12 -04:00
|
|
|
import org.apache.jackrabbit.webdav.client.methods.DavMethodBase;
|
2011-07-05 02:55:41 -04:00
|
|
|
import org.apache.jackrabbit.webdav.client.methods.MoveMethod;
|
2009-04-01 11:51:12 -04:00
|
|
|
import org.apache.jackrabbit.webdav.client.methods.PropFindMethod;
|
2009-08-21 05:58:19 -04:00
|
|
|
import org.apache.jackrabbit.webdav.property.DavPropertyNameSet;
|
2009-09-17 17:40:47 -04:00
|
|
|
import org.apache.log4j.Logger;
|
2008-11-03 20:47:10 -05:00
|
|
|
|
|
|
|
import java.io.IOException;
|
2010-07-23 10:54:24 -04:00
|
|
|
import java.net.InetSocketAddress;
|
|
|
|
import java.net.Proxy;
|
|
|
|
import java.net.ProxySelector;
|
|
|
|
import java.net.URISyntaxException;
|
2009-11-24 19:39:08 -05:00
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.Collection;
|
|
|
|
import java.util.List;
|
2012-08-23 18:05:40 -04:00
|
|
|
import java.util.regex.Matcher;
|
|
|
|
import java.util.regex.Pattern;
|
2008-11-03 20:47:10 -05:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Create HttpClient instance according to DavGateway Settings
|
|
|
|
*/
|
2008-12-17 10:27:56 -05:00
|
|
|
public final class DavGatewayHttpClientFacade {
|
2009-09-17 17:40:47 -04:00
|
|
|
static final Logger LOGGER = Logger.getLogger("davmail.http.DavGatewayHttpClientFacade");
|
|
|
|
|
2010-04-12 18:38:26 -04:00
|
|
|
static final String IE_USER_AGENT = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)";
|
2009-04-16 18:20:30 -04:00
|
|
|
static final int MAX_REDIRECTS = 10;
|
2009-09-18 05:27:00 -04:00
|
|
|
static final Object LOCK = new Object();
|
2010-02-08 15:48:12 -05:00
|
|
|
private static boolean needNTLM;
|
2008-12-08 07:59:47 -05:00
|
|
|
|
2009-04-16 18:20:30 -04:00
|
|
|
static final long ONE_MINUTE = 60000;
|
2009-04-01 18:59:04 -04:00
|
|
|
|
2010-07-23 10:54:24 -04:00
|
|
|
private static IdleConnectionTimeoutThread httpConnectionManagerThread;
|
2009-04-01 18:59:04 -04:00
|
|
|
|
2008-11-30 13:05:36 -05:00
|
|
|
static {
|
2010-09-01 16:15:55 -04:00
|
|
|
// workaround for TLS Renegotiation issue see http://java.sun.com/javase/javaseforbusiness/docs/TLSReadme.html
|
|
|
|
System.setProperty("sun.security.ssl.allowUnsafeRenegotiation", "true");
|
|
|
|
|
2008-12-08 08:49:21 -05:00
|
|
|
DavGatewayHttpClientFacade.start();
|
2008-11-30 13:05:36 -05:00
|
|
|
|
2010-09-01 16:15:55 -04:00
|
|
|
// register custom cookie policy
|
2010-08-13 15:58:51 -04:00
|
|
|
CookiePolicy.registerCookieSpec("DavMailCookieSpec", DavMailCookieSpec.class);
|
2011-02-03 18:01:33 -05:00
|
|
|
|
2011-10-29 17:17:17 -04:00
|
|
|
AuthPolicy.registerAuthScheme(AuthPolicy.BASIC, LenientBasicScheme.class);
|
|
|
|
|
2010-08-13 15:58:51 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-12-02 05:20:46 -05:00
|
|
|
private DavGatewayHttpClientFacade() {
|
|
|
|
}
|
|
|
|
|
2010-08-13 15:58:51 -04:00
|
|
|
/**
|
|
|
|
* Create basic http client with default params.
|
|
|
|
*
|
|
|
|
* @return HttpClient instance
|
|
|
|
*/
|
|
|
|
private static HttpClient getBaseInstance() {
|
|
|
|
HttpClient httpClient = new HttpClient();
|
|
|
|
httpClient.getParams().setParameter(HttpMethodParams.USER_AGENT, IE_USER_AGENT);
|
|
|
|
httpClient.getParams().setParameter(HttpClientParams.MAX_REDIRECTS, MAX_REDIRECTS);
|
|
|
|
httpClient.getParams().setCookiePolicy("DavMailCookieSpec");
|
|
|
|
return httpClient;
|
|
|
|
}
|
|
|
|
|
2008-11-03 20:47:10 -05:00
|
|
|
/**
|
|
|
|
* Create a configured HttpClient instance.
|
|
|
|
*
|
2010-03-24 05:59:23 -04:00
|
|
|
* @param url target url
|
2008-11-03 20:47:10 -05:00
|
|
|
* @return httpClient
|
2010-03-24 05:59:23 -04:00
|
|
|
* @throws DavMailException on error
|
2008-11-03 20:47:10 -05:00
|
|
|
*/
|
2010-03-24 05:59:23 -04:00
|
|
|
public static HttpClient getInstance(String url) throws DavMailException {
|
2008-11-03 20:47:10 -05:00
|
|
|
// create an HttpClient instance
|
2010-08-13 15:58:51 -04:00
|
|
|
HttpClient httpClient = getBaseInstance();
|
2010-03-24 05:59:23 -04:00
|
|
|
configureClient(httpClient, url);
|
2008-11-03 20:47:10 -05:00
|
|
|
return httpClient;
|
|
|
|
}
|
|
|
|
|
2009-08-21 05:58:19 -04:00
|
|
|
/**
|
2011-01-05 15:37:11 -05:00
|
|
|
* Set credentials on HttpClient instance.
|
2009-08-21 05:58:19 -04:00
|
|
|
*
|
2011-01-05 15:37:11 -05:00
|
|
|
* @param httpClient httpClient instance
|
2011-01-31 17:38:55 -05:00
|
|
|
* @param userName user name
|
|
|
|
* @param password user password
|
2009-08-21 05:58:19 -04:00
|
|
|
*/
|
2011-01-05 15:37:11 -05:00
|
|
|
public static void setCredentials(HttpClient httpClient, String userName, String password) {
|
2010-03-24 05:59:23 -04:00
|
|
|
// some Exchange servers redirect to a different host for freebusy, use wide auth scope
|
|
|
|
AuthScope authScope = new AuthScope(null, -1);
|
2011-01-14 04:42:25 -05:00
|
|
|
httpClient.getState().setCredentials(authScope, new NTCredentials(userName, password, "UNKNOWN", ""));
|
2009-03-18 13:26:33 -04:00
|
|
|
}
|
|
|
|
|
2008-11-03 20:47:10 -05:00
|
|
|
/**
|
2010-09-02 16:19:47 -04:00
|
|
|
* Set http client current host configuration.
|
2008-11-03 20:47:10 -05:00
|
|
|
*
|
|
|
|
* @param httpClient current Http client
|
2010-03-24 05:59:23 -04:00
|
|
|
* @param url target url
|
|
|
|
* @throws DavMailException on error
|
2008-11-03 20:47:10 -05:00
|
|
|
*/
|
2010-09-02 16:19:47 -04:00
|
|
|
public static void setClientHost(HttpClient httpClient, String url) throws DavMailException {
|
2010-03-24 05:59:23 -04:00
|
|
|
try {
|
|
|
|
HostConfiguration hostConfig = httpClient.getHostConfiguration();
|
|
|
|
URI httpURI = new URI(url, true);
|
|
|
|
hostConfig.setHost(httpURI);
|
|
|
|
} catch (URIException e) {
|
|
|
|
throw new DavMailException("LOG_INVALID_URL", url);
|
|
|
|
}
|
2010-09-02 16:19:47 -04:00
|
|
|
}
|
|
|
|
|
2012-08-28 16:50:21 -04:00
|
|
|
protected static boolean isNoProxyFor(java.net.URI uri) {
|
|
|
|
final String noProxyFor = Settings.getProperty("davmail.noProxyFor");
|
|
|
|
if (noProxyFor != null) {
|
|
|
|
final String urihost = uri.getHost().toLowerCase();
|
|
|
|
final String[] domains = noProxyFor.toLowerCase().split(",\\s*");
|
|
|
|
for (String domain : domains) {
|
|
|
|
if (urihost.endsWith(domain)) {
|
|
|
|
return true; //break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2010-09-02 16:19:47 -04:00
|
|
|
/**
|
|
|
|
* Update http client configuration (proxy)
|
|
|
|
*
|
|
|
|
* @param httpClient current Http client
|
|
|
|
* @param url target url
|
|
|
|
* @throws DavMailException on error
|
|
|
|
*/
|
|
|
|
public static void configureClient(HttpClient httpClient, String url) throws DavMailException {
|
|
|
|
setClientHost(httpClient, url);
|
2010-03-24 05:59:23 -04:00
|
|
|
|
2013-02-11 08:59:54 -05:00
|
|
|
if (Settings.getBooleanProperty("davmail.enableKerberos", false)) {
|
|
|
|
AuthPolicy.registerAuthScheme("Negotiate", SpNegoScheme.class);
|
2012-08-24 07:52:39 -04:00
|
|
|
ArrayList<String> authPrefs = new ArrayList<String>();
|
|
|
|
authPrefs.add("Negotiate");
|
|
|
|
httpClient.getParams().setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, authPrefs);
|
2013-02-11 08:59:54 -05:00
|
|
|
} else if (!needNTLM) {
|
2010-02-08 15:48:12 -05:00
|
|
|
ArrayList<String> authPrefs = new ArrayList<String>();
|
|
|
|
authPrefs.add(AuthPolicy.DIGEST);
|
|
|
|
authPrefs.add(AuthPolicy.BASIC);
|
|
|
|
// exclude NTLM authentication scheme
|
|
|
|
httpClient.getParams().setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, authPrefs);
|
|
|
|
}
|
2009-11-24 19:39:08 -05:00
|
|
|
|
2008-11-03 20:47:10 -05:00
|
|
|
boolean enableProxy = Settings.getBooleanProperty("davmail.enableProxy");
|
2011-11-23 16:13:04 -05:00
|
|
|
boolean useSystemProxies = Settings.getBooleanProperty("davmail.useSystemProxies", Boolean.FALSE);
|
2008-11-03 20:47:10 -05:00
|
|
|
String proxyHost = null;
|
|
|
|
int proxyPort = 0;
|
|
|
|
String proxyUser = null;
|
|
|
|
String proxyPassword = null;
|
|
|
|
|
2012-08-27 16:35:47 -04:00
|
|
|
try {
|
|
|
|
java.net.URI uri = new java.net.URI(url);
|
2012-08-28 16:50:21 -04:00
|
|
|
if (isNoProxyFor(uri)) {
|
2012-08-27 16:35:47 -04:00
|
|
|
LOGGER.debug("no proxy for "+uri.getHost());
|
|
|
|
} else if (useSystemProxies) {
|
|
|
|
// get proxy for url from system settings
|
|
|
|
System.setProperty("java.net.useSystemProxies", "true");
|
|
|
|
List<Proxy> proxyList = getProxyForURI(uri);
|
2011-02-03 18:01:33 -05:00
|
|
|
if (!proxyList.isEmpty() && proxyList.get(0).address() != null) {
|
|
|
|
InetSocketAddress inetSocketAddress = (InetSocketAddress) proxyList.get(0).address();
|
|
|
|
proxyHost = inetSocketAddress.getHostName();
|
|
|
|
proxyPort = inetSocketAddress.getPort();
|
|
|
|
|
|
|
|
// we may still need authentication credentials
|
|
|
|
proxyUser = Settings.getProperty("davmail.proxyUser");
|
|
|
|
proxyPassword = Settings.getProperty("davmail.proxyPassword");
|
2010-03-24 05:59:23 -04:00
|
|
|
}
|
2012-08-27 16:35:47 -04:00
|
|
|
} else if (enableProxy) {
|
|
|
|
proxyHost = Settings.getProperty("davmail.proxyHost");
|
|
|
|
proxyPort = Settings.getIntProperty("davmail.proxyPort");
|
|
|
|
proxyUser = Settings.getProperty("davmail.proxyUser");
|
|
|
|
proxyPassword = Settings.getProperty("davmail.proxyPassword");
|
2010-03-24 05:59:23 -04:00
|
|
|
}
|
2012-08-27 16:35:47 -04:00
|
|
|
} catch (URISyntaxException e) {
|
|
|
|
throw new DavMailException("LOG_INVALID_URL", url);
|
2008-11-03 20:47:10 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// configure proxy
|
|
|
|
if (proxyHost != null && proxyHost.length() > 0) {
|
|
|
|
httpClient.getHostConfiguration().setProxy(proxyHost, proxyPort);
|
|
|
|
if (proxyUser != null && proxyUser.length() > 0) {
|
|
|
|
|
2009-04-01 11:51:12 -04:00
|
|
|
AuthScope authScope = new AuthScope(proxyHost, proxyPort, AuthScope.ANY_REALM);
|
|
|
|
|
2009-04-01 17:31:44 -04:00
|
|
|
// detect ntlm authentication (windows domain name in user name)
|
2009-04-16 17:16:40 -04:00
|
|
|
int backslashindex = proxyUser.indexOf('\\');
|
2008-11-03 20:47:10 -05:00
|
|
|
if (backslashindex > 0) {
|
2009-04-01 11:51:12 -04:00
|
|
|
httpClient.getState().setProxyCredentials(authScope,
|
2008-11-03 20:47:10 -05:00
|
|
|
new NTCredentials(proxyUser.substring(backslashindex + 1),
|
2011-01-14 04:42:25 -05:00
|
|
|
proxyPassword, "UNKNOWN",
|
2008-11-03 20:47:10 -05:00
|
|
|
proxyUser.substring(0, backslashindex)));
|
|
|
|
} else {
|
2009-04-01 11:51:12 -04:00
|
|
|
httpClient.getState().setProxyCredentials(authScope,
|
2011-01-14 04:42:25 -05:00
|
|
|
new NTCredentials(proxyUser, proxyPassword, "UNKNOWN", ""));
|
2008-11-03 20:47:10 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2011-05-23 17:40:45 -04:00
|
|
|
/**
|
|
|
|
* Retrieve Proxy Selector
|
|
|
|
*
|
2011-07-05 02:55:41 -04:00
|
|
|
* @param uri target uri
|
2011-05-23 17:40:45 -04:00
|
|
|
* @return proxy selector
|
|
|
|
*/
|
2011-07-05 02:55:41 -04:00
|
|
|
private static List<Proxy> getProxyForURI(java.net.URI uri) {
|
2011-09-16 05:25:49 -04:00
|
|
|
LOGGER.debug("get Default proxy selector");
|
|
|
|
ProxySelector proxySelector = ProxySelector.getDefault();
|
2011-07-05 02:55:41 -04:00
|
|
|
LOGGER.debug("getProxyForURI(" + uri + ')');
|
2011-09-16 05:25:49 -04:00
|
|
|
List<Proxy> proxies = proxySelector.select(uri);
|
2011-07-05 02:55:41 -04:00
|
|
|
LOGGER.debug("got system proxies:" + proxies);
|
|
|
|
return proxies;
|
2011-05-23 17:40:45 -04:00
|
|
|
}
|
|
|
|
|
2008-11-03 20:47:10 -05:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Get Http Status code for the given URL
|
|
|
|
*
|
2011-01-05 15:37:11 -05:00
|
|
|
* @param httpClient httpClient instance
|
2011-01-31 17:38:55 -05:00
|
|
|
* @param url url string
|
2008-11-03 20:47:10 -05:00
|
|
|
* @return HttpStatus code
|
|
|
|
*/
|
2011-06-08 15:58:29 -04:00
|
|
|
public static int getHttpStatus(HttpClient httpClient, String url) {
|
2008-11-03 20:47:10 -05:00
|
|
|
int status = 0;
|
|
|
|
HttpMethod testMethod = new GetMethod(url);
|
2008-11-04 05:37:36 -05:00
|
|
|
testMethod.setDoAuthentication(false);
|
2008-11-03 20:47:10 -05:00
|
|
|
try {
|
|
|
|
status = httpClient.executeMethod(testMethod);
|
2010-09-30 19:18:24 -04:00
|
|
|
} catch (IOException e) {
|
|
|
|
LOGGER.warn(e.getMessage(), e);
|
2008-11-03 20:47:10 -05:00
|
|
|
} finally {
|
|
|
|
testMethod.releaseConnection();
|
|
|
|
}
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
2009-08-21 05:58:19 -04:00
|
|
|
/**
|
|
|
|
* Check if status is a redirect (various 30x values).
|
|
|
|
*
|
|
|
|
* @param status Http status
|
|
|
|
* @return true if status is a redirect
|
|
|
|
*/
|
2008-11-03 20:47:10 -05:00
|
|
|
public static boolean isRedirect(int status) {
|
|
|
|
return status == HttpStatus.SC_MOVED_PERMANENTLY
|
|
|
|
|| status == HttpStatus.SC_MOVED_TEMPORARILY
|
|
|
|
|| status == HttpStatus.SC_SEE_OTHER
|
|
|
|
|| status == HttpStatus.SC_TEMPORARY_REDIRECT;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Execute given url, manually follow redirects.
|
|
|
|
* Workaround for HttpClient bug (GET full URL over HTTPS and proxy)
|
|
|
|
*
|
|
|
|
* @param httpClient HttpClient instance
|
|
|
|
* @param url url string
|
|
|
|
* @return executed method
|
|
|
|
* @throws IOException on error
|
|
|
|
*/
|
|
|
|
public static HttpMethod executeFollowRedirects(HttpClient httpClient, String url) throws IOException {
|
|
|
|
HttpMethod method = new GetMethod(url);
|
2008-12-01 07:38:49 -05:00
|
|
|
method.setFollowRedirects(false);
|
|
|
|
return executeFollowRedirects(httpClient, method);
|
|
|
|
}
|
|
|
|
|
2011-01-04 16:32:24 -05:00
|
|
|
private static int checkNTLM(HttpClient httpClient, HttpMethod currentMethod) throws IOException {
|
|
|
|
int status = currentMethod.getStatusCode();
|
|
|
|
if ((status == HttpStatus.SC_UNAUTHORIZED || status == HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED)
|
2013-02-12 07:55:10 -05:00
|
|
|
&& acceptsNTLMOnly(currentMethod) && !hasNTLMorNegotiate(httpClient)) {
|
2011-01-04 16:32:24 -05:00
|
|
|
LOGGER.debug("Received " + status + " unauthorized at " + currentMethod.getURI() + ", retrying with NTLM");
|
|
|
|
resetMethod(currentMethod);
|
|
|
|
addNTLM(httpClient);
|
|
|
|
status = httpClient.executeMethod(currentMethod);
|
|
|
|
}
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
2012-08-23 18:05:40 -04:00
|
|
|
/**
|
|
|
|
* Checks if there is a Javascript redirect inside the page,
|
|
|
|
* and returns it.
|
2012-08-28 16:50:21 -04:00
|
|
|
* <p/>
|
2012-08-23 18:05:40 -04:00
|
|
|
* A Javascript redirect is usually found on OTP pre-auth page,
|
|
|
|
* when the pre-auth form is in a distinct page from the regular Exchange login one.
|
|
|
|
*
|
|
|
|
* @param method http method
|
|
|
|
* @return the redirect URL if found, or null if no Javascript redirect has been found
|
|
|
|
*/
|
|
|
|
private static String getJavascriptRedirectUrl(HttpMethod method) throws IOException {
|
|
|
|
String responseBody = method.getResponseBodyAsString();
|
|
|
|
String jsRedirectionUrl = null;
|
|
|
|
if (responseBody.indexOf("javascript:go_url()") > 0) {
|
|
|
|
// Create a pattern to match a javascript redirect url
|
|
|
|
Pattern p = Pattern.compile("go_url\\(\\)[^{]+\\{[^l]+location.replace\\(\"(/[^\"]+)\"\\)");
|
|
|
|
Matcher m = p.matcher(responseBody);
|
|
|
|
if (m.find()) {
|
|
|
|
// Javascript redirect found!
|
|
|
|
jsRedirectionUrl = m.group(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return jsRedirectionUrl;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static String getLocationValue(HttpMethod method) throws URIException {
|
2012-08-23 17:58:50 -04:00
|
|
|
String locationValue = null;
|
|
|
|
Header location = method.getResponseHeader("Location");
|
|
|
|
if (location != null && isRedirect(method.getStatusCode())) {
|
|
|
|
locationValue = location.getValue();
|
|
|
|
// Novell iChain workaround
|
|
|
|
if (locationValue.indexOf('"') >= 0) {
|
|
|
|
locationValue = URIUtil.encodePath(locationValue);
|
|
|
|
}
|
|
|
|
// workaround for invalid relative location
|
|
|
|
if (locationValue.startsWith("./")) {
|
|
|
|
locationValue = locationValue.substring(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return locationValue;
|
|
|
|
}
|
|
|
|
|
2009-08-21 05:58:19 -04:00
|
|
|
/**
|
|
|
|
* Execute method with httpClient, follow 30x redirects.
|
|
|
|
*
|
|
|
|
* @param httpClient Http client instance
|
|
|
|
* @param method Http method
|
|
|
|
* @return last http method after redirects
|
|
|
|
* @throws IOException on error
|
|
|
|
*/
|
2008-12-01 07:38:49 -05:00
|
|
|
public static HttpMethod executeFollowRedirects(HttpClient httpClient, HttpMethod method) throws IOException {
|
2009-04-16 17:52:17 -04:00
|
|
|
HttpMethod currentMethod = method;
|
2008-11-03 20:47:10 -05:00
|
|
|
try {
|
2009-04-23 10:54:06 -04:00
|
|
|
DavGatewayTray.debug(new BundleMessage("LOG_EXECUTE_FOLLOW_REDIRECTS", currentMethod.getURI()));
|
2011-01-04 16:32:24 -05:00
|
|
|
httpClient.executeMethod(currentMethod);
|
2012-08-23 17:58:50 -04:00
|
|
|
checkNTLM(httpClient, currentMethod);
|
|
|
|
|
|
|
|
String locationValue = getLocationValue(currentMethod);
|
2012-08-23 18:05:40 -04:00
|
|
|
// check javascript redirect (multiple authentication pages)
|
|
|
|
if (locationValue == null) {
|
|
|
|
locationValue = getJavascriptRedirectUrl(currentMethod);
|
|
|
|
}
|
2011-01-04 16:32:24 -05:00
|
|
|
|
2008-11-03 20:47:10 -05:00
|
|
|
int redirectCount = 0;
|
|
|
|
while (redirectCount++ < 10
|
2012-08-23 17:58:50 -04:00
|
|
|
&& locationValue != null) {
|
2009-04-16 17:52:17 -04:00
|
|
|
currentMethod.releaseConnection();
|
2010-09-30 19:18:24 -04:00
|
|
|
currentMethod = new GetMethod(locationValue);
|
2009-04-16 17:52:17 -04:00
|
|
|
currentMethod.setFollowRedirects(false);
|
2009-04-23 10:54:06 -04:00
|
|
|
DavGatewayTray.debug(new BundleMessage("LOG_EXECUTE_FOLLOW_REDIRECTS_COUNT", currentMethod.getURI(), redirectCount));
|
2009-04-16 17:52:17 -04:00
|
|
|
httpClient.executeMethod(currentMethod);
|
2011-01-04 16:32:24 -05:00
|
|
|
checkNTLM(httpClient, currentMethod);
|
2012-08-23 17:58:50 -04:00
|
|
|
locationValue = getLocationValue(currentMethod);
|
2008-11-03 20:47:10 -05:00
|
|
|
}
|
2012-08-23 17:58:50 -04:00
|
|
|
if (locationValue != null) {
|
2009-04-16 17:52:17 -04:00
|
|
|
currentMethod.releaseConnection();
|
2008-11-03 20:47:10 -05:00
|
|
|
throw new HttpException("Maximum redirections reached");
|
|
|
|
}
|
|
|
|
} catch (IOException e) {
|
2009-04-16 17:52:17 -04:00
|
|
|
currentMethod.releaseConnection();
|
2008-11-03 20:47:10 -05:00
|
|
|
throw e;
|
|
|
|
}
|
|
|
|
// caller will need to release connection
|
2009-04-16 17:52:17 -04:00
|
|
|
return currentMethod;
|
2008-11-03 20:47:10 -05:00
|
|
|
}
|
2008-12-08 08:49:21 -05:00
|
|
|
|
2010-07-28 13:11:18 -04:00
|
|
|
/**
|
|
|
|
* Execute method with httpClient, do not follow 30x redirects.
|
|
|
|
*
|
|
|
|
* @param httpClient Http client instance
|
|
|
|
* @param method Http method
|
|
|
|
* @return status
|
|
|
|
* @throws IOException on error
|
|
|
|
*/
|
|
|
|
public static int executeNoRedirect(HttpClient httpClient, HttpMethod method) throws IOException {
|
|
|
|
int status;
|
|
|
|
try {
|
|
|
|
status = httpClient.executeMethod(method);
|
|
|
|
// check NTLM
|
|
|
|
if ((status == HttpStatus.SC_UNAUTHORIZED || status == HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED)
|
2013-02-12 07:55:10 -05:00
|
|
|
&& acceptsNTLMOnly(method) && !hasNTLMorNegotiate(httpClient)) {
|
2010-07-28 13:11:18 -04:00
|
|
|
LOGGER.debug("Received " + status + " unauthorized at " + method.getURI() + ", retrying with NTLM");
|
|
|
|
resetMethod(method);
|
|
|
|
addNTLM(httpClient);
|
|
|
|
status = httpClient.executeMethod(method);
|
|
|
|
}
|
|
|
|
} finally {
|
|
|
|
method.releaseConnection();
|
|
|
|
}
|
|
|
|
// caller will need to release connection
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
2008-12-17 10:27:56 -05:00
|
|
|
/**
|
2009-03-18 13:26:33 -04:00
|
|
|
* Execute webdav search method.
|
|
|
|
*
|
|
|
|
* @param httpClient http client instance
|
|
|
|
* @param path <i>encoded</i> searched folder path
|
2008-12-17 10:27:56 -05:00
|
|
|
* @param searchRequest (SQL like) search request
|
2010-08-13 15:58:51 -04:00
|
|
|
* @param maxCount max item count
|
2009-03-18 13:26:33 -04:00
|
|
|
* @return Responses enumeration
|
2008-12-17 10:27:56 -05:00
|
|
|
* @throws IOException on error
|
|
|
|
*/
|
2010-07-27 16:34:43 -04:00
|
|
|
public static MultiStatusResponse[] executeSearchMethod(HttpClient httpClient, String path, String searchRequest,
|
|
|
|
int maxCount) throws IOException {
|
2012-01-06 06:56:55 -05:00
|
|
|
ExchangeSearchMethod searchMethod = new ExchangeSearchMethod(path, searchRequest);
|
2010-07-27 16:34:43 -04:00
|
|
|
if (maxCount > 0) {
|
2010-08-13 15:58:51 -04:00
|
|
|
searchMethod.addRequestHeader("Range", "rows=0-" + (maxCount - 1));
|
2010-07-27 16:34:43 -04:00
|
|
|
}
|
2009-03-18 13:26:33 -04:00
|
|
|
return executeMethod(httpClient, searchMethod);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Execute webdav propfind method.
|
|
|
|
*
|
|
|
|
* @param httpClient http client instance
|
|
|
|
* @param path <i>encoded</i> searched folder path
|
|
|
|
* @param depth propfind request depth
|
|
|
|
* @param properties propfind requested properties
|
|
|
|
* @return Responses enumeration
|
|
|
|
* @throws IOException on error
|
|
|
|
*/
|
2009-04-01 11:51:12 -04:00
|
|
|
public static MultiStatusResponse[] executePropFindMethod(HttpClient httpClient, String path, int depth, DavPropertyNameSet properties) throws IOException {
|
|
|
|
PropFindMethod propFindMethod = new PropFindMethod(path, properties, depth);
|
2009-03-18 13:26:33 -04:00
|
|
|
return executeMethod(httpClient, propFindMethod);
|
|
|
|
}
|
|
|
|
|
2009-08-21 05:58:19 -04:00
|
|
|
/**
|
|
|
|
* Execute a delete method on the given path with httpClient.
|
|
|
|
*
|
|
|
|
* @param httpClient Http client instance
|
|
|
|
* @param path Path to be deleted
|
2011-07-20 09:24:56 -04:00
|
|
|
* @return http status
|
2012-08-28 16:50:21 -04:00
|
|
|
* @throws IOException on error
|
2009-08-21 05:58:19 -04:00
|
|
|
*/
|
2011-07-20 09:24:56 -04:00
|
|
|
public static int executeDeleteMethod(HttpClient httpClient, String path) throws IOException {
|
2009-03-18 13:26:33 -04:00
|
|
|
DeleteMethod deleteMethod = new DeleteMethod(path);
|
2009-09-17 17:40:47 -04:00
|
|
|
deleteMethod.setFollowRedirects(false);
|
2009-03-18 13:26:33 -04:00
|
|
|
|
|
|
|
int status = executeHttpMethod(httpClient, deleteMethod);
|
|
|
|
// do not throw error if already deleted
|
|
|
|
if (status != HttpStatus.SC_OK && status != HttpStatus.SC_NOT_FOUND) {
|
|
|
|
throw DavGatewayHttpClientFacade.buildHttpException(deleteMethod);
|
|
|
|
}
|
2011-07-20 09:24:56 -04:00
|
|
|
return status;
|
2009-03-18 13:26:33 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Execute webdav request.
|
|
|
|
*
|
|
|
|
* @param httpClient http client instance
|
|
|
|
* @param method webdav method
|
|
|
|
* @return Responses enumeration
|
|
|
|
* @throws IOException on error
|
|
|
|
*/
|
2009-04-01 11:51:12 -04:00
|
|
|
public static MultiStatusResponse[] executeMethod(HttpClient httpClient, DavMethodBase method) throws IOException {
|
|
|
|
MultiStatusResponse[] responses = null;
|
2008-12-17 10:27:56 -05:00
|
|
|
try {
|
2009-03-18 13:26:33 -04:00
|
|
|
int status = httpClient.executeMethod(method);
|
|
|
|
|
2009-12-09 16:13:43 -05:00
|
|
|
// need to follow redirects (once) on public folders
|
|
|
|
if (isRedirect(status)) {
|
|
|
|
method.releaseConnection();
|
|
|
|
URI targetUri = new URI(method.getResponseHeader("Location").getValue(), true);
|
|
|
|
checkExpiredSession(targetUri.getQuery());
|
|
|
|
method.setURI(targetUri);
|
|
|
|
status = httpClient.executeMethod(method);
|
|
|
|
}
|
|
|
|
|
2009-03-18 13:26:33 -04:00
|
|
|
if (status != HttpStatus.SC_MULTI_STATUS) {
|
|
|
|
throw buildHttpException(method);
|
2008-12-17 10:27:56 -05:00
|
|
|
}
|
2009-04-01 11:51:12 -04:00
|
|
|
responses = method.getResponseBodyAsMultiStatus().getResponses();
|
2009-03-18 13:26:33 -04:00
|
|
|
|
2009-04-01 11:51:12 -04:00
|
|
|
} catch (DavException e) {
|
|
|
|
throw new IOException(e.getMessage());
|
2009-03-18 13:26:33 -04:00
|
|
|
} finally {
|
|
|
|
method.releaseConnection();
|
|
|
|
}
|
2009-04-01 11:51:12 -04:00
|
|
|
return responses;
|
2009-03-18 13:26:33 -04:00
|
|
|
}
|
2008-12-17 10:27:56 -05:00
|
|
|
|
2012-01-06 06:56:55 -05:00
|
|
|
/**
|
|
|
|
* Execute webdav request.
|
|
|
|
*
|
|
|
|
* @param httpClient http client instance
|
|
|
|
* @param method webdav method
|
|
|
|
* @return Responses enumeration
|
|
|
|
* @throws IOException on error
|
|
|
|
*/
|
|
|
|
public static MultiStatusResponse[] executeMethod(HttpClient httpClient, ExchangeDavMethod method) throws IOException {
|
|
|
|
MultiStatusResponse[] responses = null;
|
|
|
|
try {
|
|
|
|
int status = httpClient.executeMethod(method);
|
|
|
|
|
|
|
|
// need to follow redirects (once) on public folders
|
|
|
|
if (isRedirect(status)) {
|
|
|
|
method.releaseConnection();
|
|
|
|
URI targetUri = new URI(method.getResponseHeader("Location").getValue(), true);
|
|
|
|
checkExpiredSession(targetUri.getQuery());
|
|
|
|
method.setURI(targetUri);
|
|
|
|
status = httpClient.executeMethod(method);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (status != HttpStatus.SC_MULTI_STATUS) {
|
|
|
|
throw buildHttpException(method);
|
|
|
|
}
|
|
|
|
responses = method.getResponses();
|
|
|
|
|
|
|
|
} finally {
|
|
|
|
method.releaseConnection();
|
|
|
|
}
|
|
|
|
return responses;
|
|
|
|
}
|
|
|
|
|
2009-08-21 05:58:19 -04:00
|
|
|
/**
|
|
|
|
* Execute method with httpClient.
|
|
|
|
*
|
|
|
|
* @param httpClient Http client instance
|
|
|
|
* @param method Http method
|
|
|
|
* @return Http status
|
|
|
|
* @throws IOException on error
|
|
|
|
*/
|
2009-03-18 13:26:33 -04:00
|
|
|
public static int executeHttpMethod(HttpClient httpClient, HttpMethod method) throws IOException {
|
|
|
|
int status = 0;
|
|
|
|
try {
|
|
|
|
status = httpClient.executeMethod(method);
|
2008-12-17 10:27:56 -05:00
|
|
|
} finally {
|
2009-03-18 13:26:33 -04:00
|
|
|
method.releaseConnection();
|
2008-12-17 10:27:56 -05:00
|
|
|
}
|
2009-03-18 13:26:33 -04:00
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
2010-02-01 17:52:36 -05:00
|
|
|
/**
|
|
|
|
* Test if NTLM auth scheme is enabled.
|
2010-02-08 15:48:12 -05:00
|
|
|
*
|
2010-02-01 17:52:36 -05:00
|
|
|
* @param httpClient HttpClient instance
|
|
|
|
* @return true if NTLM is enabled
|
|
|
|
*/
|
2013-02-12 07:55:10 -05:00
|
|
|
public static boolean hasNTLMorNegotiate(HttpClient httpClient) {
|
2009-11-24 19:39:08 -05:00
|
|
|
Object authPrefs = httpClient.getParams().getParameter(AuthPolicy.AUTH_SCHEME_PRIORITY);
|
2013-02-12 07:55:10 -05:00
|
|
|
return authPrefs == null || (authPrefs instanceof List<?> &&
|
|
|
|
(((Collection) authPrefs).contains(AuthPolicy.NTLM) || ((Collection) authPrefs).contains("Negotiate")));
|
2009-11-24 19:39:08 -05:00
|
|
|
}
|
|
|
|
|
2010-03-30 16:46:57 -04:00
|
|
|
/**
|
|
|
|
* Enable NTLM authentication on http client
|
2010-07-20 05:10:39 -04:00
|
|
|
*
|
2010-03-30 16:46:57 -04:00
|
|
|
* @param httpClient HttpClient instance
|
|
|
|
*/
|
|
|
|
public static void addNTLM(HttpClient httpClient) {
|
2010-07-25 15:35:10 -04:00
|
|
|
// disable preemptive authentication
|
|
|
|
httpClient.getParams().setParameter(HttpClientParams.PREEMPTIVE_AUTHENTICATION, false);
|
2011-01-05 15:37:11 -05:00
|
|
|
|
2010-04-22 04:09:09 -04:00
|
|
|
// register the jcifs based NTLMv2 implementation
|
|
|
|
AuthPolicy.registerAuthScheme(AuthPolicy.NTLM, NTLMv2Scheme.class);
|
2010-07-20 05:10:39 -04:00
|
|
|
|
2009-11-24 19:39:08 -05:00
|
|
|
ArrayList<String> authPrefs = new ArrayList<String>();
|
|
|
|
authPrefs.add(AuthPolicy.NTLM);
|
|
|
|
authPrefs.add(AuthPolicy.DIGEST);
|
|
|
|
authPrefs.add(AuthPolicy.BASIC);
|
|
|
|
httpClient.getParams().setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, authPrefs);
|
2010-08-17 02:56:38 -04:00
|
|
|
|
|
|
|
// separate domain from username in credentials
|
|
|
|
AuthScope authScope = new AuthScope(null, -1);
|
|
|
|
NTCredentials credentials = (NTCredentials) httpClient.getState().getCredentials(authScope);
|
|
|
|
String userName = credentials.getUserName();
|
|
|
|
int backSlashIndex = userName.indexOf('\\');
|
2010-09-01 16:15:55 -04:00
|
|
|
if (backSlashIndex >= 0) {
|
2010-08-17 02:56:38 -04:00
|
|
|
String domain = userName.substring(0, backSlashIndex);
|
2010-09-01 16:15:55 -04:00
|
|
|
userName = userName.substring(backSlashIndex + 1);
|
2011-01-14 04:42:25 -05:00
|
|
|
credentials = new NTCredentials(userName, credentials.getPassword(), "UNKNOWN", domain);
|
2010-09-01 16:15:55 -04:00
|
|
|
httpClient.getState().setCredentials(authScope, credentials);
|
2010-08-17 02:56:38 -04:00
|
|
|
}
|
|
|
|
|
2010-02-08 15:48:12 -05:00
|
|
|
// make sure NTLM is always active
|
|
|
|
needNTLM = true;
|
2009-11-24 19:39:08 -05:00
|
|
|
}
|
|
|
|
|
2010-03-24 05:59:23 -04:00
|
|
|
/**
|
|
|
|
* Test method header for supported authentication mode,
|
|
|
|
* return true if Basic authentication is not available
|
|
|
|
*
|
|
|
|
* @param getMethod http method
|
|
|
|
* @return true if only NTLM is enabled
|
|
|
|
*/
|
2010-02-08 15:48:12 -05:00
|
|
|
public static boolean acceptsNTLMOnly(HttpMethod getMethod) {
|
2010-02-01 17:52:36 -05:00
|
|
|
Header authenticateHeader = null;
|
|
|
|
if (getMethod.getStatusCode() == HttpStatus.SC_UNAUTHORIZED) {
|
2010-05-14 09:59:22 -04:00
|
|
|
authenticateHeader = getMethod.getResponseHeader("WWW-Authenticate");
|
2010-02-01 17:52:36 -05:00
|
|
|
} else if (getMethod.getStatusCode() == HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED) {
|
2010-02-08 15:48:12 -05:00
|
|
|
authenticateHeader = getMethod.getResponseHeader("Proxy-Authenticate");
|
|
|
|
}
|
|
|
|
if (authenticateHeader == null) {
|
|
|
|
return false;
|
|
|
|
} else {
|
|
|
|
boolean acceptBasic = false;
|
|
|
|
boolean acceptNTLM = false;
|
|
|
|
HeaderElement[] headerElements = authenticateHeader.getElements();
|
|
|
|
for (HeaderElement headerElement : headerElements) {
|
|
|
|
if ("NTLM".equalsIgnoreCase(headerElement.getName())) {
|
|
|
|
acceptNTLM = true;
|
|
|
|
}
|
2010-05-14 09:59:22 -04:00
|
|
|
if ("Basic realm".equalsIgnoreCase(headerElement.getName())) {
|
2010-07-20 05:10:39 -04:00
|
|
|
acceptBasic = true;
|
2010-02-08 15:48:12 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return acceptNTLM && !acceptBasic;
|
|
|
|
|
2010-02-01 17:52:36 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-02-12 05:23:07 -05:00
|
|
|
/**
|
|
|
|
* Execute test method from checkConfig, with proxy credentials, but without Exchange credentials.
|
|
|
|
*
|
2010-03-24 05:59:23 -04:00
|
|
|
* @param httpClient Http client instance
|
|
|
|
* @param method Http method
|
2010-02-12 05:23:07 -05:00
|
|
|
* @return Http status
|
|
|
|
* @throws IOException on error
|
|
|
|
*/
|
|
|
|
public static int executeTestMethod(HttpClient httpClient, GetMethod method) throws IOException {
|
2010-03-24 05:59:23 -04:00
|
|
|
// do not follow redirects in expired sessions
|
2010-02-12 05:23:07 -05:00
|
|
|
method.setFollowRedirects(false);
|
|
|
|
int status = httpClient.executeMethod(method);
|
|
|
|
if (status == HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED
|
2013-02-12 07:55:10 -05:00
|
|
|
&& acceptsNTLMOnly(method) && !hasNTLMorNegotiate(httpClient)) {
|
2010-04-22 06:32:44 -04:00
|
|
|
resetMethod(method);
|
2010-02-12 05:23:07 -05:00
|
|
|
LOGGER.debug("Received " + status + " unauthorized at " + method.getURI() + ", retrying with NTLM");
|
|
|
|
addNTLM(httpClient);
|
|
|
|
status = httpClient.executeMethod(method);
|
|
|
|
}
|
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
2010-03-24 05:59:23 -04:00
|
|
|
|
2009-09-17 17:40:47 -04:00
|
|
|
/**
|
|
|
|
* Execute Get method, do not follow redirects.
|
|
|
|
*
|
2009-10-16 04:58:04 -04:00
|
|
|
* @param httpClient Http client instance
|
|
|
|
* @param method Http method
|
|
|
|
* @param followRedirects Follow redirects flag
|
2010-02-08 15:48:12 -05:00
|
|
|
* @throws IOException on error
|
2009-09-17 17:40:47 -04:00
|
|
|
*/
|
2010-07-20 05:10:39 -04:00
|
|
|
public static void executeGetMethod(HttpClient httpClient, GetMethod method, boolean followRedirects) throws IOException {
|
2009-09-17 17:40:47 -04:00
|
|
|
// do not follow redirects in expired sessions
|
2009-10-16 04:58:04 -04:00
|
|
|
method.setFollowRedirects(followRedirects);
|
2009-09-17 17:40:47 -04:00
|
|
|
int status = httpClient.executeMethod(method);
|
2010-02-01 17:52:36 -05:00
|
|
|
if ((status == HttpStatus.SC_UNAUTHORIZED || status == HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED)
|
2013-02-12 07:55:10 -05:00
|
|
|
&& acceptsNTLMOnly(method) && !hasNTLMorNegotiate(httpClient)) {
|
2010-04-22 06:32:44 -04:00
|
|
|
resetMethod(method);
|
2010-02-08 15:48:12 -05:00
|
|
|
LOGGER.debug("Received " + status + " unauthorized at " + method.getURI() + ", retrying with NTLM");
|
2009-11-24 19:39:08 -05:00
|
|
|
addNTLM(httpClient);
|
|
|
|
status = httpClient.executeMethod(method);
|
|
|
|
}
|
2010-02-01 17:52:36 -05:00
|
|
|
if (status != HttpStatus.SC_OK && (followRedirects || !isRedirect(status))) {
|
2010-10-14 16:54:20 -04:00
|
|
|
LOGGER.warn("GET failed with status " + status + " at " + method.getURI());
|
|
|
|
if (status != HttpStatus.SC_NOT_FOUND && status != HttpStatus.SC_FORBIDDEN) {
|
|
|
|
LOGGER.warn(method.getResponseBodyAsString());
|
|
|
|
}
|
2009-12-07 04:35:25 -05:00
|
|
|
throw DavGatewayHttpClientFacade.buildHttpException(method);
|
2009-09-17 17:40:47 -04:00
|
|
|
}
|
2009-10-16 04:58:04 -04:00
|
|
|
// check for expired session
|
|
|
|
if (followRedirects) {
|
|
|
|
String queryString = method.getQueryString();
|
2009-12-09 16:13:43 -05:00
|
|
|
checkExpiredSession(queryString);
|
2009-10-16 04:58:04 -04:00
|
|
|
}
|
2009-09-17 17:40:47 -04:00
|
|
|
}
|
|
|
|
|
2010-04-22 06:32:44 -04:00
|
|
|
private static void resetMethod(HttpMethod method) {
|
|
|
|
// reset method state
|
|
|
|
method.releaseConnection();
|
|
|
|
method.getHostAuthState().invalidate();
|
|
|
|
method.getProxyAuthState().invalidate();
|
|
|
|
}
|
|
|
|
|
2009-12-09 16:13:43 -05:00
|
|
|
private static void checkExpiredSession(String queryString) throws DavMailAuthenticationException {
|
2010-11-09 17:27:57 -05:00
|
|
|
if (queryString != null && (queryString.contains("reason=2") || queryString.contains("reason=0"))) {
|
|
|
|
LOGGER.warn("Request failed, session expired");
|
2009-12-09 16:13:43 -05:00
|
|
|
throw new DavMailAuthenticationException("EXCEPTION_SESSION_EXPIRED");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-03-18 13:26:33 -04:00
|
|
|
/**
|
|
|
|
* Build Http Exception from methode status
|
|
|
|
*
|
|
|
|
* @param method Http Method
|
|
|
|
* @return Http Exception
|
|
|
|
*/
|
|
|
|
public static HttpException buildHttpException(HttpMethod method) {
|
2009-08-11 12:55:35 -04:00
|
|
|
int status = method.getStatusCode();
|
2009-09-21 17:50:47 -04:00
|
|
|
StringBuilder message = new StringBuilder();
|
|
|
|
message.append(status).append(' ').append(method.getStatusText());
|
|
|
|
try {
|
|
|
|
message.append(" at ").append(method.getURI().getURI());
|
2011-07-05 02:55:41 -04:00
|
|
|
if (method instanceof CopyMethod || method instanceof MoveMethod) {
|
2010-10-27 04:52:27 -04:00
|
|
|
message.append(" to ").append(method.getRequestHeader("Destination"));
|
|
|
|
}
|
2009-09-21 17:50:47 -04:00
|
|
|
} catch (URIException e) {
|
|
|
|
message.append(method.getPath());
|
|
|
|
}
|
2010-11-09 17:12:38 -05:00
|
|
|
// 440 means forbidden on Exchange
|
|
|
|
if (status == 440) {
|
2011-01-04 16:32:24 -05:00
|
|
|
return new LoginTimeoutException(message.toString());
|
2010-11-09 17:12:38 -05:00
|
|
|
} else if (status == HttpStatus.SC_FORBIDDEN) {
|
2009-09-25 05:13:02 -04:00
|
|
|
return new HttpForbiddenException(message.toString());
|
|
|
|
} else if (status == HttpStatus.SC_NOT_FOUND) {
|
|
|
|
return new HttpNotFoundException(message.toString());
|
2010-10-04 17:24:50 -04:00
|
|
|
} else if (status == HttpStatus.SC_PRECONDITION_FAILED) {
|
|
|
|
return new HttpPreconditionFailedException(message.toString());
|
2009-12-07 04:35:25 -05:00
|
|
|
} else if (status == HttpStatus.SC_INTERNAL_SERVER_ERROR) {
|
|
|
|
return new HttpServerErrorException(message.toString());
|
2009-09-25 05:13:02 -04:00
|
|
|
} else {
|
|
|
|
return new HttpException(message.toString());
|
|
|
|
}
|
2008-12-17 10:27:56 -05:00
|
|
|
}
|
|
|
|
|
2011-06-17 05:17:31 -04:00
|
|
|
/**
|
|
|
|
* Test if the method response is gzip encoded
|
2011-07-05 02:55:41 -04:00
|
|
|
*
|
2011-06-17 05:17:31 -04:00
|
|
|
* @param method http method
|
|
|
|
* @return true if response is gzip encoded
|
|
|
|
*/
|
|
|
|
public static boolean isGzipEncoded(HttpMethod method) {
|
|
|
|
Header[] contentEncodingHeaders = method.getResponseHeaders("Content-Encoding");
|
|
|
|
if (contentEncodingHeaders != null) {
|
|
|
|
for (Header header : contentEncodingHeaders) {
|
|
|
|
if ("gzip".equals(header.getValue())) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2009-08-21 05:58:19 -04:00
|
|
|
/**
|
|
|
|
* Stop HttpConnectionManager.
|
|
|
|
*/
|
2008-12-08 08:49:21 -05:00
|
|
|
public static void stop() {
|
2009-09-18 05:27:00 -04:00
|
|
|
synchronized (LOCK) {
|
2011-01-04 16:32:24 -05:00
|
|
|
if (httpConnectionManagerThread != null) {
|
|
|
|
httpConnectionManagerThread.interrupt();
|
|
|
|
httpConnectionManagerThread = null;
|
|
|
|
}
|
|
|
|
MultiThreadedHttpConnectionManager.shutdownAll();
|
2009-09-18 05:27:00 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-01-05 15:37:11 -05:00
|
|
|
/**
|
|
|
|
* Create and set connection pool.
|
|
|
|
*
|
|
|
|
* @param httpClient httpClient instance
|
|
|
|
*/
|
|
|
|
public static void createMultiThreadedHttpConnectionManager(HttpClient httpClient) {
|
2010-07-23 10:54:24 -04:00
|
|
|
MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
|
|
|
|
connectionManager.getParams().setDefaultMaxConnectionsPerHost(100);
|
|
|
|
connectionManager.getParams().setConnectionTimeout(10000);
|
2010-07-25 07:34:37 -04:00
|
|
|
synchronized (LOCK) {
|
|
|
|
httpConnectionManagerThread.addConnectionManager(connectionManager);
|
|
|
|
}
|
2011-01-05 15:37:11 -05:00
|
|
|
httpClient.setHttpConnectionManager(connectionManager);
|
2008-12-08 08:49:21 -05:00
|
|
|
}
|
|
|
|
|
2009-08-21 05:58:19 -04:00
|
|
|
/**
|
2009-09-17 05:22:19 -04:00
|
|
|
* Create and start a new HttpConnectionManager, close idle connections every minute.
|
2009-08-21 05:58:19 -04:00
|
|
|
*/
|
2008-12-08 08:49:21 -05:00
|
|
|
public static void start() {
|
2009-09-18 05:27:00 -04:00
|
|
|
synchronized (LOCK) {
|
2011-01-04 15:35:30 -05:00
|
|
|
if (httpConnectionManagerThread == null) {
|
2010-07-23 10:54:24 -04:00
|
|
|
httpConnectionManagerThread = new IdleConnectionTimeoutThread();
|
|
|
|
httpConnectionManagerThread.setName(IdleConnectionTimeoutThread.class.getSimpleName());
|
|
|
|
httpConnectionManagerThread.setConnectionTimeout(ONE_MINUTE);
|
|
|
|
httpConnectionManagerThread.setTimeoutInterval(ONE_MINUTE);
|
2009-09-18 05:27:00 -04:00
|
|
|
httpConnectionManagerThread.start();
|
|
|
|
}
|
2008-12-08 08:49:21 -05:00
|
|
|
}
|
|
|
|
}
|
2008-11-03 20:47:10 -05:00
|
|
|
}
|