]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-3555 Content type is missing on static files provided by plugins
authorSimon Brandhof <simon.brandhof@gmail.com>
Wed, 6 Jun 2012 08:24:41 +0000 (10:24 +0200)
committerSimon Brandhof <simon.brandhof@gmail.com>
Wed, 6 Jun 2012 08:25:34 +0000 (10:25 +0200)
sonar-server/src/main/java/org/sonar/server/plugins/MimeTypes.java [new file with mode: 0644]
sonar-server/src/main/java/org/sonar/server/plugins/StaticResourcesServlet.java
sonar-server/src/test/java/org/sonar/server/plugins/MimeTypesTest.java [new file with mode: 0644]
sonar-server/src/test/java/org/sonar/server/plugins/StaticResourcesServletTest.java

diff --git a/sonar-server/src/main/java/org/sonar/server/plugins/MimeTypes.java b/sonar-server/src/main/java/org/sonar/server/plugins/MimeTypes.java
new file mode 100644 (file)
index 0000000..da607b0
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
+ */
+package org.sonar.server.plugins;
+
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableMap;
+import org.apache.commons.io.FilenameUtils;
+
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * @since 3.1
+ */
+public final class MimeTypes {
+  private MimeTypes() {
+  }
+
+  private static final Map<String, String> MAP = new ImmutableMap.Builder<String, String>()
+    .put("json", "application/json")
+    .put("zip", "application/zip")
+    .put("tgz", "application/tgz")
+    .put("ps", "application/postscript")
+    .put("jnlp", "application/jnlp")
+    .put("jar", "application/java-archive")
+    .put("xls", "application/vnd.ms-excel")
+    .put("ppt", "application/vnd.ms-powerpoint")
+    .put("tar", "application/x-tar")
+    .put("xml", "application/xml")
+    .put("dtd", "application/xml-dtd")
+    .put("xslt", "application/xslt+xml")
+    .put("bmp", "image/bmp")
+    .put("gif", "image/gif")
+    .put("jpg", "image/jpeg")
+    .put("jpeg", "image/jpeg")
+    .put("tiff", "image/tiff")
+    .put("png", "image/png")
+    .put("svg", "image/svg+xml")
+    .put("ico", "image/x-icon")
+    .put("txt", "text/plain")
+    .put("csv", "text/csv")
+    .put("properties", "text/plain")
+    .put("rtf", "text/rtf")
+    .put("html", "text/html")
+    .put("css", "text/css")
+    .put("tsv", "text/tab-separated-values")
+    .build();
+
+  public static final String DEFAULT = "application/octet-stream";
+
+  public static String getByFilename(String filename) {
+    String extension = FilenameUtils.getExtension(filename);
+    String mime = null;
+    if (!Strings.isNullOrEmpty(extension)) {
+      mime = MAP.get(extension.toLowerCase(Locale.ENGLISH));
+    }
+    return mime != null ? mime : DEFAULT;
+  }
+}
index 6e06c03e0e76dcb8d967c8034484619715d92835..fbc269dc6fbc9487fc30add58df157c36509d6ac 100644 (file)
  */
 package org.sonar.server.plugins;
 
+import com.google.common.annotations.VisibleForTesting;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.sonar.server.platform.Platform;
 
+import javax.activation.MimetypesFileTypeMap;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
@@ -37,6 +39,7 @@ public class StaticResourcesServlet extends HttpServlet {
 
   private static final Logger LOG = LoggerFactory.getLogger(StaticResourcesServlet.class);
   private static final long serialVersionUID = -2577454614650178426L;
+  private static final MimetypesFileTypeMap MIME_TYPES = new MimetypesFileTypeMap();
 
   @Override
   public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
@@ -57,6 +60,8 @@ public class StaticResourcesServlet extends HttpServlet {
       if (in != null) {
         out = response.getOutputStream();
         IOUtils.copy(in, out);
+        completeContentType(response, resource);
+
       } else {
         LOG.error("Unable to find resource '" + resource + "' in plugin '" + pluginKey + "'");
         response.sendError(HttpServletResponse.SC_NOT_FOUND);
@@ -87,4 +92,9 @@ public class StaticResourcesServlet extends HttpServlet {
   protected String getResourcePath(HttpServletRequest request) {
     return "static/" + StringUtils.substringAfter(getPluginKeyAndResourcePath(request), "/");
   }
+
+  @VisibleForTesting
+  void completeContentType(HttpServletResponse response, String filename) {
+    response.setContentType(MimeTypes.getByFilename(filename));
+  }
 }
diff --git a/sonar-server/src/test/java/org/sonar/server/plugins/MimeTypesTest.java b/sonar-server/src/test/java/org/sonar/server/plugins/MimeTypesTest.java
new file mode 100644 (file)
index 0000000..b955066
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
+ */
+package org.sonar.server.plugins;
+
+import org.junit.Test;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+public class MimeTypesTest {
+  @Test
+  public void getByFilename_default_mime_type() {
+    assertThat(MimeTypes.getByFilename("")).isEqualTo(MimeTypes.DEFAULT);
+    assertThat(MimeTypes.getByFilename("unknown.extension")).isEqualTo(MimeTypes.DEFAULT);
+  }
+
+  @Test
+  public void getByFilename() {
+    assertThat(MimeTypes.getByFilename("static/sqale/sqale.css")).isEqualTo("text/css");
+    assertThat(MimeTypes.getByFilename("sqale.css")).isEqualTo("text/css");
+  }
+}
index 96868ed4a3d80642b1bb1a88600cbd848a36a706..d4d0efce1ba7ae89c01773912195006dbb4afcc5 100644 (file)
@@ -23,10 +23,11 @@ import org.junit.Before;
 import org.junit.Test;
 
 import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
 
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertThat;
+import static org.fest.assertions.Assertions.assertThat;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 public class StaticResourcesServletTest {
@@ -45,13 +46,13 @@ public class StaticResourcesServletTest {
     when(request.getContextPath()).thenReturn("/");
     when(request.getServletPath()).thenReturn("static");
     when(request.getRequestURI()).thenReturn("/static/myplugin/image.png");
-    assertThat(servlet.getPluginKey(request), is("myplugin"));
+    assertThat(servlet.getPluginKey(request)).isEqualTo("myplugin");
 
     when(request.getRequestURI()).thenReturn("/static/myplugin/images/image.png");
-    assertThat(servlet.getPluginKey(request), is("myplugin"));
+    assertThat(servlet.getPluginKey(request)).isEqualTo("myplugin");
 
     when(request.getRequestURI()).thenReturn("/static/myplugin/");
-    assertThat(servlet.getPluginKey(request), is("myplugin"));
+    assertThat(servlet.getPluginKey(request)).isEqualTo("myplugin");
   }
 
   @Test
@@ -59,12 +60,19 @@ public class StaticResourcesServletTest {
     when(request.getContextPath()).thenReturn("/");
     when(request.getServletPath()).thenReturn("static");
     when(request.getRequestURI()).thenReturn("/static/myplugin/image.png");
-    assertThat(servlet.getResourcePath(request), is("static/image.png"));
+    assertThat(servlet.getResourcePath(request)).isEqualTo("static/image.png");
 
     when(request.getRequestURI()).thenReturn("/static/myplugin/images/image.png");
-    assertThat(servlet.getResourcePath(request), is("static/images/image.png"));
+    assertThat(servlet.getResourcePath(request)).isEqualTo("static/images/image.png");
 
     when(request.getRequestURI()).thenReturn("/static/myplugin/");
-    assertThat(servlet.getResourcePath(request), is("static/"));
+    assertThat(servlet.getResourcePath(request)).isEqualTo("static/");
+  }
+
+  @Test
+  public void completeMimeType() {
+    HttpServletResponse response = mock(HttpServletResponse.class);
+    servlet.completeContentType(response, "static/sqale/sqale.css");
+    verify(response).setContentType("text/css");
   }
 }