From ff17f7bac432b4ba8310ba3ea335748a34859d50 Mon Sep 17 00:00:00 2001 From: James Moger Date: Mon, 5 May 2014 09:53:24 -0400 Subject: Replace RawPage with RawServlet --- src/main/java/WEB-INF/web.xml | 30 +- src/main/java/com/gitblit/Constants.java | 2 +- .../java/com/gitblit/servlet/BranchFilter.java | 126 ------ .../java/com/gitblit/servlet/BranchServlet.java | 480 --------------------- src/main/java/com/gitblit/servlet/PagesFilter.java | 2 +- .../java/com/gitblit/servlet/PagesServlet.java | 2 +- src/main/java/com/gitblit/servlet/RawFilter.java | 126 ++++++ src/main/java/com/gitblit/servlet/RawServlet.java | 472 ++++++++++++++++++++ .../java/com/gitblit/wicket/GitBlitWebApp.java | 4 +- .../java/com/gitblit/wicket/MarkupProcessor.java | 11 +- .../java/com/gitblit/wicket/pages/BasePage.java | 4 + .../java/com/gitblit/wicket/pages/BlobPage.java | 12 +- .../com/gitblit/wicket/pages/CommitDiffPage.java | 5 +- .../java/com/gitblit/wicket/pages/CommitPage.java | 5 +- .../java/com/gitblit/wicket/pages/ComparePage.java | 5 +- .../java/com/gitblit/wicket/pages/DocPage.java | 6 +- .../java/com/gitblit/wicket/pages/DocsPage.java | 9 +- .../java/com/gitblit/wicket/pages/TreePage.java | 6 +- .../java/com/gitblit/wicket/panels/TagsPanel.java | 11 +- 19 files changed, 664 insertions(+), 654 deletions(-) delete mode 100644 src/main/java/com/gitblit/servlet/BranchFilter.java delete mode 100644 src/main/java/com/gitblit/servlet/BranchServlet.java create mode 100644 src/main/java/com/gitblit/servlet/RawFilter.java create mode 100644 src/main/java/com/gitblit/servlet/RawServlet.java (limited to 'src') diff --git a/src/main/java/WEB-INF/web.xml b/src/main/java/WEB-INF/web.xml index d60992dd..cb483af4 100644 --- a/src/main/java/WEB-INF/web.xml +++ b/src/main/java/WEB-INF/web.xml @@ -134,18 +134,18 @@ - - BranchServlet - com.gitblit.servlet.BranchServlet + RawServlet + com.gitblit.servlet.RawServlet - BranchServlet - /branch/* + RawServlet + /raw/* @@ -280,16 +280,16 @@ - BranchFilter - com.gitblit.servlet.BranchFilter + RawFilter + com.gitblit.servlet.RawFilter - BranchFilter - /branch/* + RawFilter + /raw/* @@ -340,12 +340,12 @@ * FederationServlet * RpcFilter * RpcServlet - * BranchFilter - * BranchServlet + * RawFilter + * RawServlet * PagesFilter * PagesServlet * com.gitblit.Constants.PAGES_PATH --> - r/,git/,pt,feed/,zip/,federation/,rpc/,branch/,pages/,robots.txt,logo.png,graph/,sparkleshare/ + r/,git/,pt,feed/,zip/,federation/,rpc/,raw/,pages/,robots.txt,logo.png,graph/,sparkleshare/ diff --git a/src/main/java/com/gitblit/Constants.java b/src/main/java/com/gitblit/Constants.java index 96f13c89..4b9755f3 100644 --- a/src/main/java/com/gitblit/Constants.java +++ b/src/main/java/com/gitblit/Constants.java @@ -68,7 +68,7 @@ public class Constants { public static final String SPARKLESHARE_INVITE_PATH = "/sparkleshare/"; - public static final String BRANCH = "/branch/"; + public static final String RAW_PATH = "/raw/"; public static final String BRANCH_GRAPH_PATH = "/graph/"; diff --git a/src/main/java/com/gitblit/servlet/BranchFilter.java b/src/main/java/com/gitblit/servlet/BranchFilter.java deleted file mode 100644 index 58b8f433..00000000 --- a/src/main/java/com/gitblit/servlet/BranchFilter.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright 2012 gitblit.com. - * - * 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.gitblit.servlet; - -import org.eclipse.jgit.lib.Repository; - -import com.gitblit.Constants.AccessRestrictionType; -import com.gitblit.models.RepositoryModel; -import com.gitblit.models.UserModel; - -/** - * The BranchFilter is an AccessRestrictionFilter which ensures http branch - * requests for a view-restricted repository are authenticated and authorized. - * - * @author James Moger - * - */ -public class BranchFilter extends AccessRestrictionFilter { - - /** - * Extract the repository name from the url. - * - * @param url - * @return repository name - */ - @Override - protected String extractRepositoryName(String url) { - // get the repository name from the url by finding a known url suffix - String repository = ""; - Repository r = null; - int offset = 0; - while (r == null) { - int slash = url.indexOf('/', offset); - if (slash == -1) { - repository = url; - } else { - repository = url.substring(0, slash); - } - r = repositoryManager.getRepository(repository, false); - if (r == null) { - // try again - offset = slash + 1; - } else { - // close the repo - r.close(); - } - if (repository.equals(url)) { - // either only repository in url or no repository found - break; - } - } - return repository; - } - - /** - * Analyze the url and returns the action of the request. - * - * @param cloneUrl - * @return action of the request - */ - @Override - protected String getUrlRequestAction(String suffix) { - return "VIEW"; - } - - /** - * Determine if a non-existing repository can be created using this filter. - * - * @return true if the filter allows repository creation - */ - @Override - protected boolean isCreationAllowed() { - return false; - } - - /** - * Determine if the action may be executed on the repository. - * - * @param repository - * @param action - * @return true if the action may be performed - */ - @Override - protected boolean isActionAllowed(RepositoryModel repository, String action) { - return true; - } - - /** - * Determine if the repository requires authentication. - * - * @param repository - * @param action - * @return true if authentication required - */ - @Override - protected boolean requiresAuthentication(RepositoryModel repository, String action) { - return repository.accessRestriction.atLeast(AccessRestrictionType.VIEW); - } - - /** - * Determine if the user can access the repository and perform the specified - * action. - * - * @param repository - * @param user - * @param action - * @return true if user may execute the action on the repository - */ - @Override - protected boolean canAccess(RepositoryModel repository, UserModel user, String action) { - return user.canView(repository); - } -} diff --git a/src/main/java/com/gitblit/servlet/BranchServlet.java b/src/main/java/com/gitblit/servlet/BranchServlet.java deleted file mode 100644 index 33808961..00000000 --- a/src/main/java/com/gitblit/servlet/BranchServlet.java +++ /dev/null @@ -1,480 +0,0 @@ -/* - * Copyright 2014 gitblit.com. - * - * 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.gitblit.servlet; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; -import java.text.MessageFormat; -import java.text.ParseException; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; - -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.tika.Tika; -import org.eclipse.jgit.lib.FileMode; -import org.eclipse.jgit.lib.MutableObjectId; -import org.eclipse.jgit.lib.ObjectLoader; -import org.eclipse.jgit.lib.ObjectReader; -import org.eclipse.jgit.lib.Repository; -import org.eclipse.jgit.revwalk.RevCommit; -import org.eclipse.jgit.revwalk.RevWalk; -import org.eclipse.jgit.treewalk.TreeWalk; -import org.eclipse.jgit.treewalk.filter.PathFilter; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.gitblit.Constants; -import com.gitblit.Keys; -import com.gitblit.dagger.DaggerServlet; -import com.gitblit.manager.IRepositoryManager; -import com.gitblit.manager.IRuntimeManager; -import com.gitblit.models.PathModel; -import com.gitblit.utils.ByteFormat; -import com.gitblit.utils.JGitUtils; -import com.gitblit.utils.MarkdownUtils; -import com.gitblit.utils.StringUtils; - -import dagger.ObjectGraph; - -/** - * Serves the content of a branch. - * - * @author James Moger - * - */ -public class BranchServlet extends DaggerServlet { - - private static final long serialVersionUID = 1L; - - private transient Logger logger = LoggerFactory.getLogger(BranchServlet.class); - - private IRuntimeManager runtimeManager; - - private IRepositoryManager repositoryManager; - - @Override - protected void inject(ObjectGraph dagger) { - this.runtimeManager = dagger.get(IRuntimeManager.class); - this.repositoryManager = dagger.get(IRepositoryManager.class); - } - - /** - * Returns an url to this servlet for the specified parameters. - * - * @param baseURL - * @param repository - * @param branch - * @param path - * @return an url - */ - public static String asLink(String baseURL, String repository, String branch, String path) { - if (baseURL.length() > 0 && baseURL.charAt(baseURL.length() - 1) == '/') { - baseURL = baseURL.substring(0, baseURL.length() - 1); - } - String encodedPath = path.replace(' ', '-'); - try { - encodedPath = URLEncoder.encode(encodedPath, "UTF-8"); - } catch (UnsupportedEncodingException e) { - } - return baseURL + Constants.BRANCH + repository + "/" + (branch == null ? "" : (branch + "/" + (path == null ? "" : (encodedPath + "/")))); - } - - protected String getBranch(String repository, HttpServletRequest request) { - String pi = request.getPathInfo(); - String branch = pi.substring(pi.indexOf(repository) + repository.length() + 1); - int fs = branch.indexOf('/'); - if (fs > -1) { - branch = branch.substring(0, fs); - } - return branch; - } - - protected String getPath(String repository, String branch, HttpServletRequest request) { - String base = repository + "/" + branch; - String pi = request.getPathInfo().substring(1); - if (pi.equals(base)) { - return ""; - } - String path = pi.substring(pi.indexOf(base) + base.length() + 1); - if (path.endsWith("/")) { - path = path.substring(0, path.length() - 1); - } - return path; - } - - protected boolean renderIndex() { - return false; - } - - /** - * Retrieves the specified resource from the specified branch of the - * repository. - * - * @param request - * @param response - * @throws javax.servlet.ServletException - * @throws java.io.IOException - */ - private void processRequest(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - String path = request.getPathInfo(); - if (path.toLowerCase().endsWith(".git")) { - // forward to url with trailing / - // this is important for relative pages links - response.sendRedirect(request.getServletPath() + path + "/"); - return; - } - if (path.charAt(0) == '/') { - // strip leading / - path = path.substring(1); - } - - // determine repository and resource from url - String repository = ""; - 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; - r = repositoryManager.getRepository(repository, false); - if (repository.equals(path)) { - // either only repository in url or no repository found - break; - } - } - - ServletContext context = request.getSession().getServletContext(); - - try { - if (r == null) { - // repository not found! - String mkd = MessageFormat.format( - "# Error\nSorry, no valid **repository** specified in this url: {0}!", - path); - error(response, mkd); - return; - } - - // identify the branch - String branch = getBranch(repository, request); - if (StringUtils.isEmpty(branch)) { - branch = r.getBranch(); - if (branch == null) { - // no branches found! empty? - String mkd = MessageFormat.format( - "# Error\nSorry, no valid **branch** specified in this url: {0}!", - path); - error(response, mkd); - } else { - // redirect to default branch - String base = request.getRequestURI(); - String url = base + branch + "/"; - response.sendRedirect(url); - } - return; - } - - // identify the requested path - String requestedPath = getPath(repository, branch, request); - - // identify the commit - RevCommit commit = JGitUtils.getCommit(r, branch); - if (commit == null) { - // branch not found! - String mkd = MessageFormat.format( - "# Error\nSorry, the repository {0} does not have a **{1}** branch!", - repository, branch); - error(response, mkd); - return; - } - - - List 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); - - if (contentType == null) { - // ask the container for the content type - contentType = context.getMimeType(requestedPath); - - if (contentType == null) { - // still unknown content type, assume binary - contentType = "application/octet-stream"; - } - } - - setContentType(response, contentType); - - if (isTextType(contentType)) { - - // load, interpret, and serve text content as UTF-8 - String [] encodings = runtimeManager.getSettings().getStrings(Keys.web.blobEncodings).toArray(new String[0]); - String content = JGitUtils.getStringContent(r, commit.getTree(), requestedPath, encodings); - - byte [] bytes = content.getBytes(Constants.ENCODING); - response.setContentLength(bytes.length); - ByteArrayInputStream is = new ByteArrayInputStream(bytes); - sendContent(response, JGitUtils.getCommitDate(commit), is); - - } else { - // serve binary content - String filename = StringUtils.getLastPathElement(requestedPath); - try { - String userAgent = request.getHeader("User-Agent"); - if (userAgent != null && userAgent.indexOf("MSIE 5.5") > -1) { - response.setHeader("Content-Disposition", "filename=\"" - + URLEncoder.encode(filename, Constants.ENCODING) + "\""); - } else if (userAgent != null && userAgent.indexOf("MSIE") > -1) { - response.setHeader("Content-Disposition", "attachment; filename=\"" - + URLEncoder.encode(filename, Constants.ENCODING) + "\""); - } else { - response.setHeader("Content-Disposition", "attachment; filename=\"" - + new String(filename.getBytes(Constants.ENCODING), "latin1") + "\""); - } - } - catch (UnsupportedEncodingException e) { - response.setHeader("Content-Disposition", "attachment; filename=\"" + filename + "\""); - } - - // stream binary content directly from the repository - streamFromRepo(response, r, commit, requestedPath); - } - return; - } catch (Exception e) { - logger.error(null, e); - } - } else { - // path request - if (!request.getPathInfo().endsWith("/")) { - // redirect to trailing '/' url - response.sendRedirect(request.getServletPath() + request.getPathInfo() + "/"); - return; - } - - if (renderIndex()) { - // locate and render an index file - Map names = new TreeMap(); - for (PathModel entry : pathEntries) { - names.put(entry.name.toLowerCase(), entry.name); - } - - List extensions = new ArrayList(); - extensions.add("html"); - extensions.add("htm"); - - String content = null; - for (String ext : extensions) { - String key = "index." + ext; - - if (names.containsKey(key)) { - String fileName = names.get(key); - String fullPath = fileName; - if (!requestedPath.isEmpty()) { - fullPath = requestedPath + "/" + fileName; - } - - String [] encodings = runtimeManager.getSettings().getStrings(Keys.web.blobEncodings).toArray(new String[0]); - String stringContent = JGitUtils.getStringContent(r, commit.getTree(), fullPath, encodings); - if (stringContent == null) { - continue; - } - content = stringContent; - requestedPath = fullPath; - break; - } - } - - response.setContentType("text/html; charset=" + Constants.ENCODING); - byte [] bytes = content.getBytes(Constants.ENCODING); - response.setContentLength(bytes.length); - - ByteArrayInputStream is = new ByteArrayInputStream(bytes); - sendContent(response, JGitUtils.getCommitDate(commit), is); - return; - } - } - - // no content, document list or 404 page - if (pathEntries.isEmpty()) { - // default 404 page - String str = MessageFormat.format( - "# Error\nSorry, the requested resource **{0}** was not found.", - requestedPath); - String content = MarkdownUtils.transformMarkdown(str); - - try { - response.setStatus(HttpServletResponse.SC_NOT_FOUND); - - byte [] bytes = content.getBytes(Constants.ENCODING); - ByteArrayInputStream is = new ByteArrayInputStream(bytes); - sendContent(response, new Date(), is); - return; - } catch (Throwable t) { - logger.error("Failed to write page to client", t); - } - } else { - // - // directory list - // - response.setContentType("text/html"); - response.getWriter().append(""); - response.getWriter().append(""); - response.getWriter().append(""); - response.getWriter().append(""); - response.getWriter().append(""); - String pattern = ""; - final ByteFormat byteFormat = new ByteFormat(); - if (!pathEntries.isEmpty()) { - 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)); - } - } - - String basePath = request.getServletPath() + request.getPathInfo(); - if (basePath.charAt(basePath.length() - 1) == '/') { - // strip trailing slash - basePath = basePath.substring(0, basePath.length() - 1); - } - for (PathModel entry : pathEntries) { - String pp = URLEncoder.encode(entry.name, Constants.ENCODING); - response.getWriter().append(MessageFormat.format(pattern, basePath, pp, - JGitUtils.getPermissionsFromMode(entry.mode), byteFormat.format(entry.size))); - } - response.getWriter().append(""); - response.getWriter().append("
pathmodesize
{1}{2}{3}
"); - } - } catch (Throwable t) { - logger.error("Failed to write page to client", t); - } finally { - r.close(); - } - } - - protected boolean isTextType(String contentType) { - if (contentType.startsWith("text/") - || "application/json".equals(contentType) - || "application/xml".equals(contentType)) { - return true; - } - return false; - } - - /** - * Override all text types to be plain text. - * - * @param response - * @param contentType - */ - protected void setContentType(HttpServletResponse response, String contentType) { - if (isTextType(contentType)) { - response.setContentType("text/plain"); - } else { - response.setContentType(contentType); - } - } - - private void streamFromRepo(HttpServletResponse response, Repository repository, - RevCommit commit, String requestedPath) throws IOException { - - response.setDateHeader("Last-Modified", JGitUtils.getCommitDate(commit).getTime()); - response.setHeader("Cache-Control", "public, max-age=3600, must-revalidate"); - - RevWalk rw = new RevWalk(repository); - TreeWalk tw = new TreeWalk(repository); - try { - tw.reset(); - tw.addTree(commit.getTree()); - PathFilter f = PathFilter.create(requestedPath); - tw.setFilter(f); - tw.setRecursive(true); - MutableObjectId id = new MutableObjectId(); - ObjectReader reader = tw.getObjectReader(); - while (tw.next()) { - FileMode mode = tw.getFileMode(0); - if (mode == FileMode.GITLINK || mode == FileMode.TREE) { - continue; - } - tw.getObjectId(id, 0); - - long len = reader.getObjectSize(id, org.eclipse.jgit.lib.Constants.OBJ_BLOB); - response.setIntHeader("Content-Length", (int) len); - ObjectLoader ldr = repository.open(id); - ldr.copyTo(response.getOutputStream()); - } - } finally { - tw.release(); - rw.dispose(); - } - - response.flushBuffer(); - } - - private void sendContent(HttpServletResponse response, Date date, InputStream is) throws ServletException, IOException { - response.setDateHeader("Last-Modified", date.getTime()); - response.setHeader("Cache-Control", "public, max-age=3600, must-revalidate"); - try { - byte[] tmp = new byte[8192]; - int len = 0; - while ((len = is.read(tmp)) > -1) { - response.getOutputStream().write(tmp, 0, len); - } - } finally { - is.close(); - } - response.flushBuffer(); - } - - private void error(HttpServletResponse response, String mkd) throws ServletException, - IOException, ParseException { - String content = MarkdownUtils.transformMarkdown(mkd); - response.setContentType("text/html; charset=" + Constants.ENCODING); - response.getWriter().write(content); - } - - @Override - protected void doPost(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - processRequest(request, response); - } - - @Override - protected void doGet(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - processRequest(request, response); - } -} diff --git a/src/main/java/com/gitblit/servlet/PagesFilter.java b/src/main/java/com/gitblit/servlet/PagesFilter.java index 0535ea06..e07d9b3b 100644 --- a/src/main/java/com/gitblit/servlet/PagesFilter.java +++ b/src/main/java/com/gitblit/servlet/PagesFilter.java @@ -23,7 +23,7 @@ package com.gitblit.servlet; * @author James Moger * */ -public class PagesFilter extends BranchFilter { +public class PagesFilter extends RawFilter { } diff --git a/src/main/java/com/gitblit/servlet/PagesServlet.java b/src/main/java/com/gitblit/servlet/PagesServlet.java index 7919e442..f578f86f 100644 --- a/src/main/java/com/gitblit/servlet/PagesServlet.java +++ b/src/main/java/com/gitblit/servlet/PagesServlet.java @@ -26,7 +26,7 @@ import com.gitblit.Constants; * @author James Moger * */ -public class PagesServlet extends BranchServlet { +public class PagesServlet extends RawServlet { private static final long serialVersionUID = 1L; diff --git a/src/main/java/com/gitblit/servlet/RawFilter.java b/src/main/java/com/gitblit/servlet/RawFilter.java new file mode 100644 index 00000000..34989c98 --- /dev/null +++ b/src/main/java/com/gitblit/servlet/RawFilter.java @@ -0,0 +1,126 @@ +/* + * Copyright 2012 gitblit.com. + * + * 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.gitblit.servlet; + +import org.eclipse.jgit.lib.Repository; + +import com.gitblit.Constants.AccessRestrictionType; +import com.gitblit.models.RepositoryModel; +import com.gitblit.models.UserModel; + +/** + * The RawFilter is an AccessRestrictionFilter which ensures http branch + * requests for a view-restricted repository are authenticated and authorized. + * + * @author James Moger + * + */ +public class RawFilter extends AccessRestrictionFilter { + + /** + * Extract the repository name from the url. + * + * @param url + * @return repository name + */ + @Override + protected String extractRepositoryName(String url) { + // get the repository name from the url by finding a known url suffix + String repository = ""; + Repository r = null; + int offset = 0; + while (r == null) { + int slash = url.indexOf('/', offset); + if (slash == -1) { + repository = url; + } else { + repository = url.substring(0, slash); + } + r = repositoryManager.getRepository(repository, false); + if (r == null) { + // try again + offset = slash + 1; + } else { + // close the repo + r.close(); + } + if (repository.equals(url)) { + // either only repository in url or no repository found + break; + } + } + return repository; + } + + /** + * Analyze the url and returns the action of the request. + * + * @param cloneUrl + * @return action of the request + */ + @Override + protected String getUrlRequestAction(String suffix) { + return "VIEW"; + } + + /** + * Determine if a non-existing repository can be created using this filter. + * + * @return true if the filter allows repository creation + */ + @Override + protected boolean isCreationAllowed() { + return false; + } + + /** + * Determine if the action may be executed on the repository. + * + * @param repository + * @param action + * @return true if the action may be performed + */ + @Override + protected boolean isActionAllowed(RepositoryModel repository, String action) { + return true; + } + + /** + * Determine if the repository requires authentication. + * + * @param repository + * @param action + * @return true if authentication required + */ + @Override + protected boolean requiresAuthentication(RepositoryModel repository, String action) { + return repository.accessRestriction.atLeast(AccessRestrictionType.VIEW); + } + + /** + * Determine if the user can access the repository and perform the specified + * action. + * + * @param repository + * @param user + * @param action + * @return true if user may execute the action on the repository + */ + @Override + protected boolean canAccess(RepositoryModel repository, UserModel user, String action) { + return user.canView(repository); + } +} diff --git a/src/main/java/com/gitblit/servlet/RawServlet.java b/src/main/java/com/gitblit/servlet/RawServlet.java new file mode 100644 index 00000000..cde7b2e1 --- /dev/null +++ b/src/main/java/com/gitblit/servlet/RawServlet.java @@ -0,0 +1,472 @@ +/* + * Copyright 2014 gitblit.com. + * + * 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.gitblit.servlet; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.text.MessageFormat; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.tika.Tika; +import org.eclipse.jgit.lib.FileMode; +import org.eclipse.jgit.lib.MutableObjectId; +import org.eclipse.jgit.lib.ObjectLoader; +import org.eclipse.jgit.lib.ObjectReader; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.jgit.revwalk.RevWalk; +import org.eclipse.jgit.treewalk.TreeWalk; +import org.eclipse.jgit.treewalk.filter.PathFilter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.gitblit.Constants; +import com.gitblit.Keys; +import com.gitblit.dagger.DaggerServlet; +import com.gitblit.manager.IRepositoryManager; +import com.gitblit.manager.IRuntimeManager; +import com.gitblit.models.PathModel; +import com.gitblit.utils.ByteFormat; +import com.gitblit.utils.JGitUtils; +import com.gitblit.utils.MarkdownUtils; +import com.gitblit.utils.StringUtils; + +import dagger.ObjectGraph; + +/** + * Serves the content of a branch. + * + * @author James Moger + * + */ +public class RawServlet extends DaggerServlet { + + private static final long serialVersionUID = 1L; + + private transient Logger logger = LoggerFactory.getLogger(RawServlet.class); + + private IRuntimeManager runtimeManager; + + private IRepositoryManager repositoryManager; + + @Override + protected void inject(ObjectGraph dagger) { + this.runtimeManager = dagger.get(IRuntimeManager.class); + this.repositoryManager = dagger.get(IRepositoryManager.class); + } + + /** + * Returns an url to this servlet for the specified parameters. + * + * @param baseURL + * @param repository + * @param branch + * @param path + * @return an url + */ + public static String asLink(String baseURL, String repository, String branch, String path) { + if (baseURL.length() > 0 && baseURL.charAt(baseURL.length() - 1) == '/') { + baseURL = baseURL.substring(0, baseURL.length() - 1); + } + String encodedPath = path.replace(' ', '-'); + try { + encodedPath = URLEncoder.encode(encodedPath, "UTF-8"); + } catch (UnsupportedEncodingException e) { + } + return baseURL + Constants.RAW_PATH + repository + "/" + (branch == null ? "" : (branch + "/" + (path == null ? "" : encodedPath))); + } + + protected String getBranch(String repository, HttpServletRequest request) { + String pi = request.getPathInfo(); + String branch = pi.substring(pi.indexOf(repository) + repository.length() + 1); + int fs = branch.indexOf('/'); + if (fs > -1) { + branch = branch.substring(0, fs); + } + return branch; + } + + protected String getPath(String repository, String branch, HttpServletRequest request) { + String base = repository + "/" + branch; + String pi = request.getPathInfo().substring(1); + if (pi.equals(base)) { + return ""; + } + String path = pi.substring(pi.indexOf(base) + base.length() + 1); + if (path.endsWith("/")) { + path = path.substring(0, path.length() - 1); + } + return path; + } + + protected boolean renderIndex() { + return false; + } + + /** + * Retrieves the specified resource from the specified branch of the + * repository. + * + * @param request + * @param response + * @throws javax.servlet.ServletException + * @throws java.io.IOException + */ + private void processRequest(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + String path = request.getPathInfo(); + if (path.toLowerCase().endsWith(".git")) { + // forward to url with trailing / + // this is important for relative pages links + response.sendRedirect(request.getServletPath() + path + "/"); + return; + } + if (path.charAt(0) == '/') { + // strip leading / + path = path.substring(1); + } + + // determine repository and resource from url + String repository = ""; + 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; + r = repositoryManager.getRepository(repository, false); + if (repository.equals(path)) { + // either only repository in url or no repository found + break; + } + } + + ServletContext context = request.getSession().getServletContext(); + + try { + if (r == null) { + // repository not found! + String mkd = MessageFormat.format( + "# Error\nSorry, no valid **repository** specified in this url: {0}!", + path); + error(response, mkd); + return; + } + + // identify the branch + String branch = getBranch(repository, request); + if (StringUtils.isEmpty(branch)) { + branch = r.getBranch(); + if (branch == null) { + // no branches found! empty? + String mkd = MessageFormat.format( + "# Error\nSorry, no valid **branch** specified in this url: {0}!", + path); + error(response, mkd); + } else { + // redirect to default branch + String base = request.getRequestURI(); + String url = base + branch + "/"; + response.sendRedirect(url); + } + return; + } + + // identify the requested path + String requestedPath = getPath(repository, branch, request); + + // identify the commit + RevCommit commit = JGitUtils.getCommit(r, branch); + if (commit == null) { + // branch not found! + String mkd = MessageFormat.format( + "# Error\nSorry, the repository {0} does not have a **{1}** branch!", + repository, branch); + error(response, mkd); + return; + } + + + List 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); + + if (contentType == null) { + // ask the container for the content type + contentType = context.getMimeType(requestedPath); + + if (contentType == null) { + // still unknown content type, assume binary + contentType = "application/octet-stream"; + } + } + + setContentType(response, contentType); + + if (isTextType(contentType)) { + + // load, interpret, and serve text content as UTF-8 + String [] encodings = runtimeManager.getSettings().getStrings(Keys.web.blobEncodings).toArray(new String[0]); + String content = JGitUtils.getStringContent(r, commit.getTree(), requestedPath, encodings); + + byte [] bytes = content.getBytes(Constants.ENCODING); + response.setContentLength(bytes.length); + ByteArrayInputStream is = new ByteArrayInputStream(bytes); + sendContent(response, JGitUtils.getCommitDate(commit), is); + + } else { + // serve binary content + String filename = StringUtils.getLastPathElement(requestedPath); + try { + String userAgent = request.getHeader("User-Agent"); + if (userAgent != null && userAgent.indexOf("MSIE 5.5") > -1) { + response.setHeader("Content-Disposition", "filename=\"" + + URLEncoder.encode(filename, Constants.ENCODING) + "\""); + } else if (userAgent != null && userAgent.indexOf("MSIE") > -1) { + response.setHeader("Content-Disposition", "attachment; filename=\"" + + URLEncoder.encode(filename, Constants.ENCODING) + "\""); + } else { + response.setHeader("Content-Disposition", "attachment; filename=\"" + + new String(filename.getBytes(Constants.ENCODING), "latin1") + "\""); + } + } + catch (UnsupportedEncodingException e) { + response.setHeader("Content-Disposition", "attachment; filename=\"" + filename + "\""); + } + + // stream binary content directly from the repository + streamFromRepo(response, r, commit, requestedPath); + } + return; + } catch (Exception e) { + logger.error(null, e); + } + } else { + // path request + if (!request.getPathInfo().endsWith("/")) { + // redirect to trailing '/' url + response.sendRedirect(request.getServletPath() + request.getPathInfo() + "/"); + return; + } + + if (renderIndex()) { + // locate and render an index file + Map names = new TreeMap(); + for (PathModel entry : pathEntries) { + names.put(entry.name.toLowerCase(), entry.name); + } + + List extensions = new ArrayList(); + extensions.add("html"); + extensions.add("htm"); + + String content = null; + for (String ext : extensions) { + String key = "index." + ext; + + if (names.containsKey(key)) { + String fileName = names.get(key); + String fullPath = fileName; + if (!requestedPath.isEmpty()) { + fullPath = requestedPath + "/" + fileName; + } + + String [] encodings = runtimeManager.getSettings().getStrings(Keys.web.blobEncodings).toArray(new String[0]); + String stringContent = JGitUtils.getStringContent(r, commit.getTree(), fullPath, encodings); + if (stringContent == null) { + continue; + } + content = stringContent; + requestedPath = fullPath; + break; + } + } + + response.setContentType("text/html; charset=" + Constants.ENCODING); + byte [] bytes = content.getBytes(Constants.ENCODING); + response.setContentLength(bytes.length); + + ByteArrayInputStream is = new ByteArrayInputStream(bytes); + sendContent(response, JGitUtils.getCommitDate(commit), is); + return; + } + } + + // no content, document list or 404 page + if (pathEntries.isEmpty()) { + // default 404 page + String str = MessageFormat.format( + "# Error\nSorry, the requested resource **{0}** was not found.", + requestedPath); + response.setStatus(HttpServletResponse.SC_NOT_FOUND); + error(response, str); + return; + } else { + // + // directory list + // + response.setContentType("text/html"); + response.getWriter().append(""); + response.getWriter().append(""); + response.getWriter().append(""); + response.getWriter().append(""); + response.getWriter().append(""); + String pattern = ""; + final ByteFormat byteFormat = new ByteFormat(); + if (!pathEntries.isEmpty()) { + 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)); + } + } + + String basePath = request.getServletPath() + request.getPathInfo(); + if (basePath.charAt(basePath.length() - 1) == '/') { + // strip trailing slash + basePath = basePath.substring(0, basePath.length() - 1); + } + for (PathModel entry : pathEntries) { + String pp = URLEncoder.encode(entry.name, Constants.ENCODING); + response.getWriter().append(MessageFormat.format(pattern, basePath, pp, + JGitUtils.getPermissionsFromMode(entry.mode), + entry.isFile() ? byteFormat.format(entry.size) : "")); + } + response.getWriter().append(""); + response.getWriter().append("
pathmodesize
{1}{2}{3}
"); + } + } catch (Throwable t) { + logger.error("Failed to write page to client", t); + } finally { + r.close(); + } + } + + protected boolean isTextType(String contentType) { + if (contentType.startsWith("text/") + || "application/json".equals(contentType) + || "application/xml".equals(contentType)) { + return true; + } + return false; + } + + /** + * Override all text types to be plain text. + * + * @param response + * @param contentType + */ + protected void setContentType(HttpServletResponse response, String contentType) { + if (isTextType(contentType)) { + response.setContentType("text/plain"); + } else { + response.setContentType(contentType); + } + } + + private void streamFromRepo(HttpServletResponse response, Repository repository, + RevCommit commit, String requestedPath) throws IOException { + + response.setDateHeader("Last-Modified", JGitUtils.getCommitDate(commit).getTime()); + response.setHeader("Cache-Control", "public, max-age=3600, must-revalidate"); + + RevWalk rw = new RevWalk(repository); + TreeWalk tw = new TreeWalk(repository); + try { + tw.reset(); + tw.addTree(commit.getTree()); + PathFilter f = PathFilter.create(requestedPath); + tw.setFilter(f); + tw.setRecursive(true); + MutableObjectId id = new MutableObjectId(); + ObjectReader reader = tw.getObjectReader(); + while (tw.next()) { + FileMode mode = tw.getFileMode(0); + if (mode == FileMode.GITLINK || mode == FileMode.TREE) { + continue; + } + tw.getObjectId(id, 0); + + long len = reader.getObjectSize(id, org.eclipse.jgit.lib.Constants.OBJ_BLOB); + response.setIntHeader("Content-Length", (int) len); + ObjectLoader ldr = repository.open(id); + ldr.copyTo(response.getOutputStream()); + } + } finally { + tw.release(); + rw.dispose(); + } + + response.flushBuffer(); + } + + private void sendContent(HttpServletResponse response, Date date, InputStream is) throws ServletException, IOException { + response.setDateHeader("Last-Modified", date.getTime()); + response.setHeader("Cache-Control", "public, max-age=3600, must-revalidate"); + try { + byte[] tmp = new byte[8192]; + int len = 0; + while ((len = is.read(tmp)) > -1) { + response.getOutputStream().write(tmp, 0, len); + } + } finally { + is.close(); + } + response.flushBuffer(); + } + + private void error(HttpServletResponse response, String mkd) throws ServletException, + IOException, ParseException { + String content = MarkdownUtils.transformMarkdown(mkd); + response.setContentType("text/html; charset=" + Constants.ENCODING); + response.getWriter().write(content); + } + + @Override + protected void doPost(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + processRequest(request, response); + } + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + processRequest(request, response); + } +} diff --git a/src/main/java/com/gitblit/wicket/GitBlitWebApp.java b/src/main/java/com/gitblit/wicket/GitBlitWebApp.java index 9f002d2b..dc79af26 100644 --- a/src/main/java/com/gitblit/wicket/GitBlitWebApp.java +++ b/src/main/java/com/gitblit/wicket/GitBlitWebApp.java @@ -64,13 +64,13 @@ import com.gitblit.wicket.pages.LogoutPage; import com.gitblit.wicket.pages.LuceneSearchPage; import com.gitblit.wicket.pages.MetricsPage; import com.gitblit.wicket.pages.MyDashboardPage; +import com.gitblit.wicket.pages.MyTicketsPage; import com.gitblit.wicket.pages.NewMilestonePage; import com.gitblit.wicket.pages.NewTicketPage; import com.gitblit.wicket.pages.OverviewPage; import com.gitblit.wicket.pages.PatchPage; import com.gitblit.wicket.pages.ProjectPage; import com.gitblit.wicket.pages.ProjectsPage; -import com.gitblit.wicket.pages.RawPage; import com.gitblit.wicket.pages.ReflogPage; import com.gitblit.wicket.pages.RepositoriesPage; import com.gitblit.wicket.pages.ReviewProposalPage; @@ -81,7 +81,6 @@ import com.gitblit.wicket.pages.TicketsPage; import com.gitblit.wicket.pages.TreePage; import com.gitblit.wicket.pages.UserPage; import com.gitblit.wicket.pages.UsersPage; -import com.gitblit.wicket.pages.MyTicketsPage; public class GitBlitWebApp extends WebApplication { @@ -173,7 +172,6 @@ public class GitBlitWebApp extends WebApplication { mount("/tag", TagPage.class, "r", "h"); mount("/tree", TreePage.class, "r", "h", "f"); mount("/blob", BlobPage.class, "r", "h", "f"); - mount("/raw", RawPage.class, "r", "h", "f"); mount("/blobdiff", BlobDiffPage.class, "r", "h", "f"); mount("/commitdiff", CommitDiffPage.class, "r", "h"); mount("/compare", ComparePage.class, "r", "h"); diff --git a/src/main/java/com/gitblit/wicket/MarkupProcessor.java b/src/main/java/com/gitblit/wicket/MarkupProcessor.java index ff6fbce2..e7681f2c 100644 --- a/src/main/java/com/gitblit/wicket/MarkupProcessor.java +++ b/src/main/java/com/gitblit/wicket/MarkupProcessor.java @@ -56,11 +56,11 @@ import org.slf4j.LoggerFactory; import com.gitblit.IStoredSettings; import com.gitblit.Keys; import com.gitblit.models.PathModel; +import com.gitblit.servlet.RawServlet; import com.gitblit.utils.JGitUtils; import com.gitblit.utils.MarkdownUtils; import com.gitblit.utils.StringUtils; import com.gitblit.wicket.pages.DocPage; -import com.gitblit.wicket.pages.RawPage; import com.google.common.base.Joiner; /** @@ -260,7 +260,8 @@ public class MarkupProcessor { if (imagePath.indexOf("://") == -1) { // relative image String path = doc.getRelativePath(imagePath); - url = getWicketUrl(RawPage.class, repositoryName, commitId, path); + String contextUrl = RequestCycle.get().getRequest().getRelativePathPrefixToContextRoot(); + url = RawServlet.asLink(contextUrl, repositoryName, commitId, path); } else { // absolute image url = imagePath; @@ -312,7 +313,8 @@ public class MarkupProcessor { if (node.url.indexOf("://") == -1) { // repository-relative image link String path = doc.getRelativePath(node.url); - String url = getWicketUrl(RawPage.class, repositoryName, commitId, path); + String contextUrl = RequestCycle.get().getRequest().getRelativePathPrefixToContextRoot(); + String url = RawServlet.asLink(contextUrl, repositoryName, commitId, path); return new Rendering(url, text); } // absolute image link @@ -325,7 +327,8 @@ public class MarkupProcessor { if (url.indexOf("://") == -1) { // repository-relative image link String path = doc.getRelativePath(url); - String wurl = getWicketUrl(RawPage.class, repositoryName, commitId, path); + String contextUrl = RequestCycle.get().getRequest().getRelativePathPrefixToContextRoot(); + String wurl = RawServlet.asLink(contextUrl, repositoryName, commitId, path); rendering = new Rendering(wurl, alt); } else { // absolute image link diff --git a/src/main/java/com/gitblit/wicket/pages/BasePage.java b/src/main/java/com/gitblit/wicket/pages/BasePage.java index 7d3d3a24..49710397 100644 --- a/src/main/java/com/gitblit/wicket/pages/BasePage.java +++ b/src/main/java/com/gitblit/wicket/pages/BasePage.java @@ -98,6 +98,10 @@ public abstract class BasePage extends SessionPage { } } + protected String getContextUrl() { + return getRequest().getRelativePathPrefixToContextRoot(); + } + protected String getCanonicalUrl() { return getCanonicalUrl(getClass(), getPageParameters()); } diff --git a/src/main/java/com/gitblit/wicket/pages/BlobPage.java b/src/main/java/com/gitblit/wicket/pages/BlobPage.java index 299d8dbc..f3d0bc92 100644 --- a/src/main/java/com/gitblit/wicket/pages/BlobPage.java +++ b/src/main/java/com/gitblit/wicket/pages/BlobPage.java @@ -24,10 +24,12 @@ import org.apache.wicket.PageParameters; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.image.Image; import org.apache.wicket.markup.html.link.BookmarkablePageLink; +import org.apache.wicket.markup.html.link.ExternalLink; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.revwalk.RevCommit; import com.gitblit.Keys; +import com.gitblit.servlet.RawServlet; import com.gitblit.utils.JGitUtils; import com.gitblit.utils.StringUtils; import com.gitblit.wicket.CacheControl; @@ -57,8 +59,8 @@ public class BlobPage extends RepositoryPage { WicketUtils.newPathParameter(repositoryName, objectId, blobPath)) .setEnabled(false)); add(new BookmarkablePageLink("historyLink", HistoryPage.class).setEnabled(false)); - add(new BookmarkablePageLink("rawLink", RawPage.class, - WicketUtils.newPathParameter(repositoryName, objectId, blobPath))); + String rawUrl = RawServlet.asLink(getContextUrl(), repositoryName, objectId, blobPath); + add(new ExternalLink("rawLink", rawUrl)); add(new CommitHeaderPanel("commitHeader", objectId)); add(new PathBreadcrumbsPanel("breadcrumbs", repositoryName, blobPath, objectId)); Component c = new Label("blobText", JGitUtils.getStringContent(r, objectId, encodings)); @@ -87,8 +89,8 @@ public class BlobPage extends RepositoryPage { WicketUtils.newPathParameter(repositoryName, objectId, blobPath))); add(new BookmarkablePageLink("historyLink", HistoryPage.class, WicketUtils.newPathParameter(repositoryName, objectId, blobPath))); - add(new BookmarkablePageLink("rawLink", RawPage.class, - WicketUtils.newPathParameter(repositoryName, objectId, blobPath))); + String rawUrl = RawServlet.asLink(getContextUrl(), repositoryName, objectId, blobPath); + add(new ExternalLink("rawLink", rawUrl)); add(new CommitHeaderPanel("commitHeader", repositoryName, commit)); @@ -115,7 +117,7 @@ public class BlobPage extends RepositoryPage { case 2: // image blobs add(new Label("blobText").setVisible(false)); - add(new ExternalImage("blobImage", urlFor(RawPage.class, WicketUtils.newPathParameter(repositoryName, objectId, blobPath)).toString())); + add(new ExternalImage("blobImage", rawUrl)); break; case 3: // binary blobs diff --git a/src/main/java/com/gitblit/wicket/pages/CommitDiffPage.java b/src/main/java/com/gitblit/wicket/pages/CommitDiffPage.java index 7f2a8a61..71a5ea67 100644 --- a/src/main/java/com/gitblit/wicket/pages/CommitDiffPage.java +++ b/src/main/java/com/gitblit/wicket/pages/CommitDiffPage.java @@ -34,6 +34,7 @@ import com.gitblit.Constants; import com.gitblit.models.GitNote; import com.gitblit.models.PathModel.PathChangeModel; import com.gitblit.models.SubmoduleModel; +import com.gitblit.servlet.RawServlet; import com.gitblit.utils.DiffUtils; import com.gitblit.utils.DiffUtils.DiffOutput; import com.gitblit.utils.DiffUtils.DiffOutputType; @@ -170,8 +171,8 @@ public class CommitDiffPage extends RepositoryPage { item.add(new BookmarkablePageLink("view", BlobPage.class, WicketUtils .newPathParameter(repositoryName, entry.commitId, entry.path)) .setEnabled(!entry.changeType.equals(ChangeType.DELETE))); - item.add(new BookmarkablePageLink("raw", RawPage.class, WicketUtils - .newPathParameter(repositoryName, entry.commitId, entry.path)) + String rawUrl = RawServlet.asLink(getContextUrl(), repositoryName, entry.commitId, entry.path); + item.add(new ExternalLink("raw", rawUrl) .setEnabled(!entry.changeType.equals(ChangeType.DELETE))); item.add(new BookmarkablePageLink("blame", BlamePage.class, WicketUtils .newPathParameter(repositoryName, entry.commitId, entry.path)) diff --git a/src/main/java/com/gitblit/wicket/pages/CommitPage.java b/src/main/java/com/gitblit/wicket/pages/CommitPage.java index 8bc98489..6fadec5b 100644 --- a/src/main/java/com/gitblit/wicket/pages/CommitPage.java +++ b/src/main/java/com/gitblit/wicket/pages/CommitPage.java @@ -35,6 +35,7 @@ import com.gitblit.Constants; import com.gitblit.models.GitNote; import com.gitblit.models.PathModel.PathChangeModel; import com.gitblit.models.SubmoduleModel; +import com.gitblit.servlet.RawServlet; import com.gitblit.utils.JGitUtils; import com.gitblit.wicket.CacheControl; import com.gitblit.wicket.CacheControl.LastModified; @@ -222,8 +223,8 @@ public class CommitPage extends RepositoryPage { item.add(new BookmarkablePageLink("view", BlobPage.class, WicketUtils .newPathParameter(repositoryName, entry.commitId, entry.path)) .setEnabled(!entry.changeType.equals(ChangeType.DELETE))); - item.add(new BookmarkablePageLink("raw", RawPage.class, WicketUtils - .newPathParameter(repositoryName, entry.commitId, entry.path)) + String rawUrl = RawServlet.asLink(getContextUrl(), repositoryName, entry.commitId, entry.path); + item.add(new ExternalLink("raw", rawUrl) .setEnabled(!entry.changeType.equals(ChangeType.DELETE))); item.add(new BookmarkablePageLink("blame", BlamePage.class, WicketUtils .newPathParameter(repositoryName, entry.commitId, entry.path)) diff --git a/src/main/java/com/gitblit/wicket/pages/ComparePage.java b/src/main/java/com/gitblit/wicket/pages/ComparePage.java index 2024bf17..1ec66133 100644 --- a/src/main/java/com/gitblit/wicket/pages/ComparePage.java +++ b/src/main/java/com/gitblit/wicket/pages/ComparePage.java @@ -41,6 +41,7 @@ import com.gitblit.models.PathModel.PathChangeModel; import com.gitblit.models.RefModel; import com.gitblit.models.RepositoryModel; import com.gitblit.models.SubmoduleModel; +import com.gitblit.servlet.RawServlet; import com.gitblit.utils.DiffUtils; import com.gitblit.utils.DiffUtils.DiffOutput; import com.gitblit.utils.DiffUtils.DiffOutputType; @@ -184,8 +185,8 @@ public class ComparePage extends RepositoryPage { item.add(new BookmarkablePageLink("view", BlobPage.class, WicketUtils .newPathParameter(repositoryName, endId, entry.path)) .setEnabled(!entry.changeType.equals(ChangeType.DELETE))); - item.add(new BookmarkablePageLink("raw", RawPage.class, WicketUtils - .newPathParameter(repositoryName, endId, entry.path)) + String rawUrl = RawServlet.asLink(getContextUrl(), repositoryName, endId, entry.path); + item.add(new ExternalLink("raw", rawUrl) .setEnabled(!entry.changeType.equals(ChangeType.DELETE))); item.add(new BookmarkablePageLink("blame", BlamePage.class, WicketUtils .newPathParameter(repositoryName, endId, entry.path)) diff --git a/src/main/java/com/gitblit/wicket/pages/DocPage.java b/src/main/java/com/gitblit/wicket/pages/DocPage.java index bf99978c..c06d8065 100644 --- a/src/main/java/com/gitblit/wicket/pages/DocPage.java +++ b/src/main/java/com/gitblit/wicket/pages/DocPage.java @@ -20,10 +20,12 @@ import java.util.List; import org.apache.wicket.PageParameters; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.link.BookmarkablePageLink; +import org.apache.wicket.markup.html.link.ExternalLink; import org.apache.wicket.markup.html.panel.Fragment; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.revwalk.RevCommit; +import com.gitblit.servlet.RawServlet; import com.gitblit.utils.BugtraqProcessor; import com.gitblit.utils.JGitUtils; import com.gitblit.utils.StringUtils; @@ -87,8 +89,8 @@ public class DocPage extends RepositoryPage { WicketUtils.newPathParameter(repositoryName, objectId, documentPath))); fragment.add(new BookmarkablePageLink("historyLink", HistoryPage.class, WicketUtils.newPathParameter(repositoryName, objectId, documentPath))); - fragment.add(new BookmarkablePageLink("rawLink", RawPage.class, WicketUtils.newPathParameter( - repositoryName, objectId, documentPath))); + String rawUrl = RawServlet.asLink(getContextUrl(), repositoryName, objectId, documentPath); + fragment.add(new ExternalLink("rawLink", rawUrl)); fragment.add(new Label("content", markupDoc.html).setEscapeModelStrings(false)); add(fragment); diff --git a/src/main/java/com/gitblit/wicket/pages/DocsPage.java b/src/main/java/com/gitblit/wicket/pages/DocsPage.java index 907dd6e2..fc56ee07 100644 --- a/src/main/java/com/gitblit/wicket/pages/DocsPage.java +++ b/src/main/java/com/gitblit/wicket/pages/DocsPage.java @@ -31,6 +31,7 @@ import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.revwalk.RevCommit; import com.gitblit.models.PathModel; +import com.gitblit.servlet.RawServlet; import com.gitblit.utils.ByteFormat; import com.gitblit.utils.JGitUtils; import com.gitblit.utils.StringUtils; @@ -103,8 +104,8 @@ public class DocsPage extends RepositoryPage { WicketUtils.newPathParameter(repositoryName, commitId, doc.documentPath))); item.add(new BookmarkablePageLink("historyLink", HistoryPage.class, WicketUtils.newPathParameter(repositoryName, commitId, doc.documentPath))); - item.add(new BookmarkablePageLink("rawLink", RawPage.class, WicketUtils.newPathParameter( - repositoryName, commitId, doc.documentPath))); + String rawUrl = RawServlet.asLink(getContextUrl(), repositoryName, commitId, doc.documentPath); + item.add(new ExternalLink("rawLink", rawUrl)); // document content String file = StringUtils.getLastPathElement(doc.documentPath); @@ -145,8 +146,8 @@ public class DocsPage extends RepositoryPage { // links item.add(new BookmarkablePageLink("view", DocPage.class, WicketUtils .newPathParameter(repositoryName, id, entry.path))); - item.add(new BookmarkablePageLink("raw", RawPage.class, WicketUtils - .newPathParameter(repositoryName, id, entry.path))); + String rawUrl = RawServlet.asLink(getContextUrl(), repositoryName, id, entry.path); + item.add(new ExternalLink("raw", rawUrl)); item.add(new BookmarkablePageLink("blame", BlamePage.class, WicketUtils .newPathParameter(repositoryName, id, entry.path))); item.add(new BookmarkablePageLink("history", HistoryPage.class, WicketUtils diff --git a/src/main/java/com/gitblit/wicket/pages/TreePage.java b/src/main/java/com/gitblit/wicket/pages/TreePage.java index d6bf1fe1..722b824f 100644 --- a/src/main/java/com/gitblit/wicket/pages/TreePage.java +++ b/src/main/java/com/gitblit/wicket/pages/TreePage.java @@ -20,6 +20,7 @@ import java.util.List; import org.apache.wicket.PageParameters; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.link.BookmarkablePageLink; +import org.apache.wicket.markup.html.link.ExternalLink; import org.apache.wicket.markup.html.panel.Fragment; import org.apache.wicket.markup.repeater.Item; import org.apache.wicket.markup.repeater.data.DataView; @@ -30,6 +31,7 @@ import org.eclipse.jgit.revwalk.RevCommit; import com.gitblit.models.PathModel; import com.gitblit.models.SubmoduleModel; +import com.gitblit.servlet.RawServlet; import com.gitblit.utils.ByteFormat; import com.gitblit.utils.JGitUtils; import com.gitblit.wicket.CacheControl; @@ -162,8 +164,8 @@ public class TreePage extends RepositoryPage { links.add(new BookmarkablePageLink("view", BlobPage.class, WicketUtils.newPathParameter(repositoryName, id, path))); - links.add(new BookmarkablePageLink("raw", RawPage.class, WicketUtils - .newPathParameter(repositoryName, id, path))); + String rawUrl = RawServlet.asLink(getContextUrl(), repositoryName, id, path); + links.add(new ExternalLink("raw", rawUrl)); links.add(new BookmarkablePageLink("blame", BlamePage.class, WicketUtils.newPathParameter(repositoryName, id, path))); diff --git a/src/main/java/com/gitblit/wicket/panels/TagsPanel.java b/src/main/java/com/gitblit/wicket/panels/TagsPanel.java index 9f3987be..f1f82739 100644 --- a/src/main/java/com/gitblit/wicket/panels/TagsPanel.java +++ b/src/main/java/com/gitblit/wicket/panels/TagsPanel.java @@ -17,9 +17,11 @@ package com.gitblit.wicket.panels; import java.util.List; +import org.apache.wicket.RequestCycle; import org.apache.wicket.markup.html.WebPage; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.link.BookmarkablePageLink; +import org.apache.wicket.markup.html.link.ExternalLink; import org.apache.wicket.markup.html.panel.Fragment; import org.apache.wicket.markup.repeater.Item; import org.apache.wicket.markup.repeater.data.DataView; @@ -29,13 +31,13 @@ import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.Repository; import com.gitblit.models.RefModel; +import com.gitblit.servlet.RawServlet; import com.gitblit.utils.JGitUtils; import com.gitblit.utils.StringUtils; import com.gitblit.wicket.WicketUtils; import com.gitblit.wicket.pages.BlobPage; import com.gitblit.wicket.pages.CommitPage; import com.gitblit.wicket.pages.LogPage; -import com.gitblit.wicket.pages.RawPage; import com.gitblit.wicket.pages.TagPage; import com.gitblit.wicket.pages.TagsPage; import com.gitblit.wicket.pages.TreePage; @@ -113,9 +115,10 @@ public class TagsPanel extends BasePanel { .newObjectParameter(repositoryName, entry.getReferencedObjectId() .getName()))); - fragment.add(new BookmarkablePageLink("raw", RawPage.class, WicketUtils - .newObjectParameter(repositoryName, entry.getReferencedObjectId() - .getName()))); + String contextUrl = RequestCycle.get().getRequest().getRelativePathPrefixToContextRoot(); + String rawUrl = RawServlet.asLink(contextUrl, repositoryName, entry.displayName, + entry.getReferencedObjectId().getName()); + fragment.add(new ExternalLink("raw", rawUrl)); item.add(fragment); } else { // TODO Tree Tag Object -- cgit v1.2.3