James Moger
2013-11-18 11642275bab78a22da2f85ed06eb2246f8444f4f
Instantiate and register all servlets and filters from code (servlet 3)

Change-Id: I6009e8e157232feab40ec275547a59e2cea23950
1 files added
11 files modified
609 ■■■■ changed files
src/main/java/WEB-INF/web.xml 267 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/DownloadZipFilter.java 3 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/EnforceAuthenticationFilter.java 3 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/GitBlit.java 59 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/GitFilter.java 3 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/InjectionContextListener.java 241 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/PagesFilter.java 3 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/RpcFilter.java 3 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/SyndicationFilter.java 3 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/SyndicationServlet.java 3 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/git/GitServlet.java 3 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/wicket/GitblitWicketFilter.java 18 ●●●●● patch | view | raw | blame | history
src/main/java/WEB-INF/web.xml
@@ -35,271 +35,4 @@
    </display-name>
    <!-- PARAMS --> 
    <!-- Gitblit Context Listener --><!-- STRIP
    <listener>
         <listener-class>com.gitblit.GitBlit</listener-class>
     </listener>STRIP -->
    <!-- Git Servlet
         <url-pattern> MUST match:
            * GitFilter
            * com.gitblit.Constants.GIT_PATH
            * Wicket Filter ignorePaths parameter -->
    <servlet>
        <servlet-name>GitServlet</servlet-name>
        <servlet-class>com.gitblit.git.GitServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>GitServlet</servlet-name>
        <url-pattern>/git/*</url-pattern>
    </servlet-mapping>
    <!-- SparkleShare Invite Servlet
         <url-pattern> MUST match:
            * com.gitblit.Constants.SPARKLESHARE_INVITE_PATH
            * Wicket Filter ignorePaths parameter -->
    <servlet>
        <servlet-name>SparkleShareInviteServlet</servlet-name>
        <servlet-class>com.gitblit.SparkleShareInviteServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>SparkleShareInviteServlet</servlet-name>
        <url-pattern>/sparkleshare/*</url-pattern>
    </servlet-mapping>
    <!-- Syndication Servlet
         <url-pattern> MUST match:
            * SyndicationFilter
            * com.gitblit.Constants.SYNDICATION_PATH
            * Wicket Filter ignorePaths parameter -->
    <servlet>
        <servlet-name>SyndicationServlet</servlet-name>
        <servlet-class>com.gitblit.SyndicationServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>SyndicationServlet</servlet-name>
        <url-pattern>/feed/*</url-pattern>
    </servlet-mapping>
    <!-- Zip Servlet
         <url-pattern> MUST match:
            * ZipServlet
            * com.gitblit.Constants.ZIP_PATH
            * Wicket Filter ignorePaths parameter -->
    <servlet>
        <servlet-name>ZipServlet</servlet-name>
        <servlet-class>com.gitblit.DownloadZipServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>ZipServlet</servlet-name>
        <url-pattern>/zip/*</url-pattern>
    </servlet-mapping>
    <!-- Federation Servlet
         <url-pattern> MUST match:
             * com.gitblit.Constants.FEDERATION_PATH
            * Wicket Filter ignorePaths parameter -->
    <servlet>
        <servlet-name>FederationServlet</servlet-name>
        <servlet-class>com.gitblit.FederationServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>FederationServlet</servlet-name>
        <url-pattern>/federation/*</url-pattern>
    </servlet-mapping>
    <!-- Rpc Servlet
         <url-pattern> MUST match:
             * com.gitblit.Constants.RPC_PATH
            * Wicket Filter ignorePaths parameter -->
    <servlet>
        <servlet-name>RpcServlet</servlet-name>
        <servlet-class>com.gitblit.RpcServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>RpcServlet</servlet-name>
        <url-pattern>/rpc/*</url-pattern>
    </servlet-mapping>
    <!-- Pages Servlet
         <url-pattern> MUST match:
            * PagesFilter
            * com.gitblit.Constants.PAGES_PATH
            * Wicket Filter ignorePaths parameter -->
    <servlet>
        <servlet-name>PagesServlet</servlet-name>
        <servlet-class>com.gitblit.PagesServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>PagesServlet</servlet-name>
        <url-pattern>/pages/*</url-pattern>
    </servlet-mapping>
    <!-- Logo Servlet
         <url-pattern> MUST match:
            * Wicket Filter ignorePaths parameter -->
    <servlet>
        <servlet-name>LogoServlet</servlet-name>
        <servlet-class>com.gitblit.LogoServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>LogoServlet</servlet-name>
        <url-pattern>/logo.png</url-pattern>
    </servlet-mapping>
    <!-- Branch Graph Servlet
         <url-pattern> MUST match:
            * Wicket Filter ignorePaths parameter -->
    <servlet>
        <servlet-name>BranchGraphServlet</servlet-name>
        <servlet-class>com.gitblit.BranchGraphServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>BranchGraphServlet</servlet-name>
        <url-pattern>/graph/*</url-pattern>
    </servlet-mapping>
    <!-- Robots.txt Servlet
         <url-pattern> MUST match:
            * Wicket Filter ignorePaths parameter -->
    <servlet>
        <servlet-name>RobotsTxtServlet</servlet-name>
        <servlet-class>com.gitblit.RobotsTxtServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>RobotsTxtServlet</servlet-name>
        <url-pattern>/robots.txt</url-pattern>
    </servlet-mapping>
    <!-- Git Access Restriction Filter
         <url-pattern> MUST match:
            * GitServlet
            * com.gitblit.Constants.GIT_PATH
            * Wicket Filter ignorePaths parameter -->
    <filter>
        <filter-name>GitFilter</filter-name>
        <filter-class>com.gitblit.GitFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>GitFilter</filter-name>
        <url-pattern>/git/*</url-pattern>
    </filter-mapping>
    <!-- Syndication Restriction Filter
         <url-pattern> MUST match:
            * SyndicationServlet
            * com.gitblit.Constants.SYNDICATION_PATH
            * Wicket Filter ignorePaths parameter -->
    <filter>
        <filter-name>SyndicationFilter</filter-name>
        <filter-class>com.gitblit.SyndicationFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>SyndicationFilter</filter-name>
        <url-pattern>/feed/*</url-pattern>
    </filter-mapping>
    <!-- Download Zip Restriction Filter
         <url-pattern> MUST match:
            * DownloadZipServlet
            * com.gitblit.Constants.ZIP_PATH
            * Wicket Filter ignorePaths parameter -->
    <filter>
        <filter-name>ZipFilter</filter-name>
        <filter-class>com.gitblit.DownloadZipFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>ZipFilter</filter-name>
        <url-pattern>/zip/*</url-pattern>
    </filter-mapping>
    <!-- Rpc Restriction Filter
         <url-pattern> MUST match:
            * RpcServlet
            * com.gitblit.Constants.RPC_PATH
            * Wicket Filter ignorePaths parameter -->
    <filter>
        <filter-name>RpcFilter</filter-name>
        <filter-class>com.gitblit.RpcFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>RpcFilter</filter-name>
        <url-pattern>/rpc/*</url-pattern>
    </filter-mapping>
    <!-- Pges Restriction Filter
         <url-pattern> MUST match:
            * PagesServlet
            * com.gitblit.Constants.PAGES_PATH
            * Wicket Filter ignorePaths parameter -->
    <filter>
        <filter-name>PagesFilter</filter-name>
        <filter-class>com.gitblit.PagesFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>PagesFilter</filter-name>
        <url-pattern>/pages/*</url-pattern>
    </filter-mapping>
    <filter>
        <filter-name>EnforceAuthenticationFilter</filter-name>
        <filter-class>com.gitblit.EnforceAuthenticationFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>EnforceAuthenticationFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <!-- Wicket Filter -->
    <filter>
        <filter-name>wicketFilter</filter-name>
        <filter-class>
            com.gitblit.wicket.GitblitWicketFilter
        </filter-class>
        <init-param>
            <param-name>applicationClassName</param-name>
            <param-value>com.gitblit.wicket.GitBlitWebApp</param-value>
        </init-param>
        <init-param>
            <param-name>ignorePaths</param-name>
            <!-- Paths should match
                 * SyndicationFilter <url-pattern>
                 * SyndicationServlet <url-pattern>
                 * com.gitblit.Constants.SYNDICATION_PATH
                 * GitFilter <url-pattern>
                 * GitServlet <url-pattern>
                 * com.gitblit.Constants.GIT_PATH
                 * SparkleshareInviteServlet <url-pattern>
                 * com.gitblit.Constants.SPARKLESHARE_INVITE_PATH
                 * Zipfilter <url-pattern>
                 * ZipServlet <url-pattern>
                 * com.gitblit.Constants.ZIP_PATH
                 * FederationServlet <url-pattern>
                 * RpcFilter <url-pattern>
                 * RpcServlet <url-pattern>
                 * PagesFilter <url-pattern>
                 * PagesServlet <url-pattern>
                 * com.gitblit.Constants.PAGES_PATH -->
            <param-value>git/,feed/,zip/,federation/,rpc/,pages/,robots.txt,logo.png,graph/,sparkleshare/</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>wicketFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>
src/main/java/com/gitblit/DownloadZipFilter.java
@@ -29,6 +29,9 @@
 */
public class DownloadZipFilter extends AccessRestrictionFilter {
    public DownloadZipFilter() {
    }
    /**
     * Extract the repository name from the url.
     *
src/main/java/com/gitblit/EnforceAuthenticationFilter.java
@@ -46,6 +46,9 @@
    protected transient Logger logger = LoggerFactory.getLogger(getClass());
    public EnforceAuthenticationFilter() {
    }
    /*
     * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
     */
src/main/java/com/gitblit/GitBlit.java
@@ -66,7 +66,7 @@
import javax.naming.NamingException;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -83,7 +83,6 @@
import org.eclipse.jgit.util.FS;
import org.eclipse.jgit.util.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.gitblit.Constants.AccessPermission;
import com.gitblit.Constants.AccessRestrictionType;
@@ -100,6 +99,7 @@
import com.gitblit.fanout.FanoutService;
import com.gitblit.fanout.FanoutSocketService;
import com.gitblit.git.GitDaemon;
import com.gitblit.git.GitServlet;
import com.gitblit.manager.IFederationManager;
import com.gitblit.manager.IGitblitManager;
import com.gitblit.manager.INotificationManager;
@@ -144,6 +144,7 @@
import com.gitblit.utils.TimeUtils;
import com.gitblit.utils.X509Utils.X509Metadata;
import com.gitblit.wicket.GitBlitWebSession;
import com.gitblit.wicket.GitblitWicketFilter;
import com.gitblit.wicket.WicketUtils;
import com.google.gson.Gson;
import com.google.gson.JsonIOException;
@@ -153,21 +154,18 @@
/**
 * GitBlit is the servlet context listener singleton that acts as the core for
 * the web ui and the servlets. This class is either directly instantiated by
 * the GitBlitServer class (Gitblit GO) or is reflectively instantiated from the
 * definition in the web.xml file (Gitblit WAR).
 * the GitBlitServer class (Gitblit GO) or is reflectively instantiated by the
 * servlet 3 container (Gitblit WAR or Express).
 *
 * This class is the central logic processor for Gitblit. All settings, user
 * object, and repository object operations pass through this class.
 *
 * Repository Resolution. There are two pathways for finding repositories. One
 * pathway, for web ui display and repository authentication & authorization, is
 * within this class. The other pathway is through the standard GitServlet.
 *
 * @author James Moger
 *
 */
public class GitBlit implements ServletContextListener,
                                IRuntimeManager,
@WebListener
public class GitBlit extends InjectionContextListener
                     implements IRuntimeManager,
                                INotificationManager,
                                IUserManager,
                                ISessionManager,
@@ -179,8 +177,6 @@
    private static GitBlit gitblit;
    private final IStoredSettings goSettings;
    private final Logger logger = LoggerFactory.getLogger(GitBlit.class);
    private final ScheduledExecutorService scheduledExecutor = Executors.newScheduledThreadPool(10);
@@ -204,8 +200,6 @@
    private final ObjectCache<String> projectMarkdownCache = new ObjectCache<String>();
    private final ObjectCache<String> projectRepositoriesMarkdownCache = new ObjectCache<String>();
    private ServletContext servletContext;
    private File baseFolder;
@@ -3718,11 +3712,9 @@
     * @see ServletContextListener.contextInitialize(ServletContextEvent)
     */
    @Override
    public void contextInitialized(ServletContextEvent contextEvent) {
        servletContext = contextEvent.getServletContext();
    protected void beforeServletInjection(ServletContext context) {
        if (settings == null) {
            // Gitblit is running in a servlet container
            ServletContext context = contextEvent.getServletContext();
            WebXmlSettings webxmlSettings = new WebXmlSettings(context);
            String contextRealPath = context.getRealPath("/");
            File contextFolder = (contextRealPath != null) ? new File(contextRealPath) : null;
@@ -3807,7 +3799,7 @@
        }
        settingsModel = loadSettingModels();
        serverStatus.servletContainer = servletContext.getServerInfo();
        serverStatus.servletContainer = context.getServerInfo();
    }
    protected void extractResources(ServletContext context, String path, File toDir) {
@@ -4059,4 +4051,35 @@
        setCookie(response,  null);
        userService.logout(user);
    }
    /**
     * Instantiate and inject all filters and servlets into the container using
     * the servlet 3 specification.
     */
    @Override
    protected void injectServlets(ServletContext context) {
        // access restricted servlets
        serve(context, Constants.GIT_PATH, GitServlet.class, GitFilter.class);
        serve(context, Constants.PAGES, PagesServlet.class, PagesFilter.class);
        serve(context, Constants.RPC_PATH, RpcServlet.class, RpcFilter.class);
        serve(context, Constants.ZIP_PATH, DownloadZipServlet.class, DownloadZipFilter.class);
        serve(context, Constants.SYNDICATION_PATH, SyndicationServlet.class, SyndicationFilter.class);
        // servlets
        serve(context, Constants.FEDERATION_PATH, FederationServlet.class);
        serve(context, Constants.SPARKLESHARE_INVITE_PATH, SparkleShareInviteServlet.class);
        serve(context, Constants.BRANCH_GRAPH_PATH, BranchGraphServlet.class);
        file(context, "/robots.txt", RobotsTxtServlet.class);
        file(context, "/logo.png", LogoServlet.class);
        // optional force basic authentication
        filter(context, "/*", EnforceAuthenticationFilter.class, null);
        // Wicket
        String toIgnore = StringUtils.flattenStrings(getRegisteredPaths(), ",");
        Map<String, String> params = new HashMap<String, String>();
        params.put(GitblitWicketFilter.FILTER_MAPPING_PARAM, "/*");
        params.put(GitblitWicketFilter.IGNORE_PATHS_PARAM, toIgnore);
        filter(context, "/*", GitblitWicketFilter.class, params);
    }
}
src/main/java/com/gitblit/GitFilter.java
@@ -42,6 +42,9 @@
    protected static final String[] suffixes = { gitReceivePack, gitUploadPack, "/info/refs", "/HEAD",
            "/objects" };
    public GitFilter() {
    }
    /**
     * Extract the repository name from the url.
     *
src/main/java/com/gitblit/InjectionContextListener.java
New file
@@ -0,0 +1,241 @@
/*
 * 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;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.FilterRegistration;
import javax.servlet.Servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletRegistration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
 * Injection context listener instantiates and injects servlets, filters, and
 * anything else you might want into a servlet context.  This class provides
 * convenience methods for servlet & filter registration and also tracks
 * registered paths.
 *
 * @author James Moger
 *
 */
public abstract class InjectionContextListener implements ServletContextListener {
    protected final Logger logger = LoggerFactory.getLogger(getClass());
    private final List<String> registeredPaths = new ArrayList<String>();
    protected final List<String> getRegisteredPaths() {
        return registeredPaths;
    }
    /**
     * Hook for subclasses to manipulate context initialization before
     * standard initialization procedure.
     *
     * @param context
     */
    protected void beforeServletInjection(ServletContext context) {
        // NOOP
    }
    /**
     * Hook for subclasses to instantiate and inject servlets and filters
     * into the servlet context.
     *
     * @param context
     */
    protected abstract void injectServlets(ServletContext context);
    /**
     * Hook for subclasses to manipulate context initialization after
     * servlet registration.
     *
     * @param context
     */
    protected void afterServletInjection(ServletContext context) {
        // NOOP
    }
    /**
     * Configure Gitblit from the web.xml, if no configuration has already been
     * specified.
     *
     * @see ServletContextListener.contextInitialize(ServletContextEvent)
     */
    @Override
    public final void contextInitialized(ServletContextEvent contextEvent) {
        ServletContext context = contextEvent.getServletContext();
        beforeServletInjection(context);
        injectServlets(context);
        afterServletInjection(context);
    }
    /**
     * Registers a file path.
     *
     * @param context
     * @param file
     * @param servletClass
     */
    protected void file(ServletContext context, String file, Class<? extends Servlet> servletClass) {
        file(context, file, servletClass, null);
    }
    /**
     * Registers a file path with init parameters.
     *
     * @param context
     * @param file
     * @param servletClass
     * @param initParams
     */
    protected void file(ServletContext context, String file, Class<? extends Servlet> servletClass, Map<String, String> initParams) {
        Servlet servlet = instantiate(context, servletClass);
        ServletRegistration.Dynamic d = context.addServlet(sanitize(servletClass.getSimpleName() + file), servlet);
        d.addMapping(file);
        if (initParams != null) {
            d.setInitParameters(initParams);
        }
        registeredPaths.add(file);
    }
    /**
     * Serves a path (trailing wildcard will be appended).
     *
     * @param context
     * @param route
     * @param servletClass
     */
    protected void serve(ServletContext context, String route, Class<? extends Servlet> servletClass) {
        serve(context, route, servletClass, (Class<Filter>) null);
    }
    /**
     * Serves a path (trailing wildcard will be appended) with init parameters.
     *
     * @param context
     * @param route
     * @param servletClass
     * @param initParams
     */
    protected void serve(ServletContext context, String route, Class<? extends Servlet> servletClass, Map<String, String> initParams) {
        Servlet servlet = instantiate(context, servletClass);
        ServletRegistration.Dynamic d = context.addServlet(sanitize(servletClass.getSimpleName() + route), servlet);
        d.addMapping(route + "*");
        if (initParams != null) {
            d.setInitParameters(initParams);
        }
        registeredPaths.add(route);
    }
    /**
     * Serves a path (trailing wildcard will be appended) and also maps a filter
     * to that path.
     *
     * @param context
     * @param route
     * @param servletClass
     * @param filterClass
     */
    protected void serve(ServletContext context, String route, Class<? extends Servlet> servletClass, Class<? extends Filter> filterClass) {
        Servlet servlet = instantiate(context, servletClass);
        ServletRegistration.Dynamic d = context.addServlet(sanitize(servletClass.getSimpleName() + route), servlet);
        d.addMapping(route + "*");
        if (filterClass != null) {
            filter(context, route + "*", filterClass);
        }
        registeredPaths.add(route);
    }
    /**
     * Registers a path filter.
     *
     * @param context
     * @param route
     * @param filterClass
     */
    protected void filter(ServletContext context, String route, Class<? extends Filter> filterClass) {
        filter(context, route, filterClass, null);
    }
    /**
     * Registers a path filter with init parameters.
     *
     * @param context
     * @param route
     * @param filterClass
     * @param initParams
     */
    protected void filter(ServletContext context, String route, Class<? extends Filter> filterClass, Map<String, String> initParams) {
        Filter filter = instantiate(context, filterClass);
        FilterRegistration.Dynamic d = context.addFilter(sanitize(filterClass.getSimpleName() + route), filter);
        d.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, route);
        if (initParams != null) {
            d.setInitParameters(initParams);
        }
    }
    /**
     * Limit the generated servlet/filter names to alpha-numeric values with a
     * handful of acceptable other characters.
     *
     * @param name
     * @return a sanitized name
     */
    protected String sanitize(String name) {
        StringBuilder sb = new StringBuilder();
        for (char c : name.toCharArray()) {
            if (Character.isLetterOrDigit(c)) {
                sb.append(c);
            } else if ('-' == c) {
                sb.append(c);
            } else if ('*' == c) {
                sb.append("all");
            } else if ('.' == c) {
                sb.append('.');
            } else {
                sb.append('_');
            }
        }
        return sb.toString();
    }
    /**
     * Instantiates an object.
     *
     * @param clazz
     * @return the object
     */
    protected <X> X instantiate(ServletContext context, Class<X> clazz) {
        try {
            return clazz.newInstance();
        } catch (Throwable t) {
            logger.error(null, t);
        }
        return null;
    }
}
src/main/java/com/gitblit/PagesFilter.java
@@ -31,6 +31,9 @@
 */
public class PagesFilter extends AccessRestrictionFilter {
    public PagesFilter() {
    }
    /**
     * Extract the repository name from the url.
     *
src/main/java/com/gitblit/RpcFilter.java
@@ -44,6 +44,9 @@
 */
public class RpcFilter extends AuthenticationFilter {
    public RpcFilter() {
    }
    /**
     * doFilter does the actual work of preprocessing the request to ensure that
     * the user may proceed.
src/main/java/com/gitblit/SyndicationFilter.java
@@ -43,6 +43,9 @@
 */
public class SyndicationFilter extends AuthenticationFilter {
    public SyndicationFilter() {
    }
    /**
     * Extract the repository name from the url.
     *
src/main/java/com/gitblit/SyndicationServlet.java
@@ -59,6 +59,9 @@
    private transient Logger logger = LoggerFactory.getLogger(SyndicationServlet.class);
    public SyndicationServlet() {
    }
    /**
     * Create a feed link for the specified repository and branch/tag/commit id.
     *
src/main/java/com/gitblit/git/GitServlet.java
@@ -33,6 +33,9 @@
    private static final long serialVersionUID = 1L;
    public GitServlet() {
    }
    @Override
    public void init(ServletConfig config) throws ServletException {
        IRepositoryManager repositoryManager = GitBlit.getManager(IRepositoryManager.class);
src/main/java/com/gitblit/wicket/GitblitWicketFilter.java
@@ -19,6 +19,8 @@
import javax.servlet.http.HttpServletRequest;
import org.apache.wicket.protocol.http.IWebApplicationFactory;
import org.apache.wicket.protocol.http.WebApplication;
import org.apache.wicket.protocol.http.WicketFilter;
import org.apache.wicket.util.string.Strings;
import org.eclipse.jgit.lib.Repository;
@@ -45,6 +47,19 @@
 */
public class GitblitWicketFilter extends WicketFilter {
    public GitblitWicketFilter() {
    }
    @Override
    protected IWebApplicationFactory getApplicationFactory() {
        return new IWebApplicationFactory() {
            @Override
            public WebApplication createApplication(WicketFilter filter) {
                return new GitBlitWebApp();
            }
        };
    }
    /**
     * Determines the last-modified date of the requested resource.
     *
@@ -54,8 +69,9 @@
    @Override
    protected long getLastModified(final HttpServletRequest servletRequest)    {
        final String pathInfo = getRelativePath(servletRequest);
        if (Strings.isEmpty(pathInfo))
        if (Strings.isEmpty(pathInfo)) {
            return -1;
        }
        long lastModified = super.getLastModified(servletRequest);
        if (lastModified > -1) {
            return lastModified;