Article(javax.mail.Message) now has a safe method to read the byte body from the given message object (fixes #16).
authorcli
Sun, 29 Aug 2010 17:03:21 +0200
changeset 33f9bf183447d1
parent 31 087ef6fe6a1a
child 34 9f0b95aafaa3
Article(javax.mail.Message) now has a safe method to read the byte body from the given message object (fixes #16).
AUTHORS
org/sonews/storage/Article.java
     1.1 --- a/AUTHORS	Wed May 12 11:18:02 2010 +0200
     1.2 +++ b/AUTHORS	Sun Aug 29 17:03:21 2010 +0200
     1.3 @@ -7,9 +7,13 @@
     1.4  
     1.5  sonews News Server
     1.6  -------------------
     1.7 -Copyright (c) 2009 by Christian Lins <christian.lins@fh-osnabrueck.de>
     1.8 +Copyright (c) 2009, 2010 by
     1.9  
    1.10 -based partly upon
    1.11 +Christian Lins <christian.lins@fh-osnabrueck.de>
    1.12 +Bernd Eilers <bernd.eilers@sun.com>
    1.13 +
    1.14 +
    1.15 +sonews based partly upon
    1.16  
    1.17  Neat NNTP Daemon (n3tpd)
    1.18  ------------------------
     2.1 --- a/org/sonews/storage/Article.java	Wed May 12 11:18:02 2010 +0200
     2.2 +++ b/org/sonews/storage/Article.java	Sun Aug 29 17:03:21 2010 +0200
     2.3 @@ -21,8 +21,6 @@
     2.4  import java.io.ByteArrayInputStream;
     2.5  import java.io.ByteArrayOutputStream;
     2.6  import java.io.IOException;
     2.7 -import java.io.InputStream;
     2.8 -import java.nio.charset.Charset;
     2.9  import java.security.MessageDigest;
    2.10  import java.security.NoSuchAlgorithmException;
    2.11  import java.util.UUID;
    2.12 @@ -32,10 +30,8 @@
    2.13  import javax.mail.Header;
    2.14  import javax.mail.Message;
    2.15  import javax.mail.MessagingException;
    2.16 -import javax.mail.Multipart;
    2.17  import javax.mail.internet.InternetHeaders;
    2.18  import org.sonews.config.Config;
    2.19 -import org.sonews.util.Log;
    2.20  
    2.21  /**
    2.22   * Represents a newsgroup article.
    2.23 @@ -97,7 +93,7 @@
    2.24  
    2.25    /**
    2.26     * Creates an Article instance using the data from the javax.mail.Message
    2.27 -   * object.
    2.28 +   * object. This constructor is called by the Mailinglist gateway.
    2.29     * @see javax.mail.Message
    2.30     * @param msg
    2.31     * @throws IOException
    2.32 @@ -113,61 +109,25 @@
    2.33        final Header header = (Header)e.nextElement();
    2.34        this.headers.addHeader(header.getName(), header.getValue());
    2.35      }
    2.36 -    
    2.37 -    // The "content" of the message can be a String if it's a simple text/plain
    2.38 -    // message, a Multipart object or an InputStream if the content is unknown.
    2.39 -    final Object content = msg.getContent();
    2.40 -    if(content instanceof String)
    2.41 -    {
    2.42 -      this.body = ((String)content).getBytes(getBodyCharset());
    2.43 -    }
    2.44 -    else if(content instanceof Multipart) // probably subclass MimeMultipart
    2.45 -    {
    2.46 -      // We're are not interested in the different parts of the MultipartMessage,
    2.47 -      // so we simply read in all data which *can* be huge.
    2.48 -      InputStream in = msg.getInputStream();
    2.49 -      this.body = readContent(in);
    2.50 -    }
    2.51 -    else if(content instanceof InputStream)
    2.52 -    {
    2.53 -      // The message format is unknown to the Message class, but we can
    2.54 -      // simply read in the whole message data.
    2.55 -      this.body = readContent((InputStream)content);
    2.56 -    }
    2.57 -    else
    2.58 -    {
    2.59 -      // Unknown content is probably a malformed mail we should skip.
    2.60 -      // On the other hand we produce an inconsistent mail mirror, but no
    2.61 -      // mail system must transport invalid content.
    2.62 -      Log.get().severe("Skipping message due to unknown content. Throwing exception...");
    2.63 -      MessagingException ex = new MessagingException("Unknown content: " + content);
    2.64 -      Log.get().throwing("Article.java", "<init>", ex);
    2.65 -      throw ex;
    2.66 -    }
    2.67 +
    2.68 +	// Reads the raw byte body using Message.writeTo(OutputStream out)
    2.69 +	this.body = readContent(msg);
    2.70      
    2.71      // Validate headers
    2.72      validateHeaders();
    2.73    }
    2.74  
    2.75    /**
    2.76 -   * Reads from the given InputString into a byte array.
    2.77 -   * TODO: Move this generalized method to org.sonews.util.io.Resource.
    2.78 +   * Reads from the given Message into a byte array.
    2.79     * @param in
    2.80     * @return
    2.81     * @throws IOException
    2.82     */
    2.83 -  private byte[] readContent(InputStream in)
    2.84 -    throws IOException
    2.85 +  private byte[] readContent(Message in)
    2.86 +    throws IOException, MessagingException
    2.87    {
    2.88      ByteArrayOutputStream out = new ByteArrayOutputStream();
    2.89 -
    2.90 -    int b = in.read();
    2.91 -    while(b >= 0)
    2.92 -    {
    2.93 -      out.write(b);
    2.94 -      b = in.read();
    2.95 -    }
    2.96 -
    2.97 +    in.writeTo(out);
    2.98      return out.toByteArray();
    2.99    }
   2.100  
   2.101 @@ -226,51 +186,6 @@
   2.102    {
   2.103      return body;
   2.104    }
   2.105 -
   2.106 -  /**
   2.107 -   * @return Charset of the body text
   2.108 -   */
   2.109 -  private Charset getBodyCharset()
   2.110 -  {
   2.111 -    // We espect something like 
   2.112 -    // Content-Type: text/plain; charset=ISO-8859-15
   2.113 -    String contentType = getHeader(Headers.CONTENT_TYPE)[0];
   2.114 -    int idxCharsetStart = contentType.indexOf("charset=") + "charset=".length();
   2.115 -    int idxCharsetEnd   = contentType.indexOf(";", idxCharsetStart);
   2.116 -    
   2.117 -    String charsetName = "UTF-8";
   2.118 -    if(idxCharsetStart >= 0 && idxCharsetStart < contentType.length())
   2.119 -    {
   2.120 -      if(idxCharsetEnd < 0)
   2.121 -      {
   2.122 -        charsetName = contentType.substring(idxCharsetStart);
   2.123 -      }
   2.124 -      else
   2.125 -      {
   2.126 -        charsetName = contentType.substring(idxCharsetStart, idxCharsetEnd);
   2.127 -      }
   2.128 -    }
   2.129 -    
   2.130 -    // Sometimes there are '"' around the name
   2.131 -    if(charsetName.length() > 2 &&
   2.132 -      charsetName.charAt(0) == '"' && charsetName.endsWith("\""))
   2.133 -    {
   2.134 -      charsetName = charsetName.substring(1, charsetName.length() - 2);
   2.135 -    }
   2.136 -    
   2.137 -    // Create charset
   2.138 -    Charset charset = Charset.forName("UTF-8"); // This MUST be supported by JVM
   2.139 -    try
   2.140 -    {
   2.141 -      charset = Charset.forName(charsetName);
   2.142 -    }
   2.143 -    catch(Exception ex)
   2.144 -    {
   2.145 -      Log.get().severe(ex.getMessage());
   2.146 -      Log.get().severe("Article.getBodyCharset(): Unknown charset: " + charsetName);
   2.147 -    }
   2.148 -    return charset;
   2.149 -  }
   2.150    
   2.151    /**
   2.152     * @return Numerical IDs of the newsgroups this Article belongs to.