Browse Source

Teach ReceivePack how to use an RPC style interface

If biDirectionalPipe is false ReceivePack does not start out with the
advertisement but instead assumes it should read the command set once,
process that, and write the status report out.  This means it only is
doing one read through the input followed by one write to the output,
which fits with the HTTP request processing model, and any other type
of RPC system... assuming that the payload for input can be a very big
entity like the command stream followed by the pack file.

Change-Id: I6f31f6537a3b7498803a8a54e10b0622105718c1
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
stable-0.7
Shawn O. Pearce 15 years ago
parent
commit
2a5c8cb46c
  1. 45
      org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java

45
org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java

@ -96,6 +96,19 @@ public class ReceivePack {
/** Revision traversal support over {@link #db}. */ /** Revision traversal support over {@link #db}. */
private final RevWalk walk; private final RevWalk walk;
/**
* Is the client connection a bi-directional socket or pipe?
* <p>
* If true, this class assumes it can perform multiple read and write cycles
* with the client over the input and output streams. This matches the
* functionality available with a standard TCP/IP connection, or a local
* operating system or in-memory pipe.
* <p>
* If false, this class runs in a read everything then output results mode,
* making it suitable for single round-trip systems RPCs such as HTTP.
*/
private boolean biDirectionalPipe = true;
/** Should an incoming transfer validate objects? */ /** Should an incoming transfer validate objects? */
private boolean checkReceivedObjects; private boolean checkReceivedObjects;
@ -219,6 +232,27 @@ public class ReceivePack {
return refs; return refs;
} }
/**
* @return true if this class expects a bi-directional pipe opened between
* the client and itself. The default is true.
*/
public boolean isBiDirectionalPipe() {
return biDirectionalPipe;
}
/**
* @param twoWay
* if true, this class will assume the socket is a fully
* bidirectional pipe between the two peers and takes advantage
* of that by first transmitting the known refs, then waiting to
* read commands. If false, this class assumes it must read the
* commands before writing output and does not perform the
* initial advertising.
*/
public void setBiDirectionalPipe(final boolean twoWay) {
biDirectionalPipe = twoWay;
}
/** /**
* @return true if this instance will verify received objects are formatted * @return true if this instance will verify received objects are formatted
* correctly. Validating objects requires more CPU time on this side * correctly. Validating objects requires more CPU time on this side
@ -484,7 +518,10 @@ public class ReceivePack {
} }
private void service() throws IOException { private void service() throws IOException {
sendAdvertisedRefs(); if (biDirectionalPipe)
sendAdvertisedRefs();
else
refs = db.getAllRefs();
recvCommands(); recvCommands();
if (!commands.isEmpty()) { if (!commands.isEmpty()) {
enableCapabilities(); enableCapabilities();
@ -587,7 +624,11 @@ public class ReceivePack {
final ObjectId newId = ObjectId.fromString(line.substring(41, 81)); final ObjectId newId = ObjectId.fromString(line.substring(41, 81));
final String name = line.substring(82); final String name = line.substring(82);
final ReceiveCommand cmd = new ReceiveCommand(oldId, newId, name); final ReceiveCommand cmd = new ReceiveCommand(oldId, newId, name);
cmd.setRef(refs.get(cmd.getRefName())); if (name.equals(Constants.HEAD)) {
cmd.setResult(Result.REJECTED_CURRENT_BRANCH);
} else {
cmd.setRef(refs.get(cmd.getRefName()));
}
commands.add(cmd); commands.add(cmd);
} }
} }

Loading…
Cancel
Save