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