Bug 518093 - Unable to deploy via web interface when file's path is part of the file name
diff --git a/org.eclipse.virgo.management.console/src/main/java/org/eclipse/virgo/management/console/UploadServlet.java b/org.eclipse.virgo.management.console/src/main/java/org/eclipse/virgo/management/console/UploadServlet.java
index eacbce0..3be4788 100644
--- a/org.eclipse.virgo.management.console/src/main/java/org/eclipse/virgo/management/console/UploadServlet.java
+++ b/org.eclipse.virgo.management.console/src/main/java/org/eclipse/virgo/management/console/UploadServlet.java
@@ -10,13 +10,13 @@
*******************************************************************************/
package org.eclipse.virgo.management.console;
-import java.io.File;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.lang.management.ManagementFactory;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.List;
+import org.apache.commons.fileupload.FileItem;
+import org.apache.commons.fileupload.FileItemFactory;
+import org.apache.commons.fileupload.disk.DiskFileItemFactory;
+import org.apache.commons.fileupload.servlet.ServletFileUpload;
+import org.osgi.framework.BundleContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
@@ -27,136 +27,152 @@
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-
-import org.apache.commons.fileupload.FileItem;
-import org.apache.commons.fileupload.FileItemFactory;
-import org.apache.commons.fileupload.disk.DiskFileItemFactory;
-import org.apache.commons.fileupload.servlet.ServletFileUpload;
-import org.osgi.framework.BundleContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.lang.management.ManagementFactory;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
/**
- *
+ *
*
*/
public class UploadServlet extends HttpServlet {
- private static final String[] DEPLOYMENT_IDENTITY_FIELDS = new String[]{"type", "symbolicName", "version"};
+ private static final String[] DEPLOYMENT_IDENTITY_FIELDS = new String[]{"type", "symbolicName", "version"};
- private static final int HTTP_RESPONSE_INTERNAL_SERVER_ERROR = 500;
+ private static final int HTTP_RESPONSE_INTERNAL_SERVER_ERROR = 500;
private static final String ORG_ECLIPSE_VIRGO_KERNEL_HOME = "org.eclipse.virgo.kernel.home";
-
+
private static final String DEPLOYER_MBEAN_NAME = "org.eclipse.virgo.kernel:category=Control,type=Deployer";
-
- private static final long serialVersionUID = 1L;
-
- private static final String STAGING_DIR = "/work/org.eclipse.virgo.apps.admin.web.UploadServlet";
-
- private static final Logger log = LoggerFactory.getLogger(UploadServlet.class);
- private MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
-
- private String serverHome = null;
-
- private BundleContext bundleContext = null;
+ private static final long serialVersionUID = 1L;
- public UploadServlet() {
- }
-
- public UploadServlet(BundleContext bundleContext) {
- this.bundleContext = bundleContext;
- }
+ private static final String STAGING_DIR = "/work/org.eclipse.virgo.apps.admin.web.UploadServlet";
- /**
- * Do not use this method with the HTTPService unless the BundleContext has already been set.
- */
- public void init(ServletConfig config) throws ServletException {
- super.init(config);
- if(bundleContext == null){
- this.bundleContext = (BundleContext) config.getServletContext().getAttribute("osgi-bundlecontext");
- }
- this.serverHome = this.bundleContext.getProperty(ORG_ECLIPSE_VIRGO_KERNEL_HOME);
+ private static final Logger log = LoggerFactory.getLogger(UploadServlet.class);
+
+ private MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
+
+ private String serverHome = null;
+
+ private BundleContext bundleContext = null;
+
+ public UploadServlet() {
}
-
- protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
- try {
- File stagingDir = createStagingDirectory();
- FileItemFactory factory = new DiskFileItemFactory();
- ServletFileUpload upload = new ServletFileUpload(factory);
- response.setContentType("text/html");
- List<FileItem> items = (List<FileItem>) upload.parseRequest(request);
- List<File> uploadedFiles = new ArrayList<File>();
- for (FileItem fileItem : items) {
- File uploadedFile = this.doUpload(fileItem, stagingDir);
- if(uploadedFile != null){
- uploadedFiles.add(uploadedFile);
- }
- }
- doDeployment(uploadedFiles, response);
- } catch (IllegalArgumentException ea){
- PrintWriter writer = response.getWriter();
- writer.append("<ol id=\"uploadResults\"><li>File name contains '/' or '\\', this is not allowed.</ol>");
- writer.close();
- } catch (Exception e) {
- log.error(e.toString());
- response.sendError(HTTP_RESPONSE_INTERNAL_SERVER_ERROR, e.toString());
- }
- }
-
- File doUpload(FileItem fileItem, File stagingDir) throws Exception{
- if (!fileItem.isFormField()) {
- String name = fileItem.getName();
- if(name != null && name.length() > 0){
- if(name.contains("\\") || name.contains("/")){
- throw new IllegalArgumentException("Security violation, file name contains '/' or '\\'");
- }
- File uploadedFile = new File(stagingDir, name);
- fileItem.write(uploadedFile);
- log.info(String.format("Uploaded artifact of size (%db) to %s", fileItem.getSize(), uploadedFile.getPath()));
- return uploadedFile;
- }
- }
- return null;
- }
-
- private void doDeployment(List<File> uploadedFiles, HttpServletResponse response) throws MalformedObjectNameException, NullPointerException, IOException{
- ObjectName objectName = new ObjectName(DEPLOYER_MBEAN_NAME);
- PrintWriter writer = response.getWriter();
+
+ public UploadServlet(BundleContext bundleContext) {
+ this.bundleContext = bundleContext;
+ }
+
+ /**
+ * Do not use this method with the HTTPService unless the BundleContext has already been set.
+ */
+ public void init(ServletConfig config) throws ServletException {
+ super.init(config);
+ if (bundleContext == null) {
+ this.bundleContext = (BundleContext) config.getServletContext().getAttribute("osgi-bundlecontext");
+ }
+ this.serverHome = this.bundleContext.getProperty(ORG_ECLIPSE_VIRGO_KERNEL_HOME);
+ }
+
+ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
+ try {
+ File stagingDir = createStagingDirectory();
+ FileItemFactory factory = new DiskFileItemFactory();
+ ServletFileUpload upload = new ServletFileUpload(factory);
+ response.setContentType("text/html");
+ List<FileItem> items = (List<FileItem>) upload.parseRequest(request);
+ List<File> uploadedFiles = new ArrayList<File>();
+ for (FileItem fileItem : items) {
+ File uploadedFile = this.doUpload(fileItem, stagingDir);
+ if (uploadedFile != null) {
+ uploadedFiles.add(uploadedFile);
+ }
+ }
+ doDeployment(uploadedFiles, response);
+ } catch (IllegalArgumentException ea) {
+ PrintWriter writer = response.getWriter();
+ writer.append("<ol id=\"uploadResults\"><li>File name contains '/' or '\\', this is not allowed.</ol>");
+ writer.close();
+ } catch (Exception e) {
+ log.error(e.toString());
+ response.sendError(HTTP_RESPONSE_INTERNAL_SERVER_ERROR, e.toString());
+ }
+ }
+
+ File doUpload(FileItem fileItem, File stagingDir) throws Exception {
+ if (!fileItem.isFormField()) {
+ String name = fileItem.getName();
+ if (name != null && name.length() > 0) {
+ if (name.contains("\\") || name.contains("/")) {
+ name = getFileNameFromPath(name);
+ }
+ File uploadedFile = new File(stagingDir, name);
+ fileItem.write(uploadedFile);
+ log.info(String.format("Uploaded artifact of size (%db) to %s", fileItem.getSize(), uploadedFile.getPath()));
+ return uploadedFile;
+ }
+ }
+ return null;
+ }
+
+ private String getFileNameFromPath(String fileName) {
+
+ String strippedFileName = fileName;
+
+ if (fileName.contains("\\") && fileName.contains("/")) {
+ throw new IllegalArgumentException("Security violation, file name contains '/' and '\\'");
+ } else if (fileName.contains("\\")) {
+ String[] fileNameParts = fileName.split("\\\\");
+ strippedFileName = fileNameParts[fileNameParts.length - 1];
+ } else if (fileName.contains("/")) {
+ String[] fileNameParts = fileName.split("/");
+ strippedFileName = fileNameParts[fileNameParts.length - 1];
+ }
+
+ return strippedFileName;
+ }
+
+ private void doDeployment(List<File> uploadedFiles, HttpServletResponse response) throws MalformedObjectNameException, NullPointerException, IOException {
+ ObjectName objectName = new ObjectName(DEPLOYER_MBEAN_NAME);
+ PrintWriter writer = response.getWriter();
writer.append("<ol id=\"uploadResults\">");
for (File file : uploadedFiles) {
- URI uri = file.toURI();
- try {
- Object invoke = this.mBeanServer.invoke(objectName, "deploy", new Object[]{uri.toString()}, new String[]{String.class.getName()});
- writer.append("<li>" + file.getName() + " deployed as " + getDeploymentIdentity(invoke) + "</li>");
- } catch (Exception e) {
- writer.append("<li>" + file.getName() + " failed to deploy '" + e.getMessage() + "'</li>");
- }
- writer.append("<li />");
- }
+ URI uri = file.toURI();
+ try {
+ Object invoke = this.mBeanServer.invoke(objectName, "deploy", new Object[]{uri.toString()}, new String[]{String.class.getName()});
+ writer.append("<li>" + file.getName() + " deployed as " + getDeploymentIdentity(invoke) + "</li>");
+ } catch (Exception e) {
+ writer.append("<li>" + file.getName() + " failed to deploy '" + e.getMessage() + "'</li>");
+ }
+ writer.append("<li />");
+ }
writer.append("</ol>");
- writer.close();
- }
-
- private String getDeploymentIdentity(Object deploymentIdentity) {
- StringBuilder builder = new StringBuilder();
- if(deploymentIdentity instanceof CompositeDataSupport){
- CompositeDataSupport deploymentIdentityInstance = (CompositeDataSupport) deploymentIdentity;
- Object[] all = deploymentIdentityInstance.getAll(DEPLOYMENT_IDENTITY_FIELDS);
- builder.append(all[0]);
- builder.append(" - ").append(all[1]);
- builder.append(": ").append(all[2]);
- }
- return builder.toString();
- }
+ writer.close();
+ }
+
+ private String getDeploymentIdentity(Object deploymentIdentity) {
+ StringBuilder builder = new StringBuilder();
+ if (deploymentIdentity instanceof CompositeDataSupport) {
+ CompositeDataSupport deploymentIdentityInstance = (CompositeDataSupport) deploymentIdentity;
+ Object[] all = deploymentIdentityInstance.getAll(DEPLOYMENT_IDENTITY_FIELDS);
+ builder.append(all[0]);
+ builder.append(" - ").append(all[1]);
+ builder.append(": ").append(all[2]);
+ }
+ return builder.toString();
+ }
private File createStagingDirectory() throws IOException {
File pathReference = new File(String.format("%s%s", this.serverHome, STAGING_DIR));
if (!pathReference.exists()) {
- if (!pathReference.mkdirs()) {
- throw new IOException("Unable to create directory " + pathReference.getAbsolutePath());
- }
+ if (!pathReference.mkdirs()) {
+ throw new IOException("Unable to create directory " + pathReference.getAbsolutePath());
+ }
}
return pathReference.getAbsoluteFile();
}
diff --git a/org.eclipse.virgo.management.console/src/test/java/org/eclipse/virgo/management/console/UploadServletTests.java b/org.eclipse.virgo.management.console/src/test/java/org/eclipse/virgo/management/console/UploadServletTests.java
index ca6c9f5..884d821 100644
--- a/org.eclipse.virgo.management.console/src/test/java/org/eclipse/virgo/management/console/UploadServletTests.java
+++ b/org.eclipse.virgo.management.console/src/test/java/org/eclipse/virgo/management/console/UploadServletTests.java
@@ -10,43 +10,68 @@
*******************************************************************************/
package org.eclipse.virgo.management.console;
-import static org.junit.Assert.assertNotNull;
-
-import java.io.File;
-import java.io.IOException;
-
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItem;
import org.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
+import java.io.File;
+import java.io.IOException;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
public class UploadServletTests {
- @Test
- public void testDoPost() throws IOException {
- UploadServlet uploadServlet = new UploadServlet();
- MockHttpServletRequest request = new MockHttpServletRequest("POST", null);
- uploadServlet.doPost(request, new MockHttpServletResponse());
- }
-
- @Test(expected=RuntimeException.class)
- public void testDoUploadFail() throws Exception {
- UploadServlet uploadServlet = new UploadServlet();
- FileItem fileItem = new DiskFileItem("foo", "json/application", false, "src/test/resources/test.upload", 500, new File("build"));
- File stagingDir = new File("build");
- fileItem.getOutputStream();
- uploadServlet.doUpload(fileItem, stagingDir);
- }
-
- @Test
- public void testDoUpload() throws Exception {
- UploadServlet uploadServlet = new UploadServlet();
- FileItem fileItem = new DiskFileItem("foo", "json/application", false, "test.upload", 500, new File("build"));
- File stagingDir = new File("src/test/resources");
- fileItem.getOutputStream();
- File doUpload = uploadServlet.doUpload(fileItem, stagingDir);
- assertNotNull(doUpload);
- }
+ @Test
+ public void testDoPost() throws IOException {
+ UploadServlet uploadServlet = new UploadServlet();
+ MockHttpServletRequest request = new MockHttpServletRequest("POST", null);
+ uploadServlet.doPost(request, new MockHttpServletResponse());
+ }
+ @Test(expected = RuntimeException.class)
+ public void testDoUploadFail() throws Exception {
+ UploadServlet uploadServlet = new UploadServlet();
+ FileItem fileItem = new DiskFileItem("foo", "json/application", false, "src/test/resources\\test.upload", 500, new File("build"));
+ File stagingDir = new File("build");
+ fileItem.getOutputStream();
+ uploadServlet.doUpload(fileItem, stagingDir);
+ }
+
+ @Test
+ public void testDoUpload() throws Exception {
+ UploadServlet uploadServlet = new UploadServlet();
+ FileItem fileItem = new DiskFileItem("foo", "json/application", false, "test.upload", 500, new File("build"));
+ File stagingDir = new File("src/test/resources");
+ fileItem.getOutputStream();
+ File doUpload = uploadServlet.doUpload(fileItem, stagingDir);
+ assertNotNull(doUpload);
+ assertTrue("test.upload".equals(doUpload.getName()));
+ }
+
+ @Test
+ public void testDoUploadWithFullPathUnix() throws Exception {
+ UploadServlet uploadServlet = new UploadServlet();
+ FileItem fileItem = new DiskFileItem("foo", "json/application", false, "src/test/resources/test.upload", 500, new File("build"));
+ File stagingDir = new File("src/test/resources");
+ fileItem.getOutputStream();
+ File doUpload = uploadServlet.doUpload(fileItem, stagingDir);
+ System.out.println(doUpload.getName());
+ assertNotNull(doUpload);
+ assertTrue("test.upload".equals(doUpload.getName()));
+ }
+
+
+ @Test
+ public void testDoUploadWithFullPathWin() throws Exception {
+ UploadServlet uploadServlet = new UploadServlet();
+ FileItem fileItem = new DiskFileItem("foo", "json/application", false, "src\\test\\resources\\test.upload", 500, new File("build"));
+ File stagingDir = new File("src/test/resources");
+ fileItem.getOutputStream();
+ File doUpload = uploadServlet.doUpload(fileItem, stagingDir);
+ assertNotNull(doUpload);
+ assertTrue("test.upload".equals(doUpload.getName()));
+ }
}