From: James Moger Date: Fri, 23 May 2014 12:17:11 +0000 (-0400) Subject: Use Guice-Servlet rather than custom code and expose the Injector X-Git-Tag: v1.7.0~1^2~202^2~16 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=c828cf2db88956094a31a79741145688876879df;p=gitblit.git Use Guice-Servlet rather than custom code and expose the Injector This is a fairly functional variation of Gitblit with one notable exception: The security filters are not working properly. This is a design flaw in Guice that I have reported upstream [1]. The general idea is that Guice-Servlet filters are not properly wrapping the ServletRequest. This has historically been a problem for Guice-Servlet servlets but Google has fixed most of those issues. Unfortunately, all the same flaws reported against the servlet delegation also exist in Guice-Servlet filter delegation. :( [1]: https://code.google.com/p/google-guice/issues/detail?id=807 --- diff --git a/.classpath b/.classpath index ec9495fb..9c3e7b8c 100644 --- a/.classpath +++ b/.classpath @@ -9,6 +9,7 @@ + diff --git a/build.moxie b/build.moxie index 0501b779..b25a4222 100644 --- a/build.moxie +++ b/build.moxie @@ -112,6 +112,7 @@ properties: { wikitext.version : 1.4 sshd.version: 0.11.1-atlassian-1 mina.version: 2.0.7 + guice.version : 4.0-beta4 } # Dependencies @@ -127,7 +128,8 @@ properties: { dependencies: # Dagger dependency injection library (annotation processor) -- compile 'com.google.inject:guice:4.0-beta4' :war +- compile 'com.google.inject:guice:${guice.version}' :war +- compile 'com.google.inject.extensions:guice-servlet:${guice.version}' :war - compile 'com.google.guava:guava:16.0.1' :war # Standard dependencies - compile 'com.intellij:annotations:12.0' :war diff --git a/gitblit.iml b/gitblit.iml index 9a689dab..f8a8a674 100644 --- a/gitblit.iml +++ b/gitblit.iml @@ -57,6 +57,17 @@ + + + + + + + + + + + diff --git a/src/main/java/WEB-INF/web.xml b/src/main/java/WEB-INF/web.xml index 2a570e32..88422249 100644 --- a/src/main/java/WEB-INF/web.xml +++ b/src/main/java/WEB-INF/web.xml @@ -1,7 +1,7 @@ - + xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> Gitblit - @gb.version@ + + com.gitblit.servlet.GitblitContext + + + + guiceFilter + com.google.inject.servlet.GuiceFilter + + + + guiceFilter + /* + + \ No newline at end of file diff --git a/src/main/java/com/gitblit/guice/CoreModule.java b/src/main/java/com/gitblit/guice/CoreModule.java new file mode 100644 index 00000000..9b479c09 --- /dev/null +++ b/src/main/java/com/gitblit/guice/CoreModule.java @@ -0,0 +1,100 @@ +/* + * 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.guice; + +import javax.inject.Singleton; + +import com.gitblit.FileSettings; +import com.gitblit.GitBlit; +import com.gitblit.IStoredSettings; +import com.gitblit.Keys; +import com.gitblit.manager.AuthenticationManager; +import com.gitblit.manager.FederationManager; +import com.gitblit.manager.IAuthenticationManager; +import com.gitblit.manager.IFederationManager; +import com.gitblit.manager.IGitblit; +import com.gitblit.manager.INotificationManager; +import com.gitblit.manager.IPluginManager; +import com.gitblit.manager.IProjectManager; +import com.gitblit.manager.IRepositoryManager; +import com.gitblit.manager.IRuntimeManager; +import com.gitblit.manager.IUserManager; +import com.gitblit.manager.NotificationManager; +import com.gitblit.manager.PluginManager; +import com.gitblit.manager.ProjectManager; +import com.gitblit.manager.RepositoryManager; +import com.gitblit.manager.RuntimeManager; +import com.gitblit.manager.UserManager; +import com.gitblit.transport.ssh.FileKeyManager; +import com.gitblit.transport.ssh.IPublicKeyManager; +import com.gitblit.transport.ssh.MemoryKeyManager; +import com.gitblit.transport.ssh.NullKeyManager; +import com.gitblit.utils.StringUtils; +import com.google.inject.AbstractModule; +import com.google.inject.Provides; + +/** + * CoreModule references all the core business objects. + * + * @author James Moger + * + */ +public class CoreModule extends AbstractModule { + + @Override + protected void configure() { + + bind(IStoredSettings.class).toInstance(new FileSettings()); + + // core managers + bind(IRuntimeManager.class).to(RuntimeManager.class).in(Singleton.class); + bind(IPluginManager.class).to(PluginManager.class).in(Singleton.class); + bind(INotificationManager.class).to(NotificationManager.class).in(Singleton.class); + bind(IUserManager.class).to(UserManager.class).in(Singleton.class); + bind(IAuthenticationManager.class).to(AuthenticationManager.class).in(Singleton.class); + bind(IRepositoryManager.class).to(RepositoryManager.class).in(Singleton.class); + bind(IProjectManager.class).to(ProjectManager.class).in(Singleton.class); + bind(IFederationManager.class).to(FederationManager.class).in(Singleton.class); + + // the monolithic manager + bind(IGitblit.class).to(GitBlit.class).in(Singleton.class); + } + + @Provides + @Singleton + IPublicKeyManager providePublicKeyManager(IStoredSettings settings, IRuntimeManager runtimeManager) { + + String clazz = settings.getString(Keys.git.sshKeysManager, FileKeyManager.class.getName()); + if (StringUtils.isEmpty(clazz)) { + clazz = FileKeyManager.class.getName(); + } + if (FileKeyManager.class.getName().equals(clazz)) { + return new FileKeyManager(runtimeManager); + } else if (NullKeyManager.class.getName().equals(clazz)) { + return new NullKeyManager(); + } else if (MemoryKeyManager.class.getName().equals(clazz)) { + return new MemoryKeyManager(); + } else { + try { + Class mgrClass = Class.forName(clazz); + return (IPublicKeyManager) mgrClass.newInstance(); + } catch (Exception e) { + + } + return null; + } + } +} \ No newline at end of file diff --git a/src/main/java/com/gitblit/guice/GuiceContext.java b/src/main/java/com/gitblit/guice/GuiceContext.java deleted file mode 100644 index 4361b7bd..00000000 --- a/src/main/java/com/gitblit/guice/GuiceContext.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2014 gitblit.com. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.gitblit.guice; - -import javax.servlet.ServletContext; -import javax.servlet.ServletContextEvent; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.gitblit.servlet.InjectionContextListener; -import com.google.inject.AbstractModule; -import com.google.inject.Guice; -import com.google.inject.Injector; - -/** - * Guice servlet context listener is a context listener that uses Guice to - * instantiate and inject servlets, filters, and anything else you might want. - * - * @author James Moger - * - */ -public abstract class GuiceContext extends InjectionContextListener { - - public static final String INJECTOR_NAME = Injector.class.getName(); - - protected final Logger logger = LoggerFactory.getLogger(getClass()); - - protected abstract AbstractModule [] getModules(); - - protected abstract void destroyContext(ServletContext context); - - protected Injector getInjector(ServletContext context) { - Object o = context.getAttribute(INJECTOR_NAME); - if (o == null) { - logger.debug("instantiating Guice modules"); - AbstractModule [] modules = getModules(); - logger.debug("getting Guice injector"); - try { - o = Guice.createInjector(modules); - logger.debug("setting Guice injector into {} attribute", INJECTOR_NAME); - context.setAttribute(INJECTOR_NAME, o); - } catch (Throwable t) { - logger.error("an error occurred creating the Guice injector", t); - } - } - return (Injector) o; - } - - /** - * Instantiates an object. - * - * @param clazz - * @return the object - */ - @Override - protected X instantiate(ServletContext context, Class clazz) { - try { - Injector injector = getInjector(context); - return injector.getInstance(clazz); - } catch (Throwable t) { - logger.error(null, t); - } - return null; - } - - @Override - public final void contextDestroyed(ServletContextEvent contextEvent) { - ServletContext context = contextEvent.getServletContext(); - context.removeAttribute(INJECTOR_NAME); - destroyContext(context); - } -} diff --git a/src/main/java/com/gitblit/guice/GuiceModule.java b/src/main/java/com/gitblit/guice/GuiceModule.java deleted file mode 100644 index 254e0680..00000000 --- a/src/main/java/com/gitblit/guice/GuiceModule.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2014 gitblit.com. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.gitblit.guice; - -import javax.inject.Singleton; - -import com.gitblit.FileSettings; -import com.gitblit.GitBlit; -import com.gitblit.IStoredSettings; -import com.gitblit.Keys; -import com.gitblit.manager.AuthenticationManager; -import com.gitblit.manager.FederationManager; -import com.gitblit.manager.IAuthenticationManager; -import com.gitblit.manager.IFederationManager; -import com.gitblit.manager.IGitblit; -import com.gitblit.manager.INotificationManager; -import com.gitblit.manager.IPluginManager; -import com.gitblit.manager.IProjectManager; -import com.gitblit.manager.IRepositoryManager; -import com.gitblit.manager.IRuntimeManager; -import com.gitblit.manager.IUserManager; -import com.gitblit.manager.NotificationManager; -import com.gitblit.manager.PluginManager; -import com.gitblit.manager.ProjectManager; -import com.gitblit.manager.RepositoryManager; -import com.gitblit.manager.RuntimeManager; -import com.gitblit.manager.UserManager; -import com.gitblit.transport.ssh.FileKeyManager; -import com.gitblit.transport.ssh.IPublicKeyManager; -import com.gitblit.transport.ssh.MemoryKeyManager; -import com.gitblit.transport.ssh.NullKeyManager; -import com.gitblit.utils.StringUtils; -import com.google.inject.AbstractModule; -import com.google.inject.Provides; - -/** - * GuiceModule references all injectable objects. - * - * @author James Moger - * - */ -public class GuiceModule extends AbstractModule { - - @Override - protected void configure() { - - bind(IStoredSettings.class).toInstance(new FileSettings()); - - // core managers - bind(IRuntimeManager.class).to(RuntimeManager.class).in(Singleton.class); - bind(IPluginManager.class).to(PluginManager.class).in(Singleton.class); - bind(INotificationManager.class).to(NotificationManager.class).in(Singleton.class); - bind(IUserManager.class).to(UserManager.class).in(Singleton.class); - bind(IAuthenticationManager.class).to(AuthenticationManager.class).in(Singleton.class); - bind(IRepositoryManager.class).to(RepositoryManager.class).in(Singleton.class); - bind(IProjectManager.class).to(ProjectManager.class).in(Singleton.class); - bind(IFederationManager.class).to(FederationManager.class).in(Singleton.class); - - // the monolithic manager - bind(IGitblit.class).to(GitBlit.class).in(Singleton.class); - } - - @Provides - @Singleton - IPublicKeyManager providePublicKeyManager(IStoredSettings settings, IRuntimeManager runtimeManager) { - - String clazz = settings.getString(Keys.git.sshKeysManager, FileKeyManager.class.getName()); - if (StringUtils.isEmpty(clazz)) { - clazz = FileKeyManager.class.getName(); - } - if (FileKeyManager.class.getName().equals(clazz)) { - return new FileKeyManager(runtimeManager); - } else if (NullKeyManager.class.getName().equals(clazz)) { - return new NullKeyManager(); - } else if (MemoryKeyManager.class.getName().equals(clazz)) { - return new MemoryKeyManager(); - } else { - try { - Class mgrClass = Class.forName(clazz); - return (IPublicKeyManager) mgrClass.newInstance(); - } catch (Exception e) { - - } - return null; - } - } -} \ No newline at end of file diff --git a/src/main/java/com/gitblit/guice/WebModule.java b/src/main/java/com/gitblit/guice/WebModule.java new file mode 100644 index 00000000..b4f9899f --- /dev/null +++ b/src/main/java/com/gitblit/guice/WebModule.java @@ -0,0 +1,99 @@ +/* + * 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.guice; + +import java.util.HashMap; +import java.util.Map; + +import com.gitblit.Constants; +import com.gitblit.servlet.BranchGraphServlet; +import com.gitblit.servlet.DownloadZipServlet; +import com.gitblit.servlet.EnforceAuthenticationFilter; +import com.gitblit.servlet.FederationServlet; +import com.gitblit.servlet.GitServlet; +import com.gitblit.servlet.LogoServlet; +import com.gitblit.servlet.PagesServlet; +import com.gitblit.servlet.ProxyFilter; +import com.gitblit.servlet.PtServlet; +import com.gitblit.servlet.RawServlet; +import com.gitblit.servlet.RobotsTxtServlet; +import com.gitblit.servlet.RpcServlet; +import com.gitblit.servlet.SparkleShareInviteServlet; +import com.gitblit.servlet.SyndicationServlet; +import com.gitblit.wicket.GitblitWicketFilter; +import com.google.common.base.Joiner; +import com.google.inject.servlet.ServletModule; + +/** + * Defines all the web servlets & filters. + * + * @author James Moger + * + */ +public class WebModule extends ServletModule { + + final static String ALL = "/*"; + + @Override + protected void configureServlets() { + // servlets + serve(fuzzy(Constants.R_PATH), fuzzy(Constants.GIT_PATH)).with(GitServlet.class); + serve(fuzzy(Constants.RAW_PATH)).with(RawServlet.class); + serve(fuzzy(Constants.PAGES)).with(PagesServlet.class); + serve(fuzzy(Constants.RPC_PATH)).with(RpcServlet.class); + serve(fuzzy(Constants.ZIP_PATH)).with(DownloadZipServlet.class); + serve(fuzzy(Constants.SYNDICATION_PATH)).with(SyndicationServlet.class); + + serve(fuzzy(Constants.FEDERATION_PATH)).with(FederationServlet.class); + serve(fuzzy(Constants.SPARKLESHARE_INVITE_PATH)).with(SparkleShareInviteServlet.class); + serve(fuzzy(Constants.BRANCH_GRAPH_PATH)).with(BranchGraphServlet.class); + serve(Constants.PT_PATH).with(PtServlet.class); + serve("/robots.txt").with(RobotsTxtServlet.class); + serve("/logo.png").with(LogoServlet.class); + + // global filters + filter(ALL).through(ProxyFilter.class); + filter(ALL).through(EnforceAuthenticationFilter.class); + + // security filters +// filter(fuzzy(Constants.R_PATH), fuzzy(Constants.GIT_PATH)).through(GitFilter.class); +// filter(fuzzy(Constants.RAW_PATH)).through(RawFilter.class); +// filter(fuzzy(Constants.PAGES)).through(PagesFilter.class); +// filter(fuzzy(Constants.RPC_PATH)).through(RpcFilter.class); +// filter(fuzzy(Constants.ZIP_PATH)).through(DownloadZipFilter.class); +// filter(fuzzy(Constants.SYNDICATION_PATH)).through(SyndicationFilter.class); + + // Wicket + String toIgnore = Joiner.on(",").join(Constants.R_PATH, Constants.GIT_PATH, Constants.RAW_PATH, + Constants.PAGES, Constants.RPC_PATH, Constants.ZIP_PATH, Constants.SYNDICATION_PATH, + Constants.FEDERATION_PATH, Constants.SPARKLESHARE_INVITE_PATH, Constants.BRANCH_GRAPH_PATH, + Constants.PT_PATH, "/robots.txt", "/logo.png"); + + Map params = new HashMap(); + params.put(GitblitWicketFilter.FILTER_MAPPING_PARAM, ALL); + params.put(GitblitWicketFilter.IGNORE_PATHS_PARAM, toIgnore); + filter(ALL).through(GitblitWicketFilter.class, params); + } + + private String fuzzy(String path) { + if (path.endsWith(ALL)) { + return path; + } else if (path.endsWith("/")) { + return path + "*"; + } + return path + ALL; + } +} diff --git a/src/main/java/com/gitblit/manager/GitblitManager.java b/src/main/java/com/gitblit/manager/GitblitManager.java index 98ad33e7..a0718f77 100644 --- a/src/main/java/com/gitblit/manager/GitblitManager.java +++ b/src/main/java/com/gitblit/manager/GitblitManager.java @@ -87,6 +87,7 @@ import com.google.gson.Gson; import com.google.gson.JsonIOException; import com.google.gson.JsonSyntaxException; import com.google.gson.reflect.TypeToken; +import com.google.inject.Injector; /** * GitblitManager is an aggregate interface delegate. It implements all the manager @@ -656,6 +657,11 @@ public class GitblitManager implements IGitblit { return runtimeManager.getStatus(); } + @Override + public Injector getInjector() { + return runtimeManager.getInjector(); + } + /* * NOTIFICATION MANAGER */ diff --git a/src/main/java/com/gitblit/manager/IRuntimeManager.java b/src/main/java/com/gitblit/manager/IRuntimeManager.java index b2d7a2b3..f736a057 100644 --- a/src/main/java/com/gitblit/manager/IRuntimeManager.java +++ b/src/main/java/com/gitblit/manager/IRuntimeManager.java @@ -24,9 +24,12 @@ import java.util.TimeZone; import com.gitblit.IStoredSettings; import com.gitblit.models.ServerSettings; import com.gitblit.models.ServerStatus; +import com.google.inject.Injector; public interface IRuntimeManager extends IManager { + Injector getInjector(); + void setBaseFolder(File folder); File getBaseFolder(); diff --git a/src/main/java/com/gitblit/manager/RuntimeManager.java b/src/main/java/com/gitblit/manager/RuntimeManager.java index 00fe1c91..f2520085 100644 --- a/src/main/java/com/gitblit/manager/RuntimeManager.java +++ b/src/main/java/com/gitblit/manager/RuntimeManager.java @@ -34,6 +34,7 @@ import com.gitblit.models.ServerSettings; import com.gitblit.models.ServerStatus; import com.gitblit.models.SettingModel; import com.gitblit.utils.StringUtils; +import com.google.inject.Injector; public class RuntimeManager implements IRuntimeManager { @@ -49,6 +50,9 @@ public class RuntimeManager implements IRuntimeManager { private TimeZone timezone; + @Inject + private Injector injector; + @Inject public RuntimeManager(IStoredSettings settings) { this(settings, null); @@ -77,6 +81,11 @@ public class RuntimeManager implements IRuntimeManager { return this; } + @Override + public Injector getInjector() { + return injector; + } + @Override public File getBaseFolder() { return baseFolder; diff --git a/src/main/java/com/gitblit/servlet/AuthenticationFilter.java b/src/main/java/com/gitblit/servlet/AuthenticationFilter.java index 6f13252a..35a62365 100644 --- a/src/main/java/com/gitblit/servlet/AuthenticationFilter.java +++ b/src/main/java/com/gitblit/servlet/AuthenticationFilter.java @@ -99,8 +99,12 @@ public abstract class AuthenticationFilter implements Filter { * @return url */ protected String getFullUrl(HttpServletRequest httpRequest) { - String servletUrl = httpRequest.getContextPath() + httpRequest.getServletPath(); - String url = httpRequest.getRequestURI().substring(servletUrl.length()); + String contextPath = httpRequest.getContextPath(); + String servletPath = httpRequest.getServletPath(); + String pathInfo = httpRequest.getPathInfo(); + String servletUrl = contextPath + servletPath; + String requestURI = httpRequest.getRequestURI(); + String url = requestURI.substring(servletUrl.length()); String params = httpRequest.getQueryString(); if (url.length() > 0 && url.charAt(0) == '/') { url = url.substring(1); diff --git a/src/main/java/com/gitblit/servlet/GitblitContext.java b/src/main/java/com/gitblit/servlet/GitblitContext.java index fb16d32d..86b2fb3a 100644 --- a/src/main/java/com/gitblit/servlet/GitblitContext.java +++ b/src/main/java/com/gitblit/servlet/GitblitContext.java @@ -23,24 +23,26 @@ import java.io.InputStream; import java.io.OutputStream; import java.text.MessageFormat; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.servlet.ServletContext; +import javax.servlet.ServletContextEvent; import javax.servlet.annotation.WebListener; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.gitblit.Constants; import com.gitblit.FileSettings; import com.gitblit.IStoredSettings; import com.gitblit.Keys; import com.gitblit.WebXmlSettings; import com.gitblit.extensions.LifeCycleListener; -import com.gitblit.guice.GuiceContext; -import com.gitblit.guice.GuiceModule; +import com.gitblit.guice.CoreModule; +import com.gitblit.guice.WebModule; import com.gitblit.manager.IAuthenticationManager; import com.gitblit.manager.IFederationManager; import com.gitblit.manager.IGitblit; @@ -54,9 +56,10 @@ import com.gitblit.manager.IUserManager; import com.gitblit.transport.ssh.IPublicKeyManager; import com.gitblit.utils.ContainerUtils; import com.gitblit.utils.StringUtils; -import com.gitblit.wicket.GitblitWicketFilter; import com.google.inject.AbstractModule; +import com.google.inject.Guice; import com.google.inject.Injector; +import com.google.inject.servlet.GuiceServletContextListener; /** * This class is the main entry point for the entire webapp. It is a singleton @@ -70,10 +73,12 @@ import com.google.inject.Injector; * */ @WebListener -public class GitblitContext extends GuiceContext { +public class GitblitContext extends GuiceServletContextListener { private static GitblitContext gitblit; + protected final Logger logger = LoggerFactory.getLogger(getClass()); + private final List managers = new ArrayList(); private final IStoredSettings goSettings; @@ -115,20 +120,37 @@ public class GitblitContext extends GuiceContext { return null; } + @Override + protected Injector getInjector() { + return Guice.createInjector(getModules()); + } + /** * Returns Gitblit's Guice injection modules. */ - @Override protected AbstractModule [] getModules() { - return new AbstractModule [] { new GuiceModule() }; + return new AbstractModule [] { new CoreModule(), new WebModule() }; } /** - * Prepare runtime settings and start all manager instances. + * Configure Gitblit from the web.xml, if no configuration has already been + * specified. + * + * @see ServletContextListener.contextInitialize(ServletContextEvent) */ @Override - protected void beforeServletInjection(ServletContext context) { - Injector injector = getInjector(context); + public final void contextInitialized(ServletContextEvent contextEvent) { + super.contextInitialized(contextEvent); + + ServletContext context = contextEvent.getServletContext(); + startCore(context); + } + + /** + * Prepare runtime settings and start all manager instances. + */ + protected void startCore(ServletContext context) { + Injector injector = (Injector) context.getAttribute(Injector.class.getName()); // create the runtime settings object IStoredSettings runtimeSettings = injector.getInstance(IStoredSettings.class); @@ -229,46 +251,17 @@ public class GitblitContext extends GuiceContext { logger.info("----[{}]----", clazz.getName()); } - /** - * 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.R_PATH, GitServlet.class, GitFilter.class); - serve(context, Constants.GIT_PATH, GitServlet.class, GitFilter.class); - serve(context, Constants.RAW_PATH, RawServlet.class, RawFilter.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); - serve(context, Constants.PT_PATH, PtServlet.class); - file(context, "/robots.txt", RobotsTxtServlet.class); - file(context, "/logo.png", LogoServlet.class); - - // global filters - filter(context, "/*", ProxyFilter.class, null); - filter(context, "/*", EnforceAuthenticationFilter.class, null); - - // Wicket - String toIgnore = StringUtils.flattenStrings(getRegisteredPaths(), ","); - Map params = new HashMap(); - params.put(GitblitWicketFilter.FILTER_MAPPING_PARAM, "/*"); - params.put(GitblitWicketFilter.IGNORE_PATHS_PARAM, toIgnore); - filter(context, "/*", GitblitWicketFilter.class, params); + public final void contextDestroyed(ServletContextEvent contextEvent) { + super.contextDestroyed(contextEvent); + ServletContext context = contextEvent.getServletContext(); + destroyContext(context); } /** * Gitblit is being shutdown either because the servlet container is * shutting down or because the servlet container is re-deploying Gitblit. */ - @Override protected void destroyContext(ServletContext context) { logger.info("Gitblit context destroyed by servlet container."); diff --git a/src/main/java/com/gitblit/servlet/InjectionContextListener.java b/src/main/java/com/gitblit/servlet/InjectionContextListener.java deleted file mode 100644 index 17de6dad..00000000 --- a/src/main/java/com/gitblit/servlet/InjectionContextListener.java +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright 2014 gitblit.com. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.gitblit.servlet; - -import java.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 registeredPaths = new ArrayList(); - - protected final List 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 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 servletClass, Map 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 servletClass) { - serve(context, route, servletClass, (Class) 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 servletClass, Map 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 servletClass, Class 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 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 filterClass, Map 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 instantiate(ServletContext context, Class clazz) { - try { - return clazz.newInstance(); - } catch (Throwable t) { - logger.error(null, t); - } - return null; - } -} diff --git a/src/test/java/com/gitblit/tests/mock/MockRuntimeManager.java b/src/test/java/com/gitblit/tests/mock/MockRuntimeManager.java index 54be539f..36a0218e 100644 --- a/src/test/java/com/gitblit/tests/mock/MockRuntimeManager.java +++ b/src/test/java/com/gitblit/tests/mock/MockRuntimeManager.java @@ -28,6 +28,7 @@ import com.gitblit.manager.IRuntimeManager; import com.gitblit.models.ServerSettings; import com.gitblit.models.ServerStatus; import com.gitblit.models.SettingModel; +import com.google.inject.Injector; public class MockRuntimeManager implements IRuntimeManager { @@ -56,6 +57,11 @@ public class MockRuntimeManager implements IRuntimeManager { this.serverSettings = new ServerSettings(); } + @Override + public Injector getInjector() { + return null; + } + @Override public void setBaseFolder(File folder) { this.baseFolder = folder;