org/sonews/util/io/ArticleWriter.java
author cli
Fri, 25 Dec 2009 15:42:46 +0100
changeset 25 dd05c3f2fa24
parent 18 7e527fdf0fa8
permissions -rw-r--r--
Fix for too early disconnects on slow client connections. (#563)
     1 /*
     2  *   SONEWS News Server
     3  *   see AUTHORS for the list of contributors
     4  *
     5  *   This program is free software: you can redistribute it and/or modify
     6  *   it under the terms of the GNU General Public License as published by
     7  *   the Free Software Foundation, either version 3 of the License, or
     8  *   (at your option) any later version.
     9  *
    10  *   This program is distributed in the hope that it will be useful,
    11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13  *   GNU General Public License for more details.
    14  *
    15  *   You should have received a copy of the GNU General Public License
    16  *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
    17  */
    18 
    19 package org.sonews.util.io;
    20 
    21 import java.io.BufferedOutputStream;
    22 import java.io.BufferedReader;
    23 import java.io.IOException;
    24 import java.io.InputStreamReader;
    25 import java.io.UnsupportedEncodingException;
    26 import java.net.Socket;
    27 import java.net.UnknownHostException;
    28 import org.sonews.storage.Article;
    29 
    30 /**
    31  * Posts an Article to a NNTP server using the POST command.
    32  * @author Christian Lins
    33  * @since sonews/0.5.0
    34  */
    35 public class ArticleWriter 
    36 {
    37   
    38   private BufferedOutputStream out;
    39   private BufferedReader       inr;
    40 
    41   public ArticleWriter(String host, int port)
    42     throws IOException, UnknownHostException
    43   {
    44     // Connect to NNTP server
    45     Socket socket = new Socket(host, port);
    46     this.out = new BufferedOutputStream(socket.getOutputStream());
    47     this.inr = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    48     String line = inr.readLine();
    49     if(line == null || !line.startsWith("200 "))
    50     {
    51       throw new IOException("Invalid hello from server: " + line);
    52     }
    53   }
    54   
    55   public void close()
    56     throws IOException, UnsupportedEncodingException
    57   {
    58     this.out.write("QUIT\r\n".getBytes("UTF-8"));
    59     this.out.flush();
    60   }
    61 
    62   protected void finishPOST()
    63     throws IOException
    64   {
    65     this.out.write("\r\n.\r\n".getBytes());
    66     this.out.flush();
    67     String line = inr.readLine();
    68     if(line == null || !line.startsWith("240 ") || !line.startsWith("441 "))
    69     {
    70       throw new IOException(line);
    71     }
    72   }
    73 
    74   protected void preparePOST()
    75     throws IOException
    76   {
    77     this.out.write("POST\r\n".getBytes("UTF-8"));
    78     this.out.flush();
    79 
    80     String line = this.inr.readLine();
    81     if(line == null || !line.startsWith("340 "))
    82     {
    83       throw new IOException(line);
    84     }
    85   }
    86 
    87   public void writeArticle(Article article)
    88     throws IOException, UnsupportedEncodingException
    89   {
    90     byte[] buf = new byte[512];
    91     ArticleInputStream in = new ArticleInputStream(article);
    92 
    93     preparePOST();
    94     
    95     int len = in.read(buf);
    96     while(len != -1)
    97     {
    98       writeLine(buf, len);
    99       len = in.read(buf);
   100     }
   101 
   102     finishPOST();
   103   }
   104 
   105   /**
   106    * Writes the raw content of an article to the remote server. This method
   107    * does no charset conversion/handling of any kind so its the preferred
   108    * method for sending an article to remote peers.
   109    * @param rawArticle
   110    * @throws IOException
   111    */
   112   public void writeArticle(byte[] rawArticle)
   113     throws IOException
   114   {
   115     preparePOST();
   116     writeLine(rawArticle, rawArticle.length);
   117     finishPOST();
   118   }
   119 
   120   /**
   121    * Writes the given buffer to the connect remote server.
   122    * @param buffer
   123    * @param len
   124    * @throws IOException
   125    */
   126   protected void writeLine(byte[] buffer, int len)
   127     throws IOException
   128   {
   129     this.out.write(buffer, 0, len);
   130     this.out.flush();
   131   }
   132 
   133 }