/* * Copyright 2013 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.wicket; import java.util.Date; import javax.servlet.http.HttpServletRequest; import org.apache.wicket.protocol.http.WicketFilter; import org.apache.wicket.util.string.Strings; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.revwalk.RevCommit; import com.gitblit.GitBlit; import com.gitblit.Keys; import com.gitblit.models.ProjectModel; import com.gitblit.models.RepositoryModel; import com.gitblit.utils.JGitUtils; import com.gitblit.utils.StringUtils; /** * * Customization of the WicketFilter to allow smart browser-side caching of * some pages. * * @author James Moger * */ public class GitblitWicketFilter extends WicketFilter { /** * Determines the last-modified date of the requested resource. * * @param servletRequest * @return The last modified time stamp */ protected long getLastModified(final HttpServletRequest servletRequest) { final String pathInfo = getRelativePath(servletRequest); if (Strings.isEmpty(pathInfo)) return -1; long lastModified = super.getLastModified(servletRequest); if (lastModified > -1) { return lastModified; } // try to match request against registered CacheControl pages String [] paths = pathInfo.split("/"); String page = paths[0]; String repo = ""; String commitId = ""; if (paths.length >= 2) { repo = paths[1]; } if (paths.length >= 3) { commitId = paths[2]; } if (!StringUtils.isEmpty(servletRequest.getParameter("r"))) { repo = servletRequest.getParameter("r"); } if (!StringUtils.isEmpty(servletRequest.getParameter("h"))) { commitId = servletRequest.getParameter("h"); } repo = repo.replace("%2f", "/").replace("%2F", "/").replace(GitBlit.getChar(Keys.web.forwardSlashCharacter, '/'), '/'); GitBlitWebApp app = (GitBlitWebApp) getWebApplication(); int expires = GitBlit.getInteger(Keys.web.pageCacheExpires, 0); if (!StringUtils.isEmpty(page) && app.isCacheablePage(page) && expires > 0) { // page can be cached by the browser CacheControl cacheControl = app.getCacheControl(page); Date bootDate = GitBlit.getBootDate(); switch (cacheControl.value()) { case ACTIVITY: // returns the last activity date of the server Date activityDate = GitBlit.getLastActivityDate(); if (activityDate != null) { return activityDate.after(bootDate) ? activityDate.getTime() : bootDate.getTime(); } return bootDate.getTime(); case BOOT: // return the boot date of the server return bootDate.getTime(); case PROJECT: // return the latest change date for the project OR the boot date ProjectModel project = GitBlit.self().getProjectModel(StringUtils.getRootPath(repo)); if (project != null) { return project.lastChange.after(bootDate) ? project.lastChange.getTime() : bootDate.getTime(); } break; case REPOSITORY: // return the lastest change date for the repository OR the boot // date, whichever is latest RepositoryModel repository = GitBlit.self().getRepositoryModel(repo); if (repository != null && repository.lastChange != null) { return repository.lastChange.after(bootDate) ? repository.lastChange.getTime() : bootDate.getTime(); } break; case COMMIT: // get the date of the specified commit if (StringUtils.isEmpty(commitId)) { // no commit id, use boot date return bootDate.getTime(); } else { // last modified date is the commit date Repository r = null; try { // return the timestamp of the associated commit r = GitBlit.self().getRepository(repo); if (r != null) { RevCommit commit = JGitUtils.getCommit(r, commitId); if (commit != null) { Date date = JGitUtils.getCommitDate(commit); return date.after(bootDate) ? date.getTime() : bootDate.getTime(); } } } finally { if (r != null) { r.close(); } } } break; default: break; } } return -1; } }