diff --git a/k9mail-library/src/main/java/com/fsck/k9/mail/store/webdav/WebDavFolder.java b/k9mail-library/src/main/java/com/fsck/k9/mail/store/webdav/WebDavFolder.java index 0f7d8da1b..0d1c0c394 100644 --- a/k9mail-library/src/main/java/com/fsck/k9/mail/store/webdav/WebDavFolder.java +++ b/k9mail-library/src/main/java/com/fsck/k9/mail/store/webdav/WebDavFolder.java @@ -27,7 +27,6 @@ import java.io.InputStreamReader; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; -import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.List; @@ -373,7 +372,7 @@ class WebDavFolder extends Folder { if (store.getAuthentication() == WebDavConstants.AUTH_TYPE_BASIC) { httpget.setHeader("Authorization", store.getAuthString()); } - response = httpclient.executeOverride(httpget, store.getContext()); + response = httpclient.executeOverride(httpget, store.getHttpContext()); statusCode = response.getStatusLine().getStatusCode(); diff --git a/k9mail-library/src/main/java/com/fsck/k9/mail/store/webdav/WebDavStore.java b/k9mail-library/src/main/java/com/fsck/k9/mail/store/webdav/WebDavStore.java index 44ed5fa04..d20d9c785 100644 --- a/k9mail-library/src/main/java/com/fsck/k9/mail/store/webdav/WebDavStore.java +++ b/k9mail-library/src/main/java/com/fsck/k9/mail/store/webdav/WebDavStore.java @@ -1,14 +1,40 @@ package com.fsck.k9.mail.store.webdav; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; +import java.net.URI; +import java.net.URISyntaxException; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + import android.util.Log; -import com.fsck.k9.mail.*; -import com.fsck.k9.mail.filter.Base64; import com.fsck.k9.mail.CertificateValidationException; +import com.fsck.k9.mail.ConnectionSecurity; +import com.fsck.k9.mail.Folder; +import com.fsck.k9.mail.K9MailLib; +import com.fsck.k9.mail.Message; +import com.fsck.k9.mail.MessagingException; +import com.fsck.k9.mail.ServerSettings; +import com.fsck.k9.mail.filter.Base64; import com.fsck.k9.mail.store.RemoteStore; import com.fsck.k9.mail.store.StoreConfig; - -import org.apache.http.*; +import javax.net.ssl.SSLException; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; +import org.apache.http.Header; +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; import org.apache.http.client.CookieStore; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.protocol.ClientContext; @@ -23,22 +49,9 @@ import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; -import javax.net.ssl.SSLException; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; - -import java.io.*; -import java.net.URI; -import java.net.URISyntaxException; -import java.security.KeyManagementException; -import java.security.NoSuchAlgorithmException; -import java.util.*; - import static com.fsck.k9.mail.K9MailLib.DEBUG_PROTOCOL_WEBDAV; import static com.fsck.k9.mail.K9MailLib.LOG_TAG; import static com.fsck.k9.mail.helper.UrlEncodingHelper.decodeUtf8; -import static com.fsck.k9.mail.helper.UrlEncodingHelper.encodeUtf8; /** @@ -47,6 +60,7 @@ import static com.fsck.k9.mail.helper.UrlEncodingHelper.encodeUtf8; * and email information. * */ +@SuppressWarnings("deprecation") public class WebDavStore extends RemoteStore { public static WebDavStoreSettings decodeUri(String uri) { @@ -58,31 +72,31 @@ public class WebDavStore extends RemoteStore { } private ConnectionSecurity mConnectionSecurity; - private String mUsername; /* Stores the username for authentications */ - private String mAlias; /* Stores the alias for the user's mailbox */ - private String mPassword; /* Stores the password for authentications */ - private String mUrl; /* Stores the base URL for the server */ - private String mHost; /* Stores the host name for the server */ - private int mPort; - private String mPath; /* Stores the path for the server */ - private String mAuthPath; /* Stores the path off of the server to post data to for form based authentication */ - private String mMailboxPath; /* Stores the user specified path to the mailbox */ + private String username; + private String alias; + private String password; + private String baseUrl; + private String hostname; + private int port; + private String path; + private String formBasedAuthPath; + private String mailboxPath; - private final WebDavHttpClient.WebDavHttpClientFactory mHttpClientFactory; - private WebDavHttpClient mHttpClient = null; - private HttpContext mContext = null; - private String mAuthString; - private CookieStore mAuthCookies = null; - private short mAuthentication = WebDavConstants.AUTH_TYPE_NONE; - private String mCachedLoginUrl; + private final WebDavHttpClient.WebDavHttpClientFactory httpClientFactory; + private WebDavHttpClient httpClient = null; + private HttpContext httpContext = null; + private String authString; + private CookieStore authCookies = null; + private short authenticationType = WebDavConstants.AUTH_TYPE_NONE; + private String cachedLoginUrl; - private Folder mSendFolder = null; - private Map mFolderList = new HashMap(); + private Folder sendFolder = null; + private Map folderList = new HashMap<>(); public WebDavStore(StoreConfig storeConfig, WebDavHttpClient.WebDavHttpClientFactory clientFactory) throws MessagingException { super(storeConfig, null); - mHttpClientFactory = clientFactory; + httpClientFactory = clientFactory; WebDavStoreSettings settings; try { @@ -91,43 +105,43 @@ public class WebDavStore extends RemoteStore { throw new MessagingException("Error while decoding store URI", e); } - mHost = settings.host; - mPort = settings.port; + hostname = settings.host; + port = settings.port; mConnectionSecurity = settings.connectionSecurity; - mUsername = settings.username; - mPassword = settings.password; - mAlias = settings.alias; + username = settings.username; + password = settings.password; + alias = settings.alias; - mPath = settings.path; - mAuthPath = settings.authPath; - mMailboxPath = settings.mailboxPath; + path = settings.path; + formBasedAuthPath = settings.authPath; + mailboxPath = settings.mailboxPath; - if (mPath == null || mPath.equals("")) { - mPath = "/Exchange"; - } else if (!mPath.startsWith("/")) { - mPath = "/" + mPath; + if (path == null || path.equals("")) { + path = "/Exchange"; + } else if (!path.startsWith("/")) { + path = "/" + path; } - if (mMailboxPath == null || mMailboxPath.equals("")) { - mMailboxPath = "/" + mAlias; - } else if (!mMailboxPath.startsWith("/")) { - mMailboxPath = "/" + mMailboxPath; + if (mailboxPath == null || mailboxPath.equals("")) { + mailboxPath = "/" + alias; + } else if (!mailboxPath.startsWith("/")) { + mailboxPath = "/" + mailboxPath; } - if (mAuthPath != null && - !mAuthPath.equals("") && - !mAuthPath.startsWith("/")) { - mAuthPath = "/" + mAuthPath; + if (formBasedAuthPath != null && + !formBasedAuthPath.equals("") && + !formBasedAuthPath.startsWith("/")) { + formBasedAuthPath = "/" + formBasedAuthPath; } // The URL typically looks like the following: "https://mail.domain.com/Exchange/alias". // The inbox path would look like: "https://mail.domain.com/Exchange/alias/Inbox". - mUrl = getRoot() + mPath + mMailboxPath; + baseUrl = getRoot() + path + mailboxPath; - mAuthString = "Basic " + Base64.encode(mUsername + ":" + mPassword); + authString = "Basic " + Base64.encode(username + ":" + password); } private String getRoot() { @@ -137,16 +151,16 @@ public class WebDavStore extends RemoteStore { } else { root = "http"; } - root += "://" + mHost + ":" + mPort; + root += "://" + hostname + ":" + port; return root; } - HttpContext getContext() { - return mContext; + HttpContext getHttpContext() { + return httpContext; } short getAuthentication() { - return mAuthentication; + return authenticationType; } StoreConfig getStoreConfig() { @@ -160,20 +174,20 @@ public class WebDavStore extends RemoteStore { @Override public List getPersonalNamespaces(boolean forceListAll) throws MessagingException { - List folderList = new LinkedList(); - /** + List folderList = new LinkedList<>(); + /* * We have to check authentication here so we have the proper URL stored */ getHttpClient(); - /** + /* * Firstly we get the "special" folders list (inbox, outbox, etc) * and setup the account accordingly */ - Map headers = new HashMap(); + Map headers = new HashMap<>(); headers.put("Depth", "0"); headers.put("Brief", "t"); - DataSet dataset = processRequest(this.mUrl, "PROPFIND", getSpecialFoldersList(), headers); + DataSet dataset = processRequest(this.baseUrl, "PROPFIND", getSpecialFoldersList(), headers); Map specialFoldersMap = dataset.getSpecialFolderToUrl(); String folderName = getFolderName(specialFoldersMap.get(WebDavConstants.DAV_MAIL_INBOX_FOLDER)); @@ -183,16 +197,19 @@ public class WebDavStore extends RemoteStore { } folderName = getFolderName(specialFoldersMap.get(WebDavConstants.DAV_MAIL_DRAFTS_FOLDER)); - if (folderName != null) + if (folderName != null) { mStoreConfig.setDraftsFolderName(folderName); + } folderName = getFolderName(specialFoldersMap.get(WebDavConstants.DAV_MAIL_TRASH_FOLDER)); - if (folderName != null) + if (folderName != null) { mStoreConfig.setTrashFolderName(folderName); + } folderName = getFolderName(specialFoldersMap.get(WebDavConstants.DAV_MAIL_SPAM_FOLDER)); - if (folderName != null) + if (folderName != null) { mStoreConfig.setSpamFolderName(folderName); + } // K-9 Mail's outbox is a special local folder and different from Exchange/WebDAV's outbox. /* @@ -202,21 +219,23 @@ public class WebDavStore extends RemoteStore { */ folderName = getFolderName(specialFoldersMap.get(WebDavConstants.DAV_MAIL_SENT_FOLDER)); - if (folderName != null) + if (folderName != null) { mStoreConfig.setSentFolderName(folderName); + } - /** + /* * Next we get all the folders (including "special" ones) */ - headers = new HashMap(); + headers = new HashMap<>(); headers.put("Brief", "t"); - dataset = processRequest(this.mUrl, "SEARCH", getFolderListXml(), headers); + dataset = processRequest(this.baseUrl, "SEARCH", getFolderListXml(), headers); String[] folderUrls = dataset.getHrefs(); for (String tempUrl : folderUrls) { WebDavFolder folder = createFolder(tempUrl); - if (folder != null) + if (folder != null) { folderList.add(folder); + } } return folderList; @@ -227,11 +246,14 @@ public class WebDavStore extends RemoteStore { * already created) and adds this to our store folder map. * * @param folderUrl - * @return + * URL + * + * @return WebDAV remote folder */ private WebDavFolder createFolder(String folderUrl) { - if (folderUrl == null) + if (folderUrl == null) { return null; + } WebDavFolder wdFolder = null; String folderName = getFolderName(folderUrl); @@ -247,8 +269,9 @@ public class WebDavStore extends RemoteStore { } private String getFolderName(String folderUrl) { - if (folderUrl == null) + if (folderUrl == null) { return null; + } // Here we extract the folder name starting from the complete url. // folderUrl is in the form http://mail.domain.com/exchange/username/foldername @@ -256,18 +279,20 @@ public class WebDavStore extends RemoteStore { int folderSlash = -1; for (int j = 0; j < 5; j++) { folderSlash = folderUrl.indexOf('/', folderSlash + 1); - if (folderSlash < 0) + if (folderSlash < 0) { break; + } } if (folderSlash > 0) { String fullPathName; // Removes the final slash if present - if (folderUrl.charAt(folderUrl.length() - 1) == '/') + if (folderUrl.charAt(folderUrl.length() - 1) == '/') { fullPathName = folderUrl.substring(folderSlash + 1, folderUrl.length() - 1); - else + } else { fullPathName = folderUrl.substring(folderSlash + 1); + } // Decodes the url-encoded folder name (i.e. "My%20folder" => "My Folder" @@ -279,21 +304,22 @@ public class WebDavStore extends RemoteStore { @Override public WebDavFolder getFolder(String name) { - WebDavFolder folder; + WebDavFolder folder = this.folderList.get(name); - if ((folder = this.mFolderList.get(name)) == null) { + if (folder == null) { folder = new WebDavFolder(this, name); - mFolderList.put(name, folder); + folderList.put(name, folder); } return folder; } - public Folder getSendSpoolFolder() throws MessagingException { - if (mSendFolder == null) - mSendFolder = getFolder(WebDavConstants.DAV_MAIL_SEND_FOLDER); + private Folder getSendSpoolFolder() throws MessagingException { + if (sendFolder == null) { + sendFolder = getFolder(WebDavConstants.DAV_MAIL_SEND_FOLDER); + } - return mSendFolder; + return sendFolder; } @Override @@ -307,50 +333,42 @@ public class WebDavStore extends RemoteStore { } private String getSpecialFoldersList() { - StringBuilder builder = new StringBuilder(200); - builder.append(""); - builder.append(""); - builder.append(""); - builder.append("<").append(WebDavConstants.DAV_MAIL_INBOX_FOLDER).append(" xmlns=\"urn:schemas:httpmail:\"/>"); - builder.append("<").append(WebDavConstants.DAV_MAIL_DRAFTS_FOLDER).append(" xmlns=\"urn:schemas:httpmail:\"/>"); - builder.append("<").append(WebDavConstants.DAV_MAIL_OUTBOX_FOLDER).append(" xmlns=\"urn:schemas:httpmail:\"/>"); - builder.append("<").append(WebDavConstants.DAV_MAIL_SENT_FOLDER).append(" xmlns=\"urn:schemas:httpmail:\"/>"); - builder.append("<").append(WebDavConstants.DAV_MAIL_TRASH_FOLDER).append(" xmlns=\"urn:schemas:httpmail:\"/>"); - // This should always be ##DavMailSubmissionURI## for which we already have a constant - // buffer.append(""); - - builder.append("<").append(WebDavConstants.DAV_MAIL_SPAM_FOLDER).append(" xmlns=\"urn:schemas:httpmail:\"/>"); - - builder.append(""); - builder.append(""); - return builder.toString(); + return "" + + "" + + "" + + "<" + WebDavConstants.DAV_MAIL_INBOX_FOLDER + " xmlns=\"urn:schemas:httpmail:\"/>" + + "<" + WebDavConstants.DAV_MAIL_DRAFTS_FOLDER + " xmlns=\"urn:schemas:httpmail:\"/>" + + "<" + WebDavConstants.DAV_MAIL_OUTBOX_FOLDER + " xmlns=\"urn:schemas:httpmail:\"/>" + + "<" + WebDavConstants.DAV_MAIL_SENT_FOLDER + " xmlns=\"urn:schemas:httpmail:\"/>" + + "<" + WebDavConstants.DAV_MAIL_TRASH_FOLDER + " xmlns=\"urn:schemas:httpmail:\"/>" + + "<" + WebDavConstants.DAV_MAIL_SPAM_FOLDER + " xmlns=\"urn:schemas:httpmail:\"/>" + + // This should always be ##DavMailSubmissionURI## for which we already have a constant + // "" + + "" + + ""; } /*************************************************************** * WebDAV XML Request body retrieval functions */ private String getFolderListXml() { - StringBuilder builder = new StringBuilder(200); - builder.append(""); - builder.append("\r\n"); - builder.append("SELECT \"DAV:uid\", \"DAV:ishidden\"\r\n"); - builder.append(" FROM SCOPE('deep traversal of \"").append(this.mUrl).append("\"')\r\n"); - builder.append(" WHERE \"DAV:ishidden\"=False AND \"DAV:isfolder\"=True\r\n"); - builder.append("\r\n"); - return builder.toString(); + return "" + + "\r\n" + + "SELECT \"DAV:uid\", \"DAV:ishidden\"\r\n" + + " FROM SCOPE('deep traversal of \"" + this.baseUrl + "\"')\r\n" + + " WHERE \"DAV:ishidden\"=False AND \"DAV:isfolder\"=True\r\n" + + "\r\n"; } String getMessageCountXml(String messageState) { - StringBuilder builder = new StringBuilder(200); - builder.append(""); - builder.append("\r\n"); - builder.append("SELECT \"DAV:visiblecount\"\r\n"); - builder.append(" FROM \"\"\r\n"); - builder.append(" WHERE \"DAV:ishidden\"=False AND \"DAV:isfolder\"=False AND \"urn:schemas:httpmail:read\"=") - .append(messageState).append("\r\n"); - builder.append(" GROUP BY \"DAV:ishidden\"\r\n"); - builder.append("\r\n"); - return builder.toString(); + return "" + + "\r\n" + + "SELECT \"DAV:visiblecount\"\r\n" + + " FROM \"\"\r\n" + + " WHERE \"DAV:ishidden\"=False AND \"DAV:isfolder\"=False AND \"urn:schemas:httpmail:read\"=" + + messageState + "\r\n" + + " GROUP BY \"DAV:ishidden\"\r\n" + + "\r\n"; } String getMessageEnvelopeXml(String[] uids) { @@ -384,14 +402,12 @@ public class WebDavStore extends RemoteStore { } String getMessagesXml() { - StringBuilder builder = new StringBuilder(200); - builder.append(""); - builder.append("\r\n"); - builder.append("SELECT \"DAV:uid\"\r\n"); - builder.append(" FROM \"\"\r\n"); - builder.append(" WHERE \"DAV:ishidden\"=False AND \"DAV:isfolder\"=False\r\n"); - builder.append("\r\n"); - return builder.toString(); + return "" + + "\r\n" + + "SELECT \"DAV:uid\"\r\n" + + " FROM \"\"\r\n" + + " WHERE \"DAV:ishidden\"=False AND \"DAV:isfolder\"=False\r\n" + + "\r\n"; } String getMessageUrlsXml(String[] uids) { @@ -475,32 +491,23 @@ public class WebDavStore extends RemoteStore { return buffer.toString(); } - /*************************************************************** - * Authentication related methods - */ - - /** - * Determines which type of authentication Exchange is using and authenticates appropriately. - * - * @throws MessagingException - */ - public boolean authenticate() + private boolean authenticate() throws MessagingException { try { - if (mAuthentication == WebDavConstants.AUTH_TYPE_NONE) { + if (authenticationType == WebDavConstants.AUTH_TYPE_NONE) { ConnectionInfo info = doInitialConnection(); if (info.requiredAuthType == WebDavConstants.AUTH_TYPE_BASIC) { - HttpGeneric request = new HttpGeneric(mUrl); + HttpGeneric request = new HttpGeneric(baseUrl); request.setMethod("GET"); - request.setHeader("Authorization", mAuthString); + request.setHeader("Authorization", authString); WebDavHttpClient httpClient = getHttpClient(); - HttpResponse response = httpClient.executeOverride(request, mContext); + HttpResponse response = httpClient.executeOverride(request, httpContext); int statusCode = response.getStatusLine().getStatusCode(); if (statusCode >= 200 && statusCode < 300) { - mAuthentication = WebDavConstants.AUTH_TYPE_BASIC; + authenticationType = WebDavConstants.AUTH_TYPE_BASIC; } else if (statusCode == 401) { throw new MessagingException("Invalid username or password for authentication."); } else { @@ -508,29 +515,23 @@ public class WebDavStore extends RemoteStore { " during request processing: " + response.getStatusLine().toString()); } } else if (info.requiredAuthType == WebDavConstants.AUTH_TYPE_FORM_BASED) { - doFBA(info); + performFormBasedAuthentication(info); } - } else if (mAuthentication == WebDavConstants.AUTH_TYPE_BASIC) { + } else if (authenticationType == WebDavConstants.AUTH_TYPE_BASIC) { // Nothing to do, we authenticate with every request when // using basic authentication. - } else if (mAuthentication == WebDavConstants.AUTH_TYPE_FORM_BASED) { + } else if (authenticationType == WebDavConstants.AUTH_TYPE_FORM_BASED) { // Our cookie expired, re-authenticate. - doFBA(null); + performFormBasedAuthentication(null); } } catch (IOException ioe) { Log.e(LOG_TAG, "Error during authentication: " + ioe + "\nStack: " + WebDavUtils.processException(ioe)); throw new MessagingException("Error during authentication", ioe); } - return mAuthentication != WebDavConstants.AUTH_TYPE_NONE; + return authenticationType != WebDavConstants.AUTH_TYPE_NONE; } - /** - * Makes the initial connection to Exchange for authentication. Determines the type of authentication necessary for - * the server. - * - * @throws MessagingException - */ private ConnectionInfo doInitialConnection() throws MessagingException { // For our initial connection we are sending an empty GET request to @@ -547,11 +548,11 @@ public class WebDavStore extends RemoteStore { WebDavHttpClient httpClient = getHttpClient(); - HttpGeneric request = new HttpGeneric(mUrl); + HttpGeneric request = new HttpGeneric(baseUrl); request.setMethod("GET"); try { - HttpResponse response = httpClient.executeOverride(request, mContext); + HttpResponse response = httpClient.executeOverride(request, httpContext); info.statusCode = response.getStatusLine().getStatusCode(); if (info.statusCode == 401) { @@ -568,9 +569,9 @@ public class WebDavStore extends RemoteStore { // authorization URL. info.requiredAuthType = WebDavConstants.AUTH_TYPE_FORM_BASED; - if (mAuthPath != null && !mAuthPath.equals("")) { + if (formBasedAuthPath != null && !formBasedAuthPath.equals("")) { // The user specified their own authentication path, use that. - info.guessedAuthUrl = getRoot() + mAuthPath; + info.guessedAuthUrl = getRoot() + formBasedAuthPath; } else { // Use the default path to the authentication dll. info.guessedAuthUrl = getRoot() + "/exchweb/bin/auth/owaauth.dll"; @@ -595,23 +596,20 @@ public class WebDavStore extends RemoteStore { return info; } - /** - * Performs form-based authentication. - * - * @throws MessagingException - */ - public void doFBA(ConnectionInfo info) + private void performFormBasedAuthentication(ConnectionInfo info) throws IOException, MessagingException { // Clear out cookies from any previous authentication. - if (mAuthCookies != null) mAuthCookies.clear(); + if (authCookies != null) { + authCookies.clear(); + } WebDavHttpClient httpClient = getHttpClient(); String loginUrl; if (info != null) { loginUrl = info.guessedAuthUrl; - } else if (mCachedLoginUrl != null && !mCachedLoginUrl.equals("")) { - loginUrl = mCachedLoginUrl; + } else if (cachedLoginUrl != null && !cachedLoginUrl.equals("")) { + loginUrl = cachedLoginUrl; } else { throw new MessagingException("No valid login URL available for form-based authentication."); } @@ -620,10 +618,10 @@ public class WebDavStore extends RemoteStore { request.setMethod("POST"); // Build the POST data. - List pairs = new ArrayList(); - pairs.add(new BasicNameValuePair("destination", mUrl)); - pairs.add(new BasicNameValuePair("username", mUsername)); - pairs.add(new BasicNameValuePair("password", mPassword)); + List pairs = new ArrayList<>(); + pairs.add(new BasicNameValuePair("destination", baseUrl)); + pairs.add(new BasicNameValuePair("username", username)); + pairs.add(new BasicNameValuePair("password", password)); pairs.add(new BasicNameValuePair("flags", "0")); pairs.add(new BasicNameValuePair("SubmitCreds", "Log+On")); pairs.add(new BasicNameValuePair("forcedownlevel", "0")); @@ -632,7 +630,7 @@ public class WebDavStore extends RemoteStore { UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(pairs); request.setEntity(formEntity); - HttpResponse response = httpClient.executeOverride(request, mContext); + HttpResponse response = httpClient.executeOverride(request, httpContext); boolean authenticated = testAuthenticationResponse(response); if (!authenticated) { // Check the response from the authentication request above for a form action. @@ -645,7 +643,7 @@ public class WebDavStore extends RemoteStore { request = new HttpGeneric(loginUrl); request.setMethod("GET"); - response = httpClient.executeOverride(request, mContext); + response = httpClient.executeOverride(request, httpContext); formAction = findFormAction(WebDavHttpClient.getUngzippedContent(response.getEntity())); } } @@ -687,7 +685,7 @@ public class WebDavStore extends RemoteStore { request.setMethod("POST"); request.setEntity(formEntity); - response = httpClient.executeOverride(request, mContext); + response = httpClient.executeOverride(request, httpContext); authenticated = testAuthenticationResponse(response); } catch (URISyntaxException e) { Log.e(LOG_TAG, "URISyntaxException caught " + e + "\nTrace: " + WebDavUtils.processException(e)); @@ -699,18 +697,13 @@ public class WebDavStore extends RemoteStore { } if (authenticated) { - mAuthentication = WebDavConstants.AUTH_TYPE_FORM_BASED; - mCachedLoginUrl = loginUrl; + authenticationType = WebDavConstants.AUTH_TYPE_FORM_BASED; + cachedLoginUrl = loginUrl; } else { throw new MessagingException("Invalid credentials provided for authentication."); } } - /** - * Searches the specified stream for an HTML form and returns the form's action target. - * - * @throws IOException - */ private String findFormAction(InputStream istream) throws IOException { String formAction = null; @@ -718,9 +711,10 @@ public class WebDavStore extends RemoteStore { BufferedReader reader = new BufferedReader(new InputStreamReader(istream), 4096); String tempText; + //TODO: Use proper HTML parsing for this // Read line by line until we find something like:
. - while ((tempText = reader.readLine()) != null && - formAction == null) { + tempText = reader.readLine(); + while (formAction == null) { if (tempText.contains(" action=")) { String[] actionParts = tempText.split(" action="); if (actionParts.length > 1 && actionParts[1].length() > 1) { @@ -736,6 +730,7 @@ public class WebDavStore extends RemoteStore { } } } + tempText = reader.readLine(); } return formAction; @@ -747,7 +742,7 @@ public class WebDavStore extends RemoteStore { int statusCode = response.getStatusLine().getStatusCode(); // Exchange 2007 will return a 302 status code no matter what. if (((statusCode >= 200 && statusCode < 300) || statusCode == 302) && - mAuthCookies != null && !mAuthCookies.getCookies().isEmpty()) { + authCookies != null && !authCookies.getCookies().isEmpty()) { // We may be authenticated, we need to send a test request to know for sure. // Exchange 2007 adds the same cookies whether the username and password were valid or not. ConnectionInfo info = doInitialConnection(); @@ -760,7 +755,7 @@ public class WebDavStore extends RemoteStore { // The redirect is in the form: https://hostname:port/owa/alias. // Do a simple replace and compare the resulting strings. try { - String thisPath = new URI(mUrl).getPath(); + String thisPath = new URI(baseUrl).getPath(); String redirectPath = new URI(info.redirectUrl).getPath(); if (!thisPath.endsWith("/")) { @@ -793,31 +788,31 @@ public class WebDavStore extends RemoteStore { } public CookieStore getAuthCookies() { - return mAuthCookies; + return authCookies; } public String getAlias() { - return mAlias; + return alias; } public String getUrl() { - return mUrl; + return baseUrl; } public WebDavHttpClient getHttpClient() throws MessagingException { - if (mHttpClient == null) { - mHttpClient = mHttpClientFactory.create(); + if (httpClient == null) { + httpClient = httpClientFactory.create(); // Disable automatic redirects on the http client. - mHttpClient.getParams().setBooleanParameter("http.protocol.handle-redirects", false); + httpClient.getParams().setBooleanParameter("http.protocol.handle-redirects", false); // Setup a cookie store for forms-based authentication. - mContext = new BasicHttpContext(); - mAuthCookies = new BasicCookieStore(); - mContext.setAttribute(ClientContext.COOKIE_STORE, mAuthCookies); + httpContext = new BasicHttpContext(); + authCookies = new BasicCookieStore(); + httpContext.setAttribute(ClientContext.COOKIE_STORE, authCookies); - SchemeRegistry reg = mHttpClient.getConnectionManager().getSchemeRegistry(); + SchemeRegistry reg = httpClient.getConnectionManager().getSchemeRegistry(); try { - Scheme s = new Scheme("https", new WebDavSocketFactory(mHost, 443), 443); + Scheme s = new Scheme("https", new WebDavSocketFactory(hostname, 443), 443); reg.register(s); } catch (NoSuchAlgorithmException nsa) { Log.e(LOG_TAG, "NoSuchAlgorithmException in getHttpClient: " + nsa); @@ -827,11 +822,11 @@ public class WebDavStore extends RemoteStore { throw new MessagingException("KeyManagementException in getHttpClient: " + kme); } } - return mHttpClient; + return httpClient; } protected InputStream sendRequest(String url, String method, StringEntity messageBody, - Map headers, boolean tryAuth) + Map headers, boolean tryAuth) throws MessagingException { if (url == null || method == null) { return null; @@ -855,16 +850,16 @@ public class WebDavStore extends RemoteStore { } } - if (mAuthentication == WebDavConstants.AUTH_TYPE_NONE) { + if (authenticationType == WebDavConstants.AUTH_TYPE_NONE) { if (!tryAuth || !authenticate()) { throw new MessagingException("Unable to authenticate in sendRequest()."); } - } else if (mAuthentication == WebDavConstants.AUTH_TYPE_BASIC) { - httpMethod.setHeader("Authorization", mAuthString); + } else if (authenticationType == WebDavConstants.AUTH_TYPE_BASIC) { + httpMethod.setHeader("Authorization", authString); } httpMethod.setMethod(method); - response = httpClient.executeOverride(httpMethod, mContext); + response = httpClient.executeOverride(httpMethod, httpContext); statusCode = response.getStatusLine().getStatusCode(); entity = response.getEntity(); @@ -872,9 +867,9 @@ public class WebDavStore extends RemoteStore { if (statusCode == 401) { throw new MessagingException("Invalid username or password for Basic authentication."); } else if (statusCode == 440) { - if (tryAuth && mAuthentication == WebDavConstants.AUTH_TYPE_FORM_BASED) { + if (tryAuth && authenticationType == WebDavConstants.AUTH_TYPE_FORM_BASED) { // Our cookie expired, re-authenticate. - doFBA(null); + performFormBasedAuthentication(null); sendRequest(url, method, messageBody, headers, false); } else { throw new MessagingException("Authentication failure in sendRequest()."); @@ -904,7 +899,7 @@ public class WebDavStore extends RemoteStore { if (response.getFirstHeader("Location") != null) { // TODO: This may indicate lack of authentication or may alternatively be something we should follow throw new IOException("Unexpected redirect during request processing. " + - "Expected response from: "+url+" but told to redirect to:" + + "Expected response from: " + url + " but told to redirect to:" + response.getFirstHeader("Location").getValue()); } else { throw new IOException("Unexpected redirect during request processing. " + @@ -913,11 +908,11 @@ public class WebDavStore extends RemoteStore { } public String getAuthString() { - return mAuthString; + return authString; } /** - * Performs an httprequest to the supplied url using the supplied method. messageBody and headers are optional as + * Performs an HttpRequest to the supplied url using the supplied method. messageBody and headers are optional as * not all requests will need them. There are two signatures to support calls that don't require parsing of the * response. */ @@ -927,7 +922,7 @@ public class WebDavStore extends RemoteStore { } DataSet processRequest(String url, String method, String messageBody, Map headers, - boolean needsParsing) + boolean needsParsing) throws MessagingException { DataSet dataset = new DataSet(); if (K9MailLib.isDebug() && DEBUG_PROTOCOL_WEBDAV) { @@ -964,7 +959,8 @@ public class WebDavStore extends RemoteStore { dataset = myHandler.getDataSet(); } catch (SAXException se) { - Log.e(LOG_TAG, "SAXException in processRequest() " + se + "\nTrace: " + WebDavUtils.processException(se)); + Log.e(LOG_TAG, + "SAXException in processRequest() " + se + "\nTrace: " + WebDavUtils.processException(se)); throw new MessagingException("SAXException in processRequest() ", se); } catch (ParserConfigurationException pce) { Log.e(LOG_TAG, "ParserConfigurationException in processRequest() " + pce + "\nTrace: " @@ -992,7 +988,7 @@ public class WebDavStore extends RemoteStore { @Override public void sendMessages(List messages) throws MessagingException { - WebDavFolder tmpFolder = (WebDavFolder) getFolder(mStoreConfig.getDraftsFolderName()); + WebDavFolder tmpFolder = getFolder(mStoreConfig.getDraftsFolderName()); try { tmpFolder.open(Folder.OPEN_MODE_RW); List retMessages = tmpFolder.appendWebDavMessages(messages);