📄 pop3handler.java
字号:
// Clear config data theConfigData = null; } /** * Implements a "stat". If the handler is currently in * a transaction state, this amounts to a rollback of the * mailbox contents to the beginning of the transaction. * This method is also called when first entering the * transaction state to initialize the handler copies of the * user inbox. * */ private void stat() { userMailbox = new ArrayList(); userMailbox.add(DELETED); try { for (Iterator it = userInbox.list(); it.hasNext(); ) { String key = (String) it.next(); Mail mc = userInbox.retrieve(key); // Retrieve can return null if the mail is no longer in the store. // In this case we simply continue to the next key if (mc == null) { continue; } userMailbox.add(mc); } } catch(MessagingException e) { // In the event of an exception being thrown there may or may not be anything in userMailbox getLogger().error("Unable to STAT mail box ", e); } finally { backupUserMailbox = (ArrayList) userMailbox.clone(); } } /** * Reads a line of characters off the command line. * * @return the trimmed input line * @throws IOException if an exception is generated reading in the input characters */ final String readCommandLine() throws IOException { for (;;) try { String commandLine = in.readLine(); if (commandLine != null) { commandLine = commandLine.trim(); } return commandLine; } catch (CRLFTerminatedReader.TerminationException te) { writeLoggedFlushedResponse("-ERR Syntax error at character position " + te.position() + ". CR and LF must be CRLF paired. See RFC 1939 #3."); } } /** * This method parses POP3 commands read off the wire in handleConnection. * Actual processing of the command (possibly including additional back and * forth communication with the client) is delegated to one of a number of * command specific handler methods. The primary purpose of this method is * to parse the raw command string to determine exactly which handler should * be called. It returns true if expecting additional commands, false otherwise. * * @param rawCommand the raw command string passed in over the socket * * @return whether additional commands are expected. */ private boolean parseCommand(String rawCommand) { if (rawCommand == null) { return false; } boolean returnValue = true; String command = rawCommand; StringTokenizer commandLine = new StringTokenizer(command, " "); int arguments = commandLine.countTokens(); if (arguments == 0) { return true; } else if(arguments > 0) { command = commandLine.nextToken().toUpperCase(Locale.US); } if (getLogger().isDebugEnabled()) { // Don't display password in logger if (!command.equals("PASS")) { getLogger().debug("Command received: " + rawCommand); } else { getLogger().debug("Command received: PASS <password omitted>"); } } String argument = (String) null; if(arguments > 1) { argument = commandLine.nextToken(); } String argument1 = (String) null; if(arguments > 2) { argument1 = commandLine.nextToken(); } if (command.equals("USER")) { doUSER(command,argument,argument1); } else if (command.equals("PASS")) { doPASS(command,argument,argument1); } else if (command.equals("STAT")) { doSTAT(command,argument,argument1); } else if (command.equals("LIST")) { doLIST(command,argument,argument1); } else if (command.equals("UIDL")) { doUIDL(command,argument,argument1); } else if (command.equals("RSET")) { doRSET(command,argument,argument1); } else if (command.equals("DELE")) { doDELE(command,argument,argument1); } else if (command.equals("NOOP")) { doNOOP(command,argument,argument1); } else if (command.equals("RETR")) { doRETR(command,argument,argument1); } else if (command.equals("TOP")) { doTOP(command,argument,argument1); } else if (command.equals("QUIT")) { returnValue = false; doQUIT(command,argument,argument1); } else { doUnknownCmd(command,argument,argument1); } return returnValue; } /** * Handler method called upon receipt of a USER command. * Reads in the user id. * * @param command the command parsed by the parseCommand method * @param argument the first argument parsed by the parseCommand method * @param argument1 the second argument parsed by the parseCommand method */ private void doUSER(String command,String argument,String argument1) { String responseString = null; if (state == AUTHENTICATION_READY && argument != null) { user = argument; state = AUTHENTICATION_USERSET; responseString = OK_RESPONSE; } else { responseString = ERR_RESPONSE; } writeLoggedFlushedResponse(responseString); } /** * Handler method called upon receipt of a PASS command. * Reads in and validates the password. * * @param command the command parsed by the parseCommand method * @param argument the first argument parsed by the parseCommand method * @param argument1 the second argument parsed by the parseCommand method */ private void doPASS(String command,String argument,String argument1) { String responseString = null; if (state == AUTHENTICATION_USERSET && argument != null) { String passArg = argument; if (theConfigData.getUsersRepository().test(user, passArg)) { StringBuffer responseBuffer = new StringBuffer(64) .append(OK_RESPONSE) .append(" Welcome ") .append(user); responseString = responseBuffer.toString(); state = TRANSACTION; writeLoggedFlushedResponse(responseString); userInbox = theConfigData.getMailServer().getUserInbox(user); stat(); } else { responseString = ERR_RESPONSE + " Authentication failed."; state = AUTHENTICATION_READY; writeLoggedFlushedResponse(responseString); } } else { responseString = ERR_RESPONSE; writeLoggedFlushedResponse(responseString); } } /** * Handler method called upon receipt of a STAT command. * Returns the number of messages in the mailbox and its * aggregate size. * * @param command the command parsed by the parseCommand method * @param argument the first argument parsed by the parseCommand method * @param argument1 the second argument parsed by the parseCommand method */ private void doSTAT(String command,String argument,String argument1) { String responseString = null; if (state == TRANSACTION) { long size = 0; int count = 0; try { for (Iterator i = userMailbox.iterator(); i.hasNext(); ) { MailImpl mc = (MailImpl) i.next(); if (mc != DELETED) { size += mc.getMessageSize(); count++; } } StringBuffer responseBuffer = new StringBuffer(32) .append(OK_RESPONSE) .append(" ") .append(count) .append(" ") .append(size); responseString = responseBuffer.toString(); writeLoggedFlushedResponse(responseString); } catch (MessagingException me) { responseString = ERR_RESPONSE; writeLoggedFlushedResponse(responseString); } } else { responseString = ERR_RESPONSE; writeLoggedFlushedResponse(responseString); } } /** * Handler method called upon receipt of a LIST command. * Returns the number of messages in the mailbox and its * aggregate size, or optionally, the number and size of * a single message. * * @param command the command parsed by the parseCommand method * @param argument the first argument parsed by the parseCommand method * @param argument1 the second argument parsed by the parseCommand method */ private void doLIST(String command,String argument,String argument1) { String responseString = null; if (state == TRANSACTION) { if (argument == null) { long size = 0; int count = 0; try { for (Iterator i = userMailbox.iterator(); i.hasNext(); ) { MailImpl mc = (MailImpl) i.next(); if (mc != DELETED) { size += mc.getMessageSize(); count++; } } StringBuffer responseBuffer = new StringBuffer(32) .append(OK_RESPONSE) .append(" ") .append(count) .append(" ") .append(size); responseString = responseBuffer.toString(); writeLoggedFlushedResponse(responseString); count = 0; for (Iterator i = userMailbox.iterator(); i.hasNext(); count++) { MailImpl mc = (MailImpl) i.next(); if (mc != DELETED) { responseBuffer = new StringBuffer(16) .append(count) .append(" ") .append(mc.getMessageSize()); out.println(responseBuffer.toString()); } } out.println("."); out.flush(); } catch (MessagingException me) { responseString = ERR_RESPONSE; writeLoggedFlushedResponse(responseString); } } else { int num = 0; try { num = Integer.parseInt(argument); MailImpl mc = (MailImpl) userMailbox.get(num); if (mc != DELETED) { StringBuffer responseBuffer = new StringBuffer(64) .append(OK_RESPONSE) .append(" ") .append(num) .append(" ") .append(mc.getMessageSize()); responseString = responseBuffer.toString(); writeLoggedFlushedResponse(responseString); } else { StringBuffer responseBuffer = new StringBuffer(64) .append(ERR_RESPONSE) .append(" Message (") .append(num) .append(") already deleted."); responseString = responseBuffer.toString(); writeLoggedFlushedResponse(responseString); } } catch (IndexOutOfBoundsException npe) { StringBuffer responseBuffer = new StringBuffer(64) .append(ERR_RESPONSE) .append(" Message (") .append(num) .append(") does not exist."); responseString = responseBuffer.toString(); writeLoggedFlushedResponse(responseString); } catch (NumberFormatException nfe) { StringBuffer responseBuffer = new StringBuffer(64) .append(ERR_RESPONSE) .append(" ") .append(argument) .append(" is not a valid number"); responseString = responseBuffer.toString(); writeLoggedFlushedResponse(responseString); } catch (MessagingException me) { responseString = ERR_RESPONSE; writeLoggedFlushedResponse(responseString); } } } else { responseString = ERR_RESPONSE; writeLoggedFlushedResponse(responseString); } } /** * Handler method called upon receipt of a UIDL command. * Returns a listing of message ids to the client. * * @param command the command parsed by the parseCommand method * @param argument the first argument parsed by the parseCommand method * @param argument1 the second argument parsed by the parseCommand method */ private void doUIDL(String command,String argument,String argument1) { String responseString = null; if (state == TRANSACTION) { if (argument == null) { responseString = OK_RESPONSE + " unique-id listing follows"; writeLoggedFlushedResponse(responseString); int count = 0; for (Iterator i = userMailbox.iterator(); i.hasNext(); count++) { MailImpl mc = (MailImpl) i.next(); if (mc != DELETED) { StringBuffer responseBuffer = new StringBuffer(64) .append(count) .append(" ") .append(mc.getName()); out.println(responseBuffer.toString()); } } out.println("."); out.flush(); } else { int num = 0; try { num = Integer.parseInt(argument); MailImpl mc = (MailImpl) userMailbox.get(num); if (mc != DELETED) { StringBuffer responseBuffer = new StringBuffer(64) .append(OK_RESPONSE) .append(" ") .append(num) .append(" ") .append(mc.getName()); responseString = responseBuffer.toString();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -