Mercurial Hosting > nabble
view src/nabble/view/web/forum/FileDownload.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 source
package nabble.view.web.forum; import fschmidt.util.java.HtmlUtils; import fschmidt.util.java.IoUtils; import fschmidt.util.servlet.AuthorizingServlet; import fschmidt.util.servlet.JtpContext; import nabble.model.FileUpload; import nabble.model.Message; 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.Enumeration; import java.util.HashMap; import java.util.LinkedHashSet; import java.util.Map; import java.util.ResourceBundle; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; public final class FileDownload extends HttpServlet implements UrlMappable, AuthorizingServlet { private static final Pattern urlPtn = Pattern.compile("/file/(([a-z])(\\d+)/)?([^/]*)$"); public static String url(String filename,Message.Source src) { return baseUrl(src) + path(filename,src); } public static String path(String filename,Message.Source src) { StringBuilder buf = new StringBuilder(); buf.append( "/file/" ); if (!src.getMessageSourceType().equals(Message.SourceType.SITE)) { buf.append( src.getMessageSourceType().getCode() ); buf.append( src.getSourceId() ); buf.append( "/" ); } buf.append( HtmlUtils.urlEncode(filename) ); return buf.toString(); } private static String baseUrl(Message.Source src) { return src.getSite().getBaseUrl(); } 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[]>(); if (m.group(1) == null) params.put("type",new String[]{String.valueOf(Message.SourceType.SITE.getCode())}); else { String type = m.group(2); params.put("type",new String[]{type}); String fileId = m.group(3); params.put("id",new String[]{fileId}); } String name = m.group(4); params.put("name",new String[]{name}); return params; } public Pattern getUrlPattern() { return urlPtn; } public String getAuthorizationKey(HttpServletRequest request) throws ServletException { Message.Source src = getSource(request); return src instanceof Node ? Jtp.getReadAuthorizationKey((Node)src) : null; } public boolean authorize(String key,HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { return Jtp.authorizeForRead(key,request,response); } private static final Map<String,String> mimeMap = new HashMap<String,String>(); static { ResourceBundle mime = ResourceBundle.getBundle("org/eclipse/jetty/http/mime"); Enumeration<String> i = mime.getKeys(); while( i.hasMoreElements() ) { String ext = i.nextElement(); String type = mime.getString(ext); mimeMap.put(ext.toLowerCase(),type); } } static String getMimeByExtension(String fileName) { return mimeMap.get( fileName.substring(fileName.lastIndexOf('.')+1).toLowerCase() ); } protected void service(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { JtpContext jtpContext = (JtpContext)getServletContext().getAttribute(JtpContext.attrName); char type = request.getParameter("type").charAt(0); Message.Source src = getSource(request); if (src == null) { response.sendError(HttpServletResponse.SC_NOT_FOUND,"File not found"); return; } switch(type) { case 't': break; case 's': jtpContext.setEtag(request,response, Cache.siteChangeEvent(src.getSite()) ); break; case 'n': { Set<String> events = new LinkedHashSet<String>(); if( src instanceof Node ) { Node node = (Node)src; events.add( Cache.nodeFileChangeEvent(node) ); Jtp.addBreadCrumbEvents(events, node); } jtpContext.setEtag(request,response, events.toArray(new String[events.size()]) ); } break; case 'a': jtpContext.setEtag(request,response, Cache.userFileChangeEvent(((Message.AvatarSource)src).getUser()) ); break; default: if( Jtp.invalidReferer(request) ) { throw new ServletException("type = '"+type+"'"); } else { throw new RuntimeException("type = '"+type+"'"); } } response.setHeader("Cache-Control",null); String name = request.getParameter("name"); InputStream in = FileUpload.getFileContent(src,name); if (in == null) { name = HtmlUtils.urlDecode(name); in = FileUpload.getFileContent(src, name); if (in == null) { // We have to find a better way to track this down -- the log is too full of missing images [Hugo/Jun-2010] response.sendError(HttpServletResponse.SC_NOT_FOUND,"File not found"); return; } } OutputStream out = response.getOutputStream(); response.setContentType(getMimeByExtension(name)); try { IoUtils.copyAll(in,out); } finally { in.close(); } } private static Message.Source getSource(HttpServletRequest request) throws ServletException { char type = request.getParameter("type").charAt(0); Message.SourceType sourceType = Message.SourceType.getType(type); if( sourceType==null ) return null; Site site = Jtp.getSite(request); if (site == null) return null; if (sourceType.equals(Message.SourceType.SITE)) return site; long fileId = Jtp.getLong(request,"id"); return sourceType.getSource(site,fileId); } }