Clover icon

Magnolia Resources Module 2.4.2

  1. Project Clover database Fri Nov 6 2015 16:15:26 CET
  2. Package info.magnolia.module.resources

File ResourcesServlet.java

 

Coverage histogram

../../../../img/srcFileCovDistChart8.png
32% of files have more coverage

Code metrics

14
40
4
1
152
84
16
0.4
10
4
4
3.3% of code in this file is excluded from these metrics.

Classes

Class Line # Actions
ResourcesServlet 62 40 3.3% 16 13
0.775862177.6%
 

Contributing tests

This file is covered by 10 tests. .

Source view

1    /**
2    * This file Copyright (c) 2015 Magnolia International
3    * Ltd. (http://www.magnolia-cms.com). All rights reserved.
4    *
5    *
6    * This file is dual-licensed under both the Magnolia
7    * Network Agreement and the GNU General Public License.
8    * You may elect to use one or the other of these licenses.
9    *
10    * This file is distributed in the hope that it will be
11    * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the
12    * implied warranty of MERCHANTABILITY or FITNESS FOR A
13    * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
14    * Redistribution, except as permitted by whichever of the GPL
15    * or MNA you select, is prohibited.
16    *
17    * 1. For the GPL license (GPL), you can redistribute and/or
18    * modify this file under the terms of the GNU General
19    * Public License, Version 3, as published by the Free Software
20    * Foundation. You should have received a copy of the GNU
21    * General Public License, Version 3 along with this program;
22    * if not, write to the Free Software Foundation, Inc., 51
23    * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24    *
25    * 2. For the Magnolia Network Agreement (MNA), this file
26    * and the accompanying materials are made available under the
27    * terms of the MNA which accompanies this distribution, and
28    * is available at http://www.magnolia-cms.com/mna.html
29    *
30    * Any modifications to this file must keep this entire header
31    * intact.
32    *
33    */
34    package info.magnolia.module.resources;
35   
36    import info.magnolia.cms.beans.config.MIMEMapping;
37    import info.magnolia.cms.filters.SelfMappingServlet;
38    import info.magnolia.resourceloader.Resource;
39   
40    import java.io.IOException;
41    import java.io.InputStream;
42    import java.io.OutputStream;
43    import java.util.regex.Pattern;
44   
45    import javax.inject.Inject;
46    import javax.servlet.ServletException;
47    import javax.servlet.http.HttpServlet;
48    import javax.servlet.http.HttpServletRequest;
49    import javax.servlet.http.HttpServletResponse;
50   
51    import org.apache.commons.io.IOUtils;
52    import org.apache.commons.lang3.StringUtils;
53    import org.slf4j.Logger;
54    import org.slf4j.LoggerFactory;
55   
56    import com.google.common.net.HttpHeaders;
57   
58    /**
59    * Web resource servlet that serves resources from the resources loader. The servlet exposes all web resources of the
60    * resources loader ({@link info.magnolia.resourceloader.ResourceOrigin}) under the path <code>/.resources/</code>.
61    */
 
62    public class ResourcesServlet extends HttpServlet implements SelfMappingServlet {
63   
64    private final static Logger log = LoggerFactory.getLogger(ResourcesServlet.class);
65   
66    private static final Pattern FORBIDDEN_RESOURCES_PATTERN = Pattern.compile("\\S+.(ftl|java|class|yaml)");
67   
68    private final ResourceLinker linker;
69   
 
70  10 toggle @Inject
71    public ResourcesServlet(ResourceLinker linker) {
72  10 this.linker = linker;
73    }
74   
 
75    toggle @Override
76    public String getSelfMappingPath() {
77    return linker.getServletMapping();
78    }
79   
 
80  11 toggle @Override
81    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
82  11 final String requestedResourcePath = getResourcePathFromRequest(request);
83   
84  11 if (StringUtils.isBlank(requestedResourcePath)) {
85  1 log.warn("Invalid resource request : {} ", request.getRequestURI());
86  1 response.sendError(HttpServletResponse.SC_BAD_REQUEST);
87  1 return;
88    }
89   
90  10 final Resource resource = linker.getResource(requestedResourcePath);
91   
92  10 if (resource == null) {
93  2 log.debug("Requested resource not found for path {}", requestedResourcePath);
94  2 response.sendError(HttpServletResponse.SC_NOT_FOUND);
95  2 return;
96    }
97   
98  8 if (FORBIDDEN_RESOURCES_PATTERN.matcher(resource.getPath()).matches()) {
99  2 log.warn("Requested resource '{}' is forbidden to access.", requestedResourcePath);
100    // send 404 instead to avoid disclosing resource existence ?
101  2 response.sendError(HttpServletResponse.SC_FORBIDDEN);
102  2 return;
103    }
104   
105  6 if (resource.isDirectory()) {
106  0 log.warn("Invalid resource request: {} is a directory", request.getRequestURI());
107    // send 404 instead to avoid disclosing resource existence ?
108  0 response.sendError(HttpServletResponse.SC_BAD_REQUEST);
109  0 return;
110    }
111  6 serveResource(response, resource);
112    }
113   
 
114  11 toggle protected String getResourcePathFromRequest(HttpServletRequest request) {
115    // handle includes
116  11 String resourcePath = (String) request.getAttribute("javax.servlet.include.path_info");
117   
118    // handle forwards
119  11 if (resourcePath == null) {
120  11 resourcePath = (String) request.getAttribute("javax.servlet.forward.path_info");
121    }
122   
123    // standard request
124  11 if (resourcePath == null) {
125  11 resourcePath = request.getPathInfo();
126    }
127   
128  11 return resourcePath;
129    }
130   
 
131  6 toggle protected void serveResource(HttpServletResponse response, Resource resource) throws IOException {
132  6 final String extension = StringUtils.substringAfterLast(resource.getName(), ".");
133  6 final String mimeType = MIMEMapping.getMIMEType(extension);
134   
135  6 response.setContentType(mimeType);
136  6 response.setDateHeader(HttpHeaders.LAST_MODIFIED, resource.getLastModified());
137   
138  6 try (InputStream in = resource.openStream(); OutputStream out = response.getOutputStream()) {
139  6 IOUtils.copy(in, out);
140  6 out.flush();
141    } catch (IOException e) {
142  0 log.debug("Can't load resource {} : {}", resource, e, e);
143  0 response.sendError(HttpServletResponse.SC_NOT_FOUND);
144   
145    // tomcat usually throws a ClientAbortException anytime the user stop loading the page
146  0 log.debug("Unable to serve resource due to a {} exception: ", e, e);
147  0 if (!response.isCommitted()) {
148  0 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
149    }
150    }
151    }
152    }