• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

openmrs / openmrs-core / 24803983538

22 Apr 2026 09:33PM UTC coverage: 63.689% (-0.04%) from 63.73%
24803983538

push

github

ibacher
Fix issues with Javadocs

21841 of 34293 relevant lines covered (63.69%)

0.64 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/web/src/main/java/org/openmrs/module/web/ModuleResourcesServlet.java
1
/**
2
 * This Source Code Form is subject to the terms of the Mozilla Public License,
3
 * v. 2.0. If a copy of the MPL was not distributed with this file, You can
4
 * obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under
5
 * the terms of the Healthcare Disclaimer located at http://openmrs.org/license.
6
 *
7
 * Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS
8
 * graphic logo is a trademark of OpenMRS Inc.
9
 */
10
package org.openmrs.module.web;
11

12
import java.io.File;
13
import java.io.FileInputStream;
14
import java.io.IOException;
15
import java.nio.file.Path;
16
import java.nio.file.Paths;
17

18
import javax.servlet.ServletException;
19
import javax.servlet.http.HttpServlet;
20
import javax.servlet.http.HttpServletRequest;
21
import javax.servlet.http.HttpServletResponse;
22

23
import org.openmrs.module.Module;
24
import org.openmrs.module.ModuleUtil;
25
import org.openmrs.util.OpenmrsUtil;
26
import org.slf4j.Logger;
27
import org.slf4j.LoggerFactory;
28

29
public class ModuleResourcesServlet extends HttpServlet {
×
30
        
31
        private static final String MODULE_PATH = "/WEB-INF/view/module/";
32
        
33
        private static final long serialVersionUID = 1239820102030344L;
34
        
35
        private static final Logger log = LoggerFactory.getLogger(ModuleResourcesServlet.class);
×
36
        
37
        /**
38
         * Used for caching purposes
39
         *
40
         * @see javax.servlet.http.HttpServlet#getLastModified(javax.servlet.http.HttpServletRequest)
41
         */
42
        @Override
43
        protected long getLastModified(HttpServletRequest req) {
44
                File f = getFile(req);
×
45
                
46
                if (f == null) {
×
47
                        return super.getLastModified(req);
×
48
                }
49
                
50
                return f.lastModified();
×
51
        }
52
        
53
        @Override
54
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
55
                
56
                log.debug("In service method for module servlet: " + request.getPathInfo());
×
57
                
58
                File f = getFile(request);
×
59
                if (f == null) {
×
60
                        response.setStatus(HttpServletResponse.SC_NOT_FOUND);
×
61
                        return;
×
62
                }
63
                
64
                response.setDateHeader("Last-Modified", f.lastModified());
×
65
                response.setContentLength(Long.valueOf(f.length()).intValue());
×
66
                String mimeType = getServletContext().getMimeType(f.getName());
×
67
                response.setContentType(mimeType);
×
68
                
69
                FileInputStream is = new FileInputStream(f);
×
70
                try {
71
                        OpenmrsUtil.copyFile(is, response.getOutputStream());
×
72
                }
73
                finally {
74
                        OpenmrsUtil.closeStream(is);
×
75
                }
76
        }
×
77
        
78
        /**
79
         * Turns the given request/path into a File object
80
         *
81
         * @param request the current http request
82
         * @return the file being requested or null if not found
83
         */
84
        protected File getFile(HttpServletRequest request) {
85
                
86
                String path = request.getPathInfo();
×
87
                
88
                Module module = ModuleUtil.getModuleForPath(path);
×
89
                if (module == null) {
×
90
                        log.warn("No module handles the path: " + path);
×
91
                        return null;
×
92
                }
93
                
94
                String relativePath = ModuleUtil.getPathForResource(module, path);
×
95
                String realPath = getServletContext().getRealPath("") + MODULE_PATH + module.getModuleIdAsPath() + "/resources"
×
96
                        + relativePath;
97

98
                String basePath;
99

100
                //if in dev mode, load resources from the development directory
101
                File devDir = ModuleUtil.getDevelopmentDirectory(module.getModuleId());
×
102
                if (devDir != null) {
×
103
                        realPath = devDir.getAbsolutePath() + "/omod/target/classes/web/module/resources" + relativePath;
×
104
                        basePath = devDir.getAbsolutePath() + "/omod/target/classes/web/module/resources";
×
105
                } else {
106
                        basePath = getServletContext().getRealPath("") + MODULE_PATH + module.getModuleIdAsPath() + "/resources";
×
107
                }
108

109
                Path normalizedPath = Paths.get(realPath).normalize();
×
110
                Path normalizedBase = Paths.get(basePath).normalize();
×
111
                if (!normalizedPath.startsWith(normalizedBase)) {
×
112
                        log.warn("Detected attempted directory traversal with path: " + path);
×
113
                        return null;
×
114
                }
115

116
                File f = normalizedPath.toFile();
×
117
                if (!f.exists()) {
×
118
                        log.warn("No file with path '" + normalizedPath + "' exists for module '" + module.getModuleId() + "'");
×
119
                        return null;
×
120
                }
121
                
122
                return f;
×
123
        }
124
        
125
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc