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=807tags/v1.7.0
@@ -9,6 +9,7 @@ | |||
<classpathentry kind="lib" path="ext/javax.inject-1.jar" sourcepath="ext/src/javax.inject-1.jar" /> | |||
<classpathentry kind="lib" path="ext/aopalliance-1.0.jar" sourcepath="ext/src/aopalliance-1.0.jar" /> | |||
<classpathentry kind="lib" path="ext/guava-16.0.1.jar" sourcepath="ext/src/guava-16.0.1.jar" /> | |||
<classpathentry kind="lib" path="ext/guice-servlet-4.0-beta4.jar" sourcepath="ext/src/guice-servlet-4.0-beta4.jar" /> | |||
<classpathentry kind="lib" path="ext/annotations-12.0.jar" sourcepath="ext/src/annotations-12.0.jar" /> | |||
<classpathentry kind="lib" path="ext/log4j-1.2.17.jar" sourcepath="ext/src/log4j-1.2.17.jar" /> | |||
<classpathentry kind="lib" path="ext/slf4j-api-1.7.7.jar" sourcepath="ext/src/slf4j-api-1.7.7.jar" /> |
@@ -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 |
@@ -57,6 +57,17 @@ | |||
</SOURCES> | |||
</library> | |||
</orderEntry> | |||
<orderEntry type="module-library"> | |||
<library name="guice-servlet-4.0-beta4.jar"> | |||
<CLASSES> | |||
<root url="jar://$MODULE_DIR$/ext/guice-servlet-4.0-beta4.jar!/" /> | |||
</CLASSES> | |||
<JAVADOC /> | |||
<SOURCES> | |||
<root url="jar://$MODULE_DIR$/ext/src/guice-servlet-4.0-beta4.jar!/" /> | |||
</SOURCES> | |||
</library> | |||
</orderEntry> | |||
<orderEntry type="module-library"> | |||
<library name="annotations-12.0.jar"> | |||
<CLASSES> |
@@ -1,7 +1,7 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<web-app version="3.0" | |||
<web-app version="2.4" | |||
xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |||
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_3_0.xsd"> | |||
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> | |||
<!-- The base folder is used to specify the root location of your Gitblit data. | |||
@@ -32,4 +32,18 @@ | |||
<!-- Gitblit Displayname --> | |||
<display-name>Gitblit - @gb.version@</display-name> | |||
<listener> | |||
<listener-class>com.gitblit.servlet.GitblitContext</listener-class> | |||
</listener> | |||
<filter> | |||
<filter-name>guiceFilter</filter-name> | |||
<filter-class>com.google.inject.servlet.GuiceFilter</filter-class> | |||
</filter> | |||
<filter-mapping> | |||
<filter-name>guiceFilter</filter-name> | |||
<url-pattern>/*</url-pattern> | |||
</filter-mapping> | |||
</web-app> |
@@ -47,12 +47,12 @@ import com.google.inject.AbstractModule; | |||
import com.google.inject.Provides; | |||
/** | |||
* GuiceModule references all injectable objects. | |||
* CoreModule references all the core business objects. | |||
* | |||
* @author James Moger | |||
* | |||
*/ | |||
public class GuiceModule extends AbstractModule { | |||
public class CoreModule extends AbstractModule { | |||
@Override | |||
protected void configure() { |
@@ -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> X instantiate(ServletContext context, Class<X> 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); | |||
} | |||
} |
@@ -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<String, String> params = new HashMap<String, String>(); | |||
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; | |||
} | |||
} |
@@ -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 | |||
*/ |
@@ -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(); |
@@ -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; |
@@ -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); |
@@ -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<IManager> managers = new ArrayList<IManager>(); | |||
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<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); | |||
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."); | |||
@@ -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<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; | |||
} | |||
} |
@@ -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; |