FirstWant: Parse client session-id if received.

In protocol V0 the client capabilities are appended to the first line.
Parsing session-id is currently only supported during a ReceivePack
operation. This change will parse the client session-id capability if
it has been sent by the client.

If the server sends the session-id capability to the client. The client
may respond with a session ID of its own. FirstWant.fromLine will now
parse the ID and make it available via the getClientSID method.

This change does not add support to send the session-id capability from
the server. The change is necessary to support session-id in UploadPack.

Change-Id: Id3fe44fdf9a72984ee3de9cf40cc4e71d434df4a
Signed-off-by: Josh Brown <sjoshbrown@google.com>
This commit is contained in:
Josh Brown 2022-11-01 18:16:44 +00:00
parent 93097f0018
commit e8068188f1
2 changed files with 31 additions and 4 deletions

View File

@ -27,7 +27,8 @@ public class FirstWantTest {
@Test
public void testFirstWantWithOptions() throws PackProtocolException {
String line = "want b9d4d1eb2f93058814480eae9e1b67550f46ee38 "
+ "no-progress include-tag ofs-delta agent=JGit/unknown";
+ "no-progress include-tag ofs-delta agent=JGit/unknown "
+ "session-id=the.client.sid";
FirstWant r = FirstWant.fromLine(line);
assertEquals("want b9d4d1eb2f93058814480eae9e1b67550f46ee38",
@ -37,6 +38,7 @@ public void testFirstWantWithOptions() throws PackProtocolException {
Arrays.asList("no-progress", "include-tag", "ofs-delta"));
assertEquals(expectedCapabilities, capabilities);
assertEquals("JGit/unknown", r.getAgent());
assertEquals("the.client.sid", r.getClientSID());
}
@Test
@ -94,4 +96,12 @@ public void testFirstWantValidAgentName() throws PackProtocolException {
assertEquals(r.getCapabilities().size(), 0);
assertEquals("pack.age/Version", r.getAgent());
}
@Test
public void testFirstWantValidSessionID() throws PackProtocolException {
FirstWant r = FirstWant
.fromLine(makeFirstWantLine("session-id=client.session.id"));
assertEquals(r.getCapabilities().size(), 0);
assertEquals("client.session.id", r.getClientSID());
}
}

View File

@ -10,6 +10,7 @@
package org.eclipse.jgit.internal.transport.parser;
import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_AGENT;
import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_SESSION_ID;
import java.util.Collections;
import java.util.HashSet;
@ -43,8 +44,13 @@ public class FirstWant {
@Nullable
private final String agent;
@Nullable
private final String clientSID;
private static final String AGENT_PREFIX = OPTION_AGENT + '=';
private static final String SESSION_ID_PREFIX = OPTION_SESSION_ID + '=';
/**
* Parse the first want line in the protocol v0/v1 pack negotiation.
*
@ -58,6 +64,7 @@ public static FirstWant fromLine(String line) throws PackProtocolException {
String wantLine;
Set<String> capabilities;
String agent = null;
String clientSID = null;
if (line.length() > 45) {
String opt = line.substring(45);
@ -70,6 +77,9 @@ public static FirstWant fromLine(String line) throws PackProtocolException {
for (String clientCapability : opt.split(" ")) { //$NON-NLS-1$
if (clientCapability.startsWith(AGENT_PREFIX)) {
agent = clientCapability.substring(AGENT_PREFIX.length());
} else if (clientCapability.startsWith(SESSION_ID_PREFIX)) {
clientSID = clientCapability
.substring(SESSION_ID_PREFIX.length());
} else {
opts.add(clientCapability);
}
@ -81,14 +91,15 @@ public static FirstWant fromLine(String line) throws PackProtocolException {
capabilities = Collections.emptySet();
}
return new FirstWant(wantLine, capabilities, agent);
return new FirstWant(wantLine, capabilities, agent, clientSID);
}
private FirstWant(String line, Set<String> capabilities,
@Nullable String agent) {
@Nullable String agent, @Nullable String clientSID) {
this.line = line;
this.capabilities = capabilities;
this.agent = agent;
this.clientSID = clientSID;
}
/** @return non-capabilities part of the line. */
@ -98,7 +109,7 @@ public String getLine() {
/**
* @return capabilities parsed from the line as an immutable set (excluding
* agent).
* agent and session-id).
*/
public Set<String> getCapabilities() {
return capabilities;
@ -109,4 +120,10 @@ public Set<String> getCapabilities() {
public String getAgent() {
return agent;
}
/** @return client session-id parsed from the line. */
@Nullable
public String getClientSID() {
return clientSID;
}
}