diff src/nabble/view/web/forum/AttachmentDownload.java @ 0:7ecd1a4ef557

add content
author Franklin Schmidt <fschmidt@gmail.com>
date Thu, 21 Mar 2019 19:15:52 -0600
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/nabble/view/web/forum/AttachmentDownload.java	Thu Mar 21 19:15:52 2019 -0600
@@ -0,0 +1,120 @@
+package nabble.view.web.forum;
+
+import fschmidt.util.java.IoUtils;
+import fschmidt.util.servlet.AuthorizingServlet;
+import fschmidt.util.servlet.JtpContext;
+import fschmidt.util.servlet.CanonicalUrl;
+import nabble.model.MailMessageFormat;
+import nabble.model.Message;
+import nabble.model.ModelHome;
+import nabble.model.Node;
+import nabble.model.Site;
+import nabble.view.lib.Cache;
+import nabble.view.lib.Jtp;
+import nabble.view.lib.UrlMappable;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+
+public final class AttachmentDownload extends HttpServlet implements UrlMappable, AuthorizingServlet, CanonicalUrl {
+	private static final Pattern urlPtn = Pattern.compile("/attachment/(\\d+)/(\\d+)/(.*)$");
+
+	private static String url(Site site,String postId,String attachmentId,String name) {
+		return site.getBaseUrl()
+				+ path(postId,attachmentId,name);
+	}
+
+	private static String path(String postId,String attachmentId,String name) {
+		StringBuilder buf = new StringBuilder();
+		buf.append( "/attachment/" );
+		buf.append( postId );
+		buf.append( "/" );
+		buf.append( attachmentId );
+		buf.append( "/" );
+		buf.append( name );
+		return buf.toString();
+	}
+
+	public String getCanonicalUrl(HttpServletRequest request) {
+		Site site = Jtp.getSite(request);
+		if( site == null )
+			return null;
+		String postId = request.getParameter("post");
+		String attachmentId = request.getParameter("attachment");
+		String name = request.getParameter("name");
+		return url(site,postId,attachmentId,name);
+	}
+
+	public Map<String,String[]> getParameterMapFromUrl(HttpServletRequest request,String mappedUrl) {
+		Matcher m = urlPtn.matcher(mappedUrl);
+		if( !m.find() )
+			throw new RuntimeException();
+		Map<String,String[]> params = new HashMap<String,String[]>();
+		String postId = m.group(1);
+		params.put("post",new String[]{postId});
+		String attachmentId = m.group(2);
+		params.put("attachment",new String[]{attachmentId});
+		String name = m.group(3);
+		params.put("name",new String[]{name});
+		return params;
+	}
+
+	public Pattern getUrlPattern() {
+		return urlPtn;
+	}
+
+	public String getAuthorizationKey(HttpServletRequest request) throws ServletException {
+		return Jtp.getReadAuthorizationKey( Jtp.getSiteNotNull(request).getNode(Jtp.getLong(request,"post")) );
+	}
+
+	public boolean authorize(String key,HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
+		return Jtp.authorizeForRead(key,request,response); 
+	}
+
+	protected void service(HttpServletRequest request,HttpServletResponse response)
+		throws ServletException, IOException
+	{
+		OutputStream out = response.getOutputStream();
+		long postId = Long.parseLong( request.getParameter("post") );
+		int attachmentId = Integer.parseInt( request.getParameter("attachment") );
+		String name = request.getParameter("name");
+		String contentType = FileDownload.getMimeByExtension(name);
+		if (contentType==null /*|| !contentType.startsWith("image")*/) {
+			contentType = "application/x-download";
+			response.setHeader("content-disposition", "attachment; filename=\""+name+"\"");
+		}
+		response.setContentType(contentType);
+		Node post = Jtp.getSiteNotNull(request).getNode(postId);
+		if( post==null ) {
+			response.sendError(HttpServletResponse.SC_GONE,"This post has been deleted.");
+			return;
+		}
+		JtpContext jtpContext = (JtpContext)getServletContext().getAttribute(JtpContext.attrName);
+		jtpContext.setEtag(request,response, Cache.nodeChangeEvent(post) );
+		// If the user edits a mail message, we convert it into a HTML/TEXT format.
+		// After this change all attachments are lost because we lose the RAW email where
+		// the file was encoded. So we should return "404 Not Found" in such cases.
+		Message.Format fmt = post.getMessage().getFormat();
+		if (fmt instanceof MailMessageFormat) {
+			InputStream in = ((MailMessageFormat) fmt).getAttachment(post,attachmentId);
+			try {
+				IoUtils.copyAll(in,out);
+			} finally {
+				in.close();
+			}
+		} else {
+			response.sendError(HttpServletResponse.SC_NOT_FOUND, "File not found");
+		}
+	}
+
+}