1 |
|
|
2 |
|
|
3 |
|
|
4 |
|
|
5 |
|
|
6 |
|
|
7 |
|
|
8 |
|
|
9 |
|
|
10 |
|
|
11 |
|
|
12 |
|
|
13 |
|
|
14 |
|
|
15 |
|
|
16 |
|
|
17 |
|
|
18 |
|
|
19 |
|
|
20 |
|
|
21 |
|
|
22 |
|
|
23 |
|
|
24 |
|
|
25 |
|
|
26 |
|
|
27 |
|
|
28 |
|
|
29 |
|
|
30 |
|
|
31 |
|
|
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 |
|
|
60 |
|
@link |
61 |
|
|
|
|
| 77.6% |
Uncovered Elements: 13 (58) |
Complexity: 16 |
Complexity Density: 0.4 |
|
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 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (1) |
Complexity: 1 |
Complexity Density: 1 |
|
70 |
10 |
@Inject... |
71 |
|
public ResourcesServlet(ResourceLinker linker) { |
72 |
10 |
this.linker = linker; |
73 |
|
} |
74 |
|
|
|
|
| - |
Uncovered Elements: 0 (0) |
Complexity: 1 |
Complexity Density: - |
|
75 |
|
@Override... |
76 |
|
public String getSelfMappingPath() { |
77 |
|
return linker.getServletMapping(); |
78 |
|
} |
79 |
|
|
|
|
| 85.2% |
Uncovered Elements: 4 (27) |
Complexity: 5 |
Complexity Density: 0.26 |
|
80 |
11 |
@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 |
|
|
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 |
|
|
108 |
0 |
response.sendError(HttpServletResponse.SC_BAD_REQUEST); |
109 |
0 |
return; |
110 |
|
} |
111 |
6 |
serveResource(response, resource); |
112 |
|
} |
113 |
|
|
|
|
| 80% |
Uncovered Elements: 2 (10) |
Complexity: 3 |
Complexity Density: 0.5 |
|
114 |
11 |
protected String getResourcePathFromRequest(HttpServletRequest request) {... |
115 |
|
|
116 |
11 |
String resourcePath = (String) request.getAttribute("javax.servlet.include.path_info"); |
117 |
|
|
118 |
|
|
119 |
11 |
if (resourcePath == null) { |
120 |
11 |
resourcePath = (String) request.getAttribute("javax.servlet.forward.path_info"); |
121 |
|
} |
122 |
|
|
123 |
|
|
124 |
11 |
if (resourcePath == null) { |
125 |
11 |
resourcePath = request.getPathInfo(); |
126 |
|
} |
127 |
|
|
128 |
11 |
return resourcePath; |
129 |
|
} |
130 |
|
|
|
|
| 56.2% |
Uncovered Elements: 7 (16) |
Complexity: 7 |
Complexity Density: 0.5 |
|
131 |
6 |
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 |
|
|
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 |
|
} |