All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.gerrit.server.mime.MimeUtilFileTypeRegistry Maven / Gradle / Ivy

There is a newer version: 3.10.0-rc4
Show newest version
// Copyright (C) 2009 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.gerrit.server.mime;

import static java.util.Comparator.comparing;

import com.google.common.flogger.FluentLogger;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import eu.medsea.mimeutil.MimeException;
import eu.medsea.mimeutil.MimeType;
import eu.medsea.mimeutil.MimeUtil2;
import java.io.InputStream;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.jgit.lib.Config;

@Singleton
public class MimeUtilFileTypeRegistry implements FileTypeRegistry {
  private static final FluentLogger logger = FluentLogger.forEnclosingClass();

  private static final String KEY_SAFE = "safe";
  private static final String SECTION_MIMETYPE = "mimetype";

  private final Config cfg;
  private final MimeUtil2 mimeUtil;

  @Inject
  MimeUtilFileTypeRegistry(@GerritServerConfig Config gsc, MimeUtil2 mu2) {
    cfg = gsc;
    mimeUtil = mu2;
  }

  /**
   * Get specificity of mime types with generic types forced to low values
   *
   * 

"application/octet-stream" is forced to -1. "text/plain" is forced to 0. All other mime * types return the specificity reported by mimeType itself. * * @param mimeType The mimeType to get the corrected specificity for. * @return The corrected specificity. */ private int getCorrectedMimeSpecificity(MimeType mimeType) { // Although the documentation of MimeType's getSpecificity claims that for // example "application/octet-stream" always has a specificity of 0, it // effectively returns 1 for us. This causes problems when trying to get // the correct mime type via sorting. For example in // [application/octet-stream, image/x-icon] both mime types come with // specificity 1 for us. Hence, getMimeType below may end up using // application/octet-stream instead of the more specific image/x-icon. // Therefore, we have to force the specificity of generic types below the // default of 1. // final String mimeTypeStr = mimeType.toString(); if (mimeTypeStr.equals("application/octet-stream")) { return -1; } if (mimeTypeStr.equals("text/plain")) { return 0; } return mimeType.getSpecificity(); } @Override @SuppressWarnings("unchecked") public MimeType getMimeType(String path, byte[] content) { Set mimeTypes = new HashSet<>(); if (content != null && content.length > 0) { try { mimeTypes.addAll(mimeUtil.getMimeTypes(content)); } catch (MimeException e) { logger.atWarning().withCause(e).log("Unable to determine MIME type from content"); } } return getMimeType(mimeTypes, path); } @Override @SuppressWarnings("unchecked") public MimeType getMimeType(String path, InputStream is) { Set mimeTypes = new HashSet<>(); try { mimeTypes.addAll(mimeUtil.getMimeTypes(is)); } catch (MimeException e) { logger.atWarning().withCause(e).log("Unable to determine MIME type from content"); } return getMimeType(mimeTypes, path); } @SuppressWarnings("unchecked") private MimeType getMimeType(Set mimeTypes, String path) { try { mimeTypes.addAll(mimeUtil.getMimeTypes(path)); } catch (MimeException e) { logger.atWarning().withCause(e).log("Unable to determine MIME type from path"); } if (isUnknownType(mimeTypes)) { return MimeUtil2.UNKNOWN_MIME_TYPE; } return Collections.max(mimeTypes, comparing(this::getCorrectedMimeSpecificity)); } @Override public boolean isSafeInline(MimeType type) { if (MimeUtil2.UNKNOWN_MIME_TYPE.equals(type)) { // Most browsers perform content type sniffing when they get told // a generic content type. This is bad, so assume we cannot send // the file inline. // return false; } final boolean any = isSafe(cfg, "*/*", false); final boolean genericMedia = isSafe(cfg, type.getMediaType() + "/*", any); return isSafe(cfg, type.toString(), genericMedia); } private static boolean isSafe(Config cfg, String type, boolean def) { return cfg.getBoolean(SECTION_MIMETYPE, type, KEY_SAFE, def); } private static boolean isUnknownType(Collection mimeTypes) { if (mimeTypes.isEmpty()) { return true; } return mimeTypes.size() == 1 && mimeTypes.contains(MimeUtil2.UNKNOWN_MIME_TYPE); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy