Merge "UploadPack: Receive and parse client session-id"
This commit is contained in:
commit
8aa3cba7b4
|
@ -98,6 +98,25 @@ public void testRecvWantsWithAgent()
|
|||
"f900c8326a43303685c46b279b9f70411bff1a4b"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRecvWantsWithSessionID()
|
||||
throws PackProtocolException, IOException {
|
||||
PacketLineIn pckIn = formatAsPacketLine(String.join(" ", "want",
|
||||
"4624442d68ee402a94364191085b77137618633e", "thin-pack",
|
||||
"agent=JGit.test/0.0.1", "session-id=client-session-id", "\n"),
|
||||
"want f900c8326a43303685c46b279b9f70411bff1a4b\n",
|
||||
PacketLineIn.end());
|
||||
ProtocolV0Parser parser = new ProtocolV0Parser(defaultConfig());
|
||||
FetchV0Request request = parser.recvWants(pckIn);
|
||||
assertTrue(request.getClientCapabilities()
|
||||
.contains(GitProtocolConstants.OPTION_THIN_PACK));
|
||||
assertEquals(1, request.getClientCapabilities().size());
|
||||
assertEquals("client-session-id", request.getClientSID());
|
||||
assertThat(request.getWantIds(),
|
||||
hasOnlyObjectIds("4624442d68ee402a94364191085b77137618633e",
|
||||
"f900c8326a43303685c46b279b9f70411bff1a4b"));
|
||||
}
|
||||
|
||||
/*
|
||||
* First round of protocol v0 negotiation. Client send wants, no
|
||||
* capabilities.
|
||||
|
|
|
@ -361,4 +361,28 @@ public void testLsRefsRefPrefixes() throws IOException {
|
|||
assertEquals(2, req.getRefPrefixes().size());
|
||||
assertThat(req.getRefPrefixes(), hasItems("refs/for", "refs/heads"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFetchWithSessionID() throws IOException {
|
||||
PacketLineIn pckIn = formatAsPacketLine("session-id=the.client.sid",
|
||||
PacketLineIn.end());
|
||||
|
||||
ProtocolV2Parser parser = new ProtocolV2Parser(
|
||||
ConfigBuilder.start().allowFilter().done());
|
||||
FetchV2Request request = parser.parseFetchRequest(pckIn);
|
||||
|
||||
assertEquals("the.client.sid", request.getClientSID());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLsRefsWithSessionID() throws IOException {
|
||||
PacketLineIn pckIn = formatAsPacketLine("session-id=the.client.sid",
|
||||
PacketLineIn.delimiter(), PacketLineIn.end());
|
||||
|
||||
ProtocolV2Parser parser = new ProtocolV2Parser(
|
||||
ConfigBuilder.getDefault());
|
||||
LsRefsV2Request req = parser.parseLsRefsRequest(pckIn);
|
||||
|
||||
assertEquals("the.client.sid", req.getClientSID());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2428,6 +2428,24 @@ public void testGetPeerAgentProtocolV0() throws Exception {
|
|||
assertEquals(up.getPeerUserAgent(), "JGit-test/1.2.3");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSessionIDValueProtocolV0() throws Exception {
|
||||
RevCommit one = remote.commit().message("1").create();
|
||||
remote.update("one", one);
|
||||
|
||||
UploadPack up = new UploadPack(server);
|
||||
ByteArrayInputStream send = linesAsInputStream(
|
||||
"want " + one.getName() + " agent=JGit-test/1.2.3"
|
||||
+ " session-id=client-session-id\n",
|
||||
PacketLineIn.end(),
|
||||
"have 11cedf1b796d44207da702f7d420684022fc0f09\n", "done\n");
|
||||
|
||||
ByteArrayOutputStream recv = new ByteArrayOutputStream();
|
||||
up.upload(send, recv, null);
|
||||
|
||||
assertEquals(up.getClientSID(), "client-session-id");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetPeerAgentProtocolV2() throws Exception {
|
||||
server.getConfig().setString(ConfigConstants.CONFIG_PROTOCOL_SECTION,
|
||||
|
@ -2452,6 +2470,30 @@ public void testGetPeerAgentProtocolV2() throws Exception {
|
|||
assertEquals(up.getPeerUserAgent(), "JGit-test/1.2.4");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSessionIDValueProtocolV2() throws Exception {
|
||||
server.getConfig().setString(ConfigConstants.CONFIG_PROTOCOL_SECTION,
|
||||
null, ConfigConstants.CONFIG_KEY_VERSION,
|
||||
TransferConfig.ProtocolVersion.V2.version());
|
||||
|
||||
RevCommit one = remote.commit().message("1").create();
|
||||
remote.update("one", one);
|
||||
|
||||
UploadPack up = new UploadPack(server);
|
||||
up.setExtraParameters(Sets.of("version=2"));
|
||||
|
||||
ByteArrayInputStream send = linesAsInputStream("command=fetch\n",
|
||||
"agent=JGit-test/1.2.4\n", "session-id=client-session-id\n",
|
||||
PacketLineIn.delimiter(), "want " + one.getName() + "\n",
|
||||
"have 11cedf1b796d44207da702f7d420684022fc0f09\n", "done\n",
|
||||
PacketLineIn.end());
|
||||
|
||||
ByteArrayOutputStream recv = new ByteArrayOutputStream();
|
||||
up.upload(send, recv, null);
|
||||
|
||||
assertEquals(up.getClientSID(), "client-session-id");
|
||||
}
|
||||
|
||||
private static class RejectAllRefFilter implements RefFilter {
|
||||
@Override
|
||||
public Map<String, Ref> filter(Map<String, Ref> refs) {
|
||||
|
|
|
@ -40,6 +40,9 @@ abstract class FetchRequest {
|
|||
@Nullable
|
||||
final String agent;
|
||||
|
||||
@Nullable
|
||||
final String clientSID;
|
||||
|
||||
/**
|
||||
* Initialize the common fields of a fetch request.
|
||||
*
|
||||
|
@ -61,12 +64,15 @@ abstract class FetchRequest {
|
|||
* specific time, instead of depth
|
||||
* @param agent
|
||||
* agent as reported by the client in the request body
|
||||
* @param clientSID
|
||||
* agent as reported by the client in the request body
|
||||
*/
|
||||
FetchRequest(@NonNull Set<ObjectId> wantIds, int depth,
|
||||
@NonNull Set<ObjectId> clientShallowCommits,
|
||||
@NonNull FilterSpec filterSpec,
|
||||
@NonNull Set<String> clientCapabilities, int deepenSince,
|
||||
@NonNull List<String> deepenNots, @Nullable String agent) {
|
||||
@NonNull List<String> deepenNots, @Nullable String agent,
|
||||
@Nullable String clientSID) {
|
||||
this.wantIds = requireNonNull(wantIds);
|
||||
this.depth = depth;
|
||||
this.clientShallowCommits = requireNonNull(clientShallowCommits);
|
||||
|
@ -75,6 +81,7 @@ abstract class FetchRequest {
|
|||
this.deepenSince = deepenSince;
|
||||
this.deepenNots = requireNonNull(deepenNots);
|
||||
this.agent = agent;
|
||||
this.clientSID = clientSID;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -160,4 +167,13 @@ List<String> getDeepenNots() {
|
|||
String getAgent() {
|
||||
return agent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string identifying the client session ID (as sent in the request body by the
|
||||
* client)
|
||||
*/
|
||||
@Nullable
|
||||
String getClientSID() {
|
||||
return clientSID;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,9 +30,11 @@ final class FetchV0Request extends FetchRequest {
|
|||
@NonNull Set<ObjectId> clientShallowCommits,
|
||||
@NonNull FilterSpec filterSpec,
|
||||
@NonNull Set<String> clientCapabilities, int deepenSince,
|
||||
@NonNull List<String> deepenNotRefs, @Nullable String agent) {
|
||||
@NonNull List<String> deepenNotRefs, @Nullable String agent,
|
||||
@Nullable String clientSID) {
|
||||
super(wantIds, depth, clientShallowCommits, filterSpec,
|
||||
clientCapabilities, deepenSince, deepenNotRefs, agent);
|
||||
clientCapabilities, deepenSince, deepenNotRefs, agent,
|
||||
clientSID);
|
||||
}
|
||||
|
||||
static final class Builder {
|
||||
|
@ -53,6 +55,8 @@ static final class Builder {
|
|||
|
||||
String agent;
|
||||
|
||||
String clientSID;
|
||||
|
||||
/**
|
||||
* @param objectId
|
||||
* object id received in a "want" line
|
||||
|
@ -148,6 +152,16 @@ Builder setAgent(String clientAgent) {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param clientSID
|
||||
* session-id line sent by the client in the request body
|
||||
* @return this builder
|
||||
*/
|
||||
Builder setClientSID(String clientSID) {
|
||||
this.clientSID = clientSID;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param filter
|
||||
* the filter set in a filter line
|
||||
|
@ -160,7 +174,8 @@ Builder setFilterSpec(@NonNull FilterSpec filter) {
|
|||
|
||||
FetchV0Request build() {
|
||||
return new FetchV0Request(wantIds, depth, clientShallowCommits,
|
||||
filterSpec, clientCaps, deepenSince, deepenNots, agent);
|
||||
filterSpec, clientCaps, deepenSince, deepenNots, agent,
|
||||
clientSID);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -55,10 +55,11 @@ public final class FetchV2Request extends FetchRequest {
|
|||
boolean doneReceived, boolean waitForDone,
|
||||
@NonNull Set<String> clientCapabilities,
|
||||
@Nullable String agent, @NonNull List<String> serverOptions,
|
||||
boolean sidebandAll, @NonNull List<String> packfileUriProtocols) {
|
||||
boolean sidebandAll, @NonNull List<String> packfileUriProtocols,
|
||||
@Nullable String clientSID) {
|
||||
super(wantIds, depth, clientShallowCommits, filterSpec,
|
||||
clientCapabilities, deepenSince,
|
||||
deepenNots, agent);
|
||||
deepenNots, agent, clientSID);
|
||||
this.peerHas = requireNonNull(peerHas);
|
||||
this.wantedRefs = requireNonNull(wantedRefs);
|
||||
this.doneReceived = doneReceived;
|
||||
|
@ -157,6 +158,9 @@ static final class Builder {
|
|||
@Nullable
|
||||
String agent;
|
||||
|
||||
@Nullable
|
||||
String clientSID;
|
||||
|
||||
final List<String> serverOptions = new ArrayList<>();
|
||||
|
||||
boolean sidebandAll;
|
||||
|
@ -316,6 +320,17 @@ Builder setAgent(@Nullable String agentValue) {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param clientSIDValue
|
||||
* the client-supplied session capability, without the
|
||||
* leading "session-id="
|
||||
* @return this builder
|
||||
*/
|
||||
Builder setClientSID(@Nullable String clientSIDValue) {
|
||||
clientSID = clientSIDValue;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Records an application-specific option supplied in a server-option
|
||||
* line, for later retrieval with
|
||||
|
@ -354,7 +369,8 @@ FetchV2Request build() {
|
|||
depth, filterSpec, doneReceived, waitForDone, clientCapabilities,
|
||||
agent, Collections.unmodifiableList(serverOptions),
|
||||
sidebandAll,
|
||||
Collections.unmodifiableList(packfileUriProtocols));
|
||||
Collections.unmodifiableList(packfileUriProtocols),
|
||||
clientSID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,17 +36,21 @@ public final class LsRefsV2Request {
|
|||
@Nullable
|
||||
private final String agent;
|
||||
|
||||
private final String clientSID;
|
||||
|
||||
@NonNull
|
||||
private final List<String> serverOptions;
|
||||
|
||||
private LsRefsV2Request(List<String> refPrefixes, boolean symrefs,
|
||||
boolean peel, @Nullable String agent,
|
||||
@NonNull List<String> serverOptions) {
|
||||
@NonNull List<String> serverOptions,
|
||||
@Nullable String clientSID) {
|
||||
this.refPrefixes = refPrefixes;
|
||||
this.symrefs = symrefs;
|
||||
this.peel = peel;
|
||||
this.agent = agent;
|
||||
this.serverOptions = requireNonNull(serverOptions);
|
||||
this.clientSID = clientSID;
|
||||
}
|
||||
|
||||
/** @return ref prefixes that the client requested. */
|
||||
|
@ -74,6 +78,16 @@ public String getAgent() {
|
|||
return agent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return session-id as reported by the client
|
||||
*
|
||||
* @since 6.4
|
||||
*/
|
||||
@Nullable
|
||||
public String getClientSID() {
|
||||
return clientSID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get application-specific options provided by the client using
|
||||
* --server-option.
|
||||
|
@ -109,6 +123,8 @@ public static final class Builder {
|
|||
|
||||
private String agent;
|
||||
|
||||
private String clientSID;
|
||||
|
||||
private Builder() {
|
||||
}
|
||||
|
||||
|
@ -171,11 +187,28 @@ public Builder setAgent(@Nullable String value) {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Value of a session-id line received after the command and before the
|
||||
* arguments. E.g. "session-id=a.b.c" should set "a.b.c".
|
||||
*
|
||||
* @param value
|
||||
* the client-supplied session-id capability, without leading
|
||||
* "session-id="
|
||||
* @return this builder
|
||||
*
|
||||
* @since 6.4
|
||||
*/
|
||||
public Builder setClientSID(@Nullable String value) {
|
||||
clientSID = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** @return LsRefsV2Request */
|
||||
public LsRefsV2Request build() {
|
||||
return new LsRefsV2Request(
|
||||
Collections.unmodifiableList(refPrefixes), symrefs, peel,
|
||||
agent, Collections.unmodifiableList(serverOptions));
|
||||
agent, Collections.unmodifiableList(serverOptions),
|
||||
clientSID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -152,6 +152,7 @@ FetchV0Request recvWants(PacketLineIn pckIn)
|
|||
FirstWant firstLine = FirstWant.fromLine(line);
|
||||
reqBuilder.addClientCapabilities(firstLine.getCapabilities());
|
||||
reqBuilder.setAgent(firstLine.getAgent());
|
||||
reqBuilder.setClientSID(firstLine.getClientSID());
|
||||
line = firstLine.getLine();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_SIDE_BAND_64K;
|
||||
import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_THIN_PACK;
|
||||
import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_WAIT_FOR_DONE;
|
||||
import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_SESSION_ID;
|
||||
import static org.eclipse.jgit.transport.GitProtocolConstants.PACKET_DEEPEN;
|
||||
import static org.eclipse.jgit.transport.GitProtocolConstants.PACKET_DEEPEN_NOT;
|
||||
import static org.eclipse.jgit.transport.GitProtocolConstants.PACKET_DEEPEN_SINCE;
|
||||
|
@ -63,10 +64,12 @@ final class ProtocolV2Parser {
|
|||
*/
|
||||
private static String consumeCapabilities(PacketLineIn pckIn,
|
||||
Consumer<String> serverOptionConsumer,
|
||||
Consumer<String> agentConsumer) throws IOException {
|
||||
Consumer<String> agentConsumer,
|
||||
Consumer<String> clientSIDConsumer) throws IOException {
|
||||
|
||||
String serverOptionPrefix = OPTION_SERVER_OPTION + '=';
|
||||
String agentPrefix = OPTION_AGENT + '=';
|
||||
String clientSIDPrefix = OPTION_SESSION_ID + '=';
|
||||
|
||||
String line = pckIn.readString();
|
||||
while (!PacketLineIn.isDelimiter(line) && !PacketLineIn.isEnd(line)) {
|
||||
|
@ -75,6 +78,9 @@ private static String consumeCapabilities(PacketLineIn pckIn,
|
|||
.accept(line.substring(serverOptionPrefix.length()));
|
||||
} else if (line.startsWith(agentPrefix)) {
|
||||
agentConsumer.accept(line.substring(agentPrefix.length()));
|
||||
} else if (line.startsWith(clientSIDPrefix)) {
|
||||
clientSIDConsumer
|
||||
.accept(line.substring(clientSIDPrefix.length()));
|
||||
} else {
|
||||
// Unrecognized capability. Ignore it.
|
||||
}
|
||||
|
@ -108,7 +114,8 @@ FetchV2Request parseFetchRequest(PacketLineIn pckIn)
|
|||
|
||||
String line = consumeCapabilities(pckIn,
|
||||
serverOption -> reqBuilder.addServerOption(serverOption),
|
||||
agent -> reqBuilder.setAgent(agent));
|
||||
agent -> reqBuilder.setAgent(agent),
|
||||
clientSID -> reqBuilder.setClientSID(clientSID));
|
||||
|
||||
if (PacketLineIn.isEnd(line)) {
|
||||
return reqBuilder.build();
|
||||
|
@ -235,7 +242,8 @@ LsRefsV2Request parseLsRefsRequest(PacketLineIn pckIn)
|
|||
|
||||
String line = consumeCapabilities(pckIn,
|
||||
serverOption -> builder.addServerOption(serverOption),
|
||||
agent -> builder.setAgent(agent));
|
||||
agent -> builder.setAgent(agent),
|
||||
clientSID -> builder.setClientSID(clientSID));
|
||||
|
||||
if (PacketLineIn.isEnd(line)) {
|
||||
return builder.build();
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_SIDEBAND_ALL;
|
||||
import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_SIDE_BAND;
|
||||
import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_SIDE_BAND_64K;
|
||||
import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_SESSION_ID;
|
||||
import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_THIN_PACK;
|
||||
import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_WAIT_FOR_DONE;
|
||||
import static org.eclipse.jgit.transport.GitProtocolConstants.PACKET_ACK;
|
||||
|
@ -1382,6 +1383,10 @@ private List<String> getV2CapabilityAdvertisement() {
|
|||
: "")
|
||||
+ OPTION_SHALLOW);
|
||||
caps.add(CAPABILITY_SERVER_OPTION);
|
||||
if (transferConfig.isAllowReceiveClientSID()) {
|
||||
caps.add(OPTION_SESSION_ID);
|
||||
}
|
||||
|
||||
return caps;
|
||||
}
|
||||
|
||||
|
@ -1700,6 +1705,21 @@ public String getPeerUserAgent() {
|
|||
return userAgent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the session ID if received from the client.
|
||||
*
|
||||
* @return The session ID if it has been received from the client.
|
||||
* @since 6.4
|
||||
*/
|
||||
@Nullable
|
||||
public String getClientSID() {
|
||||
if (currentRequest == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return currentRequest.getClientSID();
|
||||
}
|
||||
|
||||
private boolean negotiate(FetchRequest req,
|
||||
PackStatistics.Accumulator accumulator,
|
||||
PacketLineOut pckOut)
|
||||
|
|
Loading…
Reference in New Issue