Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

PagesServlet.java 8.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. /*
  2. * Copyright 2012 gitblit.com.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package com.gitblit;
  17. import java.io.IOException;
  18. import java.text.MessageFormat;
  19. import java.text.ParseException;
  20. import java.util.ArrayList;
  21. import java.util.List;
  22. import javax.servlet.ServletContext;
  23. import javax.servlet.ServletException;
  24. import javax.servlet.http.HttpServlet;
  25. import javax.servlet.http.HttpServletRequest;
  26. import javax.servlet.http.HttpServletResponse;
  27. import org.eclipse.jgit.lib.Repository;
  28. import org.eclipse.jgit.revwalk.RevCommit;
  29. import org.eclipse.jgit.revwalk.RevTree;
  30. import org.slf4j.Logger;
  31. import org.slf4j.LoggerFactory;
  32. import com.gitblit.models.RefModel;
  33. import com.gitblit.utils.ArrayUtils;
  34. import com.gitblit.utils.JGitUtils;
  35. import com.gitblit.utils.MarkdownUtils;
  36. import com.gitblit.utils.StringUtils;
  37. import com.gitblit.wicket.MarkupProcessor;
  38. import com.gitblit.wicket.MarkupProcessor.MarkupDocument;
  39. /**
  40. * Serves the content of a gh-pages branch.
  41. *
  42. * @author James Moger
  43. *
  44. */
  45. public class PagesServlet extends HttpServlet {
  46. private static final long serialVersionUID = 1L;
  47. private transient Logger logger = LoggerFactory.getLogger(PagesServlet.class);
  48. public PagesServlet() {
  49. super();
  50. }
  51. /**
  52. * Returns an url to this servlet for the specified parameters.
  53. *
  54. * @param baseURL
  55. * @param repository
  56. * @param path
  57. * @return an url
  58. */
  59. public static String asLink(String baseURL, String repository, String path) {
  60. if (baseURL.length() > 0 && baseURL.charAt(baseURL.length() - 1) == '/') {
  61. baseURL = baseURL.substring(0, baseURL.length() - 1);
  62. }
  63. return baseURL + Constants.PAGES + repository + "/" + (path == null ? "" : ("/" + path));
  64. }
  65. /**
  66. * Retrieves the specified resource from the gh-pages branch of the
  67. * repository.
  68. *
  69. * @param request
  70. * @param response
  71. * @throws javax.servlet.ServletException
  72. * @throws java.io.IOException
  73. */
  74. private void processRequest(HttpServletRequest request, HttpServletResponse response)
  75. throws ServletException, IOException {
  76. String path = request.getPathInfo();
  77. if (path.toLowerCase().endsWith(".git")) {
  78. // forward to url with trailing /
  79. // this is important for relative pages links
  80. response.sendRedirect(request.getServletPath() + path + "/");
  81. return;
  82. }
  83. if (path.charAt(0) == '/') {
  84. // strip leading /
  85. path = path.substring(1);
  86. }
  87. // determine repository and resource from url
  88. String repository = "";
  89. String resource = "";
  90. Repository r = null;
  91. int offset = 0;
  92. while (r == null) {
  93. int slash = path.indexOf('/', offset);
  94. if (slash == -1) {
  95. repository = path;
  96. } else {
  97. repository = path.substring(0, slash);
  98. }
  99. r = GitBlit.self().getRepository(repository, false);
  100. offset = slash + 1;
  101. if (offset > 0) {
  102. resource = path.substring(offset);
  103. }
  104. if (repository.equals(path)) {
  105. // either only repository in url or no repository found
  106. break;
  107. }
  108. }
  109. ServletContext context = request.getSession().getServletContext();
  110. try {
  111. if (r == null) {
  112. // repository not found!
  113. String mkd = MessageFormat.format(
  114. "# Error\nSorry, no valid **repository** specified in this url: {0}!",
  115. repository);
  116. error(response, mkd);
  117. return;
  118. }
  119. // retrieve the content from the repository
  120. RefModel pages = JGitUtils.getPagesBranch(r);
  121. RevCommit commit = JGitUtils.getCommit(r, pages.getObjectId().getName());
  122. if (commit == null) {
  123. // branch not found!
  124. String mkd = MessageFormat.format(
  125. "# Error\nSorry, the repository {0} does not have a **gh-pages** branch!",
  126. repository);
  127. error(response, mkd);
  128. r.close();
  129. return;
  130. }
  131. MarkupProcessor processor = new MarkupProcessor(GitBlit.getSettings());
  132. String [] encodings = GitBlit.getEncodings();
  133. RevTree tree = commit.getTree();
  134. byte[] content = null;
  135. if (StringUtils.isEmpty(resource)) {
  136. // find resource
  137. List<String> extensions = new ArrayList<String>(processor.getMarkupExtensions());
  138. extensions.add("html");
  139. extensions.add("htm");
  140. for (String ext : extensions) {
  141. String file = "index." + ext;
  142. String stringContent = JGitUtils.getStringContent(r, tree, file, encodings);
  143. if (stringContent == null) {
  144. continue;
  145. }
  146. content = stringContent.getBytes(Constants.ENCODING);
  147. if (content != null) {
  148. resource = file;
  149. // assume text/html unless the servlet container
  150. // overrides
  151. response.setContentType("text/html; charset=" + Constants.ENCODING);
  152. break;
  153. }
  154. }
  155. } else {
  156. // specific resource
  157. try {
  158. String contentType = context.getMimeType(resource);
  159. if (contentType == null) {
  160. contentType = "text/plain";
  161. }
  162. if (contentType.startsWith("text")) {
  163. content = JGitUtils.getStringContent(r, tree, resource, encodings).getBytes(
  164. Constants.ENCODING);
  165. } else {
  166. content = JGitUtils.getByteContent(r, tree, resource, false);
  167. }
  168. response.setContentType(contentType);
  169. } catch (Exception e) {
  170. }
  171. }
  172. // no content, try custom 404 page
  173. if (ArrayUtils.isEmpty(content)) {
  174. String custom404 = JGitUtils.getStringContent(r, tree, "404.html", encodings);
  175. if (!StringUtils.isEmpty(custom404)) {
  176. content = custom404.getBytes(Constants.ENCODING);
  177. }
  178. // still no content
  179. if (ArrayUtils.isEmpty(content)) {
  180. String str = MessageFormat.format(
  181. "# Error\nSorry, the requested resource **{0}** was not found.",
  182. resource);
  183. content = MarkdownUtils.transformMarkdown(str).getBytes(Constants.ENCODING);
  184. }
  185. try {
  186. // output the content
  187. logger.warn("Pages 404: " + resource);
  188. response.setStatus(HttpServletResponse.SC_NOT_FOUND);
  189. response.getOutputStream().write(content);
  190. response.flushBuffer();
  191. } catch (Throwable t) {
  192. logger.error("Failed to write page to client", t);
  193. }
  194. return;
  195. }
  196. // check to see if we should transform markup files
  197. String ext = StringUtils.getFileExtension(resource);
  198. if (processor.getMarkupExtensions().contains(ext)) {
  199. String markup = new String(content, Constants.ENCODING);
  200. MarkupDocument markupDoc = processor.parse(repository, commit.getName(), resource, markup);
  201. content = markupDoc.html.getBytes("UTF-8");
  202. response.setContentType("text/html; charset=" + Constants.ENCODING);
  203. }
  204. try {
  205. // output the content
  206. response.setHeader("Cache-Control", "public, max-age=3600, must-revalidate");
  207. response.setDateHeader("Last-Modified", JGitUtils.getCommitDate(commit).getTime());
  208. response.getOutputStream().write(content);
  209. response.flushBuffer();
  210. } catch (Throwable t) {
  211. logger.error("Failed to write page to client", t);
  212. }
  213. // close the repository
  214. r.close();
  215. } catch (Throwable t) {
  216. logger.error("Failed to write page to client", t);
  217. }
  218. }
  219. private void error(HttpServletResponse response, String mkd) throws ServletException,
  220. IOException, ParseException {
  221. String content = MarkdownUtils.transformMarkdown(mkd);
  222. response.setContentType("text/html; charset=" + Constants.ENCODING);
  223. response.getWriter().write(content);
  224. }
  225. @Override
  226. protected void doPost(HttpServletRequest request, HttpServletResponse response)
  227. throws ServletException, IOException {
  228. processRequest(request, response);
  229. }
  230. @Override
  231. protected void doGet(HttpServletRequest request, HttpServletResponse response)
  232. throws ServletException, IOException {
  233. processRequest(request, response);
  234. }
  235. }