1 10 package org.mmbase.servlet; 11 12 import java.io.*; 13 import java.util.Map ; 14 import java.util.regex.Pattern ; 15 16 import javax.servlet.ServletException ; 17 import javax.servlet.http.*; 18 19 import org.mmbase.bridge.*; 20 21 import org.mmbase.util.*; 22 import org.mmbase.util.logging.*; 23 24 25 36 public class HandleServlet extends BridgeServlet { 37 private static Logger log; 38 39 private long expires; 41 protected Map getAssociations() { 42 Map a = super.getAssociations(); 43 a.put("attachments", new Integer (0)); 45 a.put("downloads", new Integer (20)); a.put("images", new Integer (-10)); return a; 48 } 49 50 54 public void init() throws ServletException { 55 super.init(); 56 log = Logging.getLoggerInstance(HandleServlet.class); 57 58 String expiresParameter = getInitParameter("expire"); 59 if (expiresParameter == null) { 60 expires = 60 * 60 * 1000; 62 } else { 63 expires = new Integer (expiresParameter).intValue() * 1000; 64 } 65 } 66 67 protected Cloud getClassCloud() { 69 return super.getClassCloud(); 70 } 71 72 76 protected String getMimeType(Node node) { 77 return "application/x-binary"; 78 } 79 80 81 protected static final Pattern legalizeFileName = Pattern.compile("[\\/\\:\\;\\\\\"]+"); 82 83 86 protected String getFileName(final Node node, Node titleNode, final String def) { 87 if (titleNode == null) titleNode = node; 88 NodeManager nm = titleNode.getNodeManager(); 89 String fileName; 91 if (node == titleNode) { 92 fileName = nm.hasField("filename") ? titleNode.getStringValue("filename") : null; 93 } else { 94 if (nm.hasField("filename")) { 95 fileName = titleNode.getStringValue("filename"); 96 String ext = node.getFunctionValue("format", null).toString(); 97 if (! ext.equals(titleNode.getFunctionValue("format", null).toString())) { 98 fileName += '.' + ext; 99 } 100 } else { 101 fileName = null; 102 } 103 } 104 if (fileName != null) { 105 int backSlash = fileName.lastIndexOf("\\"); 106 if (backSlash > -1) { 109 fileName = fileName.substring(backSlash + 1); 110 } 111 } 112 113 if (fileName == null || fileName.equals("")) { 114 fileName = nm.hasField("title") ? titleNode.getStringValue("title") + '.' + node.getFunctionValue("format", null).toString() : null; 115 } 116 if (fileName == null || fileName.equals("")) { 117 fileName = nm.hasField("name") ? titleNode.getStringValue("name") + '.' + node.getFunctionValue("format", null).toString() : null; 118 } 119 if (fileName == null || fileName.equals("")) { fileName = def + "." + node.getFunctionValue("format", null).toString(); 121 } 122 123 return legalizeFileName.matcher(fileName).replaceAll("_"); 124 } 125 126 130 protected boolean setContent(QueryParts query, Node node, String mimeType) throws IOException { 131 String disposition; 132 String fileNamePart = query.getFileName(); 133 if(fileNamePart != null && fileNamePart.startsWith("/inline/")) { 134 disposition = "inline"; 135 } else { 136 disposition = "attachment"; 137 } 138 query.getResponse().setHeader("Content-Disposition", disposition + "; filename=\"" + getFileName(node, null, "mmbase-attachment")+ "\""); 139 return true; 141 } 142 143 147 protected boolean setExpires(HttpServletResponse res, Node node) { 148 if (node.getNodeManager().getName().equals("icaches")) { 149 long never = System.currentTimeMillis() + (long) (365.25 * 24 * 60 * 60 * 1000); 151 res.setDateHeader("Expires", never); 153 } else { 154 long later = System.currentTimeMillis() + expires; 155 res.setDateHeader("Expires", later); 156 } 157 return true; 158 } 159 160 168 protected boolean setCacheControl(HttpServletResponse res, Node node) { 169 if (!node.getCloud().getUser().getRank().equals(org.mmbase.security.Rank.ANONYMOUS)) { 170 res.setHeader("Cache-Control", "private"); 171 return true; 175 } else { 176 res.setHeader("Cache-Control", "public"); 177 return false; 178 } 179 } 180 181 182 185 186 public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException , IOException { 187 QueryParts query = readQuery(req, res); 188 Node queryNode = getNode(query); 189 if (queryNode == null) { 190 return; 191 } 192 193 Node node = getServedNode(query, getNode(query)); 195 196 if (node == null) { 197 return; 198 } 199 200 NodeManager manager = node.getNodeManager(); 201 if (! manager.hasField("handle")) { 202 res.sendError(HttpServletResponse.SC_NOT_FOUND, "No handle found in node " + node.getNumber()); 203 req.setAttribute(MESSAGE_ATTRIBUTE, "No handle found in node " + node.getNumber()); 204 return; 205 } 206 207 res.setDateHeader("Date", System.currentTimeMillis()); 209 210 String mimeType = getMimeType(node); 211 res.setContentType(mimeType); 212 213 if (node.isNull("handle")) { 214 return; 215 } 216 InputStream bytes = node.getInputStreamValue("handle"); 217 218 219 227 boolean canSendLength = true; 228 if (mimeType.equals("image/jpeg") || mimeType.equals("image/jpg")) { 229 bytes = new IECompatibleJpegInputStream(bytes); 230 canSendLength = false; 231 } 233 234 if (!setContent(query, node, mimeType)) { 235 return; 236 } 237 setExpires(res, node); 238 setCacheControl(res, node); 239 240 if (canSendLength) { 241 int size = -1; 242 if (manager.hasField("size")) { 243 size = node.getIntValue("size"); 244 } else if (manager.hasField("filesize")) { 245 size = node.getIntValue("filesize"); 246 } 247 if (size >= 0) { 248 res.setContentLength(size); 249 } 250 log.debug("Serving node " + node.getNumber() + " with bytes " + size); 251 } else { 252 log.debug("Serving node " + node.getNumber() + " with unknown size, because IE sucks"); 253 } 254 sendBytes(res, bytes); 255 } 256 257 258 262 final protected void sendBytes(HttpServletResponse res, byte[] bytes) throws IOException { 263 int fileSize = bytes.length; 264 res.setContentLength(fileSize); 265 266 BufferedOutputStream out = new BufferedOutputStream(res.getOutputStream()); 267 out.write(bytes, 0, fileSize); 268 out.flush(); 269 } 270 final protected void sendBytes(HttpServletResponse res, InputStream bytes) throws IOException { 271 if (log.isDebugEnabled()) { 272 log.debug("Sending by " + bytes.getClass()); 273 } 274 BufferedOutputStream out = new BufferedOutputStream(res.getOutputStream()); 275 byte[] buf = new byte[1024]; 276 int b = 0; 277 while ((b = bytes.read(buf)) != -1) { 278 out.write(buf, 0, b); 279 } 280 out.flush(); 281 bytes.close(); 282 out.close(); 283 } 284 285 public static void main(String argv[]) { 286 System.out.println(legalizeFileName.matcher(argv[0]).replaceAll("_")); 287 } 288 289 } 290
| Popular Tags
|