From a502d96a860456ec5e8c96761db70f7cabb74751 Mon Sep 17 00:00:00 2001 From: Paul Martin <paul@paulsputer.com> Date: Sat, 30 Apr 2016 04:19:14 -0400 Subject: [PATCH] Merge pull request #1073 from gitblit/1062-DocEditorUpdates --- src/main/java/com/gitblit/servlet/RawServlet.java | 74 ++++++++++++++++++++++++------------- 1 files changed, 48 insertions(+), 26 deletions(-) diff --git a/src/main/java/com/gitblit/servlet/RawServlet.java b/src/main/java/com/gitblit/servlet/RawServlet.java index b11bed9..dca5773 100644 --- a/src/main/java/com/gitblit/servlet/RawServlet.java +++ b/src/main/java/com/gitblit/servlet/RawServlet.java @@ -24,12 +24,11 @@ import java.text.ParseException; import java.util.ArrayList; import java.util.Date; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.TreeMap; -import com.google.inject.Inject; -import com.google.inject.Singleton; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; @@ -58,6 +57,8 @@ import com.gitblit.utils.JGitUtils; import com.gitblit.utils.MarkdownUtils; import com.gitblit.utils.StringUtils; +import com.google.inject.Inject; +import com.google.inject.Singleton; /** * Serves the content of a branch. @@ -108,9 +109,8 @@ branch = Repository.shortenRefName(branch).replace('/', fsc); } - String encodedPath = path == null ? "" : path.replace(' ', '-'); - encodedPath = encodedPath.replace('/', fsc); - return baseURL + Constants.RAW_PATH + repository + "/" + (branch == null ? "" : (branch + "/" + (path == null ? "" : encodedPath))); + String encodedPath = path == null ? "" : path.replace('/', fsc); + return baseURL + Constants.RAW_PATH + repository + "/" + (branch == null ? "" : (branch + "/" + encodedPath)); } protected String getBranch(String repository, HttpServletRequest request) { @@ -166,23 +166,14 @@ } // determine repository and resource from url - String repository = ""; + String repository = path; Repository r = null; - int offset = 0; - while (r == null) { - int slash = path.indexOf('/', offset); - if (slash == -1) { - repository = path; - } else { - repository = path.substring(0, slash); - } - offset += ( slash + 1 ); + int terminator = repository.length(); + do { + repository = repository.substring(0, terminator); r = repositoryManager.getRepository(repository, false); - if (repository.equals(path)) { - // either only repository in url or no repository found - break; - } - } + terminator = repository.lastIndexOf('/'); + } while (r == null && terminator > -1 ); ServletContext context = request.getSession().getServletContext(); @@ -229,15 +220,39 @@ return; } + Map<String, String> quickContentTypes = new HashMap<>(); + quickContentTypes.put("html", "text/html"); + quickContentTypes.put("htm", "text/html"); + quickContentTypes.put("xml", "application/xml"); + quickContentTypes.put("json", "application/json"); List<PathModel> pathEntries = JGitUtils.getFilesInPath(r, requestedPath, commit); if (pathEntries.isEmpty()) { // requested a specific resource String file = StringUtils.getLastPathElement(requestedPath); try { - // query Tika for the content type - Tika tika = new Tika(); - String contentType = tika.detect(file); + + String ext = StringUtils.getFileExtension(file).toLowerCase(); + // We can't parse out an extension for classic "dotfiles", so make a general assumption that + // they're text files to allow presenting them in browser instead of only for download. + // + // However, that only holds for files with no other extension included, for files that happen + // to start with a dot but also include an extension, process the extension normally. + // This logic covers .gitattributes, .gitignore, .zshrc, etc., but does not cover .mongorc.js, .zshrc.bak + boolean isExtensionlessDotfile = file.charAt(0) == '.' && (file.length() == 1 || file.indexOf('.', 1) < 0); + String contentType = isExtensionlessDotfile ? "text/plain" : quickContentTypes.get(ext); + + if (contentType == null) { + List<String> exts = runtimeManager.getSettings().getStrings(Keys.web.prettyPrintExtensions); + if (exts.contains(ext)) { + // extension is a registered text type for pretty printing + contentType = "text/plain"; + } else { + // query Tika for the content type + Tika tika = new Tika(); + contentType = tika.detect(file); + } + } if (contentType == null) { // ask the container for the content type @@ -249,7 +264,7 @@ } } - if (isTextType(contentType)) { + if (isTextType(contentType) || isTextDataType(contentType)) { // load, interpret, and serve text content as UTF-8 String [] encodings = runtimeManager.getSettings().getStrings(Keys.web.blobEncodings).toArray(new String[0]); @@ -349,7 +364,7 @@ if (pathEntries.get(0).path.indexOf('/') > -1) { // we are in a subdirectory, add parent directory link String pp = URLEncoder.encode(requestedPath, Constants.ENCODING); - pathEntries.add(0, new PathModel("..", pp + "/..", 0, FileMode.TREE.getBits(), null, null)); + pathEntries.add(0, new PathModel("..", pp + "/..", null, 0, FileMode.TREE.getBits(), null, null)); } } @@ -378,6 +393,13 @@ if (contentType.startsWith("text/") || "application/json".equals(contentType) || "application/xml".equals(contentType)) { + return true; + } + return false; + } + + protected boolean isTextDataType(String contentType) { + if ("image/svg+xml".equals(contentType)) { return true; } return false; @@ -444,7 +466,7 @@ served = true; } } finally { - tw.release(); + tw.close(); rw.dispose(); } -- Gitblit v1.9.1