MimeTypes: Simple file extension to MIME type mapping

Change-Id: I9639f01ef48558aac734791e24c6f0b910974591
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/MimeTypes.java b/gitiles-servlet/src/main/java/com/google/gitiles/MimeTypes.java
new file mode 100644
index 0000000..ed219ce
--- /dev/null
+++ b/gitiles-servlet/src/main/java/com/google/gitiles/MimeTypes.java
@@ -0,0 +1,56 @@
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gitiles;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.collect.ImmutableMap;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Map;
+import java.util.Properties;
+
+public class MimeTypes {
+  public static final String ANY = "application/octet-stream";
+  private static final ImmutableMap<String, String> TYPES;
+
+  static {
+    Properties p = new Properties();
+    try (InputStream in = MimeTypes.class.getResourceAsStream("mime-types.properties")) {
+      p.load(in);
+    } catch (IOException e) {
+      throw new RuntimeException("Cannot load mime-types.properties", e);
+    }
+
+    ImmutableMap.Builder<String, String> m = ImmutableMap.builder();
+    for (Map.Entry<Object, Object> e : p.entrySet()) {
+      m.put(((String) e.getKey()).toLowerCase(), (String) e.getValue());
+    }
+    TYPES = m.build();
+  }
+
+  public static String getMimeType(String path) {
+    int d = path.lastIndexOf('.');
+    if (d == -1) {
+      return ANY;
+    }
+
+    String ext = path.substring(d + 1);
+    String type = TYPES.get(ext.toLowerCase());
+    return MoreObjects.firstNonNull(type, ANY);
+  }
+
+  private MimeTypes() {}
+}
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/doc/ImageLoader.java b/gitiles-servlet/src/main/java/com/google/gitiles/doc/ImageLoader.java
index 39238e1..4fca76a 100644
--- a/gitiles-servlet/src/main/java/com/google/gitiles/doc/ImageLoader.java
+++ b/gitiles-servlet/src/main/java/com/google/gitiles/doc/ImageLoader.java
@@ -14,9 +14,10 @@
 
 package com.google.gitiles.doc;
 
-import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
 import com.google.common.io.BaseEncoding;
 import com.google.gitiles.GitilesView;
+import com.google.gitiles.MimeTypes;
 import com.google.template.soy.shared.restricted.EscapingConventions.FilterImageDataUri;
 
 import org.eclipse.jgit.errors.LargeObjectException;
@@ -36,6 +37,8 @@
 /** Reads an image from Git and converts to {@code data:image/*;base64,...} */
 class ImageLoader {
   private static final Logger log = LoggerFactory.getLogger(ImageLoader.class);
+  private static final ImmutableSet<String> ALLOWED_TYPES =
+      ImmutableSet.of("image/gif", "image/jpeg", "image/png");
 
   private final ObjectReader reader;
   private final GitilesView view;
@@ -67,8 +70,8 @@
       return null;
     }
 
-    String type = getMimeType(path);
-    if (type == null) {
+    String type = MimeTypes.getMimeType(path);
+    if (!ALLOWED_TYPES.contains(type)) {
       return null;
     }
 
@@ -93,20 +96,4 @@
       return null;
     }
   }
-
-  private static final ImmutableMap<String, String> TYPES =
-      ImmutableMap.of(
-          "png", "image/png",
-          "gif", "image/gif",
-          "jpg", "image/jpeg",
-          "jpeg", "image/jpeg");
-
-  private static String getMimeType(String path) {
-    int d = path.lastIndexOf('.');
-    if (d == -1) {
-      return null;
-    }
-    String ext = path.substring(d + 1);
-    return TYPES.get(ext.toLowerCase());
-  }
 }
diff --git a/gitiles-servlet/src/main/resources/com/google/gitiles/mime-types.properties b/gitiles-servlet/src/main/resources/com/google/gitiles/mime-types.properties
new file mode 100644
index 0000000..0b4bd26
--- /dev/null
+++ b/gitiles-servlet/src/main/resources/com/google/gitiles/mime-types.properties
@@ -0,0 +1,16 @@
+bmp = image/bmp
+css = text/css
+csv = text/csv
+gif = image/gif
+htm = text/html
+html = text/html
+jpeg = image/jpeg
+jpg = image/jpeg
+js = application/javascript
+md = text/markdown
+pdf = application/pdf
+png = image/png
+svg = image/svg+xml
+tiff = image/tiff
+txt = text/plain
+xml = text/xml