diff options
38 files changed, 409 insertions, 286 deletions
diff --git a/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF b/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF index 982e4c40c0..1a833562e5 100644 --- a/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF @@ -19,5 +19,6 @@ Import-Package: javax.servlet;version="[2.5.0,3.0.0)", org.eclipse.jgit.revwalk;version="[0.12.0,0.13.0)", org.eclipse.jgit.storage.file;version="[0.12.0,0.13.0)", org.eclipse.jgit.transport;version="[0.12.0,0.13.0)", + org.eclipse.jgit.transport.resolver;version="[0.12.0,0.13.0)", org.eclipse.jgit.util;version="[0.12.0,0.13.0)", org.eclipse.jgit.util.io;version="[0.12.0,0.13.0)" diff --git a/org.eclipse.jgit.http.server/resources/org/eclipse/jgit/http/server/HttpServerText.properties b/org.eclipse.jgit.http.server/resources/org/eclipse/jgit/http/server/HttpServerText.properties index 8e36aab28b..6232f47f05 100644 --- a/org.eclipse.jgit.http.server/resources/org/eclipse/jgit/http/server/HttpServerText.properties +++ b/org.eclipse.jgit.http.server/resources/org/eclipse/jgit/http/server/HttpServerText.properties @@ -13,8 +13,6 @@ noResolverAvailable=No resolver available parameterNotSet=Parameter {0} not set pathForParamNotFound={0} (for {1}) not found pathNotSupported={0} not supported -serviceNotEnabled=Service not enabled -serviceNotPermitted=Service not permitted servletAlreadyInitialized=Servlet already initialized servletMustNotBeNull=servlet must not be null servletWasAlreadyBound=servlet was already bound diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/AsIsFileFilter.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/AsIsFileFilter.java index 810f694202..b2250e3ef3 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/AsIsFileFilter.java +++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/AsIsFileFilter.java @@ -59,9 +59,9 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eclipse.jgit.http.server.resolver.AsIsFileService; -import org.eclipse.jgit.http.server.resolver.ServiceNotAuthorizedException; -import org.eclipse.jgit.http.server.resolver.ServiceNotEnabledException; import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException; +import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; class AsIsFileFilter implements Filter { private final AsIsFileService asIs; diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/GitServlet.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/GitServlet.java index e28e4eeb29..9be5fa7e9f 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/GitServlet.java +++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/GitServlet.java @@ -48,6 +48,7 @@ import java.text.MessageFormat; import javax.servlet.ServletConfig; import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eclipse.jgit.http.server.glue.ErrorServlet; @@ -56,14 +57,14 @@ import org.eclipse.jgit.http.server.glue.RegexGroupFilter; import org.eclipse.jgit.http.server.glue.ServletBinder; import org.eclipse.jgit.http.server.resolver.DefaultReceivePackFactory; import org.eclipse.jgit.http.server.resolver.DefaultUploadPackFactory; -import org.eclipse.jgit.http.server.resolver.FileResolver; import org.eclipse.jgit.http.server.resolver.AsIsFileService; -import org.eclipse.jgit.http.server.resolver.ReceivePackFactory; -import org.eclipse.jgit.http.server.resolver.RepositoryResolver; import org.eclipse.jgit.lib.Constants; -import org.eclipse.jgit.http.server.resolver.UploadPackFactory; import org.eclipse.jgit.transport.ReceivePack; import org.eclipse.jgit.transport.UploadPack; +import org.eclipse.jgit.transport.resolver.FileResolver; +import org.eclipse.jgit.transport.resolver.ReceivePackFactory; +import org.eclipse.jgit.transport.resolver.RepositoryResolver; +import org.eclipse.jgit.transport.resolver.UploadPackFactory; import org.eclipse.jgit.util.StringUtils; /** @@ -105,13 +106,13 @@ public class GitServlet extends MetaServlet { private volatile boolean initialized; - private RepositoryResolver resolver; + private RepositoryResolver<HttpServletRequest> resolver; private AsIsFileService asIs = new AsIsFileService(); - private UploadPackFactory uploadPackFactory = new DefaultUploadPackFactory(); + private UploadPackFactory<HttpServletRequest> uploadPackFactory = new DefaultUploadPackFactory(); - private ReceivePackFactory receivePackFactory = new DefaultReceivePackFactory(); + private ReceivePackFactory<HttpServletRequest> receivePackFactory = new DefaultReceivePackFactory(); /** * New servlet that will load its base directory from {@code web.xml}. @@ -132,7 +133,7 @@ public class GitServlet extends MetaServlet { * parameter table during init, which usually comes from the * {@code web.xml} file of the web application. */ - public void setRepositoryResolver(RepositoryResolver resolver) { + public void setRepositoryResolver(RepositoryResolver<HttpServletRequest> resolver) { assertNotInitialized(); this.resolver = resolver; } @@ -153,9 +154,10 @@ public class GitServlet extends MetaServlet { * the factory to construct and configure an {@link UploadPack} * session when a fetch or clone is requested by a client. */ - public void setUploadPackFactory(UploadPackFactory f) { + @SuppressWarnings("unchecked") + public void setUploadPackFactory(UploadPackFactory<HttpServletRequest> f) { assertNotInitialized(); - this.uploadPackFactory = f != null ? f : UploadPackFactory.DISABLED; + this.uploadPackFactory = f != null ? f : (UploadPackFactory<HttpServletRequest>)UploadPackFactory.DISABLED; } /** @@ -163,9 +165,10 @@ public class GitServlet extends MetaServlet { * the factory to construct and configure a {@link ReceivePack} * session when a push is requested by a client. */ - public void setReceivePackFactory(ReceivePackFactory f) { + @SuppressWarnings("unchecked") + public void setReceivePackFactory(ReceivePackFactory<HttpServletRequest> f) { assertNotInitialized(); - this.receivePackFactory = f != null ? f : ReceivePackFactory.DISABLED; + this.receivePackFactory = f != null ? f : (ReceivePackFactory<HttpServletRequest>)ReceivePackFactory.DISABLED; } private void assertNotInitialized() { @@ -180,7 +183,7 @@ public class GitServlet extends MetaServlet { if (resolver == null) { final File root = getFile("base-path"); final boolean exportAll = getBoolean("export-all"); - setRepositoryResolver(new FileResolver(root, exportAll)); + setRepositoryResolver(new FileResolver<HttpServletRequest>(root, exportAll)); } initialized = true; diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/HttpServerText.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/HttpServerText.java index 8ad0eb0497..fc10014427 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/HttpServerText.java +++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/HttpServerText.java @@ -73,8 +73,6 @@ public class HttpServerText extends TranslationBundle { /***/ public String parameterNotSet; /***/ public String pathForParamNotFound; /***/ public String pathNotSupported; - /***/ public String serviceNotEnabled; - /***/ public String serviceNotPermitted; /***/ public String servletAlreadyInitialized; /***/ public String servletMustNotBeNull; /***/ public String servletWasAlreadyBound; diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ReceivePackServlet.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ReceivePackServlet.java index 4bc05c1886..a85e84b210 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ReceivePackServlet.java +++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ReceivePackServlet.java @@ -56,12 +56,12 @@ import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.eclipse.jgit.http.server.resolver.ReceivePackFactory; -import org.eclipse.jgit.http.server.resolver.ServiceNotAuthorizedException; -import org.eclipse.jgit.http.server.resolver.ServiceNotEnabledException; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.transport.ReceivePack; import org.eclipse.jgit.transport.RefAdvertiser.PacketLineOutRefAdvertiser; +import org.eclipse.jgit.transport.resolver.ReceivePackFactory; +import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException; +import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; /** Server side implementation of smart push over HTTP. */ class ReceivePackServlet extends HttpServlet { diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/RepositoryFilter.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/RepositoryFilter.java index 7975809e87..ceac043ea5 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/RepositoryFilter.java +++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/RepositoryFilter.java @@ -63,10 +63,10 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eclipse.jgit.errors.RepositoryNotFoundException; -import org.eclipse.jgit.http.server.resolver.RepositoryResolver; -import org.eclipse.jgit.http.server.resolver.ServiceNotAuthorizedException; -import org.eclipse.jgit.http.server.resolver.ServiceNotEnabledException; import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.transport.resolver.RepositoryResolver; +import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException; +import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; /** * Opens a repository named by the path info through {@link RepositoryResolver}. diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/SmartServiceInfoRefs.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/SmartServiceInfoRefs.java index 94e2e7f6f7..f9be95f04e 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/SmartServiceInfoRefs.java +++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/SmartServiceInfoRefs.java @@ -58,11 +58,11 @@ import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.eclipse.jgit.http.server.resolver.ServiceNotAuthorizedException; -import org.eclipse.jgit.http.server.resolver.ServiceNotEnabledException; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.transport.PacketLineOut; import org.eclipse.jgit.transport.RefAdvertiser.PacketLineOutRefAdvertiser; +import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException; +import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; /** Filter in front of {@link InfoRefsServlet} to catch smart service requests. */ abstract class SmartServiceInfoRefs implements Filter { diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/UploadPackServlet.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/UploadPackServlet.java index 602d66a90c..ff5e5d53c8 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/UploadPackServlet.java +++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/UploadPackServlet.java @@ -56,12 +56,12 @@ import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.eclipse.jgit.http.server.resolver.ServiceNotAuthorizedException; -import org.eclipse.jgit.http.server.resolver.ServiceNotEnabledException; -import org.eclipse.jgit.http.server.resolver.UploadPackFactory; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.transport.UploadPack; import org.eclipse.jgit.transport.RefAdvertiser.PacketLineOutRefAdvertiser; +import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException; +import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; +import org.eclipse.jgit.transport.resolver.UploadPackFactory; /** Server side implementation of smart fetch over HTTP. */ class UploadPackServlet extends HttpServlet { diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/AsIsFileService.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/AsIsFileService.java index b9545f9101..43a7e246d6 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/AsIsFileService.java +++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/AsIsFileService.java @@ -49,6 +49,8 @@ import org.eclipse.jgit.http.server.GitServlet; import org.eclipse.jgit.lib.Config; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.Config.SectionParser; +import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException; +import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; /** * Controls access to bare files in a repository. diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/DefaultReceivePackFactory.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/DefaultReceivePackFactory.java index 2495751da2..38a3ec2f15 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/DefaultReceivePackFactory.java +++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/DefaultReceivePackFactory.java @@ -50,6 +50,9 @@ import org.eclipse.jgit.lib.PersonIdent; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.Config.SectionParser; import org.eclipse.jgit.transport.ReceivePack; +import org.eclipse.jgit.transport.resolver.ReceivePackFactory; +import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException; +import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; /** * Create and configure {@link ReceivePack} service instance. @@ -63,7 +66,8 @@ import org.eclipse.jgit.transport.ReceivePack; * </ul> * and explicitly rejected otherwise. */ -public class DefaultReceivePackFactory implements ReceivePackFactory { +public class DefaultReceivePackFactory implements + ReceivePackFactory<HttpServletRequest> { private static final SectionParser<ServiceConfig> CONFIG = new SectionParser<ServiceConfig>() { public ServiceConfig parse(final Config cfg) { return new ServiceConfig(cfg); diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/DefaultUploadPackFactory.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/DefaultUploadPackFactory.java index a8c953e186..76f40c58a9 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/DefaultUploadPackFactory.java +++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/DefaultUploadPackFactory.java @@ -49,6 +49,9 @@ import org.eclipse.jgit.lib.Config; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.Config.SectionParser; import org.eclipse.jgit.transport.UploadPack; +import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException; +import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; +import org.eclipse.jgit.transport.resolver.UploadPackFactory; /** * Create and configure {@link UploadPack} service instance. @@ -56,7 +59,8 @@ import org.eclipse.jgit.transport.UploadPack; * Reading by upload-pack is permitted unless {@code http.uploadpack} is * explicitly set to false. */ -public class DefaultUploadPackFactory implements UploadPackFactory { +public class DefaultUploadPackFactory implements + UploadPackFactory<HttpServletRequest> { private static final SectionParser<ServiceConfig> CONFIG = new SectionParser<ServiceConfig>() { public ServiceConfig parse(final Config cfg) { return new ServiceConfig(cfg); diff --git a/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF index 4924eabb59..1b861d5f6d 100644 --- a/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF @@ -32,6 +32,7 @@ Import-Package: javax.servlet;version="[2.5.0,3.0.0)", org.eclipse.jgit.revwalk;version="[0.12.0,0.13.0)", org.eclipse.jgit.storage.file;version="[0.12.0,0.13.0)", org.eclipse.jgit.transport;version="[0.12.0,0.13.0)", + org.eclipse.jgit.transport.resolver;version="[0.12.0,0.13.0)", org.eclipse.jgit.util;version="[0.12.0,0.13.0)", org.eclipse.jgit.junit.http;version="[0.12.0,0.13.0)", org.junit;version="[4.0.0,5.0.0)", diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/AdvertiseErrorTest.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/AdvertiseErrorTest.java index 4aa0919a1c..36c351841a 100644 --- a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/AdvertiseErrorTest.java +++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/AdvertiseErrorTest.java @@ -56,9 +56,6 @@ import org.eclipse.jgit.errors.RemoteRepositoryException; import org.eclipse.jgit.errors.RepositoryNotFoundException; import org.eclipse.jgit.http.server.GitServlet; import org.eclipse.jgit.http.server.resolver.DefaultReceivePackFactory; -import org.eclipse.jgit.http.server.resolver.RepositoryResolver; -import org.eclipse.jgit.http.server.resolver.ServiceNotAuthorizedException; -import org.eclipse.jgit.http.server.resolver.ServiceNotEnabledException; import org.eclipse.jgit.junit.TestRepository; import org.eclipse.jgit.junit.http.HttpTestCase; import org.eclipse.jgit.lib.Constants; @@ -73,6 +70,9 @@ import org.eclipse.jgit.transport.ReceivePack; import org.eclipse.jgit.transport.RemoteRefUpdate; import org.eclipse.jgit.transport.Transport; import org.eclipse.jgit.transport.URIish; +import org.eclipse.jgit.transport.resolver.RepositoryResolver; +import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException; +import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; import org.junit.Before; import org.junit.Test; @@ -90,7 +90,7 @@ public class AdvertiseErrorTest extends HttpTestCase { ServletContextHandler app = server.addContext("/git"); GitServlet gs = new GitServlet(); - gs.setRepositoryResolver(new RepositoryResolver() { + gs.setRepositoryResolver(new RepositoryResolver<HttpServletRequest>() { public Repository open(HttpServletRequest req, String name) throws RepositoryNotFoundException, ServiceNotEnabledException { diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/AsIsServiceTest.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/AsIsServiceTest.java index 6bdb4969f5..a86ae0930a 100644 --- a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/AsIsServiceTest.java +++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/AsIsServiceTest.java @@ -51,11 +51,11 @@ import javax.servlet.http.HttpServletRequestWrapper; import org.eclipse.jetty.server.Request; import org.eclipse.jgit.http.server.resolver.AsIsFileService; -import org.eclipse.jgit.http.server.resolver.ServiceNotAuthorizedException; -import org.eclipse.jgit.http.server.resolver.ServiceNotEnabledException; import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.StoredConfig; +import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException; +import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; import org.junit.Before; import org.junit.Test; diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/DefaultReceivePackFactoryTest.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/DefaultReceivePackFactoryTest.java index ff6c43d454..e35197ad42 100644 --- a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/DefaultReceivePackFactoryTest.java +++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/DefaultReceivePackFactoryTest.java @@ -54,14 +54,14 @@ import javax.servlet.http.HttpServletRequestWrapper; import org.eclipse.jetty.server.Request; import org.eclipse.jgit.http.server.resolver.DefaultReceivePackFactory; -import org.eclipse.jgit.http.server.resolver.ReceivePackFactory; -import org.eclipse.jgit.http.server.resolver.ServiceNotAuthorizedException; -import org.eclipse.jgit.http.server.resolver.ServiceNotEnabledException; import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase; import org.eclipse.jgit.lib.PersonIdent; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.StoredConfig; import org.eclipse.jgit.transport.ReceivePack; +import org.eclipse.jgit.transport.resolver.ReceivePackFactory; +import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException; +import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; import org.junit.Before; import org.junit.Test; diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/DefaultUploadPackFactoryTest.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/DefaultUploadPackFactoryTest.java index def29dc027..38dc72fa33 100644 --- a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/DefaultUploadPackFactoryTest.java +++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/DefaultUploadPackFactoryTest.java @@ -53,13 +53,13 @@ import javax.servlet.http.HttpServletRequestWrapper; import org.eclipse.jetty.server.Request; import org.eclipse.jgit.http.server.resolver.DefaultUploadPackFactory; -import org.eclipse.jgit.http.server.resolver.ServiceNotAuthorizedException; -import org.eclipse.jgit.http.server.resolver.ServiceNotEnabledException; -import org.eclipse.jgit.http.server.resolver.UploadPackFactory; import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.StoredConfig; import org.eclipse.jgit.transport.UploadPack; +import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException; +import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; +import org.eclipse.jgit.transport.resolver.UploadPackFactory; import org.junit.Before; import org.junit.Test; diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/DumbClientSmartServerTest.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/DumbClientSmartServerTest.java index 2347d06cff..b81cca1ca4 100644 --- a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/DumbClientSmartServerTest.java +++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/DumbClientSmartServerTest.java @@ -65,8 +65,6 @@ import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jgit.errors.NotSupportedException; import org.eclipse.jgit.errors.RepositoryNotFoundException; import org.eclipse.jgit.http.server.GitServlet; -import org.eclipse.jgit.http.server.resolver.RepositoryResolver; -import org.eclipse.jgit.http.server.resolver.ServiceNotEnabledException; import org.eclipse.jgit.junit.TestRepository; import org.eclipse.jgit.junit.http.AccessEvent; import org.eclipse.jgit.junit.http.HttpTestCase; @@ -81,6 +79,8 @@ import org.eclipse.jgit.transport.HttpTransport; import org.eclipse.jgit.transport.Transport; import org.eclipse.jgit.transport.TransportHttp; import org.eclipse.jgit.transport.URIish; +import org.eclipse.jgit.transport.resolver.RepositoryResolver; +import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; import org.junit.Before; import org.junit.Test; @@ -102,7 +102,7 @@ public class DumbClientSmartServerTest extends HttpTestCase { ServletContextHandler app = server.addContext("/git"); GitServlet gs = new GitServlet(); - gs.setRepositoryResolver(new RepositoryResolver() { + gs.setRepositoryResolver(new RepositoryResolver<HttpServletRequest>() { public Repository open(HttpServletRequest req, String name) throws RepositoryNotFoundException, ServiceNotEnabledException { diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/FileResolverTest.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/FileResolverTest.java index 7009cf98a3..f249098849 100644 --- a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/FileResolverTest.java +++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/FileResolverTest.java @@ -53,10 +53,10 @@ import java.io.File; import java.io.IOException; import org.eclipse.jgit.errors.RepositoryNotFoundException; -import org.eclipse.jgit.http.server.resolver.FileResolver; -import org.eclipse.jgit.http.server.resolver.ServiceNotEnabledException; import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase; import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.transport.resolver.FileResolver; +import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; import org.eclipse.jgit.util.FileUtils; import org.junit.Test; diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/HookMessageTest.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/HookMessageTest.java index 31f4bb4357..2f56e42aa0 100644 --- a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/HookMessageTest.java +++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/HookMessageTest.java @@ -58,9 +58,6 @@ import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jgit.errors.RepositoryNotFoundException; import org.eclipse.jgit.http.server.GitServlet; import org.eclipse.jgit.http.server.resolver.DefaultReceivePackFactory; -import org.eclipse.jgit.http.server.resolver.RepositoryResolver; -import org.eclipse.jgit.http.server.resolver.ServiceNotAuthorizedException; -import org.eclipse.jgit.http.server.resolver.ServiceNotEnabledException; import org.eclipse.jgit.junit.TestRepository; import org.eclipse.jgit.junit.http.AccessEvent; import org.eclipse.jgit.junit.http.HttpTestCase; @@ -79,6 +76,9 @@ import org.eclipse.jgit.transport.ReceivePack; import org.eclipse.jgit.transport.RemoteRefUpdate; import org.eclipse.jgit.transport.Transport; import org.eclipse.jgit.transport.URIish; +import org.eclipse.jgit.transport.resolver.RepositoryResolver; +import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException; +import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; import org.junit.Before; import org.junit.Test; @@ -96,7 +96,7 @@ public class HookMessageTest extends HttpTestCase { ServletContextHandler app = server.addContext("/git"); GitServlet gs = new GitServlet(); - gs.setRepositoryResolver(new RepositoryResolver() { + gs.setRepositoryResolver(new RepositoryResolver<HttpServletRequest>() { public Repository open(HttpServletRequest req, String name) throws RepositoryNotFoundException, ServiceNotEnabledException { diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/HttpClientTests.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/HttpClientTests.java index 063d9d4da6..c48d9b10fa 100644 --- a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/HttpClientTests.java +++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/HttpClientTests.java @@ -64,8 +64,6 @@ import org.eclipse.jgit.errors.NoRemoteRepositoryException; import org.eclipse.jgit.errors.RepositoryNotFoundException; import org.eclipse.jgit.errors.TransportException; import org.eclipse.jgit.http.server.GitServlet; -import org.eclipse.jgit.http.server.resolver.RepositoryResolver; -import org.eclipse.jgit.http.server.resolver.ServiceNotEnabledException; import org.eclipse.jgit.junit.TestRepository; import org.eclipse.jgit.junit.http.AccessEvent; import org.eclipse.jgit.junit.http.AppServer; @@ -81,6 +79,8 @@ import org.eclipse.jgit.transport.FetchConnection; import org.eclipse.jgit.transport.Transport; import org.eclipse.jgit.transport.URIish; import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider; +import org.eclipse.jgit.transport.resolver.RepositoryResolver; +import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; public class HttpClientTests extends HttpTestCase { private TestRepository<FileRepository> remoteRepository; @@ -127,7 +127,7 @@ public class HttpClientTests extends HttpTestCase { private ServletContextHandler smart(final String path) { GitServlet gs = new GitServlet(); - gs.setRepositoryResolver(new RepositoryResolver() { + gs.setRepositoryResolver(new RepositoryResolver<HttpServletRequest>() { public Repository open(HttpServletRequest req, String name) throws RepositoryNotFoundException, ServiceNotEnabledException { diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/SmartClientSmartServerTest.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/SmartClientSmartServerTest.java index e764fe5424..209f161c9b 100644 --- a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/SmartClientSmartServerTest.java +++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/SmartClientSmartServerTest.java @@ -76,8 +76,6 @@ import org.eclipse.jgit.JGitText; import org.eclipse.jgit.errors.RepositoryNotFoundException; import org.eclipse.jgit.errors.TransportException; import org.eclipse.jgit.http.server.GitServlet; -import org.eclipse.jgit.http.server.resolver.RepositoryResolver; -import org.eclipse.jgit.http.server.resolver.ServiceNotEnabledException; import org.eclipse.jgit.junit.TestRepository; import org.eclipse.jgit.junit.TestRng; import org.eclipse.jgit.junit.http.AccessEvent; @@ -98,6 +96,8 @@ import org.eclipse.jgit.transport.RemoteRefUpdate; import org.eclipse.jgit.transport.Transport; import org.eclipse.jgit.transport.TransportHttp; import org.eclipse.jgit.transport.URIish; +import org.eclipse.jgit.transport.resolver.RepositoryResolver; +import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; import org.junit.Before; import org.junit.Test; @@ -123,7 +123,7 @@ public class SmartClientSmartServerTest extends HttpTestCase { ServletContextHandler app = server.addContext("/git"); GitServlet gs = new GitServlet(); - gs.setRepositoryResolver(new RepositoryResolver() { + gs.setRepositoryResolver(new RepositoryResolver<HttpServletRequest>() { public Repository open(HttpServletRequest req, String name) throws RepositoryNotFoundException, ServiceNotEnabledException { diff --git a/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF b/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF index 226a09a207..58324fc486 100644 --- a/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF @@ -30,5 +30,6 @@ Import-Package: javax.servlet;version="[2.5.0,3.0.0)", org.eclipse.jgit.revwalk;version="[0.12.0,0.13.0)", org.eclipse.jgit.storage.file;version="[0.12.0,0.13.0)", org.eclipse.jgit.transport;version="[0.12.0,0.13.0)", + org.eclipse.jgit.transport.resolver;version="[0.12.0,0.13.0)", org.junit;version="[4.0.0,5.0.0)" Export-Package: org.eclipse.jgit.junit.http;version="0.12.0" diff --git a/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/SimpleHttpServer.java b/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/SimpleHttpServer.java index 987f2118ea..1221e1c887 100644 --- a/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/SimpleHttpServer.java +++ b/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/SimpleHttpServer.java @@ -52,11 +52,11 @@ import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jgit.errors.RepositoryNotFoundException; import org.eclipse.jgit.http.server.GitServlet; -import org.eclipse.jgit.http.server.resolver.RepositoryResolver; -import org.eclipse.jgit.http.server.resolver.ServiceNotEnabledException; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.storage.file.FileRepository; import org.eclipse.jgit.transport.URIish; +import org.eclipse.jgit.transport.resolver.RepositoryResolver; +import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; /** * Simple http server for testing http access to Git repositories. @@ -92,7 +92,7 @@ public class SimpleHttpServer { private ServletContextHandler smart(final String path) { GitServlet gs = new GitServlet(); - gs.setRepositoryResolver(new RepositoryResolver() { + gs.setRepositoryResolver(new RepositoryResolver<HttpServletRequest>() { public Repository open(HttpServletRequest req, String name) throws RepositoryNotFoundException, ServiceNotEnabledException { diff --git a/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF b/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF index af5937e3ff..f27bcf5fd9 100644 --- a/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF @@ -21,6 +21,7 @@ Import-Package: org.eclipse.jgit.api;version="[0.12.0,0.13.0)", org.eclipse.jgit.storage.file;version="[0.12.0,0.13.0)", org.eclipse.jgit.storage.pack;version="[0.12.0,0.13.0)", org.eclipse.jgit.transport;version="[0.12.0,0.13.0)", + org.eclipse.jgit.transport.resolver;version="[0.12.0,0.13.0)", org.eclipse.jgit.treewalk;version="[0.12.0,0.13.0)", org.eclipse.jgit.treewalk.filter;version="[0.12.0,0.13.0)", org.eclipse.jgit.util;version="[0.12.0,0.13.0)", diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Daemon.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Daemon.java index 3cca87abe8..9b637cdb31 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Daemon.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Daemon.java @@ -54,7 +54,9 @@ import org.eclipse.jgit.storage.file.FileBasedConfig; import org.eclipse.jgit.storage.file.WindowCache; import org.eclipse.jgit.storage.file.WindowCacheConfig; import org.eclipse.jgit.storage.pack.PackConfig; +import org.eclipse.jgit.transport.DaemonClient; import org.eclipse.jgit.transport.DaemonService; +import org.eclipse.jgit.transport.resolver.FileResolver; import org.eclipse.jgit.util.FS; import org.kohsuke.args4j.Argument; import org.kohsuke.args4j.Option; @@ -123,13 +125,19 @@ class Daemon extends TextBuiltin { if (1 < threads) packConfig.setExecutor(Executors.newFixedThreadPool(threads)); - final org.eclipse.jgit.transport.Daemon d; + final FileResolver<DaemonClient> resolver = new FileResolver<DaemonClient>(); + for (final File f : directory) { + out.println(MessageFormat.format(CLIText.get().exporting, f.getAbsolutePath())); + resolver.exportDirectory(f); + } + resolver.setExportAll(exportAll); + final org.eclipse.jgit.transport.Daemon d; d = new org.eclipse.jgit.transport.Daemon( host != null ? new InetSocketAddress(host, port) : new InetSocketAddress(port)); - d.setExportAll(exportAll); d.setPackConfig(packConfig); + d.setRepositoryResolver(resolver); if (0 <= timeout) d.setTimeout(timeout); @@ -143,10 +151,6 @@ class Daemon extends TextBuiltin { for (final String n : forbidOverride) service(d, n).setOverridable(false); - for (final File f : directory) { - out.println(MessageFormat.format(CLIText.get().exporting, f.getAbsolutePath())); - d.exportDirectory(f); - } d.start(); out.println(MessageFormat.format(CLIText.get().listeningOn, d.getAddress())); } diff --git a/org.eclipse.jgit/META-INF/MANIFEST.MF b/org.eclipse.jgit/META-INF/MANIFEST.MF index e3152606ca..9d1f957c53 100644 --- a/org.eclipse.jgit/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit/META-INF/MANIFEST.MF @@ -25,6 +25,7 @@ Export-Package: org.eclipse.jgit;version="0.12.0", org.eclipse.jgit.storage.file;version="0.12.0", org.eclipse.jgit.storage.pack;version="0.12.0", org.eclipse.jgit.transport;version="0.12.0", + org.eclipse.jgit.transport.resolver;version="0.12.0", org.eclipse.jgit.treewalk;version="0.12.0", org.eclipse.jgit.treewalk.filter;version="0.12.0", org.eclipse.jgit.util;version="0.12.0", diff --git a/org.eclipse.jgit/resources/org/eclipse/jgit/JGitText.properties b/org.eclipse.jgit/resources/org/eclipse/jgit/JGitText.properties index 4681daa662..e48638397d 100644 --- a/org.eclipse.jgit/resources/org/eclipse/jgit/JGitText.properties +++ b/org.eclipse.jgit/resources/org/eclipse/jgit/JGitText.properties @@ -384,7 +384,9 @@ rewinding=Rewinding to commit {0} searchForReuse=Finding sources searchForSizes=Getting sizes sequenceTooLargeForDiffAlgorithm=Sequence too large for difference algorithm. +serviceNotEnabledNoName=Service not enabled serviceNotPermitted={0} not permitted +serviceNotPermittedNoName=Service not permitted shortCompressedStreamAt=Short compressed stream at {0} shortReadOfBlock=Short read of block. shortReadOfOptionalDIRCExtensionExpectedAnotherBytes=Short read of optional DIRC extension {0}; expected another {1} bytes within the section. diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/JGitText.java b/org.eclipse.jgit/src/org/eclipse/jgit/JGitText.java index e29c9bc24e..7276dd26fb 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/JGitText.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/JGitText.java @@ -444,7 +444,9 @@ public class JGitText extends TranslationBundle { /***/ public String searchForReuse; /***/ public String searchForSizes; /***/ public String sequenceTooLargeForDiffAlgorithm; + /***/ public String serviceNotEnabledNoName; /***/ public String serviceNotPermitted; + /***/ public String serviceNotPermittedNoName; /***/ public String shortCompressedStreamAt; /***/ public String shortReadOfBlock; /***/ public String shortReadOfOptionalDIRCExtensionExpectedAnotherBytes; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/Daemon.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/Daemon.java index 0bc5fb3a2b..feeabb2e61 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/Daemon.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/Daemon.java @@ -43,28 +43,26 @@ package org.eclipse.jgit.transport; -import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InterruptedIOException; +import java.io.OutputStream; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketAddress; -import java.util.Collection; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.CopyOnWriteArrayList; import org.eclipse.jgit.JGitText; -import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.errors.RepositoryNotFoundException; import org.eclipse.jgit.lib.PersonIdent; import org.eclipse.jgit.lib.Repository; -import org.eclipse.jgit.lib.RepositoryCache; -import org.eclipse.jgit.lib.RepositoryCache.FileKey; import org.eclipse.jgit.storage.pack.PackConfig; -import org.eclipse.jgit.util.FS; +import org.eclipse.jgit.transport.resolver.ReceivePackFactory; +import org.eclipse.jgit.transport.resolver.RepositoryResolver; +import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException; +import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; +import org.eclipse.jgit.transport.resolver.UploadPackFactory; /** Basic daemon for the anonymous <code>git://</code> transport protocol. */ public class Daemon { @@ -79,12 +77,6 @@ public class Daemon { private final ThreadGroup processors; - private volatile boolean exportAll; - - private Map<String, Repository> exports; - - private Collection<File> exportBase; - private boolean run; private Thread acceptThread; @@ -93,6 +85,12 @@ public class Daemon { private PackConfig packConfig; + private volatile RepositoryResolver<DaemonClient> repositoryResolver; + + private volatile UploadPackFactory<DaemonClient> uploadPackFactory; + + private volatile ReceivePackFactory<DaemonClient> receivePackFactory; + /** Configure a daemon to listen on any available network port. */ public Daemon() { this(null); @@ -107,10 +105,40 @@ public class Daemon { */ public Daemon(final InetSocketAddress addr) { myAddress = addr; - exports = new ConcurrentHashMap<String, Repository>(); - exportBase = new CopyOnWriteArrayList<File>(); processors = new ThreadGroup("Git-Daemon"); + repositoryResolver = (RepositoryResolver<DaemonClient>) RepositoryResolver.NONE; + + uploadPackFactory = new UploadPackFactory<DaemonClient>() { + public UploadPack create(DaemonClient req, Repository db) + throws ServiceNotEnabledException, + ServiceNotAuthorizedException { + UploadPack up = new UploadPack(db); + up.setTimeout(getTimeout()); + up.setPackConfig(getPackConfig()); + return up; + } + }; + + receivePackFactory = new ReceivePackFactory<DaemonClient>() { + public ReceivePack create(DaemonClient req, Repository db) + throws ServiceNotEnabledException, + ServiceNotAuthorizedException { + ReceivePack rp = new ReceivePack(db); + + InetAddress peer = req.getRemoteAddress(); + String host = peer.getCanonicalHostName(); + if (host == null) + host = peer.getHostAddress(); + String name = "anonymous"; + String email = name + "@" + host; + rp.setRefLogIdent(new PersonIdent(name, email)); + rp.setTimeout(getTimeout()); + + return rp; + } + }; + services = new DaemonService[] { new DaemonService("upload-pack", "uploadpack") { { @@ -119,12 +147,13 @@ public class Daemon { @Override protected void execute(final DaemonClient dc, - final Repository db) throws IOException { - final UploadPack rp = new UploadPack(db); - final InputStream in = dc.getInputStream(); - rp.setTimeout(Daemon.this.getTimeout()); - rp.setPackConfig(Daemon.this.packConfig); - rp.upload(in, dc.getOutputStream(), null); + final Repository db) throws IOException, + ServiceNotEnabledException, + ServiceNotAuthorizedException { + UploadPack up = uploadPackFactory.create(dc, db); + InputStream in = dc.getInputStream(); + OutputStream out = dc.getOutputStream(); + up.upload(in, out, null); } }, new DaemonService("receive-pack", "receivepack") { { @@ -133,18 +162,13 @@ public class Daemon { @Override protected void execute(final DaemonClient dc, - final Repository db) throws IOException { - final InetAddress peer = dc.getRemoteAddress(); - String host = peer.getCanonicalHostName(); - if (host == null) - host = peer.getHostAddress(); - final ReceivePack rp = new ReceivePack(db); - final InputStream in = dc.getInputStream(); - final String name = "anonymous"; - final String email = name + "@" + host; - rp.setRefLogIdent(new PersonIdent(name, email)); - rp.setTimeout(Daemon.this.getTimeout()); - rp.receive(in, dc.getOutputStream(), null); + final Repository db) throws IOException, + ServiceNotEnabledException, + ServiceNotAuthorizedException { + ReceivePack rp = receivePackFactory.create(dc, db); + InputStream in = dc.getInputStream(); + OutputStream out = dc.getOutputStream(); + rp.receive(in, out, null); } } }; } @@ -173,62 +197,6 @@ public class Daemon { return null; } - /** - * @return false if <code>git-daemon-export-ok</code> is required to export - * a repository; true if <code>git-daemon-export-ok</code> is - * ignored. - * @see #setExportAll(boolean) - */ - public boolean isExportAll() { - return exportAll; - } - - /** - * Set whether or not to export all repositories. - * <p> - * If false (the default), repositories must have a - * <code>git-daemon-export-ok</code> file to be accessed through this - * daemon. - * <p> - * If true, all repositories are available through the daemon, whether or - * not <code>git-daemon-export-ok</code> exists. - * - * @param export - */ - public void setExportAll(final boolean export) { - exportAll = export; - } - - /** - * Add a single repository to the set that is exported by this daemon. - * <p> - * The existence (or lack-thereof) of <code>git-daemon-export-ok</code> is - * ignored by this method. The repository is always published. - * - * @param name - * name the repository will be published under. - * @param db - * the repository instance. - */ - public void exportRepository(String name, final Repository db) { - if (!name.endsWith(Constants.DOT_GIT_EXT)) - name = name + Constants.DOT_GIT_EXT; - exports.put(name, db); - RepositoryCache.register(db); - } - - /** - * Recursively export all Git repositories within a directory. - * - * @param dir - * the directory to export. This directory must not itself be a - * git repository, but any directory below it which has a file - * named <code>git-daemon-export-ok</code> will be published. - */ - public void exportDirectory(final File dir) { - exportBase.add(dir); - } - /** @return timeout (in seconds) before aborting an IO operation. */ public int getTimeout() { return timeout; @@ -246,6 +214,11 @@ public class Daemon { timeout = seconds; } + /** @return configuration controlling packing, may be null. */ + public PackConfig getPackConfig() { + return packConfig; + } + /** * Set the configuration used by the pack generator. * @@ -258,6 +231,44 @@ public class Daemon { } /** + * Set the resolver used to locate a repository by name. + * + * @param resolver + * the resolver instance. + */ + public void setRepositoryResolver(RepositoryResolver<DaemonClient> resolver) { + repositoryResolver = resolver; + } + + /** + * Set the factory to construct and configure per-request UploadPack. + * + * @param factory + * the factory. If null upload-pack is disabled. + */ + @SuppressWarnings("unchecked") + public void setUploadPackFactory(UploadPackFactory<DaemonClient> factory) { + if (factory != null) + uploadPackFactory = factory; + else + uploadPackFactory = (UploadPackFactory<DaemonClient>) UploadPackFactory.DISABLED; + } + + /** + * Set the factory to construct and configure per-request ReceivePack. + * + * @param factory + * the factory. If null receive-pack is disabled. + */ + @SuppressWarnings("unchecked") + public void setReceivePackFactory(ReceivePackFactory<DaemonClient> factory) { + if (factory != null) + receivePackFactory = factory; + else + receivePackFactory = (ReceivePackFactory<DaemonClient>) ReceivePackFactory.DISABLED; + } + + /** * Start this daemon on a background thread. * * @throws IOException @@ -325,6 +336,12 @@ public class Daemon { public void run() { try { dc.execute(s); + } catch (RepositoryNotFoundException e) { + // Ignored. Client cannot use this repository. + } catch (ServiceNotEnabledException e) { + // Ignored. Client cannot use this repository. + } catch (ServiceNotAuthorizedException e) { + // Ignored. Client cannot use this repository. } catch (IOException e) { // Ignore unexpected IO exceptions from clients e.printStackTrace(); @@ -352,7 +369,7 @@ public class Daemon { return null; } - Repository openRepository(String name) { + Repository openRepository(DaemonClient client, String name) { // Assume any attempt to use \ was by a Windows client // and correct to the more typical / used in Git URIs. // @@ -363,48 +380,20 @@ public class Daemon { if (!name.startsWith("/")) return null; - // Forbid Windows UNC paths as they might escape the base - // - if (name.startsWith("//")) + try { + return repositoryResolver.open(client, name.substring(1)); + } catch (RepositoryNotFoundException e) { + // null signals it "wasn't found", which is all that is suitable + // for the remote client to know. return null; - - // Forbid funny paths which contain an up-reference, they - // might be trying to escape and read /../etc/password. - // - if (name.contains("/../")) + } catch (ServiceNotAuthorizedException e) { + // null signals it "wasn't found", which is all that is suitable + // for the remote client to know. return null; - name = name.substring(1); - - Repository db; - db = exports.get(name.endsWith(Constants.DOT_GIT_EXT) ? name : name - + Constants.DOT_GIT_EXT); - if (db != null) { - db.incrementOpen(); - return db; - } - - for (final File baseDir : exportBase) { - final File gitdir = FileKey.resolve(new File(baseDir, name), FS.DETECTED); - if (gitdir != null && canExport(gitdir)) - return openRepository(gitdir); - } - return null; - } - - private static Repository openRepository(final File gitdir) { - try { - return RepositoryCache.open(FileKey.exact(gitdir, FS.DETECTED)); - } catch (IOException err) { + } catch (ServiceNotEnabledException e) { // null signals it "wasn't found", which is all that is suitable // for the remote client to know. return null; } } - - private boolean canExport(final File d) { - if (isExportAll()) { - return true; - } - return new File(d, "git-daemon-export-ok").exists(); - } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/DaemonClient.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/DaemonClient.java index 0b8de03439..23e3379f91 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/DaemonClient.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/DaemonClient.java @@ -51,6 +51,9 @@ import java.io.OutputStream; import java.net.InetAddress; import java.net.Socket; +import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException; +import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; + /** Active network client of {@link Daemon}. */ public class DaemonClient { private final Daemon daemon; @@ -89,8 +92,8 @@ public class DaemonClient { return rawOut; } - void execute(final Socket sock) - throws IOException { + void execute(final Socket sock) throws IOException, + ServiceNotEnabledException, ServiceNotAuthorizedException { rawIn = new BufferedInputStream(sock.getInputStream()); rawOut = new BufferedOutputStream(sock.getOutputStream()); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/DaemonService.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/DaemonService.java index 2b94957983..e88b4abb7a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/DaemonService.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/DaemonService.java @@ -49,6 +49,8 @@ import java.io.IOException; import org.eclipse.jgit.lib.Config; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.Config.SectionParser; +import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException; +import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; /** A service exposed by {@link Daemon} over anonymous <code>git://</code>. */ public abstract class DaemonService { @@ -125,9 +127,10 @@ public abstract class DaemonService { } void execute(final DaemonClient client, final String commandLine) - throws IOException { + throws IOException, ServiceNotEnabledException, + ServiceNotAuthorizedException { final String name = commandLine.substring(command.length() + 1); - final Repository db = client.getDaemon().openRepository(name); + Repository db = client.getDaemon().openRepository(client, name); if (db == null) return; try { @@ -145,5 +148,6 @@ public abstract class DaemonService { } abstract void execute(DaemonClient client, Repository db) - throws IOException; + throws IOException, ServiceNotEnabledException, + ServiceNotAuthorizedException; } diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/FileResolver.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/FileResolver.java index 296725b678..1d4f2beb18 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/FileResolver.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/FileResolver.java @@ -41,24 +41,40 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package org.eclipse.jgit.http.server.resolver; +package org.eclipse.jgit.transport.resolver; import java.io.File; import java.io.IOException; - -import javax.servlet.http.HttpServletRequest; +import java.util.Collection; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArrayList; import org.eclipse.jgit.errors.RepositoryNotFoundException; +import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.RepositoryCache; import org.eclipse.jgit.lib.RepositoryCache.FileKey; import org.eclipse.jgit.util.FS; -/** Default resolver serving from a single root path in local filesystem. */ -public class FileResolver implements RepositoryResolver { - private final File basePath; +/** + * Default resolver serving from the local filesystem. + * + * @param <C> + * type of connection + */ +public class FileResolver<C> implements RepositoryResolver<C> { + private volatile boolean exportAll; + + private final Map<String, Repository> exports; + + private final Collection<File> exportBase; - private final boolean exportAll; + /** Initialize an empty file based resolver. */ + public FileResolver() { + exports = new ConcurrentHashMap<String, Repository>(); + exportBase = new CopyOnWriteArrayList<File>(); + } /** * Create a new resolver for the given path. @@ -70,54 +86,121 @@ public class FileResolver implements RepositoryResolver { * {@code git-daemon-export-ok} files. */ public FileResolver(final File basePath, final boolean exportAll) { - this.basePath = basePath; - this.exportAll = exportAll; + this(); + exportDirectory(basePath); + setExportAll(exportAll); } - public Repository open(final HttpServletRequest req, - final String repositoryName) throws RepositoryNotFoundException, - ServiceNotEnabledException { - if (isUnreasonableName(repositoryName)) - throw new RepositoryNotFoundException(repositoryName); - - final Repository db; - try { - final File gitdir = new File(basePath, repositoryName); - db = RepositoryCache.open(FileKey.lenient(gitdir, FS.DETECTED), true); - } catch (IOException e) { - throw new RepositoryNotFoundException(repositoryName, e); + public Repository open(final C req, final String name) + throws RepositoryNotFoundException, ServiceNotEnabledException { + if (isUnreasonableName(name)) + throw new RepositoryNotFoundException(name); + + Repository db = exports.get(nameWithDotGit(name)); + if (db != null) { + db.incrementOpen(); + return db; } - try { - if (isExportOk(req, repositoryName, db)) { - // We have to leak the open count to the caller, they - // are responsible for closing the repository if we - // complete successfully. - return db; - } else - throw new ServiceNotEnabledException(); - - } catch (RuntimeException e) { - db.close(); - throw new RepositoryNotFoundException(repositoryName, e); - - } catch (IOException e) { - db.close(); - throw new RepositoryNotFoundException(repositoryName, e); - - } catch (ServiceNotEnabledException e) { - db.close(); - throw e; + for (File base : exportBase) { + File dir = FileKey.resolve(new File(base, name), FS.DETECTED); + if (dir == null) + continue; + + try { + FileKey key = FileKey.exact(dir, FS.DETECTED); + db = RepositoryCache.open(key, true); + } catch (IOException e) { + throw new RepositoryNotFoundException(name, e); + } + + try { + if (isExportOk(req, name, db)) { + // We have to leak the open count to the caller, they + // are responsible for closing the repository if we + // complete successfully. + return db; + } else + throw new ServiceNotEnabledException(); + + } catch (RuntimeException e) { + db.close(); + throw new RepositoryNotFoundException(name, e); + + } catch (IOException e) { + db.close(); + throw new RepositoryNotFoundException(name, e); + + } catch (ServiceNotEnabledException e) { + db.close(); + throw e; + } } + + if (exportBase.size() == 1) { + File dir = new File(exportBase.iterator().next(), name); + throw new RepositoryNotFoundException(name, + new RepositoryNotFoundException(dir)); + } + + throw new RepositoryNotFoundException(name); } - /** @return {@code true} if all repositories are to be exported. */ - protected boolean isExportAll() { + /** + * @return false if <code>git-daemon-export-ok</code> is required to export + * a repository; true if <code>git-daemon-export-ok</code> is + * ignored. + * @see #setExportAll(boolean) + */ + public boolean isExportAll() { return exportAll; } /** - * Check if this repository can be served over HTTP. + * Set whether or not to export all repositories. + * <p> + * If false (the default), repositories must have a + * <code>git-daemon-export-ok</code> file to be accessed through this + * daemon. + * <p> + * If true, all repositories are available through the daemon, whether or + * not <code>git-daemon-export-ok</code> exists. + * + * @param export + */ + public void setExportAll(final boolean export) { + exportAll = export; + } + + /** + * Add a single repository to the set that is exported by this daemon. + * <p> + * The existence (or lack-thereof) of <code>git-daemon-export-ok</code> is + * ignored by this method. The repository is always published. + * + * @param name + * name the repository will be published under. + * @param db + * the repository instance. + */ + public void exportRepository(String name, Repository db) { + exports.put(nameWithDotGit(name), db); + } + + /** + * Recursively export all Git repositories within a directory. + * + * @param dir + * the directory to export. This directory must not itself be a + * git repository, but any directory below it which has a file + * named <code>git-daemon-export-ok</code> will be published. + */ + public void exportDirectory(final File dir) { + exportBase.add(dir); + } + + /** + * Check if this repository can be served. * <p> * The default implementation of this method returns true only if either * {@link #isExportAll()} is true, or the {@code git-daemon-export-ok} file @@ -134,8 +217,8 @@ public class FileResolver implements RepositoryResolver { * the repository could not be accessed, the caller will claim * the repository does not exist. */ - protected boolean isExportOk(HttpServletRequest req, String repositoryName, - Repository db) throws IOException { + protected boolean isExportOk(C req, String repositoryName, Repository db) + throws IOException { if (isExportAll()) return true; else if (db.getDirectory() != null) @@ -144,6 +227,12 @@ public class FileResolver implements RepositoryResolver { return false; } + private static String nameWithDotGit(String name) { + if (name.endsWith(Constants.DOT_GIT_EXT)) + return name; + return name + Constants.DOT_GIT_EXT; + } + private static boolean isUnreasonableName(final String name) { if (name.length() == 0) return true; // no empty paths diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/ReceivePackFactory.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/ReceivePackFactory.java index 2432632c01..4cf49f5531 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/ReceivePackFactory.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/ReceivePackFactory.java @@ -41,18 +41,21 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package org.eclipse.jgit.http.server.resolver; - -import javax.servlet.http.HttpServletRequest; +package org.eclipse.jgit.transport.resolver; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.transport.ReceivePack; -/** Create and configure {@link ReceivePack} service instance. */ -public interface ReceivePackFactory { - /** A factory disabling the ReceivePack service for all repositories. */ - public static final ReceivePackFactory DISABLED = new ReceivePackFactory() { - public ReceivePack create(HttpServletRequest req, Repository db) +/** + * Create and configure {@link ReceivePack} service instance. + * + * @param <C> + * type of connection + */ +public interface ReceivePackFactory<C> { + /** A factory disabling the ReceivePack service for all repositories */ + public static final ReceivePackFactory<?> DISABLED = new ReceivePackFactory<Object>() { + public ReceivePack create(Object req, Repository db) throws ServiceNotEnabledException { throw new ServiceNotEnabledException(); } @@ -62,8 +65,8 @@ public interface ReceivePackFactory { * Create and configure a new ReceivePack instance for a repository. * * @param req - * current HTTP request, in case information from the request may - * help configure the ReceivePack instance. + * current request, in case information from the request may help + * configure the ReceivePack instance. * @param db * the repository the receive would write into. * @return the newly configured ReceivePack instance, must not be null. @@ -74,6 +77,6 @@ public interface ReceivePackFactory { * this factory refuses to create the instance for this HTTP * request and repository, such as due to a permission error. */ - ReceivePack create(HttpServletRequest req, Repository db) - throws ServiceNotEnabledException, ServiceNotAuthorizedException; + ReceivePack create(C req, Repository db) throws ServiceNotEnabledException, + ServiceNotAuthorizedException; } diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/RepositoryResolver.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/RepositoryResolver.java index ba17dac45b..b2354193e1 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/RepositoryResolver.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/RepositoryResolver.java @@ -41,22 +41,33 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package org.eclipse.jgit.http.server.resolver; - -import javax.servlet.http.HttpServletRequest; +package org.eclipse.jgit.transport.resolver; import org.eclipse.jgit.errors.RepositoryNotFoundException; import org.eclipse.jgit.lib.Repository; -/** Locate a Git {@link Repository} by name from the URL. */ -public interface RepositoryResolver { +/** + * Locate a Git {@link Repository} by name from the URL. + * + * @param <C> + * type of connection. + */ +public interface RepositoryResolver<C> { + /** Resolver configured to open nothing. */ + public static final RepositoryResolver<?> NONE = new RepositoryResolver<Object>() { + public Repository open(Object req, String name) + throws RepositoryNotFoundException { + throw new RepositoryNotFoundException(name); + } + }; + /** * Locate and open a reference to a {@link Repository}. * <p> * The caller is responsible for closing the returned Repository. * * @param req - * the current HTTP request, may be used to inspect session state + * the current request, may be used to inspect session state * including cookies or user authentication. * @param name * name of the repository, as parsed out of the URL. @@ -71,7 +82,6 @@ public interface RepositoryResolver { * the repository exists, but HTTP access is not allowed on the * target repository, by any user. */ - Repository open(HttpServletRequest req, String name) - throws RepositoryNotFoundException, ServiceNotAuthorizedException, - ServiceNotEnabledException; + Repository open(C req, String name) throws RepositoryNotFoundException, + ServiceNotAuthorizedException, ServiceNotEnabledException; } diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/ServiceNotAuthorizedException.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/ServiceNotAuthorizedException.java index 6c9bf693d3..3e2047b085 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/ServiceNotAuthorizedException.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/ServiceNotAuthorizedException.java @@ -41,9 +41,9 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package org.eclipse.jgit.http.server.resolver; +package org.eclipse.jgit.transport.resolver; -import org.eclipse.jgit.http.server.HttpServerText; +import org.eclipse.jgit.JGitText; /** Indicates the request service is not authorized for current user. */ public class ServiceNotAuthorizedException extends Exception { @@ -51,6 +51,6 @@ public class ServiceNotAuthorizedException extends Exception { /** Indicates the request service is not available. */ public ServiceNotAuthorizedException() { - super(HttpServerText.get().serviceNotPermitted); + super(JGitText.get().serviceNotPermittedNoName); } } diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/ServiceNotEnabledException.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/ServiceNotEnabledException.java index adc132df3d..ac607f9b0e 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/ServiceNotEnabledException.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/ServiceNotEnabledException.java @@ -41,9 +41,9 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package org.eclipse.jgit.http.server.resolver; +package org.eclipse.jgit.transport.resolver; -import org.eclipse.jgit.http.server.HttpServerText; +import org.eclipse.jgit.JGitText; /** Indicates the request service is not enabled on a repository. */ public class ServiceNotEnabledException extends Exception { @@ -51,6 +51,6 @@ public class ServiceNotEnabledException extends Exception { /** Indicates the request service is not available. */ public ServiceNotEnabledException() { - super(HttpServerText.get().serviceNotEnabled); + super(JGitText.get().serviceNotEnabledNoName); } } diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/UploadPackFactory.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/UploadPackFactory.java index 83bf9be07d..f0d2ba865b 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/UploadPackFactory.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/UploadPackFactory.java @@ -41,18 +41,21 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package org.eclipse.jgit.http.server.resolver; - -import javax.servlet.http.HttpServletRequest; +package org.eclipse.jgit.transport.resolver; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.transport.UploadPack; -/** Create and configure {@link UploadPack} service instance. */ -public interface UploadPackFactory { +/** + * Create and configure {@link UploadPack} service instance. + * + * @param <C> + * the connection type + */ +public interface UploadPackFactory<C> { /** A factory disabling the UploadPack service for all repositories. */ - public static final UploadPackFactory DISABLED = new UploadPackFactory() { - public UploadPack create(HttpServletRequest req, Repository db) + public static final UploadPackFactory<?> DISABLED = new UploadPackFactory<Object>() { + public UploadPack create(Object req, Repository db) throws ServiceNotEnabledException { throw new ServiceNotEnabledException(); } @@ -62,8 +65,8 @@ public interface UploadPackFactory { * Create and configure a new UploadPack instance for a repository. * * @param req - * current HTTP request, in case information from the request may - * help configure the UploadPack instance. + * current request, in case information from the request may help + * configure the UploadPack instance. * @param db * the repository the upload would read from. * @return the newly configured UploadPack instance, must not be null. @@ -74,6 +77,6 @@ public interface UploadPackFactory { * this factory refuses to create the instance for this HTTP * request and repository, such as due to a permission error. */ - UploadPack create(HttpServletRequest req, Repository db) - throws ServiceNotEnabledException, ServiceNotAuthorizedException; + UploadPack create(C req, Repository db) throws ServiceNotEnabledException, + ServiceNotAuthorizedException; } |