1
2
3
4
5
6
7
8
9
10
11 package psiprobe.controllers.deploy;
12
13 import com.google.common.base.Strings;
14
15 import jakarta.servlet.http.HttpServletRequest;
16 import jakarta.servlet.http.HttpServletResponse;
17
18 import java.io.File;
19 import java.io.IOException;
20 import java.nio.charset.StandardCharsets;
21 import java.nio.file.Files;
22 import java.nio.file.Path;
23 import java.util.ArrayList;
24 import java.util.HashMap;
25 import java.util.List;
26 import java.util.Map;
27
28 import org.apache.catalina.Context;
29 import org.apache.commons.io.FileUtils;
30 import org.apache.commons.io.FilenameUtils;
31 import org.apache.tomcat.util.http.fileupload.FileItem;
32 import org.apache.tomcat.util.http.fileupload.FileItemFactory;
33 import org.apache.tomcat.util.http.fileupload.FileUpload;
34 import org.apache.tomcat.util.http.fileupload.disk.DiskFileItemFactory;
35 import org.apache.tomcat.util.http.fileupload.servlet.ServletRequestContext;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38 import org.springframework.beans.factory.annotation.Value;
39 import org.springframework.security.core.Authentication;
40 import org.springframework.security.core.context.SecurityContextHolder;
41 import org.springframework.stereotype.Controller;
42 import org.springframework.web.bind.annotation.RequestMapping;
43 import org.springframework.web.servlet.ModelAndView;
44 import org.springframework.web.servlet.view.InternalResourceView;
45
46 import psiprobe.controllers.AbstractTomcatContainerController;
47
48
49
50
51 @Controller
52 public class CopySingleFileController extends AbstractTomcatContainerController {
53
54
55 private static final Logger logger = LoggerFactory.getLogger(CopySingleFileController.class);
56
57 @RequestMapping(path = "/adm/deployfile.htm")
58 @Override
59 public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
60 throws Exception {
61 return super.handleRequest(request, response);
62 }
63
64 @Override
65 protected ModelAndView handleRequestInternal(HttpServletRequest request,
66 HttpServletResponse response) throws Exception {
67
68
69 if (!this.isMultipartContent(request)) {
70 return new ModelAndView(new InternalResourceView(getViewName()));
71 }
72
73 List<Context> apps;
74 try {
75 apps = getContainerWrapper().getTomcatContainer().findContexts();
76 } catch (NullPointerException ex) {
77 throw new IllegalStateException(
78 "No container found for your server: " + getServletContext().getServerInfo(), ex);
79 }
80
81 List<Map<String, String>> applications = new ArrayList<>();
82 for (Context appContext : apps) {
83
84 if (!Strings.isNullOrEmpty(appContext.getName())) {
85 Map<String, String> app = new HashMap<>();
86 app.put("value", appContext.getName());
87 app.put("label", appContext.getName());
88 applications.add(app);
89 }
90 }
91 request.setAttribute("apps", applications);
92
93 File tmpFile = null;
94 String contextName = null;
95 String where = null;
96 boolean reload = false;
97 boolean discard = false;
98
99
100 FileItemFactory factory =
101 new DiskFileItemFactory(1048000, Path.of(System.getProperty("java.io.tmpdir")).toFile());
102 FileUpload upload = new FileUpload();
103 upload.setFileItemFactory(factory);
104 upload.setSizeMax(-1);
105 upload.setHeaderEncoding(StandardCharsets.UTF_8.name());
106 try {
107 List<FileItem> fileItems = upload.parseRequest(new ServletRequestContext(request));
108 for (FileItem fi : fileItems) {
109 if (!fi.isFormField()) {
110 if (fi.getName() != null && fi.getName().length() > 0) {
111 tmpFile =
112 Path.of(System.getProperty("java.io.tmpdir"), FilenameUtils.getName(fi.getName()))
113 .toFile();
114 fi.write(tmpFile);
115 }
116 } else if ("context".equals(fi.getFieldName())) {
117 contextName = fi.getString();
118 } else if ("where".equals(fi.getFieldName())) {
119 where = fi.getString();
120 } else if ("reload".equals(fi.getFieldName()) && "yes".equals(fi.getString())) {
121 reload = true;
122 } else if ("discard".equals(fi.getFieldName()) && "yes".equals(fi.getString())) {
123 discard = true;
124 }
125 }
126 } catch (Exception e) {
127 logger.error("Could not process file upload", e);
128 request.setAttribute("errorMessage", getMessageSourceAccessor()
129 .getMessage("probe.src.deploy.file.uploadfailure", new Object[] {e.getMessage()}));
130 if (tmpFile != null) {
131 Files.delete(tmpFile.toPath());
132 tmpFile = null;
133 }
134 }
135
136 String errMsg = null;
137
138 if (tmpFile == null) {
139 return new ModelAndView(new InternalResourceView(getViewName()));
140 }
141
142 try {
143 if (!Strings.isNullOrEmpty(tmpFile.getName())) {
144
145 contextName = getContainerWrapper().getTomcatContainer().formatContextName(contextName);
146
147 String visibleContextName = contextName.isEmpty() ? "/" : contextName;
148 request.setAttribute("contextName", visibleContextName);
149
150
151 if (getContainerWrapper().getTomcatContainer().findContext(contextName) != null) {
152
153 File destFile = Path.of(getContainerWrapper().getTomcatContainer().getAppBase().getPath(),
154 contextName + where).toFile();
155
156
157 if (destFile.exists()) {
158 if (!destFile.getAbsolutePath().contains("..")) {
159
160 FileUtils.copyFileToDirectory(tmpFile, destFile);
161
162 request.setAttribute("successFile", Boolean.TRUE);
163
164 Authentication auth = SecurityContextHolder.getContext().getAuthentication();
165
166 String name = auth.getName();
167 logger.info(getMessageSourceAccessor().getMessage("probe.src.log.copyfile"), name,
168 contextName);
169 Context context = getContainerWrapper().getTomcatContainer().findContext(contextName);
170
171 if (discard) {
172 getContainerWrapper().getTomcatContainer().discardWorkDir(context);
173 logger.info(getMessageSourceAccessor().getMessage("probe.src.log.discardwork"),
174 name, contextName);
175 }
176
177 if (reload && context != null) {
178 context.reload();
179 request.setAttribute("reloadContext", Boolean.TRUE);
180 logger.info(getMessageSourceAccessor().getMessage("probe.src.log.reload"), name,
181 contextName);
182 }
183 } else {
184 errMsg = getMessageSourceAccessor().getMessage("probe.src.deploy.file.pathNotValid");
185 }
186 } else {
187 errMsg = getMessageSourceAccessor().getMessage("probe.src.deploy.file.notPath");
188 }
189 } else {
190 errMsg = getMessageSourceAccessor().getMessage("probe.src.deploy.file.notExists",
191 new Object[] {visibleContextName});
192 }
193 } else {
194 errMsg = getMessageSourceAccessor().getMessage("probe.src.deploy.file.notFile.failure");
195 }
196 } catch (IOException e) {
197 errMsg = getMessageSourceAccessor().getMessage("probe.src.deploy.file.failure",
198 new Object[] {e.getMessage()});
199 logger.error("Tomcat threw an exception when trying to deploy", e);
200 } finally {
201 if (errMsg != null) {
202 request.setAttribute("errorMessage", errMsg);
203 }
204
205 Files.delete(tmpFile.toPath());
206 }
207 return new ModelAndView(new InternalResourceView(getViewName()));
208 }
209
210 @Value("/adm/deploy.htm")
211 @Override
212 public void setViewName(String viewName) {
213 super.setViewName(viewName);
214 }
215
216 }