From 360d8624ca42ed13ec99fb5f30c887118e581080 Mon Sep 17 00:00:00 2001 From: Dave Borowitz Date: Sun, 23 Jun 2013 17:28:34 -0700 Subject: [PATCH] UploadPack: allow custom RequestValidator instances Make the existing concrete implementations public as well so custom implementations may delegate to them where appropriate. Treat all custom implementations as providing allow-tip-sha1 in want. Change-Id: If386fe25c0d3b4551a97c16a22350714453b03e9 --- .../eclipse/jgit/transport/UploadPack.java | 123 +++++++++++++----- 1 file changed, 90 insertions(+), 33 deletions(-) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java index 43f854e17..0d23cf792 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java @@ -141,8 +141,12 @@ public class UploadPack { ANY; } - /** Validator for client requests. */ - private interface RequestValidator { + /** + * Validator for client requests. + * + * @since 3.1 + */ + public interface RequestValidator { /** * Check a list of client wants against the request policy. * @@ -155,6 +159,7 @@ public class UploadPack { * if one or more wants is not valid. * @throws IOException * if a low-level exception occurred. + * @since 3.1 */ void checkWants(UploadPack up, List wants) throws PackProtocolException, IOException; @@ -297,7 +302,7 @@ public class UploadPack { private final RevFlagSet SAVE; - private RequestPolicy requestPolicy; + private RequestValidator requestValidator = new AdvertisedRequestValidator(); private MultiAck multiAck = MultiAck.OFF; @@ -414,9 +419,22 @@ public class UploadPack { biDirectionalPipe = twoWay; } - /** @return policy used by the service to validate client requests. */ + /** + * @return policy used by the service to validate client requests, or null for + * a custom request validator. + */ public RequestPolicy getRequestPolicy() { - return requestPolicy; + if (requestValidator instanceof AdvertisedRequestValidator) + return RequestPolicy.ADVERTISED; + if (requestValidator instanceof ReachableCommitRequestValidator) + return RequestPolicy.REACHABLE_COMMIT; + if (requestValidator instanceof TipRequestValidator) + return RequestPolicy.TIP; + if (requestValidator instanceof ReachableCommitTipRequestValidator) + return RequestPolicy.REACHABLE_COMMIT_TIP; + if (requestValidator instanceof AnyRequestValidator) + return RequestPolicy.ANY; + return null; } /** @@ -431,7 +449,34 @@ public class UploadPack { * Overrides any policy specified in a {@link TransferConfig}. */ public void setRequestPolicy(RequestPolicy policy) { - requestPolicy = policy; + switch (policy) { + case ADVERTISED: + default: + requestValidator = new AdvertisedRequestValidator(); + break; + case REACHABLE_COMMIT: + requestValidator = new ReachableCommitRequestValidator(); + break; + case TIP: + requestValidator = new TipRequestValidator(); + break; + case REACHABLE_COMMIT_TIP: + requestValidator = new ReachableCommitTipRequestValidator(); + break; + case ANY: + requestValidator = new AnyRequestValidator(); + break; + } + } + + /** + * @param validator + * custom validator for client want list. + * @since 3.1 + */ + public void setRequestValidator(RequestValidator validator) { + requestValidator = validator != null ? validator + : new AdvertisedRequestValidator(); } /** @return the hook used while advertising the refs to the client */ @@ -509,8 +554,8 @@ public class UploadPack { */ public void setTransferConfig(TransferConfig tc) { this.transferConfig = tc != null ? tc : new TransferConfig(db); - this.requestPolicy = transferConfig.isAllowTipSha1InWant() - ? RequestPolicy.TIP : RequestPolicy.ADVERTISED; + setRequestPolicy(transferConfig.isAllowTipSha1InWant() + ? RequestPolicy.TIP : RequestPolicy.ADVERTISED); } /** @return the configured logger. */ @@ -619,7 +664,7 @@ public class UploadPack { private void service() throws IOException { if (biDirectionalPipe) sendAdvertisedRefs(new PacketLineOutRefAdvertiser(pckOut)); - else if (requestPolicy == RequestPolicy.ANY) + else if (requestValidator instanceof AnyRequestValidator) advertised = Collections.emptySet(); else advertised = refIdSet(getAdvertisedOrDefaultRefs().values()); @@ -758,8 +803,10 @@ public class UploadPack { adv.advertiseCapability(OPTION_SHALLOW); if (!biDirectionalPipe) adv.advertiseCapability(OPTION_NO_DONE); - if (requestPolicy == RequestPolicy.TIP - || requestPolicy == RequestPolicy.REACHABLE_COMMIT_TIP) + RequestPolicy policy = getRequestPolicy(); + if (policy == RequestPolicy.TIP + || policy == RequestPolicy.REACHABLE_COMMIT_TIP + || policy == null) adv.advertiseCapability(OPTION_ALLOW_TIP_SHA1_IN_WANT); adv.setDerefTags(true); advertised = adv.send(getAdvertisedOrDefaultRefs()); @@ -1008,7 +1055,7 @@ public class UploadPack { } } if (notAdvertisedWants != null) - getRequestValidator().checkWants(this, notAdvertisedWants); + requestValidator.checkWants(this, notAdvertisedWants); wantIds.clear(); } catch (MissingObjectException notFound) { ObjectId id = notFound.getObjectId(); @@ -1026,23 +1073,13 @@ public class UploadPack { } } - private RequestValidator getRequestValidator() { - switch (requestPolicy) { - case ADVERTISED: - default: - return new AdvertisedRequestValidator(); - case REACHABLE_COMMIT: - return new ReachableCommitRequestValidator(); - case TIP: - return new TipRequestValidator(); - case REACHABLE_COMMIT_TIP: - return new ReachableCommitTipRequestValidator(); - case ANY: - return new AnyRequestValidator(); - } - } - - private static class AdvertisedRequestValidator implements RequestValidator { + /** + * Validator corresponding to {@link RequestPolicy#ADVERTISED}. + * + * @since 3.1 + */ + public static final class AdvertisedRequestValidator + implements RequestValidator { public void checkWants(UploadPack up, List wants) throws PackProtocolException, IOException { if (!up.isBiDirectionalPipe()) @@ -1053,7 +1090,12 @@ public class UploadPack { } } - private static class ReachableCommitRequestValidator + /** + * Validator corresponding to {@link RequestPolicy#REACHABLE_COMMIT}. + * + * @since 3.1 + */ + public static final class ReachableCommitRequestValidator implements RequestValidator { public void checkWants(UploadPack up, List wants) throws PackProtocolException, IOException { @@ -1062,7 +1104,12 @@ public class UploadPack { } } - private static class TipRequestValidator implements RequestValidator { + /** + * Validator corresponding to {@link RequestPolicy#TIP}. + * + * @since 3.1 + */ + public static final class TipRequestValidator implements RequestValidator { public void checkWants(UploadPack up, List wants) throws PackProtocolException, IOException { if (!up.isBiDirectionalPipe()) @@ -1079,7 +1126,12 @@ public class UploadPack { } } - private static class ReachableCommitTipRequestValidator + /** + * Validator corresponding to {@link RequestPolicy#REACHABLE_COMMIT_TIP}. + * + * @since 3.1 + */ + public static final class ReachableCommitTipRequestValidator implements RequestValidator { public void checkWants(UploadPack up, List wants) throws PackProtocolException, IOException { @@ -1088,7 +1140,12 @@ public class UploadPack { } } - private static class AnyRequestValidator implements RequestValidator { + /** + * Validator corresponding to {@link RequestPolicy#ANY}. + * + * @since 3.1 + */ + public static final class AnyRequestValidator implements RequestValidator { public void checkWants(UploadPack up, List wants) throws PackProtocolException, IOException { // All requests are valid.