diff -r 000000000000 -r f907866f0e4b trunk/com/so/news/command/PostCommand.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/trunk/com/so/news/command/PostCommand.java Tue Jan 20 10:21:03 2009 +0100 @@ -0,0 +1,166 @@ +/* + * StarOffice News Server + * see AUTHORS for the list of contributors + * + * 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 3 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, see . + */ + +package com.so.news.command; + +import java.io.IOException; +import java.sql.SQLException; +import java.util.Date; +import java.text.SimpleDateFormat; +import java.util.HashMap; +import java.util.Locale; + +import com.so.news.Config; +import com.so.news.Debug; +import com.so.news.NNTPConnection; +import com.so.news.storage.Article; +import com.so.news.storage.Database; + +/** + * Contains the code for the POST command. + * @author Christian Lins + * @author Dennis Schwerdel + */ +public class PostCommand extends Command +{ + public PostCommand(NNTPConnection conn) + { + super(conn); + } + + public boolean process(String[] command) throws IOException + { + printStatus(340, "send article to be posted. End with ."); + + // some initialization + Article article = new Article(); + int lineCount = 0; + long bodySize = 0; + long maxBodySize = Config.getInstance().get("n3tpd.article.maxsize", 1024) * 1024; // Size in bytes + + // begin with a stringbuilder body + StringBuilder body = new StringBuilder(); + HashMap header = new HashMap(); + + boolean isHeader = true; // are we in the header part + + String line = readTextLine(); + while(line != null) + { + bodySize += line.length(); + if(bodySize > maxBodySize) + { + printStatus(500, "article is too long"); + return false; + } + + if(!isHeader) + { // body + if(line.trim().equals(".")) + break; + + bodySize += line.length() + 1; + lineCount++; + body.append(line + NEWLINE); + } + + if(line.equals("")) + { + isHeader = false; // we finally met the blank line + // separating headers from body + } + + if(isHeader) + { // header + // split name and value and add the header to the map + int colon = line.indexOf(':'); + String fieldName = line.substring(0, colon).trim(); + String fieldValue = line.substring(colon + 1).trim(); + header.put(fieldName, fieldValue); + } + line = readTextLine(); // read a new line + } // end of input reading + + article.setBody(body.toString()); // set the article body + article.setHeader(header); // add the header entries for the article + + // Read the date header and fall back to the current date if it is not set + try + { + SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z", Locale.US); + String date = header.get("DATE"); + if(date == null) + article.setDate(new Date()); + else + article.setDate(new Date(sdf.parse(date).getTime())) ; + } + catch (Exception e) + { + e.printStackTrace(Debug.getInstance().getStream()); + printStatus(541, "posting failed - invalid date format"); + return true; + } + + // check for a cancel command + if ( header.containsKey("Control") ) + { + String[] control = header.get("Control").split(" ") ; + if ( control.length >= 2 && control[0].equalsIgnoreCase("cancel") ) + { + // this article is a cancel-article, try to delete the old article + try + { + Article.getByMessageID(control[1]).delete(); + printStatus(240, "article posted ok - original article canceled"); // quite + return true; // quit, do not actually post this article since it + } + catch (Exception e) + { + e.printStackTrace(); + printStatus(441, "posting failed - original posting not found"); + return true; + } + } + } + + // set some headers + header.put("Message-ID", article.getMessageID()); + header.put("Lines", "" + lineCount); + header.put("Bytes", "" + bodySize); + + // if needed, set an empty references header, that means this is + // a initial posting + if (!header.containsKey("References")) + header.put("References", ""); + + // try to create the article in the database + try + { + Database.getInstance().addArticle(article); + printStatus(240, "article posted ok"); + } + catch(SQLException ex) + { + System.err.println(ex.getLocalizedMessage()); + ex.printStackTrace(Debug.getInstance().getStream()); + printStatus(500, "internal server error"); + } + + return true; + } +}