]> source.dussan.org Git - gitblit.git/commitdiff
Use Guice-Servlet rather than custom code and expose the Injector
authorJames Moger <james.moger@gitblit.com>
Fri, 23 May 2014 12:17:11 +0000 (08:17 -0400)
committerJames Moger <james.moger@gitblit.com>
Thu, 3 Jul 2014 20:57:47 +0000 (16:57 -0400)
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

15 files changed:
.classpath
build.moxie
gitblit.iml
src/main/java/WEB-INF/web.xml
src/main/java/com/gitblit/guice/CoreModule.java [new file with mode: 0644]
src/main/java/com/gitblit/guice/GuiceContext.java [deleted file]
src/main/java/com/gitblit/guice/GuiceModule.java [deleted file]
src/main/java/com/gitblit/guice/WebModule.java [new file with mode: 0644]
src/main/java/com/gitblit/manager/GitblitManager.java
src/main/java/com/gitblit/manager/IRuntimeManager.java
src/main/java/com/gitblit/manager/RuntimeManager.java
src/main/java/com/gitblit/servlet/AuthenticationFilter.java
src/main/java/com/gitblit/servlet/GitblitContext.java
src/main/java/com/gitblit/servlet/InjectionContextListener.java [deleted file]
src/test/java/com/gitblit/tests/mock/MockRuntimeManager.java

index ec9495fbed381f6bea5a3e103b5d00f956948bef..9c3e7b8cf7e944cfa7a0b0268b93c9397a4c7e2b 100644 (file)
@@ -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" />
index 0501b7791e63394d7da5652dd4f0531e5562559c..b25a4222af408d2c59294cfefd01155e00ffb933 100644 (file)
@@ -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
index 9a689dab6c466aa2dd2188082d73b3b59b88dd6d..f8a8a6741f97b8739d567e25745e8b872e9a9c39 100644 (file)
         </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>
index 2a570e32aa8855d1fbc2ef1c1a83d030dbed6805..88422249236e9c948af5196d624228610dd69dcb 100644 (file)
@@ -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.
        
        <!-- 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>
\ 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 (file)
index 0000000..9b479c0
--- /dev/null
@@ -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 (file)
index 4361b7b..0000000
+++ /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> 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);
-       }
-}
diff --git a/src/main/java/com/gitblit/guice/GuiceModule.java b/src/main/java/com/gitblit/guice/GuiceModule.java
deleted file mode 100644 (file)
index 254e068..0000000
+++ /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 (file)
index 0000000..b4f9899
--- /dev/null
@@ -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;
+       }
+}
index 98ad33e737ac26f48853ed95e54bdae36ba23ab1..a0718f779213dfc5ebff3f1022a38722e0ea7357 100644 (file)
@@ -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
         */
index b2d7a2b3137f34c91f2698b314766ea9874663d5..f736a057d9168b6a460f8c8363d54c1898b63e83 100644 (file)
@@ -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();
index 00fe1c91c05646f0434522a48c85a272eab6054e..f2520085f6db39d1c3dc8c1cdb8f7557a1dfd80a 100644 (file)
@@ -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;
index 6f13252a2365e3931e7a861d3eba576f8c1bdf22..35a623651774a16bba18fbfd3ed65e704eec9b87 100644 (file)
@@ -99,8 +99,12 @@ public abstract class AuthenticationFilter implements Filter {
         * @return url\r
         */\r
        protected String getFullUrl(HttpServletRequest httpRequest) {\r
-               String servletUrl = httpRequest.getContextPath() + httpRequest.getServletPath();\r
-               String url = httpRequest.getRequestURI().substring(servletUrl.length());\r
+               String contextPath = httpRequest.getContextPath();\r
+               String servletPath = httpRequest.getServletPath();\r
+               String pathInfo = httpRequest.getPathInfo();\r
+               String servletUrl = contextPath + servletPath;\r
+               String requestURI = httpRequest.getRequestURI();\r
+               String url = requestURI.substring(servletUrl.length());\r
                String params = httpRequest.getQueryString();\r
                if (url.length() > 0 && url.charAt(0) == '/') {\r
                        url = url.substring(1);\r
index fb16d32d1b9bf42c7ea9a1ec19fc05315e296bce..86b2fb3a8e2601722c79b755de57aaf3cde36d22 100644 (file)
@@ -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.");
 
diff --git a/src/main/java/com/gitblit/servlet/InjectionContextListener.java b/src/main/java/com/gitblit/servlet/InjectionContextListener.java
deleted file mode 100644 (file)
index 17de6da..0000000
+++ /dev/null
@@ -1,241 +0,0 @@
-/*\r
- * Copyright 2014 gitblit.com.\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package com.gitblit.servlet;\r
-\r
-import java.util.ArrayList;\r
-import java.util.EnumSet;\r
-import java.util.List;\r
-import java.util.Map;\r
-\r
-import javax.servlet.DispatcherType;\r
-import javax.servlet.Filter;\r
-import javax.servlet.FilterRegistration;\r
-import javax.servlet.Servlet;\r
-import javax.servlet.ServletContext;\r
-import javax.servlet.ServletContextEvent;\r
-import javax.servlet.ServletContextListener;\r
-import javax.servlet.ServletRegistration;\r
-\r
-import org.slf4j.Logger;\r
-import org.slf4j.LoggerFactory;\r
-\r
-/**\r
- * Injection context listener instantiates and injects servlets, filters, and\r
- * anything else you might want into a servlet context.  This class provides\r
- * convenience methods for servlet & filter registration and also tracks\r
- * registered paths.\r
- *\r
- * @author James Moger\r
- *\r
- */\r
-public abstract class InjectionContextListener implements ServletContextListener {\r
-\r
-       protected final Logger logger = LoggerFactory.getLogger(getClass());\r
-\r
-       private final List<String> registeredPaths = new ArrayList<String>();\r
-\r
-       protected final List<String> getRegisteredPaths() {\r
-               return registeredPaths;\r
-       }\r
-\r
-       /**\r
-        * Hook for subclasses to manipulate context initialization before\r
-        * standard initialization procedure.\r
-        *\r
-        * @param context\r
-        */\r
-       protected void beforeServletInjection(ServletContext context) {\r
-               // NOOP\r
-       }\r
-\r
-       /**\r
-        * Hook for subclasses to instantiate and inject servlets and filters\r
-        * into the servlet context.\r
-        *\r
-        * @param context\r
-        */\r
-       protected abstract void injectServlets(ServletContext context);\r
-\r
-       /**\r
-        * Hook for subclasses to manipulate context initialization after\r
-        * servlet registration.\r
-        *\r
-        * @param context\r
-        */\r
-       protected void afterServletInjection(ServletContext context) {\r
-               // NOOP\r
-       }\r
-\r
-       /**\r
-        * Configure Gitblit from the web.xml, if no configuration has already been\r
-        * specified.\r
-        *\r
-        * @see ServletContextListener.contextInitialize(ServletContextEvent)\r
-        */\r
-       @Override\r
-       public final void contextInitialized(ServletContextEvent contextEvent) {\r
-               ServletContext context = contextEvent.getServletContext();\r
-               beforeServletInjection(context);\r
-               injectServlets(context);\r
-               afterServletInjection(context);\r
-       }\r
-\r
-\r
-       /**\r
-        * Registers a file path.\r
-        *\r
-        * @param context\r
-        * @param file\r
-        * @param servletClass\r
-        */\r
-       protected void file(ServletContext context, String file, Class<? extends Servlet> servletClass) {\r
-               file(context, file, servletClass, null);\r
-       }\r
-\r
-       /**\r
-        * Registers a file path with init parameters.\r
-        *\r
-        * @param context\r
-        * @param file\r
-        * @param servletClass\r
-        * @param initParams\r
-        */\r
-       protected void file(ServletContext context, String file, Class<? extends Servlet> servletClass, Map<String, String> initParams) {\r
-               Servlet servlet = instantiate(context, servletClass);\r
-               ServletRegistration.Dynamic d = context.addServlet(sanitize(servletClass.getSimpleName() + file), servlet);\r
-               d.addMapping(file);\r
-               if (initParams != null) {\r
-                       d.setInitParameters(initParams);\r
-               }\r
-               registeredPaths.add(file);\r
-       }\r
-\r
-       /**\r
-        * Serves a path (trailing wildcard will be appended).\r
-        *\r
-        * @param context\r
-        * @param route\r
-        * @param servletClass\r
-        */\r
-       protected void serve(ServletContext context, String route, Class<? extends Servlet> servletClass) {\r
-               serve(context, route, servletClass, (Class<Filter>) null);\r
-       }\r
-\r
-       /**\r
-        * Serves a path (trailing wildcard will be appended) with init parameters.\r
-        *\r
-        * @param context\r
-        * @param route\r
-        * @param servletClass\r
-        * @param initParams\r
-        */\r
-       protected void serve(ServletContext context, String route, Class<? extends Servlet> servletClass, Map<String, String> initParams) {\r
-               Servlet servlet = instantiate(context, servletClass);\r
-               ServletRegistration.Dynamic d = context.addServlet(sanitize(servletClass.getSimpleName() + route), servlet);\r
-               d.addMapping(route + "*");\r
-               if (initParams != null) {\r
-                       d.setInitParameters(initParams);\r
-               }\r
-               registeredPaths.add(route);\r
-       }\r
-\r
-       /**\r
-        * Serves a path (trailing wildcard will be appended) and also maps a filter\r
-        * to that path.\r
-        *\r
-        * @param context\r
-        * @param route\r
-        * @param servletClass\r
-        * @param filterClass\r
-        */\r
-       protected void serve(ServletContext context, String route, Class<? extends Servlet> servletClass, Class<? extends Filter> filterClass) {\r
-               Servlet servlet = instantiate(context, servletClass);\r
-               ServletRegistration.Dynamic d = context.addServlet(sanitize(servletClass.getSimpleName() + route), servlet);\r
-               d.addMapping(route + "*");\r
-               if (filterClass != null) {\r
-                       filter(context, route + "*", filterClass);\r
-               }\r
-               registeredPaths.add(route);\r
-       }\r
-\r
-       /**\r
-        * Registers a path filter.\r
-        *\r
-        * @param context\r
-        * @param route\r
-        * @param filterClass\r
-        */\r
-       protected void filter(ServletContext context, String route, Class<? extends Filter> filterClass) {\r
-               filter(context, route, filterClass, null);\r
-       }\r
-\r
-       /**\r
-        * Registers a path filter with init parameters.\r
-        *\r
-        * @param context\r
-        * @param route\r
-        * @param filterClass\r
-        * @param initParams\r
-        */\r
-       protected void filter(ServletContext context, String route, Class<? extends Filter> filterClass, Map<String, String> initParams) {\r
-               Filter filter = instantiate(context, filterClass);\r
-               FilterRegistration.Dynamic d = context.addFilter(sanitize(filterClass.getSimpleName() + route), filter);\r
-               d.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, route);\r
-               if (initParams != null) {\r
-                       d.setInitParameters(initParams);\r
-               }\r
-       }\r
-\r
-       /**\r
-        * Limit the generated servlet/filter names to alpha-numeric values with a\r
-        * handful of acceptable other characters.\r
-        *\r
-        * @param name\r
-        * @return a sanitized name\r
-        */\r
-       protected String sanitize(String name) {\r
-               StringBuilder sb = new StringBuilder();\r
-               for (char c : name.toCharArray()) {\r
-                       if (Character.isLetterOrDigit(c)) {\r
-                               sb.append(c);\r
-                       } else if ('-' == c) {\r
-                               sb.append(c);\r
-                       } else if ('*' == c) {\r
-                               sb.append("all");\r
-                       } else if ('.' == c) {\r
-                               sb.append('.');\r
-                       } else {\r
-                               sb.append('_');\r
-                       }\r
-               }\r
-               return sb.toString();\r
-       }\r
-\r
-       /**\r
-        * Instantiates an object.\r
-        *\r
-        * @param clazz\r
-        * @return the object\r
-        */\r
-       protected <X> X instantiate(ServletContext context, Class<X> clazz) {\r
-               try {\r
-                       return clazz.newInstance();\r
-               } catch (Throwable t) {\r
-                       logger.error(null, t);\r
-               }\r
-               return null;\r
-       }\r
-}\r
index 54be539fa61cfde7bc7d3b020fc02535fde0a412..36a0218ec7566544d414529218e8e1529c10a958 100644 (file)
@@ -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;