Browse Source

Merge "daemon: Use HTTP's resolver and factory pattern"

stable-0.12
Chris Aniszczyk 14 years ago committed by Code Review
parent
commit
22abbd338d
  1. 1
      org.eclipse.jgit.http.server/META-INF/MANIFEST.MF
  2. 2
      org.eclipse.jgit.http.server/resources/org/eclipse/jgit/http/server/HttpServerText.properties
  3. 4
      org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/AsIsFileFilter.java
  4. 29
      org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/GitServlet.java
  5. 2
      org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/HttpServerText.java
  6. 6
      org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ReceivePackServlet.java
  7. 6
      org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/RepositoryFilter.java
  8. 4
      org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/SmartServiceInfoRefs.java
  9. 6
      org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/UploadPackServlet.java
  10. 2
      org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/AsIsFileService.java
  11. 6
      org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/DefaultReceivePackFactory.java
  12. 6
      org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/DefaultUploadPackFactory.java
  13. 1
      org.eclipse.jgit.http.test/META-INF/MANIFEST.MF
  14. 8
      org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/AdvertiseErrorTest.java
  15. 4
      org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/AsIsServiceTest.java
  16. 6
      org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/DefaultReceivePackFactoryTest.java
  17. 6
      org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/DefaultUploadPackFactoryTest.java
  18. 6
      org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/DumbClientSmartServerTest.java
  19. 4
      org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/FileResolverTest.java
  20. 8
      org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/HookMessageTest.java
  21. 6
      org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/HttpClientTests.java
  22. 6
      org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/SmartClientSmartServerTest.java
  23. 1
      org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF
  24. 6
      org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/SimpleHttpServer.java
  25. 1
      org.eclipse.jgit.pgm/META-INF/MANIFEST.MF
  26. 16
      org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Daemon.java
  27. 1
      org.eclipse.jgit/META-INF/MANIFEST.MF
  28. 2
      org.eclipse.jgit/resources/org/eclipse/jgit/JGitText.properties
  29. 2
      org.eclipse.jgit/src/org/eclipse/jgit/JGitText.java
  30. 247
      org.eclipse.jgit/src/org/eclipse/jgit/transport/Daemon.java
  31. 7
      org.eclipse.jgit/src/org/eclipse/jgit/transport/DaemonClient.java
  32. 10
      org.eclipse.jgit/src/org/eclipse/jgit/transport/DaemonService.java
  33. 181
      org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/FileResolver.java
  34. 27
      org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/ReceivePackFactory.java
  35. 28
      org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/RepositoryResolver.java
  36. 6
      org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/ServiceNotAuthorizedException.java
  37. 6
      org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/ServiceNotEnabledException.java
  38. 25
      org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/UploadPackFactory.java

1
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)"

2
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

4
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;

29
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;

2
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;

6
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 {

6
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}.

4
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 {

6
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 {

2
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.

6
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);

6
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);

1
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)",

8
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 {

4
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;

6
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;

6
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;

6
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 {

4
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;

8
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 {

6
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 {

6
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 {

1
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"

6
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 {

1
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)",

16
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()));
}

1
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",

2
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.

2
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;

247
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.
*
@ -257,6 +230,44 @@ public class Daemon {
this.packConfig = pc;
}
/**
* 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.
*
@ -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();
}
}

7
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());

10
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;
}

181
org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/FileResolver.java → 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

27
org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/ReceivePackFactory.java → 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;
}

28
org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/RepositoryResolver.java → 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;
}

6
org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/ServiceNotAuthorizedException.java → 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);
}
}

6
org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/ServiceNotEnabledException.java → 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);
}
}

25
org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/UploadPackFactory.java → 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;
}
Loading…
Cancel
Save