📄 nntphandler.java
字号:
*/ private void doXHDR(String argument) { doHDR(argument); } /** * Get the values of the headers for the selected newsgroup, * with an optional range modifier. * * @param argument the argument passed in with the HDR command. */ private void doHDR(String argument) { // 9.5.3 if (argument == null) { writeLoggedFlushedResponse("501 Syntax error - missing required parameter"); return; } String hdr = argument; String range = null; int spaceIndex = hdr.indexOf(" "); if (spaceIndex >= 0 ) { range = hdr.substring(spaceIndex + 1); hdr = hdr.substring(0, spaceIndex); } if (group == null ) { writeLoggedFlushedResponse("412 No news group currently selected."); return; } if ((range == null) && (currentArticleNumber < 0)) { writeLoggedFlushedResponse("420 No current article selected"); return; } NNTPArticle[] article = getRange(range); if ( article == null ) { writeLoggedFlushedResponse("412 no newsgroup selected"); } else if ( article.length == 0 ) { writeLoggedFlushedResponse("430 no such article"); } else { writeLoggedFlushedResponse("221 Header follows"); for ( int i = 0 ; i < article.length ; i++ ) { String val = article[i].getHeader(hdr); if ( val == null ) { val = ""; } StringBuffer hdrBuffer = new StringBuffer(128) .append(article[i].getArticleNumber()) .append(" ") .append(val); writeLoggedResponse(hdrBuffer.toString()); } writeLoggedFlushedResponse("."); } } /** * Returns information from the overview database regarding the * current article, or a range of articles. * * @param range the optional article range. */ private void doXOVER(String range) { doOVER(range); } /** * Returns information from the overview database regarding the * current article, or a range of articles. * * @param range the optional article range. */ private void doOVER(String range) { // 9.5.2.2.1 if ( group == null ) { writeLoggedFlushedResponse("412 No newsgroup selected"); return; } if ((range == null) && (currentArticleNumber < 0)) { writeLoggedFlushedResponse("420 No current article selected"); return; } NNTPArticle[] article = getRange(range); if ( article.length == 0 ) { writeLoggedFlushedResponse("420 No article(s) selected"); } else { writeLoggedResponse("224 Overview information follows"); for ( int i = 0 ; i < article.length ; i++ ) { article[i].writeOverview(outs); if (i % 100 == 0) { // Reset the watchdog every hundred headers or so // to ensure the connection doesn't timeout for slow // clients theWatchdog.reset(); } } writeLoggedFlushedResponse("."); } } /** * Handles the transaction for getting the article data. */ private void createArticle() { try { InputStream msgIn = new CharTerminatedInputStream(in, NNTPTerminator); // Removes the dot stuffing msgIn = new DotStuffingInputStream(msgIn); MailHeaders headers = new MailHeaders(msgIn); processMessageHeaders(headers); processMessage(headers, msgIn); } catch (MessagingException me) { throw new NNTPException("MessagingException encountered when loading article."); } } /** * Processes the NNTP message headers coming in off the wire. * * @param headers the headers of the message being read */ private MailHeaders processMessageHeaders(MailHeaders headers) throws MessagingException { return headers; } /** * Processes the NNTP message coming in off the wire. Reads the * content and delivers to the spool. * * @param headers the headers of the message being read * @param msgIn the stream containing the message content */ private void processMessage(MailHeaders headers, InputStream bodyIn) throws MessagingException { InputStream messageIn = null; try { messageIn = new SequenceInputStream(new ByteArrayInputStream(headers.toByteArray()), bodyIn); theConfigData.getNNTPRepository().createArticle(messageIn); } finally { if (messageIn != null) { try { messageIn.close(); } catch (IOException ioe) { // Ignore exception on close. } messageIn = null; } } } /** * Returns the date from @param input. * The input tokens are assumed to be in format date time [GMT|UTC] . * 'date' is in format [XX]YYMMDD. 'time' is in format 'HHMMSS' * NOTE: This routine could do with some format checks. * * @param argument the date string */ private Date getDateFrom(String argument) { if (argument == null) { throw new NNTPException("Date argument was absent."); } StringTokenizer tok = new StringTokenizer(argument, " "); if (tok.countTokens() < 2) { throw new NNTPException("Date argument was ill-formed."); } String date = tok.nextToken(); String time = tok.nextToken(); boolean utc = ( tok.hasMoreTokens() ); Date d = new Date(); try { StringBuffer dateStringBuffer = new StringBuffer(64) .append(date) .append(" ") .append(time); Date dt = DF_RFC977.parse(dateStringBuffer.toString()); if ( utc ) { dt = new Date(dt.getTime()+UTC_OFFSET); } return dt; } catch ( ParseException pe ) { StringBuffer exceptionBuffer = new StringBuffer(128) .append("Date extraction failed: ") .append(date) .append(",") .append(time) .append(",") .append(utc); throw new NNTPException(exceptionBuffer.toString()); } } /** * Returns the list of articles that match the range. * * A precondition of this method is that the selected * group be non-null. The current article pointer must * be valid if no range is explicitly provided. * * @return null indicates insufficient information to * fetch the list of articles */ private NNTPArticle[] getRange(String range) { // check for msg id if ( isMessageId(range)) { NNTPArticle article = theConfigData.getNNTPRepository().getArticleFromID(range); return ( article == null ) ? new NNTPArticle[0] : new NNTPArticle[] { article }; } if ( range == null ) { range = "" + currentArticleNumber; } int start = -1; int end = -1; int idx = range.indexOf('-'); if ( idx == -1 ) { start = Integer.parseInt(range); end = start; } else { start = Integer.parseInt(range.substring(0,idx)); if ( (idx + 1) == range.length() ) { end = group.getLastArticleNumber(); } else { end = Integer.parseInt(range.substring(idx + 1)); } } List list = new ArrayList(); for ( int i = start ; i <= end ; i++ ) { NNTPArticle article = group.getArticle(i); if ( article != null ) { list.add(article); } } return (NNTPArticle[])list.toArray(new NNTPArticle[0]); } /** * Return whether the user associated with the connection (possibly no * user) is authorized to execute the command. * * @param the command being tested * @return whether the command is authorized */ private boolean isAuthorized(String command) { isAlreadyAuthenticated = isAlreadyAuthenticated || isAuthenticated(); if (isAlreadyAuthenticated) { return true; } // some commands are authorized, even if the user is not authenticated boolean allowed = command.equals("AUTHINFO"); allowed = allowed || command.equals("MODE"); allowed = allowed || command.equals("QUIT"); return allowed; } /** * Return whether the connection has been authenticated. * * @return whether the connection has been authenticated. */ private boolean isAuthenticated() { if ( theConfigData.isAuthRequired() ) { if ((user != null) && (password != null) && (theConfigData.getUsersRepository() != null)) { return theConfigData.getUsersRepository().test(user,password); } else { return false; } } else { return true; } } /** * Tests a string to see whether it is formatted as a message * ID. * * @param testString the string to test * * @return whether the string is a candidate message ID */ private static boolean isMessageId(String testString) { if ((testString != null) && (testString.startsWith("<")) && (testString.endsWith(">"))) { return true; } else { return false; } } /** * This method logs at a "DEBUG" level the response string that * was sent to the SMTP client. The method is provided largely * as syntactic sugar to neaten up the code base. It is declared * private and final to encourage compiler inlining. * * @param responseString the response string sent to the client */ private final void logResponseString(String responseString) { if (getLogger().isDebugEnabled()) { getLogger().debug("Sent: " + responseString); } } /** * Write and flush a response string. The response is also logged. * Should be used for the last line of a multi-line response or * for a single line response. * * @param responseString the response string sent to the client */ final void writeLoggedFlushedResponse(String responseString) { writer.println(responseString); writer.flush(); logResponseString(responseString); } /** * Write a response string. The response is also logged. * Used for multi-line responses. * * @param responseString the response string sent to the client */ final void writeLoggedResponse(String responseString) { writer.println(responseString); logResponseString(responseString); } /** * A private inner class which serves as an adaptor * between the WatchdogTarget interface and this * handler class. */ private class NNTPWatchdogTarget implements WatchdogTarget { /** * @see org.apache.james.util.watchdog.WatchdogTarget#execute() */ public void execute() { NNTPHandler.this.idleClose(); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -