Refactored ExchangeSession creation : improved Http connection handling
git-svn-id: http://svn.code.sf.net/p/davmail/code/trunk@158 3d1905a2-6b24-0410-a738-b14d5a86fcbd
This commit is contained in:
parent
60907607e7
commit
1828202211
|
@ -1,7 +1,7 @@
|
||||||
package davmail;
|
package davmail;
|
||||||
|
|
||||||
import davmail.http.DavGatewaySSLProtocolSocketFactory;
|
import davmail.http.DavGatewaySSLProtocolSocketFactory;
|
||||||
import davmail.http.DavGatewayHttpClientFactory;
|
import davmail.http.DavGatewayHttpClientFacade;
|
||||||
import davmail.pop.PopServer;
|
import davmail.pop.PopServer;
|
||||||
import davmail.smtp.SmtpServer;
|
import davmail.smtp.SmtpServer;
|
||||||
import davmail.tray.DavGatewayTray;
|
import davmail.tray.DavGatewayTray;
|
||||||
|
@ -103,9 +103,9 @@ public class DavGateway {
|
||||||
public static String getReleasedVersion() {
|
public static String getReleasedVersion() {
|
||||||
String version = null;
|
String version = null;
|
||||||
BufferedReader versionReader = null;
|
BufferedReader versionReader = null;
|
||||||
|
GetMethod getMethod = new GetMethod("http://davmail.sourceforge.net/version.txt");
|
||||||
try {
|
try {
|
||||||
HttpClient httpClient = DavGatewayHttpClientFactory.getInstance();
|
HttpClient httpClient = DavGatewayHttpClientFacade.getInstance();
|
||||||
GetMethod getMethod = new GetMethod("http://davmail.sourceforge.net/version.txt");
|
|
||||||
int status = httpClient.executeMethod(getMethod);
|
int status = httpClient.executeMethod(getMethod);
|
||||||
if (status == HttpStatus.SC_OK) {
|
if (status == HttpStatus.SC_OK) {
|
||||||
versionReader = new BufferedReader(new InputStreamReader(getMethod.getResponseBodyAsStream()));
|
versionReader = new BufferedReader(new InputStreamReader(getMethod.getResponseBodyAsStream()));
|
||||||
|
@ -121,6 +121,7 @@ public class DavGateway {
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
getMethod.releaseConnection();
|
||||||
}
|
}
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package davmail.exchange;
|
package davmail.exchange;
|
||||||
|
|
||||||
import davmail.Settings;
|
import davmail.Settings;
|
||||||
import davmail.http.DavGatewayHttpClientFactory;
|
import davmail.http.DavGatewayHttpClientFacade;
|
||||||
import org.apache.commons.httpclient.Header;
|
import org.apache.commons.httpclient.Header;
|
||||||
import org.apache.commons.httpclient.HttpClient;
|
import org.apache.commons.httpclient.HttpClient;
|
||||||
import org.apache.commons.httpclient.HttpException;
|
import org.apache.commons.httpclient.HttpException;
|
||||||
|
@ -63,6 +63,11 @@ public class ExchangeSession {
|
||||||
*/
|
*/
|
||||||
private final SimpleDateFormat dateParser;
|
private final SimpleDateFormat dateParser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base Exchange URL
|
||||||
|
*/
|
||||||
|
private String baseUrl;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Various standard mail boxes Urls
|
* Various standard mail boxes Urls
|
||||||
*/
|
*/
|
||||||
|
@ -97,32 +102,150 @@ public class ExchangeSession {
|
||||||
* @throws java.io.IOException unable to connect to exchange
|
* @throws java.io.IOException unable to connect to exchange
|
||||||
*/
|
*/
|
||||||
protected boolean isBasicAuthentication(String url) throws IOException {
|
protected boolean isBasicAuthentication(String url) throws IOException {
|
||||||
// create an HttpClient instance
|
return DavGatewayHttpClientFacade.getHttpStatus(url) == HttpStatus.SC_UNAUTHORIZED;
|
||||||
HttpClient httpClient = DavGatewayHttpClientFactory.getInstance();
|
}
|
||||||
HttpMethod testMethod = new GetMethod(url);
|
|
||||||
int status = httpClient.executeMethod(testMethod);
|
/**
|
||||||
testMethod.releaseConnection();
|
* Try to find logon method path from logon form body.
|
||||||
return status == HttpStatus.SC_UNAUTHORIZED;
|
*
|
||||||
|
* @param initmethod form body http method
|
||||||
|
* @return logon method path
|
||||||
|
*/
|
||||||
|
protected String getLogonMethodPathAndBaseUrl(HttpMethod initmethod) {
|
||||||
|
// default logon method path
|
||||||
|
String logonMethodPath = "/exchweb/bin/auth/owaauth.dll";
|
||||||
|
|
||||||
|
// try to parse login form to determine logon url and destination
|
||||||
|
BufferedReader loginFormReader = null;
|
||||||
|
try {
|
||||||
|
loginFormReader = new BufferedReader(new InputStreamReader(initmethod.getResponseBodyAsStream()));
|
||||||
|
String line;
|
||||||
|
// skip to form action
|
||||||
|
final String FORM_ACTION = "<form action=\"";
|
||||||
|
final String DESTINATION_INPUT = "name=\"destination\" value=\"";
|
||||||
|
//noinspection StatementWithEmptyBody
|
||||||
|
while ((line = loginFormReader.readLine()) != null && line.toLowerCase().indexOf(FORM_ACTION) == -1) {
|
||||||
|
}
|
||||||
|
if (line != null) {
|
||||||
|
int start = line.toLowerCase().indexOf(FORM_ACTION) + FORM_ACTION.length();
|
||||||
|
int end = line.indexOf("\"", start);
|
||||||
|
logonMethodPath = line.substring(start, end);
|
||||||
|
//noinspection StatementWithEmptyBody
|
||||||
|
while ((line = loginFormReader.readLine()) != null && line.indexOf(DESTINATION_INPUT) == -1) {
|
||||||
|
}
|
||||||
|
if (line != null) {
|
||||||
|
start = line.indexOf(DESTINATION_INPUT) + DESTINATION_INPUT.length();
|
||||||
|
end = line.indexOf("\"", start);
|
||||||
|
baseUrl = line.substring(start, end);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// allow relative URLs
|
||||||
|
if (!logonMethodPath.startsWith("/")) {
|
||||||
|
String path = initmethod.getPath();
|
||||||
|
int end = path.lastIndexOf('/');
|
||||||
|
if (end >= 0) {
|
||||||
|
logonMethodPath = path.substring(0, end + 1) + logonMethodPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOGGER.error("Error parsing login form at " + initmethod.getPath());
|
||||||
|
} finally {
|
||||||
|
if (loginFormReader != null) {
|
||||||
|
try {
|
||||||
|
loginFormReader.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOGGER.error("Error parsing login form at " + initmethod.getPath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
initmethod.releaseConnection();
|
||||||
|
}
|
||||||
|
return logonMethodPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void formLogin(HttpClient httpClient, HttpMethod initmethod, String userName, String password) throws IOException {
|
||||||
|
LOGGER.debug("Form based authentication detected");
|
||||||
|
// get logon method path and actual destination (baseUrl)
|
||||||
|
String logonMethodPath = getLogonMethodPathAndBaseUrl(initmethod);
|
||||||
|
|
||||||
|
PostMethod logonMethod = new PostMethod(
|
||||||
|
logonMethodPath + "?ForcedBasic=false&Basic=false&Private=true&Language=No_Value"
|
||||||
|
);
|
||||||
|
logonMethod.addParameter("destination", baseUrl);
|
||||||
|
logonMethod.addParameter("flags", "4");
|
||||||
|
// logonMethod.addParameter("visusername", userName.substring(userName.lastIndexOf('\\')));
|
||||||
|
logonMethod.addParameter("username", userName);
|
||||||
|
logonMethod.addParameter("password", password);
|
||||||
|
// logonMethod.addParameter("SubmitCreds", "Log On");
|
||||||
|
// logonMethod.addParameter("forcedownlevel", "0");
|
||||||
|
logonMethod.addParameter("trusted", "4");
|
||||||
|
|
||||||
|
try {
|
||||||
|
httpClient.executeMethod(logonMethod);
|
||||||
|
} finally {
|
||||||
|
logonMethod.releaseConnection();
|
||||||
|
}
|
||||||
|
Header locationHeader = logonMethod.getResponseHeader("Location");
|
||||||
|
|
||||||
|
if (logonMethod.getStatusCode() != HttpURLConnection.HTTP_MOVED_TEMP ||
|
||||||
|
locationHeader == null ||
|
||||||
|
!baseUrl.equals(locationHeader.getValue())) {
|
||||||
|
throw new HttpException("Authentication failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getMailPath(HttpMethod method) {
|
||||||
|
String result = null;
|
||||||
|
// get user mail URL from html body (multi frame)
|
||||||
|
BufferedReader mainPageReader = null;
|
||||||
|
try {
|
||||||
|
mainPageReader = new BufferedReader(new InputStreamReader(method.getResponseBodyAsStream()));
|
||||||
|
String line;
|
||||||
|
// find base url
|
||||||
|
final String BASE_HREF = "<base href=\"";
|
||||||
|
//noinspection StatementWithEmptyBody
|
||||||
|
while ((line = mainPageReader.readLine()) != null && line.toLowerCase().indexOf(BASE_HREF) == -1) {
|
||||||
|
}
|
||||||
|
if (line != null) {
|
||||||
|
int start = line.toLowerCase().indexOf(BASE_HREF) + BASE_HREF.length();
|
||||||
|
int end = line.indexOf("\"", start);
|
||||||
|
String mailBoxBaseHref = line.substring(start, end);
|
||||||
|
URL baseURL = new URL(mailBoxBaseHref);
|
||||||
|
result = baseURL.getPath();
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOGGER.error("Error parsing main page at " + method.getPath());
|
||||||
|
} finally {
|
||||||
|
if (mainPageReader != null) {
|
||||||
|
try {
|
||||||
|
mainPageReader.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOGGER.error("Error parsing main page at " + method.getPath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
method.releaseConnection();
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void login(String userName, String password) throws IOException {
|
void login(String userName, String password) throws IOException {
|
||||||
try {
|
try {
|
||||||
String url = Settings.getProperty("davmail.url");
|
baseUrl = Settings.getProperty("davmail.url");
|
||||||
|
|
||||||
boolean isBasicAuthentication = isBasicAuthentication(url);
|
boolean isBasicAuthentication = isBasicAuthentication(baseUrl);
|
||||||
|
|
||||||
// get proxy configuration from setttings properties
|
// get proxy configuration from setttings properties
|
||||||
URL urlObject = new URL(url);
|
URL urlObject = new URL(baseUrl);
|
||||||
// webdavresource is unable to create the correct url type
|
// webdavresource is unable to create the correct url type
|
||||||
HttpURL httpURL;
|
HttpURL httpURL;
|
||||||
if (url.startsWith("http://")) {
|
if (baseUrl.startsWith("http://")) {
|
||||||
httpURL = new HttpURL(userName, password,
|
httpURL = new HttpURL(userName, password,
|
||||||
urlObject.getHost(), urlObject.getPort());
|
urlObject.getHost(), urlObject.getPort());
|
||||||
} else if (url.startsWith("https://")) {
|
} else if (baseUrl.startsWith("https://")) {
|
||||||
httpURL = new HttpsURL(userName, password,
|
httpURL = new HttpsURL(userName, password,
|
||||||
urlObject.getHost(), urlObject.getPort());
|
urlObject.getHost(), urlObject.getPort());
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("Invalid URL: " + url);
|
throw new IllegalArgumentException("Invalid URL: " + baseUrl);
|
||||||
}
|
}
|
||||||
wdr = new WebdavResource(httpURL, WebdavResource.NOACTION, 0);
|
wdr = new WebdavResource(httpURL, WebdavResource.NOACTION, 0);
|
||||||
|
|
||||||
|
@ -132,107 +255,20 @@ public class ExchangeSession {
|
||||||
// get the internal HttpClient instance
|
// get the internal HttpClient instance
|
||||||
HttpClient httpClient = wdr.retrieveSessionInstance();
|
HttpClient httpClient = wdr.retrieveSessionInstance();
|
||||||
|
|
||||||
DavGatewayHttpClientFactory.configureClient(httpClient);
|
DavGatewayHttpClientFacade.configureClient(httpClient);
|
||||||
|
|
||||||
// get webmail root url
|
// get webmail root url
|
||||||
// providing credentials
|
// providing credentials
|
||||||
// manually follow redirect
|
// manually follow redirect
|
||||||
HttpMethod initmethod = new GetMethod(url);
|
HttpMethod initmethod = DavGatewayHttpClientFacade.executeFollowRedirects(httpClient, baseUrl);
|
||||||
initmethod.setFollowRedirects(false);
|
|
||||||
httpClient.executeMethod(initmethod);
|
|
||||||
int redirectCount = 0;
|
|
||||||
while (redirectCount++ < 10 && initmethod.getStatusCode() == 302) {
|
|
||||||
initmethod.releaseConnection();
|
|
||||||
initmethod = new GetMethod(initmethod.getResponseHeader("Location").getValue());
|
|
||||||
initmethod.setFollowRedirects(false);
|
|
||||||
httpClient.executeMethod(initmethod);
|
|
||||||
}
|
|
||||||
if (initmethod.getStatusCode() == 302) {
|
|
||||||
throw new IOException("Maximum redirections reached");
|
|
||||||
}
|
|
||||||
|
|
||||||
// default destination is provided url
|
|
||||||
String destination = url;
|
|
||||||
|
|
||||||
if (!isBasicAuthentication) {
|
if (!isBasicAuthentication) {
|
||||||
LOGGER.debug("Form based authentication detected");
|
formLogin(httpClient, initmethod, userName, password);
|
||||||
// default logon method path
|
|
||||||
String logonMethodPath = "/exchweb/bin/auth/owaauth.dll";
|
|
||||||
|
|
||||||
// try to parse login form to determine logon url and destination
|
|
||||||
BufferedReader loginFormReader = null;
|
|
||||||
try {
|
|
||||||
loginFormReader = new BufferedReader(new InputStreamReader(initmethod.getResponseBodyAsStream()));
|
|
||||||
String line;
|
|
||||||
// skip to form action
|
|
||||||
final String FORM_ACTION = "<form action=\"";
|
|
||||||
final String DESTINATION_INPUT = "name=\"destination\" value=\"";
|
|
||||||
//noinspection StatementWithEmptyBody
|
|
||||||
while ((line = loginFormReader.readLine()) != null && line.toLowerCase().indexOf(FORM_ACTION) == -1){}
|
|
||||||
if (line != null) {
|
|
||||||
int start = line.toLowerCase().indexOf(FORM_ACTION) + FORM_ACTION.length();
|
|
||||||
int end = line.indexOf("\"", start);
|
|
||||||
logonMethodPath = line.substring(start, end);
|
|
||||||
//noinspection StatementWithEmptyBody
|
|
||||||
while ((line = loginFormReader.readLine()) != null && line.indexOf(DESTINATION_INPUT) == -1) {}
|
|
||||||
if (line != null) {
|
|
||||||
start = line.indexOf(DESTINATION_INPUT) + DESTINATION_INPUT.length();
|
|
||||||
end = line.indexOf("\"", start);
|
|
||||||
destination = line.substring(start, end);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// allow relative URLs
|
|
||||||
if (!logonMethodPath.startsWith("/")) {
|
|
||||||
String path = initmethod.getPath();
|
|
||||||
int end = path.lastIndexOf('/');
|
|
||||||
if (end >=0) {
|
|
||||||
logonMethodPath = path.substring(0, end+1) + logonMethodPath;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
LOGGER.error("Error parsing login form at " + initmethod.getPath());
|
|
||||||
} finally {
|
|
||||||
if (loginFormReader != null) {
|
|
||||||
loginFormReader.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
PostMethod logonMethod = new PostMethod(
|
|
||||||
logonMethodPath + "?ForcedBasic=false&Basic=false&Private=true&Language=No_Value"
|
|
||||||
);
|
|
||||||
logonMethod.addParameter("destination", destination);
|
|
||||||
logonMethod.addParameter("flags", "4");
|
|
||||||
// logonMethod.addParameter("visusername", userName.substring(userName.lastIndexOf('\\')));
|
|
||||||
logonMethod.addParameter("username", userName);
|
|
||||||
logonMethod.addParameter("password", password);
|
|
||||||
// logonMethod.addParameter("SubmitCreds", "Log On");
|
|
||||||
// logonMethod.addParameter("forcedownlevel", "0");
|
|
||||||
logonMethod.addParameter("trusted", "4");
|
|
||||||
|
|
||||||
httpClient.executeMethod(logonMethod);
|
|
||||||
Header locationHeader = logonMethod.getResponseHeader("Location");
|
|
||||||
|
|
||||||
if (logonMethod.getStatusCode() != HttpURLConnection.HTTP_MOVED_TEMP ||
|
|
||||||
locationHeader == null ||
|
|
||||||
!destination.equals(locationHeader.getValue())) {
|
|
||||||
throw new HttpException("Authentication failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// User may be authenticated, get various session information
|
// User may be authenticated, get various session information
|
||||||
HttpMethod method = new GetMethod(destination);
|
HttpMethod method = DavGatewayHttpClientFacade.executeFollowRedirects(httpClient, baseUrl);
|
||||||
method.setFollowRedirects(false);
|
int status = method.getStatusCode();
|
||||||
int status = httpClient.executeMethod(method);
|
|
||||||
redirectCount = 0;
|
|
||||||
while (redirectCount++ < 10 && method.getStatusCode() == 302) {
|
|
||||||
method.releaseConnection();
|
|
||||||
method = new GetMethod(method.getResponseHeader("Location").getValue());
|
|
||||||
method.setFollowRedirects(false);
|
|
||||||
status = httpClient.executeMethod(method);
|
|
||||||
}
|
|
||||||
if (method.getStatusCode() == 302) {
|
|
||||||
throw new IOException("Maximum redirections reached");
|
|
||||||
}
|
|
||||||
if (status != HttpStatus.SC_OK) {
|
if (status != HttpStatus.SC_OK) {
|
||||||
HttpException ex = new HttpException();
|
HttpException ex = new HttpException();
|
||||||
ex.setReasonCode(status);
|
ex.setReasonCode(status);
|
||||||
|
@ -242,35 +278,14 @@ public class ExchangeSession {
|
||||||
// test form based authentication
|
// test form based authentication
|
||||||
String queryString = method.getQueryString();
|
String queryString = method.getQueryString();
|
||||||
if (queryString != null && queryString.endsWith("reason=2")) {
|
if (queryString != null && queryString.endsWith("reason=2")) {
|
||||||
throw new HttpException("Authentication failed: invalid user or password");
|
method.releaseConnection();
|
||||||
|
throw new HttpException("Authentication failed: invalid user or password");
|
||||||
}
|
}
|
||||||
|
|
||||||
// get user mail URL from html body (multi frame)
|
mailPath = getMailPath(method);
|
||||||
BufferedReader mainPageReader = null;
|
|
||||||
try {
|
|
||||||
mainPageReader = new BufferedReader(new InputStreamReader(method.getResponseBodyAsStream()));
|
|
||||||
String line;
|
|
||||||
// find base url
|
|
||||||
final String BASE_HREF = "<base href=\"";
|
|
||||||
//noinspection StatementWithEmptyBody
|
|
||||||
while ((line = mainPageReader.readLine()) != null && line.toLowerCase().indexOf(BASE_HREF) == -1){}
|
|
||||||
if (line != null) {
|
|
||||||
int start = line.toLowerCase().indexOf(BASE_HREF) + BASE_HREF.length();
|
|
||||||
int end = line.indexOf("\"", start);
|
|
||||||
String mailBoxBaseHref = line.substring(start, end);
|
|
||||||
URL baseURL = new URL(mailBoxBaseHref);
|
|
||||||
mailPath = baseURL.getPath();
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
LOGGER.error("Error parsing main page at " + method.getPath());
|
|
||||||
} finally {
|
|
||||||
if (mainPageReader != null) {
|
|
||||||
mainPageReader.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mailPath == null) {
|
if (mailPath == null) {
|
||||||
throw new HttpException(destination + " not found in body, authentication failed: password expired ?");
|
throw new HttpException(baseUrl + " not found in body, authentication failed: password expired ?");
|
||||||
}
|
}
|
||||||
|
|
||||||
// got base http mailbox http url
|
// got base http mailbox http url
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package davmail.exchange;
|
package davmail.exchange;
|
||||||
|
|
||||||
import davmail.Settings;
|
import davmail.Settings;
|
||||||
import davmail.http.DavGatewayHttpClientFactory;
|
import davmail.http.DavGatewayHttpClientFacade;
|
||||||
import org.apache.commons.httpclient.HttpClient;
|
import org.apache.commons.httpclient.HttpClient;
|
||||||
import org.apache.commons.httpclient.HttpMethod;
|
import org.apache.commons.httpclient.HttpMethod;
|
||||||
import org.apache.commons.httpclient.HttpStatus;
|
import org.apache.commons.httpclient.HttpStatus;
|
||||||
|
@ -41,14 +41,14 @@ public class ExchangeSessionFactory {
|
||||||
|
|
||||||
|
|
||||||
public static void checkConfig() throws IOException {
|
public static void checkConfig() throws IOException {
|
||||||
|
String url = Settings.getProperty("davmail.url");
|
||||||
|
HttpMethod testMethod = new GetMethod(url);
|
||||||
try {
|
try {
|
||||||
String url = Settings.getProperty("davmail.url");
|
|
||||||
|
|
||||||
// create an HttpClient instance
|
// create an HttpClient instance
|
||||||
HttpClient httpClient = DavGatewayHttpClientFactory.getInstance();
|
HttpClient httpClient = DavGatewayHttpClientFacade.getInstance();
|
||||||
|
|
||||||
// get webmail root url (will not follow redirects)
|
// get webmail root url (will not follow redirects)
|
||||||
HttpMethod testMethod = new GetMethod(url);
|
|
||||||
testMethod.setFollowRedirects(false);
|
testMethod.setFollowRedirects(false);
|
||||||
int status = httpClient.executeMethod(testMethod);
|
int status = httpClient.executeMethod(testMethod);
|
||||||
testMethod.releaseConnection();
|
testMethod.releaseConnection();
|
||||||
|
@ -72,6 +72,8 @@ public class ExchangeSessionFactory {
|
||||||
} catch (Exception exc) {
|
} catch (Exception exc) {
|
||||||
ExchangeSession.LOGGER.error("DavMail configuration exception: \n" + exc.getMessage(), exc);
|
ExchangeSession.LOGGER.error("DavMail configuration exception: \n" + exc.getMessage(), exc);
|
||||||
throw new IOException("DavMail configuration exception: \n" + exc.getMessage());
|
throw new IOException("DavMail configuration exception: \n" + exc.getMessage());
|
||||||
|
} finally {
|
||||||
|
testMethod.releaseConnection();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,142 @@
|
||||||
|
package davmail.http;
|
||||||
|
|
||||||
|
import davmail.Settings;
|
||||||
|
import org.apache.commons.httpclient.Header;
|
||||||
|
import org.apache.commons.httpclient.HttpClient;
|
||||||
|
import org.apache.commons.httpclient.HttpException;
|
||||||
|
import org.apache.commons.httpclient.HttpMethod;
|
||||||
|
import org.apache.commons.httpclient.HttpStatus;
|
||||||
|
import org.apache.commons.httpclient.NTCredentials;
|
||||||
|
import org.apache.commons.httpclient.UsernamePasswordCredentials;
|
||||||
|
import org.apache.commons.httpclient.methods.GetMethod;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create HttpClient instance according to DavGateway Settings
|
||||||
|
*/
|
||||||
|
public class DavGatewayHttpClientFacade {
|
||||||
|
/**
|
||||||
|
* Create a configured HttpClient instance.
|
||||||
|
*
|
||||||
|
* @return httpClient
|
||||||
|
*/
|
||||||
|
public static HttpClient getInstance() {
|
||||||
|
// create an HttpClient instance
|
||||||
|
HttpClient httpClient = new HttpClient();
|
||||||
|
configureClient(httpClient);
|
||||||
|
return httpClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update http client configuration (proxy)
|
||||||
|
*
|
||||||
|
* @param httpClient current Http client
|
||||||
|
*/
|
||||||
|
public static void configureClient(HttpClient httpClient) {
|
||||||
|
// do not send basic auth automatically
|
||||||
|
httpClient.getState().setAuthenticationPreemptive(false);
|
||||||
|
|
||||||
|
boolean enableProxy = Settings.getBooleanProperty("davmail.enableProxy");
|
||||||
|
String proxyHost = null;
|
||||||
|
int proxyPort = 0;
|
||||||
|
String proxyUser = null;
|
||||||
|
String proxyPassword = null;
|
||||||
|
|
||||||
|
if (enableProxy) {
|
||||||
|
proxyHost = Settings.getProperty("davmail.proxyHost");
|
||||||
|
proxyPort = Settings.getIntProperty("davmail.proxyPort");
|
||||||
|
proxyUser = Settings.getProperty("davmail.proxyUser");
|
||||||
|
proxyPassword = Settings.getProperty("davmail.proxyPassword");
|
||||||
|
}
|
||||||
|
|
||||||
|
// configure proxy
|
||||||
|
if (proxyHost != null && proxyHost.length() > 0) {
|
||||||
|
httpClient.getHostConfiguration().setProxy(proxyHost, proxyPort);
|
||||||
|
if (proxyUser != null && proxyUser.length() > 0) {
|
||||||
|
|
||||||
|
/* // Only available in newer HttpClient releases, not compatible with slide library
|
||||||
|
List authPrefs = new ArrayList();
|
||||||
|
authPrefs.add(AuthPolicy.BASIC);
|
||||||
|
httpClient.getParams().setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY,authPrefs);
|
||||||
|
*/
|
||||||
|
// instead detect ntlm authentication (windows domain name in user name)
|
||||||
|
int backslashindex = proxyUser.indexOf("\\");
|
||||||
|
if (backslashindex > 0) {
|
||||||
|
httpClient.getState().setProxyCredentials(null, proxyHost,
|
||||||
|
new NTCredentials(proxyUser.substring(backslashindex + 1),
|
||||||
|
proxyPassword, null,
|
||||||
|
proxyUser.substring(0, backslashindex)));
|
||||||
|
} else {
|
||||||
|
httpClient.getState().setProxyCredentials(null, proxyHost,
|
||||||
|
new UsernamePasswordCredentials(proxyUser, proxyPassword));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Http Status code for the given URL
|
||||||
|
*
|
||||||
|
* @param url url string
|
||||||
|
* @return HttpStatus code
|
||||||
|
* @throws IOException on error
|
||||||
|
*/
|
||||||
|
public static int getHttpStatus(String url) throws IOException {
|
||||||
|
int status = 0;
|
||||||
|
HttpClient httpClient = DavGatewayHttpClientFacade.getInstance();
|
||||||
|
HttpMethod testMethod = new GetMethod(url);
|
||||||
|
try {
|
||||||
|
status = httpClient.executeMethod(testMethod);
|
||||||
|
} finally {
|
||||||
|
testMethod.releaseConnection();
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
try {
|
||||||
|
method.setFollowRedirects(false);
|
||||||
|
httpClient.executeMethod(method);
|
||||||
|
Header location = method.getResponseHeader("Location");
|
||||||
|
int redirectCount = 0;
|
||||||
|
while (redirectCount++ < 10
|
||||||
|
&& location != null
|
||||||
|
&& isRedirect(method.getStatusCode())) {
|
||||||
|
method.releaseConnection();
|
||||||
|
method = new GetMethod(method.getResponseHeader("Location").getValue());
|
||||||
|
method.setFollowRedirects(false);
|
||||||
|
httpClient.executeMethod(method);
|
||||||
|
location = method.getResponseHeader("Location");
|
||||||
|
}
|
||||||
|
if (location != null && isRedirect(method.getStatusCode())) {
|
||||||
|
method.releaseConnection();
|
||||||
|
throw new HttpException("Maximum redirections reached");
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
method.releaseConnection();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
// caller will need to release connection
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,72 +0,0 @@
|
||||||
package davmail.http;
|
|
||||||
|
|
||||||
import org.apache.commons.httpclient.HttpClient;
|
|
||||||
import org.apache.commons.httpclient.NTCredentials;
|
|
||||||
import org.apache.commons.httpclient.UsernamePasswordCredentials;
|
|
||||||
import davmail.Settings;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create HttpClient instance according to DavGateway Settings
|
|
||||||
*/
|
|
||||||
public class DavGatewayHttpClientFactory {
|
|
||||||
/**
|
|
||||||
* Create a configured HttpClient instance.
|
|
||||||
*
|
|
||||||
* @return httpClient
|
|
||||||
*/
|
|
||||||
public static HttpClient getInstance() {
|
|
||||||
// create an HttpClient instance
|
|
||||||
HttpClient httpClient = new HttpClient();
|
|
||||||
configureClient(httpClient);
|
|
||||||
return httpClient;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update http client configuration (proxy)
|
|
||||||
*
|
|
||||||
* @param httpClient current Http client
|
|
||||||
*/
|
|
||||||
public static void configureClient(HttpClient httpClient) {
|
|
||||||
// do not send basic auth automatically
|
|
||||||
httpClient.getState().setAuthenticationPreemptive(false);
|
|
||||||
|
|
||||||
boolean enableProxy = Settings.getBooleanProperty("davmail.enableProxy");
|
|
||||||
String proxyHost = null;
|
|
||||||
int proxyPort = 0;
|
|
||||||
String proxyUser = null;
|
|
||||||
String proxyPassword = null;
|
|
||||||
|
|
||||||
if (enableProxy) {
|
|
||||||
proxyHost = Settings.getProperty("davmail.proxyHost");
|
|
||||||
proxyPort = Settings.getIntProperty("davmail.proxyPort");
|
|
||||||
proxyUser = Settings.getProperty("davmail.proxyUser");
|
|
||||||
proxyPassword = Settings.getProperty("davmail.proxyPassword");
|
|
||||||
}
|
|
||||||
|
|
||||||
// configure proxy
|
|
||||||
if (proxyHost != null && proxyHost.length() > 0) {
|
|
||||||
httpClient.getHostConfiguration().setProxy(proxyHost, proxyPort);
|
|
||||||
if (proxyUser != null && proxyUser.length() > 0) {
|
|
||||||
|
|
||||||
/* // Only available in newer HttpClient releases, not compatible with slide library
|
|
||||||
List authPrefs = new ArrayList();
|
|
||||||
authPrefs.add(AuthPolicy.BASIC);
|
|
||||||
httpClient.getParams().setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY,authPrefs);
|
|
||||||
*/
|
|
||||||
// instead detect ntlm authentication (windows domain name in user name)
|
|
||||||
int backslashindex = proxyUser.indexOf("\\");
|
|
||||||
if (backslashindex > 0) {
|
|
||||||
httpClient.getState().setProxyCredentials(null, proxyHost,
|
|
||||||
new NTCredentials(proxyUser.substring(backslashindex + 1),
|
|
||||||
proxyPassword, null,
|
|
||||||
proxyUser.substring(0, backslashindex)));
|
|
||||||
} else {
|
|
||||||
httpClient.getState().setProxyCredentials(null, proxyHost,
|
|
||||||
new UsernamePasswordCredentials(proxyUser, proxyPassword));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in New Issue