]> source.dussan.org Git - gitblit.git/commitdiff
Split pages servlet into a raw branch servlet and a gh-pages servlet
authorJames Moger <james.moger@gitblit.com>
Wed, 23 Apr 2014 19:41:14 +0000 (15:41 -0400)
committerJames Moger <james.moger@gitblit.com>
Sun, 4 May 2014 14:43:35 +0000 (10:43 -0400)
.classpath
build.moxie
gitblit.iml
releases.moxie
src/main/java/WEB-INF/web.xml
src/main/java/com/gitblit/Constants.java
src/main/java/com/gitblit/servlet/BranchFilter.java [new file with mode: 0644]
src/main/java/com/gitblit/servlet/BranchServlet.java [new file with mode: 0644]
src/main/java/com/gitblit/servlet/PagesFilter.java
src/main/java/com/gitblit/servlet/PagesServlet.java

index b2e98b1a49fd422f849d0911450d66114e03e6b5..e577b7ca4dd778d5810370bcdaad491fce219f92 100644 (file)
@@ -76,6 +76,7 @@
        <classpathentry kind="lib" path="ext/jedis-2.3.1.jar" sourcepath="ext/src/jedis-2.3.1.jar" />
        <classpathentry kind="lib" path="ext/commons-pool2-2.0.jar" sourcepath="ext/src/commons-pool2-2.0.jar" />
        <classpathentry kind="lib" path="ext/pf4j-0.8.0.jar" sourcepath="ext/src/pf4j-0.8.0.jar" />
+       <classpathentry kind="lib" path="ext/tika-core-1.5.jar" sourcepath="ext/src/tika-core-1.5.jar" />
        <classpathentry kind="lib" path="ext/junit-4.11.jar" sourcepath="ext/src/junit-4.11.jar" />
        <classpathentry kind="lib" path="ext/hamcrest-core-1.3.jar" sourcepath="ext/src/hamcrest-core-1.3.jar" />
        <classpathentry kind="lib" path="ext/selenium-java-2.28.0.jar" sourcepath="ext/src/selenium-java-2.28.0.jar" />
index 6d80c50f957a73458106d77fd0fa684412770060..5f56053226e51f52295b94d0e144aaef4958670b 100644 (file)
@@ -174,6 +174,7 @@ dependencies:
 - compile 'commons-codec:commons-codec:1.7' :war
 - compile 'redis.clients:jedis:2.3.1' :war
 - compile 'ro.fortsoft.pf4j:pf4j:0.8.0' :war
+- compile 'org.apache.tika:tika-core:1.5' :war
 - test 'junit'
 # Dependencies for Selenium web page testing
 - test 'org.seleniumhq.selenium:selenium-java:${selenium.version}' @jar
index 582127d15da1417e454693ee26c2eb285d8da035..7e25249e6e506fbac91ee05e37975d2f9df8de70 100644 (file)
         </SOURCES>
       </library>
     </orderEntry>
+    <orderEntry type="module-library">
+      <library name="tika-core-1.5.jar">
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/ext/tika-core-1.5.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES>
+          <root url="jar://$MODULE_DIR$/ext/src/tika-core-1.5.jar!/" />
+        </SOURCES>
+      </library>
+    </orderEntry>
     <orderEntry type="module-library" scope="TEST">
       <library name="junit-4.11.jar">
         <CLASSES>
index 48f430e2a2ee6a8520be28a34bc5ae4128e3a4b6..62a71c6e306b9aedf61d7e1211da0ba078a3ffe8 100644 (file)
@@ -18,10 +18,12 @@ r23: {
     - Prevent submission from New|Edit ticket page with empty titles (ticket-53)
     changes:
     - improve French translation (pr-176)
-    - simplify current plugin release detection and ignore the currentRelease registry field 
+    - simplify current plugin release detection and ignore the currentRelease registry field
+    - split pages servlet into two servlets (issue-413)
     additions: ~
     dependencyChanges:
     - update to Apache MINA/SSHD 0.11.0 (issue-410)
+    - added Apache Tiki 1.5 (issue-413)
     contributors:
     - James Moger
     - Julien Kirch
index 77456d47b9e5b71607e34e7b842b65fe2eec7fc3..d60992dd8e66de8239f01f133059e976e3a7374e 100644 (file)
        </servlet-mapping>      \r
 \r
 \r
+       <!-- Branch Servlet\r
+                <url-pattern> MUST match: \r
+                       * BranchFilter\r
+                       * com.gitblit.Constants.BRANCH_PATH\r
+                       * Wicket Filter ignorePaths parameter -->\r
+       <servlet>\r
+               <servlet-name>BranchServlet</servlet-name>\r
+               <servlet-class>com.gitblit.servlet.BranchServlet</servlet-class>\r
+       </servlet>\r
+       <servlet-mapping>\r
+               <servlet-name>BranchServlet</servlet-name>              \r
+               <url-pattern>/branch/*</url-pattern>\r
+       </servlet-mapping>      \r
+\r
+\r
        <!-- Pages Servlet\r
                 <url-pattern> MUST match: \r
                        * PagesFilter\r
        </filter-mapping>\r
 \r
 \r
-       <!-- Pges Restriction Filter\r
+       <!-- Branch Restriction Filter\r
+                <url-pattern> MUST match: \r
+                       * BranchServlet\r
+                       * com.gitblit.Constants.BRANCH_PATH\r
+                       * Wicket Filter ignorePaths parameter -->\r
+       <filter>\r
+               <filter-name>BranchFilter</filter-name>\r
+               <filter-class>com.gitblit.servlet.BranchFilter</filter-class>\r
+       </filter>\r
+       <filter-mapping>\r
+               <filter-name>BranchFilter</filter-name>\r
+               <url-pattern>/branch/*</url-pattern>\r
+       </filter-mapping>\r
+       \r
+\r
+       <!-- Pages Restriction Filter\r
                 <url-pattern> MUST match: \r
                        * PagesServlet\r
                        * com.gitblit.Constants.PAGES_PATH\r
                * FederationServlet <url-pattern>\r
                * RpcFilter <url-pattern>\r
                * RpcServlet <url-pattern>\r
+               * BranchFilter <url-pattern>\r
+               * BranchServlet <url-pattern>\r
                * PagesFilter <url-pattern>\r
                * PagesServlet <url-pattern>\r
                * com.gitblit.Constants.PAGES_PATH -->\r
-            <param-value>r/,git/,pt,feed/,zip/,federation/,rpc/,pages/,robots.txt,logo.png,graph/,sparkleshare/</param-value>\r
+            <param-value>r/,git/,pt,feed/,zip/,federation/,rpc/,branch/,pages/,robots.txt,logo.png,graph/,sparkleshare/</param-value>\r
         </init-param>\r
     </filter>\r
     <filter-mapping>\r
index af5339963d2ab0050685dcf162af551db406e8b5..96f13c89eb13d42103b40927b34d915d6fe9e8d4 100644 (file)
@@ -68,6 +68,8 @@ public class Constants {
 \r
        public static final String SPARKLESHARE_INVITE_PATH = "/sparkleshare/";\r
 \r
+       public static final String BRANCH = "/branch/";\r
+\r
        public static final String BRANCH_GRAPH_PATH = "/graph/";\r
 \r
        public static final String BORDER = "*****************************************************************";\r
diff --git a/src/main/java/com/gitblit/servlet/BranchFilter.java b/src/main/java/com/gitblit/servlet/BranchFilter.java
new file mode 100644 (file)
index 0000000..58b8f43
--- /dev/null
@@ -0,0 +1,126 @@
+/*\r
+ * Copyright 2012 gitblit.com.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package com.gitblit.servlet;\r
+\r
+import org.eclipse.jgit.lib.Repository;\r
+\r
+import com.gitblit.Constants.AccessRestrictionType;\r
+import com.gitblit.models.RepositoryModel;\r
+import com.gitblit.models.UserModel;\r
+\r
+/**\r
+ * The BranchFilter is an AccessRestrictionFilter which ensures http branch\r
+ * requests for a view-restricted repository are authenticated and authorized.\r
+ *\r
+ * @author James Moger\r
+ *\r
+ */\r
+public class BranchFilter extends AccessRestrictionFilter {\r
+\r
+       /**\r
+        * Extract the repository name from the url.\r
+        *\r
+        * @param url\r
+        * @return repository name\r
+        */\r
+       @Override\r
+       protected String extractRepositoryName(String url) {\r
+               // get the repository name from the url by finding a known url suffix\r
+               String repository = "";\r
+               Repository r = null;\r
+               int offset = 0;\r
+               while (r == null) {\r
+                       int slash = url.indexOf('/', offset);\r
+                       if (slash == -1) {\r
+                               repository = url;\r
+                       } else {\r
+                               repository = url.substring(0, slash);\r
+                       }\r
+                       r = repositoryManager.getRepository(repository, false);\r
+                       if (r == null) {\r
+                               // try again\r
+                               offset = slash + 1;\r
+                       } else {\r
+                               // close the repo\r
+                               r.close();\r
+                       }\r
+                       if (repository.equals(url)) {\r
+                               // either only repository in url or no repository found\r
+                               break;\r
+                       }\r
+               }\r
+               return repository;\r
+       }\r
+\r
+       /**\r
+        * Analyze the url and returns the action of the request.\r
+        *\r
+        * @param cloneUrl\r
+        * @return action of the request\r
+        */\r
+       @Override\r
+       protected String getUrlRequestAction(String suffix) {\r
+               return "VIEW";\r
+       }\r
+\r
+       /**\r
+        * Determine if a non-existing repository can be created using this filter.\r
+        *\r
+        * @return true if the filter allows repository creation\r
+        */\r
+       @Override\r
+       protected boolean isCreationAllowed() {\r
+               return false;\r
+       }\r
+\r
+       /**\r
+        * Determine if the action may be executed on the repository.\r
+        *\r
+        * @param repository\r
+        * @param action\r
+        * @return true if the action may be performed\r
+        */\r
+       @Override\r
+       protected boolean isActionAllowed(RepositoryModel repository, String action) {\r
+               return true;\r
+       }\r
+\r
+       /**\r
+        * Determine if the repository requires authentication.\r
+        *\r
+        * @param repository\r
+        * @param action\r
+        * @return true if authentication required\r
+        */\r
+       @Override\r
+       protected boolean requiresAuthentication(RepositoryModel repository, String action) {\r
+               return repository.accessRestriction.atLeast(AccessRestrictionType.VIEW);\r
+       }\r
+\r
+       /**\r
+        * Determine if the user can access the repository and perform the specified\r
+        * action.\r
+        *\r
+        * @param repository\r
+        * @param user\r
+        * @param action\r
+        * @return true if user may execute the action on the repository\r
+        */\r
+       @Override\r
+       protected boolean canAccess(RepositoryModel repository, UserModel user, String action) {\r
+               return user.canView(repository);\r
+       }\r
+}\r
diff --git a/src/main/java/com/gitblit/servlet/BranchServlet.java b/src/main/java/com/gitblit/servlet/BranchServlet.java
new file mode 100644 (file)
index 0000000..d6fbfe5
--- /dev/null
@@ -0,0 +1,404 @@
+/*
+ * 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.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.gitblit.Constants;
+import com.gitblit.dagger.DaggerServlet;
+import com.gitblit.manager.IRepositoryManager;
+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 IRepositoryManager repositoryManager;
+
+       @Override
+       protected void inject(ObjectGraph dagger) {
+               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);
+               }
+               return baseURL + Constants.BRANCH + repository + "/" + (branch == null ? "" : (branch + "/" + (path == null ? "" : (path + "/"))));
+       }
+
+       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<PathModel> pathEntries = JGitUtils.getFilesInPath(r, requestedPath, commit);
+                       if (pathEntries.isEmpty()) {
+                               // requested a specific resource
+                               try {
+                                       String file = StringUtils.getLastPathElement(requestedPath);
+
+                                       // 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";
+                                               }
+                                       }
+                                       response.setContentType(contentType);
+
+
+                                       if (contentType.startsWith("text/")
+                                                       || "application/json".equals(contentType)
+                                                       || "application/xml".equals(contentType)) {
+
+                                               // serve text content
+                                               String encoding = commit.getEncoding().name();
+                                               response.setCharacterEncoding(encoding);
+                                       } 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 + "\"");
+                                               }
+                                       }
+
+                                       // send content
+                                       byte [] content = JGitUtils.getByteContent(r, commit.getTree(), requestedPath, false);
+                                       InputStream is = new ByteArrayInputStream(content);
+                                       sendContent(response, JGitUtils.getCommitDate(commit), is);
+
+                                       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<String, String> names = new TreeMap<String, String>();
+                                       for (PathModel entry : pathEntries) {
+                                               names.put(entry.name.toLowerCase(), entry.name);
+                                       }
+
+                                       List<String> extensions = new ArrayList<String>();
+                                       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 encoding = commit.getEncoding().name();
+                                                       String stringContent = JGitUtils.getStringContent(r, commit.getTree(), fullPath, encoding);
+                                                       if (stringContent == null) {
+                                                               continue;
+                                                       }
+                                                       content = stringContent;
+                                                       requestedPath = fullPath;
+                                                       break;
+                                               }
+                                       }
+
+                                       response.setContentType("text/html; charset=" + Constants.ENCODING);
+                                       byte [] bytes = content.getBytes(Constants.ENCODING);
+
+                                       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("<style>table th, table td { min-width: 150px; text-align: left; }</style>");
+                               response.getWriter().append("<table>");
+                               response.getWriter().append("<thead><tr><th>path</th><th>mode</th><th>size</th></tr>");
+                               response.getWriter().append("</thead>");
+                               response.getWriter().append("<tbody>");
+                               String pattern = "<tr><td><a href=\"{0}/{1}\">{1}</a></td><td>{2}</td><td>{3}</td></tr>";
+                               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("</tbody>");
+                               response.getWriter().append("</table>");
+                       }
+               } catch (Throwable t) {
+                       logger.error("Failed to write page to client", t);
+               } finally {
+                       r.close();
+               }
+       }
+
+       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);
+       }
+}
index 9e009163d0af77a3e359b937b9aec775e7bbfacc..0535ea0660de5507465633b98488dac7759b35ea 100644 (file)
  */\r
 package com.gitblit.servlet;\r
 \r
-import org.eclipse.jgit.lib.Repository;\r
-\r
-import com.gitblit.Constants.AccessRestrictionType;\r
-import com.gitblit.models.RepositoryModel;\r
-import com.gitblit.models.UserModel;\r
 \r
 /**\r
  * The PagesFilter is an AccessRestrictionFilter which ensures the gh-pages\r
@@ -28,99 +23,7 @@ import com.gitblit.models.UserModel;
  * @author James Moger\r
  *\r
  */\r
-public class PagesFilter extends AccessRestrictionFilter {\r
-\r
-       /**\r
-        * Extract the repository name from the url.\r
-        *\r
-        * @param url\r
-        * @return repository name\r
-        */\r
-       @Override\r
-       protected String extractRepositoryName(String url) {\r
-               // get the repository name from the url by finding a known url suffix\r
-               String repository = "";\r
-               Repository r = null;\r
-               int offset = 0;\r
-               while (r == null) {\r
-                       int slash = url.indexOf('/', offset);\r
-                       if (slash == -1) {\r
-                               repository = url;\r
-                       } else {\r
-                               repository = url.substring(0, slash);\r
-                       }\r
-                       r = repositoryManager.getRepository(repository, false);\r
-                       if (r == null) {\r
-                               // try again\r
-                               offset = slash + 1;\r
-                       } else {\r
-                               // close the repo\r
-                               r.close();\r
-                       }\r
-                       if (repository.equals(url)) {\r
-                               // either only repository in url or no repository found\r
-                               break;\r
-                       }\r
-               }\r
-               return repository;\r
-       }\r
-\r
-       /**\r
-        * Analyze the url and returns the action of the request.\r
-        *\r
-        * @param cloneUrl\r
-        * @return action of the request\r
-        */\r
-       @Override\r
-       protected String getUrlRequestAction(String suffix) {\r
-               return "VIEW";\r
-       }\r
-\r
-       /**\r
-        * Determine if a non-existing repository can be created using this filter.\r
-        *\r
-        * @return true if the filter allows repository creation\r
-        */\r
-       @Override\r
-       protected boolean isCreationAllowed() {\r
-               return false;\r
-       }\r
-\r
-       /**\r
-        * Determine if the action may be executed on the repository.\r
-        *\r
-        * @param repository\r
-        * @param action\r
-        * @return true if the action may be performed\r
-        */\r
-       @Override\r
-       protected boolean isActionAllowed(RepositoryModel repository, String action) {\r
-               return true;\r
-       }\r
+public class PagesFilter extends BranchFilter {\r
 \r
-       /**\r
-        * Determine if the repository requires authentication.\r
-        *\r
-        * @param repository\r
-        * @param action\r
-        * @return true if authentication required\r
-        */\r
-       @Override\r
-       protected boolean requiresAuthentication(RepositoryModel repository, String action) {\r
-               return repository.accessRestriction.atLeast(AccessRestrictionType.VIEW);\r
-       }\r
 \r
-       /**\r
-        * Determine if the user can access the repository and perform the specified\r
-        * action.\r
-        *\r
-        * @param repository\r
-        * @param user\r
-        * @param action\r
-        * @return true if user may execute the action on the repository\r
-        */\r
-       @Override\r
-       protected boolean canAccess(RepositoryModel repository, UserModel user, String action) {\r
-               return user.canView(repository);\r
-       }\r
 }\r
index 7e48f8e2082655e7185842760bcbabf25d2c2298..777d3a876900bd8abec6e3b7de33f41ac1cd5a88 100644 (file)
  */\r
 package com.gitblit.servlet;\r
 \r
-import java.io.IOException;\r
-import java.text.MessageFormat;\r
-import java.text.ParseException;\r
-import java.util.ArrayList;\r
-import java.util.List;\r
-import java.util.Map;\r
-import java.util.TreeMap;\r
-\r
-import javax.servlet.ServletContext;\r
-import javax.servlet.ServletException;\r
 import javax.servlet.http.HttpServletRequest;\r
-import javax.servlet.http.HttpServletResponse;\r
-\r
-import org.eclipse.jgit.lib.FileMode;\r
-import org.eclipse.jgit.lib.Repository;\r
-import org.eclipse.jgit.revwalk.RevCommit;\r
-import org.eclipse.jgit.revwalk.RevTree;\r
-import org.slf4j.Logger;\r
-import org.slf4j.LoggerFactory;\r
 \r
 import com.gitblit.Constants;\r
-import com.gitblit.IStoredSettings;\r
-import com.gitblit.Keys;\r
-import com.gitblit.dagger.DaggerServlet;\r
-import com.gitblit.manager.IRepositoryManager;\r
-import com.gitblit.models.PathModel;\r
-import com.gitblit.models.RefModel;\r
-import com.gitblit.utils.ArrayUtils;\r
-import com.gitblit.utils.ByteFormat;\r
-import com.gitblit.utils.JGitUtils;\r
-import com.gitblit.utils.MarkdownUtils;\r
-import com.gitblit.utils.StringUtils;\r
-import com.gitblit.wicket.MarkupProcessor;\r
-import com.gitblit.wicket.MarkupProcessor.MarkupDocument;\r
-\r
-import dagger.ObjectGraph;\r
 \r
 /**\r
  * Serves the content of a gh-pages branch.\r
@@ -58,21 +25,10 @@ import dagger.ObjectGraph;
  * @author James Moger\r
  *\r
  */\r
-public class PagesServlet extends DaggerServlet {\r
+public class PagesServlet extends BranchServlet {\r
 \r
        private static final long serialVersionUID = 1L;\r
 \r
-       private transient Logger logger = LoggerFactory.getLogger(PagesServlet.class);\r
-\r
-       private IStoredSettings settings;\r
-\r
-       private IRepositoryManager repositoryManager;\r
-\r
-       @Override\r
-       protected void inject(ObjectGraph dagger) {\r
-               this.settings = dagger.get(IStoredSettings.class);\r
-               this.repositoryManager = dagger.get(IRepositoryManager.class);\r
-       }\r
 \r
        /**\r
         * Returns an url to this servlet for the specified parameters.\r
@@ -89,248 +45,26 @@ public class PagesServlet extends DaggerServlet {
                return baseURL + Constants.PAGES + repository + "/" + (path == null ? "" : ("/" + path));\r
        }\r
 \r
-       /**\r
-        * Retrieves the specified resource from the gh-pages branch of the\r
-        * repository.\r
-        *\r
-        * @param request\r
-        * @param response\r
-        * @throws javax.servlet.ServletException\r
-        * @throws java.io.IOException\r
-        */\r
-       private void processRequest(HttpServletRequest request, HttpServletResponse response)\r
-                       throws ServletException, IOException {\r
-               String path = request.getPathInfo();\r
-               if (path.toLowerCase().endsWith(".git")) {\r
-                       // forward to url with trailing /\r
-                       // this is important for relative pages links\r
-                       response.sendRedirect(request.getServletPath() + path + "/");\r
-                       return;\r
-               }\r
-               if (path.charAt(0) == '/') {\r
-                       // strip leading /\r
-                       path = path.substring(1);\r
-               }\r
-\r
-               // determine repository and resource from url\r
-               String repository = "";\r
-               String resource = "";\r
-               Repository r = null;\r
-               int offset = 0;\r
-               while (r == null) {\r
-                       int slash = path.indexOf('/', offset);\r
-                       if (slash == -1) {\r
-                               repository = path;\r
-                       } else {\r
-                               repository = path.substring(0, slash);\r
-                       }\r
-                       r = repositoryManager.getRepository(repository, false);\r
-                       offset = slash + 1;\r
-                       if (offset > 0) {\r
-                               resource = path.substring(offset);\r
-                       }\r
-                       if (repository.equals(path)) {\r
-                               // either only repository in url or no repository found\r
-                               break;\r
-                       }\r
-               }\r
-\r
-               ServletContext context = request.getSession().getServletContext();\r
-\r
-               try {\r
-                       if (r == null) {\r
-                               // repository not found!\r
-                               String mkd = MessageFormat.format(\r
-                                               "# Error\nSorry, no valid **repository** specified in this url: {0}!",\r
-                                               repository);\r
-                               error(response, mkd);\r
-                               return;\r
-                       }\r
-\r
-                       // retrieve the content from the repository\r
-                       RefModel pages = JGitUtils.getPagesBranch(r);\r
-                       RevCommit commit = JGitUtils.getCommit(r, pages.getObjectId().getName());\r
-\r
-                       if (commit == null) {\r
-                               // branch not found!\r
-                               String mkd = MessageFormat.format(\r
-                                               "# Error\nSorry, the repository {0} does not have a **gh-pages** branch!",\r
-                                               repository);\r
-                               error(response, mkd);\r
-                               return;\r
-                       }\r
-\r
-                       MarkupProcessor processor = new MarkupProcessor(settings);\r
-                       String [] encodings = settings.getStrings(Keys.web.blobEncodings).toArray(new String[0]);\r
-\r
-                       RevTree tree = commit.getTree();\r
-\r
-                       String res = resource;\r
-                       if (res.endsWith("/")) {\r
-                               res = res.substring(0, res.length() - 1);\r
-                       }\r
-\r
-                       List<PathModel> pathEntries = JGitUtils.getFilesInPath(r, res, commit);\r
-\r
-                       byte[] content = null;\r
-                       if (pathEntries.isEmpty()) {\r
-                               // not a path, a specific resource\r
-                               try {\r
-                                       String contentType = context.getMimeType(res);\r
-                                       if (contentType == null) {\r
-                                               contentType = "text/plain";\r
-                                       }\r
-                                       if (contentType.startsWith("text")) {\r
-                                               content = JGitUtils.getStringContent(r, tree, res, encodings).getBytes(\r
-                                                               Constants.ENCODING);\r
-                                       } else {\r
-                                               content = JGitUtils.getByteContent(r, tree, res, false);\r
-                                       }\r
-                                       response.setContentType(contentType);\r
-                               } catch (Exception e) {\r
-                               }\r
-                       } else {\r
-                               // path request\r
-                               if (!request.getPathInfo().endsWith("/")) {\r
-                                       // redirect to trailing '/' url\r
-                                       response.sendRedirect(request.getServletPath() + request.getPathInfo() + "/");\r
-                                       return;\r
-                               }\r
-\r
-                               Map<String, String> names = new TreeMap<String, String>();\r
-                               for (PathModel entry : pathEntries) {\r
-                                       names.put(entry.name.toLowerCase(), entry.name);\r
-                               }\r
-\r
-                               List<String> extensions = new ArrayList<String>();\r
-                               extensions.add("html");\r
-                               extensions.add("htm");\r
-                               extensions.addAll(processor.getMarkupExtensions());\r
-                               for (String ext : extensions) {\r
-                                       String key = "index." + ext;\r
-\r
-                                       if (names.containsKey(key)) {\r
-                                               String fileName = names.get(key);\r
-                                               String fullPath = fileName;\r
-                                               if (!res.isEmpty()) {\r
-                                                       fullPath = res + "/" + fileName;\r
-                                               }\r
-                                               String stringContent = JGitUtils.getStringContent(r, tree, fullPath, encodings);\r
-                                               if (stringContent == null) {\r
-                                                       continue;\r
-                                               }\r
-                                               content = stringContent.getBytes(Constants.ENCODING);\r
-                                               if (content != null) {\r
-                                                       res = fullPath;\r
-                                                       // assume text/html unless the servlet container\r
-                                                       // overrides\r
-                                                       response.setContentType("text/html; charset=" + Constants.ENCODING);\r
-                                                       break;\r
-                                               }\r
-                                       }\r
-                               }\r
-                       }\r
-\r
-                       // no content, document list or custom 404 page\r
-                       if (ArrayUtils.isEmpty(content)) {\r
-                               if (pathEntries.isEmpty()) {\r
-                                       // 404\r
-                                       String custom404 = JGitUtils.getStringContent(r, tree, "404.html", encodings);\r
-                                       if (!StringUtils.isEmpty(custom404)) {\r
-                                               content = custom404.getBytes(Constants.ENCODING);\r
-                                       }\r
-\r
-                                       // still no content\r
-                                       if (ArrayUtils.isEmpty(content)) {\r
-                                               String str = MessageFormat.format(\r
-                                                               "# Error\nSorry, the requested resource **{0}** was not found.",\r
-                                                               resource);\r
-                                               content = MarkdownUtils.transformMarkdown(str).getBytes(Constants.ENCODING);\r
-                                       }\r
-\r
-                                       try {\r
-                                               // output the content\r
-                                               logger.warn("Pages 404: " + resource);\r
-                                               response.setStatus(HttpServletResponse.SC_NOT_FOUND);\r
-                                               response.getOutputStream().write(content);\r
-                                               response.flushBuffer();\r
-                                       } catch (Throwable t) {\r
-                                               logger.error("Failed to write page to client", t);\r
-                                       }\r
-                               } else {\r
-                                       // document list\r
-                                       response.setContentType("text/html");\r
-                                       response.getWriter().append("<style>table th, table td { min-width: 150px; text-align: left; }</style>");\r
-                                       response.getWriter().append("<table>");\r
-                                       response.getWriter().append("<thead><tr><th>path</th><th>mode</th><th>size</th></tr>");\r
-                                       response.getWriter().append("</thead>");\r
-                                       response.getWriter().append("<tbody>");\r
-                                       String pattern = "<tr><td><a href=\"{0}/{1}\">{1}</a></td><td>{2}</td><td>{3}</td></tr>";\r
-                                       final ByteFormat byteFormat = new ByteFormat();\r
-                                       if (!pathEntries.isEmpty()) {\r
-                                               if (pathEntries.get(0).path.indexOf('/') > -1) {\r
-                                                       // we are in a subdirectory, add parent directory link\r
-                                                       pathEntries.add(0, new PathModel("..", resource + "/..", 0, FileMode.TREE.getBits(), null, null));\r
-                                               }\r
-                                       }\r
-\r
-                                       String basePath = request.getServletPath() + request.getPathInfo();\r
-                                       if (basePath.charAt(basePath.length() - 1) == '/') {\r
-                                               // strip trailing slash\r
-                                               basePath = basePath.substring(0, basePath.length() - 1);\r
-                                       }\r
-                                       for (PathModel entry : pathEntries) {\r
-                                               response.getWriter().append(MessageFormat.format(pattern, basePath, entry.name,\r
-                                                               JGitUtils.getPermissionsFromMode(entry.mode), byteFormat.format(entry.size)));\r
-                                       }\r
-                                       response.getWriter().append("</tbody>");\r
-                                       response.getWriter().append("</table>");\r
-                               }\r
-                               return;\r
-                       }\r
-\r
-                       // check to see if we should transform markup files\r
-                       String ext = StringUtils.getFileExtension(resource);\r
-                       if (processor.getMarkupExtensions().contains(ext)) {\r
-                               String markup = new String(content, Constants.ENCODING);\r
-                               MarkupDocument markupDoc = processor.parse(repository, commit.getName(), resource, markup);\r
-                               content = markupDoc.html.getBytes("UTF-8");\r
-                               response.setContentType("text/html; charset=" + Constants.ENCODING);\r
-                       }\r
-\r
-                       try {\r
-                               // output the content\r
-                               response.setHeader("Cache-Control", "public, max-age=3600, must-revalidate");\r
-                               response.setDateHeader("Last-Modified", JGitUtils.getCommitDate(commit).getTime());\r
-                               response.getOutputStream().write(content);\r
-                               response.flushBuffer();\r
-                       } catch (Throwable t) {\r
-                               logger.error("Failed to write page to client", t);\r
-                       }\r
-\r
-               } catch (Throwable t) {\r
-                       logger.error("Failed to write page to client", t);\r
-               } finally {\r
-                       r.close();\r
-               }\r
-       }\r
-\r
-       private void error(HttpServletResponse response, String mkd) throws ServletException,\r
-                       IOException, ParseException {\r
-               String content = MarkdownUtils.transformMarkdown(mkd);\r
-               response.setContentType("text/html; charset=" + Constants.ENCODING);\r
-               response.getWriter().write(content);\r
+       @Override\r
+       protected String getBranch(String repository, HttpServletRequest request) {\r
+               return "gh-pages";\r
        }\r
 \r
        @Override\r
-       protected void doPost(HttpServletRequest request, HttpServletResponse response)\r
-                       throws ServletException, IOException {\r
-               processRequest(request, response);\r
+       protected String getPath(String repository, String branch, HttpServletRequest request) {\r
+               String pi = request.getPathInfo().substring(1);\r
+               if (pi.equals(repository)) {\r
+                       return "";\r
+               }\r
+               String path = pi.substring(pi.indexOf(repository) + repository.length() + 1);\r
+               if (path.endsWith("/")) {\r
+                       path = path.substring(0, path.length() - 1);\r
+               }\r
+               return path;\r
        }\r
 \r
        @Override\r
-       protected void doGet(HttpServletRequest request, HttpServletResponse response)\r
-                       throws ServletException, IOException {\r
-               processRequest(request, response);\r
+       protected boolean renderIndex() {\r
+               return true;\r
        }\r
 }\r