Mercurial Hosting > nabble
comparison 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 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:7ecd1a4ef557 |
---|---|
1 package nabble.view.web.forum; | |
2 | |
3 import fschmidt.util.java.HtmlUtils; | |
4 import fschmidt.util.java.IoUtils; | |
5 import fschmidt.util.servlet.AuthorizingServlet; | |
6 import fschmidt.util.servlet.JtpContext; | |
7 import nabble.model.FileUpload; | |
8 import nabble.model.Message; | |
9 import nabble.model.Node; | |
10 import nabble.model.Site; | |
11 import nabble.view.lib.Cache; | |
12 import nabble.view.lib.Jtp; | |
13 import nabble.view.lib.UrlMappable; | |
14 | |
15 import javax.servlet.ServletException; | |
16 import javax.servlet.http.HttpServlet; | |
17 import javax.servlet.http.HttpServletRequest; | |
18 import javax.servlet.http.HttpServletResponse; | |
19 import java.io.IOException; | |
20 import java.io.InputStream; | |
21 import java.io.OutputStream; | |
22 import java.util.Enumeration; | |
23 import java.util.HashMap; | |
24 import java.util.LinkedHashSet; | |
25 import java.util.Map; | |
26 import java.util.ResourceBundle; | |
27 import java.util.Set; | |
28 import java.util.regex.Matcher; | |
29 import java.util.regex.Pattern; | |
30 | |
31 | |
32 public final class FileDownload extends HttpServlet implements UrlMappable, AuthorizingServlet { | |
33 | |
34 private static final Pattern urlPtn = Pattern.compile("/file/(([a-z])(\\d+)/)?([^/]*)$"); | |
35 | |
36 public static String url(String filename,Message.Source src) { | |
37 return baseUrl(src) + path(filename,src); | |
38 } | |
39 | |
40 public static String path(String filename,Message.Source src) { | |
41 StringBuilder buf = new StringBuilder(); | |
42 buf.append( "/file/" ); | |
43 if (!src.getMessageSourceType().equals(Message.SourceType.SITE)) { | |
44 buf.append( src.getMessageSourceType().getCode() ); | |
45 buf.append( src.getSourceId() ); | |
46 buf.append( "/" ); | |
47 } | |
48 buf.append( HtmlUtils.urlEncode(filename) ); | |
49 return buf.toString(); | |
50 } | |
51 | |
52 private static String baseUrl(Message.Source src) { | |
53 return src.getSite().getBaseUrl(); | |
54 } | |
55 | |
56 public Map<String,String[]> getParameterMapFromUrl(HttpServletRequest request,String mappedUrl) { | |
57 Matcher m = urlPtn.matcher(mappedUrl); | |
58 if( !m.find() ) | |
59 throw new RuntimeException(); | |
60 Map<String,String[]> params = new HashMap<String,String[]>(); | |
61 if (m.group(1) == null) | |
62 params.put("type",new String[]{String.valueOf(Message.SourceType.SITE.getCode())}); | |
63 else { | |
64 String type = m.group(2); | |
65 params.put("type",new String[]{type}); | |
66 String fileId = m.group(3); | |
67 params.put("id",new String[]{fileId}); | |
68 } | |
69 String name = m.group(4); | |
70 params.put("name",new String[]{name}); | |
71 return params; | |
72 } | |
73 | |
74 public Pattern getUrlPattern() { | |
75 return urlPtn; | |
76 } | |
77 | |
78 public String getAuthorizationKey(HttpServletRequest request) throws ServletException { | |
79 Message.Source src = getSource(request); | |
80 return src instanceof Node ? Jtp.getReadAuthorizationKey((Node)src) : null; | |
81 } | |
82 | |
83 public boolean authorize(String key,HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { | |
84 return Jtp.authorizeForRead(key,request,response); | |
85 } | |
86 | |
87 private static final Map<String,String> mimeMap = new HashMap<String,String>(); | |
88 static { | |
89 ResourceBundle mime = ResourceBundle.getBundle("org/eclipse/jetty/http/mime"); | |
90 Enumeration<String> i = mime.getKeys(); | |
91 while( i.hasMoreElements() ) { | |
92 String ext = i.nextElement(); | |
93 String type = mime.getString(ext); | |
94 mimeMap.put(ext.toLowerCase(),type); | |
95 } | |
96 } | |
97 | |
98 static String getMimeByExtension(String fileName) { | |
99 return mimeMap.get( fileName.substring(fileName.lastIndexOf('.')+1).toLowerCase() ); | |
100 } | |
101 | |
102 protected void service(HttpServletRequest request,HttpServletResponse response) | |
103 throws ServletException, IOException | |
104 { | |
105 JtpContext jtpContext = (JtpContext)getServletContext().getAttribute(JtpContext.attrName); | |
106 char type = request.getParameter("type").charAt(0); | |
107 Message.Source src = getSource(request); | |
108 if (src == null) { | |
109 response.sendError(HttpServletResponse.SC_NOT_FOUND,"File not found"); | |
110 return; | |
111 } | |
112 | |
113 switch(type) { | |
114 case 't': | |
115 break; | |
116 case 's': | |
117 jtpContext.setEtag(request,response, Cache.siteChangeEvent(src.getSite()) ); | |
118 break; | |
119 case 'n': | |
120 { | |
121 Set<String> events = new LinkedHashSet<String>(); | |
122 if( src instanceof Node ) { | |
123 Node node = (Node)src; | |
124 events.add( Cache.nodeFileChangeEvent(node) ); | |
125 Jtp.addBreadCrumbEvents(events, node); | |
126 } | |
127 jtpContext.setEtag(request,response, events.toArray(new String[events.size()]) ); | |
128 } | |
129 break; | |
130 case 'a': | |
131 jtpContext.setEtag(request,response, Cache.userFileChangeEvent(((Message.AvatarSource)src).getUser()) ); | |
132 break; | |
133 default: | |
134 if( Jtp.invalidReferer(request) ) { | |
135 throw new ServletException("type = '"+type+"'"); | |
136 } else { | |
137 throw new RuntimeException("type = '"+type+"'"); | |
138 } | |
139 } | |
140 | |
141 response.setHeader("Cache-Control",null); | |
142 String name = request.getParameter("name"); | |
143 | |
144 InputStream in = FileUpload.getFileContent(src,name); | |
145 if (in == null) { | |
146 name = HtmlUtils.urlDecode(name); | |
147 in = FileUpload.getFileContent(src, name); | |
148 if (in == null) { | |
149 // We have to find a better way to track this down -- the log is too full of missing images [Hugo/Jun-2010] | |
150 response.sendError(HttpServletResponse.SC_NOT_FOUND,"File not found"); | |
151 return; | |
152 } | |
153 } | |
154 OutputStream out = response.getOutputStream(); | |
155 response.setContentType(getMimeByExtension(name)); | |
156 try { | |
157 IoUtils.copyAll(in,out); | |
158 } finally { | |
159 in.close(); | |
160 } | |
161 } | |
162 | |
163 private static Message.Source getSource(HttpServletRequest request) | |
164 throws ServletException | |
165 { | |
166 char type = request.getParameter("type").charAt(0); | |
167 Message.SourceType sourceType = Message.SourceType.getType(type); | |
168 if( sourceType==null ) | |
169 return null; | |
170 Site site = Jtp.getSite(request); | |
171 if (site == null) | |
172 return null; | |
173 if (sourceType.equals(Message.SourceType.SITE)) | |
174 return site; | |
175 long fileId = Jtp.getLong(request,"id"); | |
176 return sourceType.getSource(site,fileId); | |
177 } | |
178 | |
179 } |