Mercurial Hosting > nabble
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"); + } + } + +}