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 @Test
public void testFirstWantWithOptions() throws PackProtocolException { public void testFirstWantWithOptions() throws PackProtocolException {
String line = "want b9d4d1eb2f93058814480eae9e1b67550f46ee38 " 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); FirstWant r = FirstWant.fromLine(line);
assertEquals("want b9d4d1eb2f93058814480eae9e1b67550f46ee38", assertEquals("want b9d4d1eb2f93058814480eae9e1b67550f46ee38",
@ -37,6 +38,7 @@ public void testFirstWantWithOptions() throws PackProtocolException {
Arrays.asList("no-progress", "include-tag", "ofs-delta")); Arrays.asList("no-progress", "include-tag", "ofs-delta"));
assertEquals(expectedCapabilities, capabilities); assertEquals(expectedCapabilities, capabilities);
assertEquals("JGit/unknown", r.getAgent()); assertEquals("JGit/unknown", r.getAgent());
assertEquals("the.client.sid", r.getClientSID());
} }
@Test @Test
@ -94,4 +96,12 @@ public void testFirstWantValidAgentName() throws PackProtocolException {
assertEquals(r.getCapabilities().size(), 0); assertEquals(r.getCapabilities().size(), 0);
assertEquals("pack.age/Version", r.getAgent()); 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; package org.eclipse.jgit.internal.transport.parser;
import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_AGENT; 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.Collections;
import java.util.HashSet; import java.util.HashSet;
@ -43,8 +44,13 @@ public class FirstWant {
@Nullable @Nullable
private final String agent; private final String agent;
@Nullable
private final String clientSID;
private static final String AGENT_PREFIX = OPTION_AGENT + '='; 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. * 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; String wantLine;
Set<String> capabilities; Set<String> capabilities;
String agent = null; String agent = null;
String clientSID = null;
if (line.length() > 45) { if (line.length() > 45) {
String opt = line.substring(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$ for (String clientCapability : opt.split(" ")) { //$NON-NLS-1$
if (clientCapability.startsWith(AGENT_PREFIX)) { if (clientCapability.startsWith(AGENT_PREFIX)) {
agent = clientCapability.substring(AGENT_PREFIX.length()); agent = clientCapability.substring(AGENT_PREFIX.length());
} else if (clientCapability.startsWith(SESSION_ID_PREFIX)) {
clientSID = clientCapability
.substring(SESSION_ID_PREFIX.length());
} else { } else {
opts.add(clientCapability); opts.add(clientCapability);
} }
@ -81,14 +91,15 @@ public static FirstWant fromLine(String line) throws PackProtocolException {
capabilities = Collections.emptySet(); capabilities = Collections.emptySet();
} }
return new FirstWant(wantLine, capabilities, agent); return new FirstWant(wantLine, capabilities, agent, clientSID);
} }
private FirstWant(String line, Set<String> capabilities, private FirstWant(String line, Set<String> capabilities,
@Nullable String agent) { @Nullable String agent, @Nullable String clientSID) {
this.line = line; this.line = line;
this.capabilities = capabilities; this.capabilities = capabilities;
this.agent = agent; this.agent = agent;
this.clientSID = clientSID;
} }
/** @return non-capabilities part of the line. */ /** @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 * @return capabilities parsed from the line as an immutable set (excluding
* agent). * agent and session-id).
*/ */
public Set<String> getCapabilities() { public Set<String> getCapabilities() {
return capabilities; return capabilities;
@ -109,4 +120,10 @@ public Set<String> getCapabilities() {
public String getAgent() { public String getAgent() {
return agent; return agent;
} }
/** @return client session-id parsed from the line. */
@Nullable
public String getClientSID() {
return clientSID;
}
} }