1 17 package org.alfresco.web.app.servlet; 18 19 import java.io.IOException ; 20 import java.io.UnsupportedEncodingException ; 21 import java.net.SocketException ; 22 import java.net.URLDecoder ; 23 import java.net.URLEncoder ; 24 import java.text.MessageFormat ; 25 import java.util.StringTokenizer ; 26 27 import javax.servlet.ServletException ; 28 import javax.servlet.http.HttpServlet ; 29 import javax.servlet.http.HttpServletRequest ; 30 import javax.servlet.http.HttpServletResponse ; 31 32 import org.alfresco.error.AlfrescoRuntimeException; 33 import org.alfresco.model.ContentModel; 34 import org.alfresco.repo.content.filestore.FileContentReader; 35 import org.alfresco.service.ServiceRegistry; 36 import org.alfresco.service.cmr.repository.ContentReader; 37 import org.alfresco.service.cmr.repository.ContentService; 38 import org.alfresco.service.cmr.repository.MimetypeService; 39 import org.alfresco.service.cmr.repository.NodeRef; 40 import org.alfresco.service.cmr.repository.StoreRef; 41 import org.alfresco.service.cmr.security.AccessStatus; 42 import org.alfresco.service.cmr.security.PermissionService; 43 import org.alfresco.service.namespace.QName; 44 import org.alfresco.web.app.Application; 45 import org.alfresco.web.ui.common.Utils; 46 import org.apache.commons.logging.Log; 47 import org.apache.commons.logging.LogFactory; 48 49 76 public class DownloadContentServlet extends BaseServlet 77 { 78 private static final long serialVersionUID = -4558907921887235966L; 79 80 private static Log logger = LogFactory.getLog(DownloadContentServlet.class); 81 82 private static final String DOWNLOAD_URL = "/download/attach/{0}/{1}/{2}/{3}"; 83 private static final String BROWSER_URL = "/download/direct/{0}/{1}/{2}/{3}"; 84 85 private static final String MIMETYPE_OCTET_STREAM = "application/octet-stream"; 86 87 private static final String MSG_ERROR_CONTENT_MISSING = "error_content_missing"; 88 89 private static final String ARG_PROPERTY = "property"; 90 private static final String ARG_ATTACH = "attach"; 91 92 95 protected void doGet(HttpServletRequest req, HttpServletResponse res) 96 throws ServletException , IOException 97 { 98 String uri = req.getRequestURI(); 104 105 if (logger.isDebugEnabled()) 106 logger.debug("Processing URL: " + uri + (req.getQueryString() != null ? ("?" + req.getQueryString()) : "")); 107 108 AuthenticationStatus status = servletAuthenticate(req, res); 109 if (status == AuthenticationStatus.Failure) 110 { 111 return; 112 } 113 114 StringTokenizer t = new StringTokenizer (uri, "/"); 118 if (t.countTokens() < 7) 119 { 120 throw new IllegalArgumentException ("Download URL did not contain all required args: " + uri); 121 } 122 123 t.nextToken(); t.nextToken(); 126 String attachToken = t.nextToken(); 127 boolean attachment = attachToken.equals(ARG_ATTACH); 128 129 StoreRef storeRef = new StoreRef(t.nextToken(), t.nextToken()); 130 String id = t.nextToken(); 131 String filename = t.nextToken(); 132 133 QName propertyQName = null; 135 String property = req.getParameter(ARG_PROPERTY); 136 if (property == null || property.length() == 0) 137 { 138 propertyQName = ContentModel.PROP_CONTENT; 139 } 140 else 141 { 142 propertyQName = QName.createQName(property); 143 } 144 145 NodeRef nodeRef = new NodeRef(storeRef, id); 147 148 if (logger.isDebugEnabled()) 149 { 150 logger.debug("Found NodeRef: " + nodeRef.toString()); 151 logger.debug("Will use filename: " + filename); 152 logger.debug("For property: " + propertyQName); 153 logger.debug("With attachment mode: " + attachment); 154 } 155 156 ServiceRegistry serviceRegistry = getServiceRegistry(getServletContext()); 158 ContentService contentService = serviceRegistry.getContentService(); 159 PermissionService permissionService = serviceRegistry.getPermissionService(); 160 161 try 162 { 163 if (permissionService.hasPermission(nodeRef, PermissionService.READ_CONTENT) == AccessStatus.DENIED) 165 { 166 if (logger.isDebugEnabled()) 167 logger.debug("User does not have permissions to read content for NodeRef: " + nodeRef.toString()); 168 redirectToLoginPage(req, res, getServletContext()); 169 return; 170 } 171 172 if (attachment == true) 173 { 174 String encname = filename.replace('%', '='); 177 res.setHeader("Content-Disposition", "attachment;filename=\"=?ISO-8859-1?Q?" + encname + "?=\""); 178 } 179 180 ContentReader reader = contentService.getReader(nodeRef, propertyQName); 182 reader = FileContentReader.getSafeContentReader( 184 reader, 185 Application.getMessage(req.getSession(), MSG_ERROR_CONTENT_MISSING), 186 nodeRef, reader); 187 188 String mimetype = reader.getMimetype(); 189 if (mimetype == null || mimetype.length() == 0) 191 { 192 MimetypeService mimetypeMap = serviceRegistry.getMimetypeService(); 193 mimetype = MIMETYPE_OCTET_STREAM; 194 int extIndex = filename.lastIndexOf('.'); 195 if (extIndex != -1) 196 { 197 String ext = filename.substring(extIndex + 1); 198 String mt = mimetypeMap.getMimetypesByExtension().get(ext); 199 if (mt != null) 200 { 201 mimetype = mt; 202 } 203 } 204 } 205 res.setContentType(mimetype); 206 207 try 211 { 212 reader.getContent( res.getOutputStream() ); 213 } 214 catch (SocketException e) 215 { 216 if (e.getMessage().contains("ClientAbortException")) 217 { 218 logger.error("Client aborted stream read:\n node: " + nodeRef + "\n content: " + reader); 220 } 221 else 222 { 223 throw e; 224 } 225 } 226 } 227 catch (Throwable err) 228 { 229 throw new AlfrescoRuntimeException("Error during download content servlet processing: " + err.getMessage(), err); 230 } 231 } 232 233 243 public final static String generateDownloadURL(NodeRef ref, String name) 244 { 245 String url = null; 246 247 try 248 { 249 url = MessageFormat.format(DOWNLOAD_URL, new Object [] { 250 ref.getStoreRef().getProtocol(), 251 ref.getStoreRef().getIdentifier(), 252 ref.getId(), 253 Utils.replace(URLEncoder.encode(name, "UTF-8"), "+", "%20") } ); 254 } 255 catch (UnsupportedEncodingException uee) 256 { 257 throw new AlfrescoRuntimeException("Failed to encode content URL for node: " + ref, uee); 258 } 259 260 return url; 261 } 262 263 273 public final static String generateBrowserURL(NodeRef ref, String name) 274 { 275 String url = null; 276 277 try 278 { 279 url = MessageFormat.format(BROWSER_URL, new Object [] { 280 ref.getStoreRef().getProtocol(), 281 ref.getStoreRef().getIdentifier(), 282 ref.getId(), 283 Utils.replace(URLEncoder.encode(name, "UTF-8"), "+", "%20") } ); 284 } 285 catch (UnsupportedEncodingException uee) 286 { 287 throw new AlfrescoRuntimeException("Failed to encode content URL for node: " + ref, uee); 288 } 289 290 return url; 291 } 292 } 293 | Popular Tags |