PacketLineIn, PacketLineOut: Add support for delim-pkt
Most pkt-lines (data-pkts) have the form
pkt-len pkt-payload
where pkt-len is a string of 4 hexadecimal digits representing the
size in bytes of the pkt-line. Since this size includes the size of
the pkt-len, no data-pkt has a length less than 4.
A pkt-line with a length field less than 4 can thus be used for
other purposes. In Git protocol v1, the only such pkt-line was
flush-pkt = "0000"
which was used to mark the end of a stream. Protocol v2 (see
Documentation/technical/protocol-v2.txt in git.git) introduces a
second special pkt-line type:
delim-pkt = "0001"
used to mark the end of a section within a stream, for example to
separate capabilities from the content of a command.
[jn: split out from a larger patch that made use of this support]
Change-Id: I10e7824fa24ed74c4f45624bd490bba978cf5c34
Signed-off-by: Jonathan Tan <jonathantanmy@google.com>
Signed-off-by: Jonathan Nieder <jrn@google.com>
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PacketLineInTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PacketLineInTest.java
index 13fc68d..982bae8 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PacketLineInTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PacketLineInTest.java
@@ -116,17 +116,6 @@
}
@Test
- public void testReadString_Len0001() {
- init("0001");
- try {
- in.readString();
- fail("incorrectly accepted invalid packet header");
- } catch (IOException e) {
- assertEquals("Invalid packet line header: 0001", e.getMessage());
- }
- }
-
- @Test
public void testReadString_Len0002() {
init("0002");
try {
@@ -164,6 +153,13 @@
assertEOF();
}
+ @Test
+ public void testReadString_Delim() throws IOException {
+ init("0001");
+ assertSame(PacketLineIn.DELIM, in.readString());
+ assertEOF();
+ }
+
// readStringNoLF
@Test
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PacketLineOutTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PacketLineOutTest.java
index eca5475..dd9a0d3 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PacketLineOutTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PacketLineOutTest.java
@@ -113,6 +113,12 @@
assertEquals(1, flushCnt[0]);
}
+ @Test
+ public void testWriteDelim() throws IOException {
+ out.writeDelim();
+ assertBuffer("0001");
+ }
+
// writePacket
@Test
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PacketLineIn.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PacketLineIn.java
index 87064e1..f64c8ef 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PacketLineIn.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PacketLineIn.java
@@ -74,6 +74,13 @@
/** Magic return from {@link #readString()} when a flush packet is found. */
public static final String END = new StringBuilder(0).toString(); /* must not string pool */
+ /**
+ * Magic return from {@link #readString()} when a delim packet is found.
+ *
+ * @since 5.0
+ */
+ public static final String DELIM = new StringBuilder(0).toString(); /* must not string pool */
+
static enum AckNackResult {
/** NAK */
NAK,
@@ -147,6 +154,7 @@
* use {@link #readStringRaw()} instead.
*
* @return the string. {@link #END} if the string was the magic flush
+ * packet, {@link #DELIM} if the string was the magic DELIM
* packet.
* @throws java.io.IOException
* the stream cannot be read.
@@ -157,6 +165,10 @@
log.debug("git< 0000"); //$NON-NLS-1$
return END;
}
+ if (len == 1) {
+ log.debug("git< 0001"); //$NON-NLS-1$
+ return DELIM;
+ }
len -= 4; // length header (4 bytes)
if (len == 0) {
@@ -232,6 +244,8 @@
if (len == 0) {
return 0;
+ } else if (len == 1) {
+ return 1;
} else if (len < 4) {
throw invalidHeader();
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PacketLineOut.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PacketLineOut.java
index 48bdd01..0cb3b0f 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PacketLineOut.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PacketLineOut.java
@@ -147,6 +147,20 @@
}
/**
+ * Write a packet delim marker (0001).
+ *
+ * @throws java.io.IOException
+ * the marker could not be written, the stream is corrupted
+ * as the marker may have been only partially written.
+ * @since 5.0
+ */
+ public void writeDelim() throws IOException {
+ formatLength(1);
+ out.write(lenbuffer, 0, 4);
+ log.debug("git> 0001"); //$NON-NLS-1$
+ }
+
+ /**
* Write a packet end marker, sometimes referred to as a flush command.
* <p>
* Technically this is a magical packet type which can be detected