* SusiMail:

- Add raw attachment download method
   - Display image attachments inline
   - Don't rezip certain attachment types, just offer link
   - Handle attachment sending directly, don't put ref in session
This commit is contained in:
zzz
2014-04-25 13:04:04 +00:00
parent 05236b093a
commit 75bd235eb2

View File

@@ -119,6 +119,7 @@ public class WebMail extends HttpServlet
private static final String REALLYDELETE = "really_delete"; private static final String REALLYDELETE = "really_delete";
private static final String SHOW = "show"; private static final String SHOW = "show";
private static final String DOWNLOAD = "download"; private static final String DOWNLOAD = "download";
private static final String RAW_ATTACHMENT = "att";
private static final String MARKALL = "markall"; private static final String MARKALL = "markall";
private static final String CLEAR = "clearselection"; private static final String CLEAR = "clearselection";
@@ -358,7 +359,6 @@ public class WebMail extends HttpServlet
String user, pass, host, error, info; String user, pass, host, error, info;
String replyTo, replyCC; String replyTo, replyCC;
String subject, body, showUIDL; String subject, body, showUIDL;
public MailPart showAttachment;
public String sentMail; public String sentMail;
public ArrayList<Attachment> attachments; public ArrayList<Attachment> attachments;
public boolean reallyDelete; public boolean reallyDelete;
@@ -480,7 +480,7 @@ public class WebMail extends HttpServlet
if( html ) { if( html ) {
out.println( "<!-- " ); out.println( "<!-- " );
out.println( "Debug: Mail Part headers follow");
for( int i = 0; i < mailPart.headerLines.length; i++ ) { for( int i = 0; i < mailPart.headerLines.length; i++ ) {
// fix Content-Type: multipart/alternative; boundary="----------8CDE39ECAF2633" // fix Content-Type: multipart/alternative; boundary="----------8CDE39ECAF2633"
out.println( mailPart.headerLines[i].replace("--", "&mdash;") ); out.println( mailPart.headerLines[i].replace("--", "&mdash;") );
@@ -579,11 +579,27 @@ public class WebMail extends HttpServlet
} }
if( prepareAttachment ) { if( prepareAttachment ) {
if( html ) { if( html ) {
// TODO can we at least show images safely?
out.println( "<hr><p class=\"mailbody\">" ); out.println( "<hr><p class=\"mailbody\">" );
String type = mailPart.type;
if (type != null && type.startsWith("image/")) {
// we at least show images safely...
out.println("<img src=\"" + myself + "?" + RAW_ATTACHMENT + "=" +
mailPart.hashCode() + "\">");
} else if (type != null && (
// type list from snark
type.startsWith("audio/") || type.equals("application/ogg") ||
type.startsWith("video/") ||
type.equals("application/zip") || type.equals("application/x-gtar") ||
type.equals("application/compress") || type.equals("application/gzip") ||
type.equals("application/x-7z-compressed") || type.equals("application/x-rar-compressed") ||
type.equals("application/x-tar") || type.equals("application/x-bzip2"))) {
out.println( "<a href=\"" + myself + "?" + RAW_ATTACHMENT + "=" +
mailPart.hashCode() + "\">" + _("Download attachment {0}", ident) + "</a>");
} else {
out.println( "<a target=\"_blank\" href=\"" + myself + "?" + DOWNLOAD + "=" + out.println( "<a target=\"_blank\" href=\"" + myself + "?" + DOWNLOAD + "=" +
mailPart.hashCode() + "\">" + _("Download attachment {0}", ident) + "</a>" + mailPart.hashCode() + "\">" + _("Download attachment {0}", ident) + "</a>" +
" (" + _("File is packed into a zipfile for security reasons.") + ')'); " (" + _("File is packed into a zipfile for security reasons.") + ')');
}
out.println( "</p>" ); out.println( "</p>" );
} }
else { else {
@@ -1135,6 +1151,7 @@ public class WebMail extends HttpServlet
} }
} }
} }
/** /**
* process buttons of message view * process buttons of message view
* @param sessionObject * @param sessionObject
@@ -1175,21 +1192,43 @@ public class WebMail extends HttpServlet
sessionObject.folder.removeElement(sessionObject.showUIDL); sessionObject.folder.removeElement(sessionObject.showUIDL);
sessionObject.showUIDL = nextUIDL; sessionObject.showUIDL = nextUIDL;
} }
}
String str = request.getParameter( DOWNLOAD ); /**
* process download link in message view
* @param sessionObject
* @param request
* @return If true, we sent an attachment or 404, do not send any other response
*/
private static boolean processDownloadLink(SessionObject sessionObject, RequestWrapper request, HttpServletResponse response)
{
String str = request.getParameter(DOWNLOAD);
boolean isRaw = false;
if (str == null) {
str = request.getParameter(RAW_ATTACHMENT);
isRaw = str != null;
}
if( str != null ) { if( str != null ) {
try { try {
int hashCode = Integer.parseInt( str ); int hashCode = Integer.parseInt( str );
Mail mail = sessionObject.mailCache.getMail( sessionObject.showUIDL, MailCache.FETCH_ALL ); Mail mail = sessionObject.mailCache.getMail( sessionObject.showUIDL, MailCache.FETCH_ALL );
MailPart part = mail != null ? getMailPartFromHashCode( mail.getPart(), hashCode ) : null; MailPart part = mail != null ? getMailPartFromHashCode( mail.getPart(), hashCode ) : null;
if( part != null ) if( part != null ) {
sessionObject.showAttachment = part; if (sendAttachment(sessionObject, part, response, isRaw))
return true;
} }
catch( NumberFormatException nfe ) { } catch( NumberFormatException nfe ) {}
sessionObject.error += _("Error parsing download parameter."); // error if we get here
sessionObject.error += _("Attachment not found.");
if (isRaw) {
try {
response.sendError(404, _("Attachment not found."));
} catch (IOException ioe) {}
} }
} }
return isRaw;
} }
/** /**
* @param hashCode * @param hashCode
* @return the part or null * @return the part or null
@@ -1418,7 +1457,6 @@ public class WebMail extends HttpServlet
sessionObject.error = ""; sessionObject.error = "";
sessionObject.info = ""; sessionObject.info = "";
sessionObject.pageChanged = false; sessionObject.pageChanged = false;
sessionObject.showAttachment = null;
sessionObject.themePath = "/themes/susimail/" + theme + '/'; sessionObject.themePath = "/themes/susimail/" + theme + '/';
sessionObject.imgPath = sessionObject.themePath + "images/"; sessionObject.imgPath = sessionObject.themePath + "images/";
sessionObject.isMobile = isMobile; sessionObject.isMobile = isMobile;
@@ -1463,6 +1501,12 @@ public class WebMail extends HttpServlet
if( sessionObject.state == STATE_SHOW ) { if( sessionObject.state == STATE_SHOW ) {
if (isPOST) if (isPOST)
processMessageButtons( sessionObject, request ); processMessageButtons( sessionObject, request );
// ?download=nnn link should be valid in any state
// but depends on current UIDL
if (processDownloadLink(sessionObject, request, response)) {
// download or raw view sent, or 404
return;
}
// If the last message has just been deleted then // If the last message has just been deleted then
// sessionObject.state = STATE_LIST and // sessionObject.state = STATE_LIST and
// sessionObject.showUIDL = null // sessionObject.showUIDL = null
@@ -1487,7 +1531,6 @@ public class WebMail extends HttpServlet
} }
} }
if( ! sendAttachment( sessionObject, response ) ) {
PrintWriter out = response.getWriter(); PrintWriter out = response.getWriter();
/* /*
@@ -1560,19 +1603,18 @@ public class WebMail extends HttpServlet
out.flush(); out.flush();
} }
} }
}
/** /**
* @param sessionObject * @param sessionObject
* @param response * @param response
* @param isRaw if true, don't zip it
* @return success * @return success
*/ */
private static boolean sendAttachment(SessionObject sessionObject, HttpServletResponse response) private static boolean sendAttachment(SessionObject sessionObject, MailPart part,
HttpServletResponse response, boolean isRaw)
{ {
boolean shown = false; boolean shown = false;
if( sessionObject.showAttachment != null ) { if(part != null) {
MailPart part = sessionObject.showAttachment;
ReadBuffer content = part.buffer; ReadBuffer content = part.buffer;
if( part.encoding != null ) { if( part.encoding != null ) {
@@ -1585,7 +1627,20 @@ public class WebMail extends HttpServlet
content = null; content = null;
} }
} }
if( content != null ) { if(content == null)
return false;
if (isRaw) {
try {
if (part.type != null)
response.setContentType(part.type);
response.setContentLength(content.length);
// cache-control?
response.getOutputStream().write(content.content, content.offset, content.length);
shown = true;
} catch (IOException e) {
e.printStackTrace();
}
} else {
ZipOutputStream zip = null; ZipOutputStream zip = null;
try { try {
zip = new ZipOutputStream( response.getOutputStream() ); zip = new ZipOutputStream( response.getOutputStream() );
@@ -2006,6 +2061,7 @@ public class WebMail extends HttpServlet
Mail mail = sessionObject.mailCache.getMail( sessionObject.showUIDL, MailCache.FETCH_ALL ); Mail mail = sessionObject.mailCache.getMail( sessionObject.showUIDL, MailCache.FETCH_ALL );
if(!RELEASE && mail != null && mail.hasBody()) { if(!RELEASE && mail != null && mail.hasBody()) {
out.println( "<!--" ); out.println( "<!--" );
out.println( "Debug: Mail header and body follow");
// FIXME encoding, escaping --, etc... but disabled. // FIXME encoding, escaping --, etc... but disabled.
ReadBuffer body = mail.getBody(); ReadBuffer body = mail.getBody();
out.println( quoteHTML( new String(body.content, body.offset, body.length ) ) ); out.println( quoteHTML( new String(body.content, body.offset, body.length ) ) );
@@ -2071,7 +2127,7 @@ public class WebMail extends HttpServlet
* Get all themes * Get all themes
* @return String[] -- Array of all the themes found. * @return String[] -- Array of all the themes found.
*/ */
public String[] getThemes() { private static String[] getThemes() {
String[] themes = null; String[] themes = null;
// "docs/themes/susimail/" // "docs/themes/susimail/"
File dir = new File(I2PAppContext.getGlobalContext().getBaseDir(), "docs/themes/susimail"); File dir = new File(I2PAppContext.getGlobalContext().getBaseDir(), "docs/themes/susimail");