diff --git a/src/java/davmail/exception/HttpForbiddenException.java b/src/java/davmail/exception/HttpForbiddenException.java new file mode 100644 index 00000000..30faa49b --- /dev/null +++ b/src/java/davmail/exception/HttpForbiddenException.java @@ -0,0 +1,35 @@ +/* + * 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. + */ +package davmail.exception; + +import org.apache.commons.httpclient.HttpException; + +/** + * HttpException with 403 forbidden status. + */ +public class HttpForbiddenException extends HttpException { + /** + * HttpException with 403 forbidden status. + * + * @param message exception message + */ + public HttpForbiddenException(String message) { + super(message); + } +} diff --git a/src/java/davmail/exception/HttpNotFoundException.java b/src/java/davmail/exception/HttpNotFoundException.java new file mode 100644 index 00000000..6604d0ed --- /dev/null +++ b/src/java/davmail/exception/HttpNotFoundException.java @@ -0,0 +1,35 @@ +/* + * 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. + */ +package davmail.exception; + +import org.apache.commons.httpclient.HttpException; + +/** + * HttpException with 404 not found status. + */ +public class HttpNotFoundException extends HttpException { + /** + * HttpException with 404 not found status. + * + * @param message exception message + */ + public HttpNotFoundException(String message) { + super(message); + } +} diff --git a/src/java/davmail/http/DavGatewayHttpClientFacade.java b/src/java/davmail/http/DavGatewayHttpClientFacade.java index cf8ac8df..a185c883 100644 --- a/src/java/davmail/http/DavGatewayHttpClientFacade.java +++ b/src/java/davmail/http/DavGatewayHttpClientFacade.java @@ -21,6 +21,8 @@ package davmail.http; import davmail.BundleMessage; import davmail.Settings; import davmail.exception.DavMailException; +import davmail.exception.HttpForbiddenException; +import davmail.exception.HttpNotFoundException; import davmail.ui.tray.DavGatewayTray; import org.apache.commons.httpclient.*; import org.apache.commons.httpclient.auth.AuthPolicy; @@ -388,7 +390,13 @@ public final class DavGatewayHttpClientFacade { } catch (URIException e) { message.append(method.getPath()); } - return new HttpException(); + if (status == HttpStatus.SC_FORBIDDEN) { + return new HttpForbiddenException(message.toString()); + } else if (status == HttpStatus.SC_NOT_FOUND) { + return new HttpNotFoundException(message.toString()); + } else { + return new HttpException(message.toString()); + } } /** diff --git a/src/java/davmail/imap/ImapConnection.java b/src/java/davmail/imap/ImapConnection.java index 87cc36fa..5f28cb1f 100644 --- a/src/java/davmail/imap/ImapConnection.java +++ b/src/java/davmail/imap/ImapConnection.java @@ -23,6 +23,8 @@ import com.sun.mail.imap.protocol.BASE64MailboxEncoder; import davmail.AbstractConnection; import davmail.BundleMessage; import davmail.exception.DavMailException; +import davmail.exception.HttpForbiddenException; +import davmail.exception.HttpNotFoundException; import davmail.exchange.ExchangeSession; import davmail.exchange.ExchangeSessionFactory; import davmail.ui.tray.DavGatewayTray; @@ -133,18 +135,45 @@ public class ImapConnection extends AbstractConnection { String folderContext = BASE64MailboxDecoder.decode(tokens.nextToken()); if (tokens.hasMoreTokens()) { String folderQuery = folderContext + BASE64MailboxDecoder.decode(tokens.nextToken()); - if (folderQuery.endsWith("%/%")) { - folderQuery = folderQuery.substring(0, folderQuery.length() - 2); - } - if (folderQuery.endsWith("%") || folderQuery.endsWith("*")) { - boolean recursive = folderQuery.endsWith("*"); + if (folderQuery.endsWith("%/%") && !"/%/%".equals(folderQuery)) { + List folders = session.getSubFolders(folderQuery.substring(0, folderQuery.length() - 3), false); + for (ExchangeSession.Folder folder : folders) { + sendClient("* " + command + " (" + folder.getFlags() + ") \"/\" \"" + BASE64MailboxEncoder.encode(folder.folderPath) + '\"'); + try { + List subfolders = session.getSubFolders(folder.folderPath, false); + for (ExchangeSession.Folder subfolder : subfolders) { + sendClient("* " + command + " (" + subfolder.getFlags() + ") \"/\" \"" + BASE64MailboxEncoder.encode(subfolder.folderPath) + '\"'); + } + } catch (HttpForbiddenException e) { + // access forbidden, ignore + } catch (HttpNotFoundException e) { + // not found, ignore + } + } + sendClient(commandId + " OK " + command + " completed"); + } else if (folderQuery.endsWith("%") || folderQuery.endsWith("*")) { + if ("/*".equals(folderQuery) || "/%".equals(folderQuery) || "/%/%".equals(folderQuery)) { + folderQuery = folderQuery.substring(1); + if ("%/%".equals(folderQuery)) { + folderQuery = folderQuery.substring(0, folderQuery.length() - 2); + } + sendClient("* " + command + " (\\HasChildren) \"/\" \"/public\""); + } + boolean recursive = folderQuery.endsWith("*") && !folderQuery.startsWith("/public"); List folders = session.getSubFolders(folderQuery.substring(0, folderQuery.length() - 1), recursive); for (ExchangeSession.Folder folder : folders) { sendClient("* " + command + " (" + folder.getFlags() + ") \"/\" \"" + BASE64MailboxEncoder.encode(folder.folderPath) + '\"'); } sendClient(commandId + " OK " + command + " completed"); } else { - ExchangeSession.Folder folder = session.getFolder(folderQuery); + ExchangeSession.Folder folder = null; + try { + session.getFolder(folderQuery); + } catch (HttpForbiddenException e) { + // access forbidden, ignore + } catch (HttpNotFoundException e) { + // not found, ignore + } if (folder != null) { sendClient("* " + command + " (" + folder.getFlags() + ") \"/\" \"" + BASE64MailboxEncoder.encode(folder.folderPath) + '\"'); sendClient(commandId + " OK " + command + " completed"); @@ -161,22 +190,26 @@ public class ImapConnection extends AbstractConnection { } else if ("select".equalsIgnoreCase(command) || "examine".equalsIgnoreCase(command)) { if (tokens.hasMoreTokens()) { String folderName = BASE64MailboxDecoder.decode(tokens.nextToken()); - currentFolder = session.getFolder(folderName); - currentFolder.loadMessages(); - sendClient("* " + currentFolder.count() + " EXISTS"); - sendClient("* " + currentFolder.count() + " RECENT"); - sendClient("* OK [UIDVALIDITY 1]"); - if (currentFolder.count() == 0) { - sendClient("* OK [UIDNEXT " + 1 + ']'); - } else { - sendClient("* OK [UIDNEXT " + currentFolder.getUidNext() + ']'); - } - sendClient("* FLAGS (\\Answered \\Deleted \\Draft \\Flagged \\Seen $Forwarded Junk)"); - sendClient("* OK [PERMANENTFLAGS (\\Answered \\Deleted \\Draft \\Flagged \\Seen $Forwarded Junk \\*)]"); - if ("select".equalsIgnoreCase(command)) { - sendClient(commandId + " OK [READ-WRITE] " + command + " completed"); - } else { - sendClient(commandId + " OK [READ-ONLY] " + command + " completed"); + try { + currentFolder = session.getFolder(folderName); + currentFolder.loadMessages(); + sendClient("* " + currentFolder.count() + " EXISTS"); + sendClient("* " + currentFolder.count() + " RECENT"); + sendClient("* OK [UIDVALIDITY 1]"); + if (currentFolder.count() == 0) { + sendClient("* OK [UIDNEXT " + 1 + ']'); + } else { + sendClient("* OK [UIDNEXT " + currentFolder.getUidNext() + ']'); + } + sendClient("* FLAGS (\\Answered \\Deleted \\Draft \\Flagged \\Seen $Forwarded Junk)"); + sendClient("* OK [PERMANENTFLAGS (\\Answered \\Deleted \\Draft \\Flagged \\Seen $Forwarded Junk \\*)]"); + if ("select".equalsIgnoreCase(command)) { + sendClient(commandId + " OK [READ-WRITE] " + command + " completed"); + } else { + sendClient(commandId + " OK [READ-ONLY] " + command + " completed"); + } + } catch (HttpForbiddenException e) { + sendClient(commandId + " NO Forbidden"); } } else { sendClient(commandId + " BAD command unrecognized");