summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShawn O. Pearce <spearce@spearce.org>2011-09-14 15:31:42 -0700
committerShawn O. Pearce <spearce@spearce.org>2011-09-14 15:34:55 -0700
commitc1a9b2ae8be6b0826b62021fe82a53de8783ea21 (patch)
tree061e847b479274bc214121ff420b45b23c82ad34
parentcc4e6109e40ac6f761b302b24bd6a793393090d5 (diff)
downloadjgit-c1a9b2ae8be6b0826b62021fe82a53de8783ea21.tar.gz
jgit-c1a9b2ae8be6b0826b62021fe82a53de8783ea21.zip
Fix smart HTTP client stream alignment errors
The client's use of UnionInputStream was broken when combined with a 8192 byte buffer used by PackParser. A smart HTTP client connection always pushes in the execute stateless RPC input stream after the data stream has ended from the remote peer. At the end of the pack, PackParser asked to fill a 8192 byte buffer, but if only e.g. 1000 bytes remained UnionInputStream went to the next stream and asked it for input, which triggered a new RPC, and failed because there was nothing pending in the request buffer. Change UnionInputStream to only return what it consumed from a single InputStream without invoking the next InputStream, just in case that second InputStream happens to be one of these magical ones that generates an RPC invocation. Change-Id: I0e51a8e6fea1647e4d2e08ac9cfc69c2945ce4cb Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/util/io/UnionInputStreamTest.java28
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java5
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/util/io/UnionInputStream.java7
3 files changed, 25 insertions, 15 deletions
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/io/UnionInputStreamTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/io/UnionInputStreamTest.java
index 5fd6816ec7..9fb323c4db 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/io/UnionInputStreamTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/io/UnionInputStreamTest.java
@@ -106,13 +106,21 @@ public class UnionInputStreamTest {
u.add(new ByteArrayInputStream(new byte[] { 4, 5 }));
final byte[] r = new byte[5];
- assertEquals(5, u.read(r, 0, 5));
- assertTrue(Arrays.equals(new byte[] { 1, 0, 2, 3, 4 }, r));
+ assertEquals(3, u.read(r, 0, 5));
+ assertTrue(Arrays.equals(new byte[] { 1, 0, 2, }, slice(r, 3)));
assertEquals(1, u.read(r, 0, 5));
- assertEquals(5, r[0]);
+ assertEquals(3, r[0]);
+ assertEquals(2, u.read(r, 0, 5));
+ assertTrue(Arrays.equals(new byte[] { 4, 5, }, slice(r, 2)));
assertEquals(-1, u.read(r, 0, 5));
}
+ private static byte[] slice(byte[] in, int len) {
+ byte[] r = new byte[len];
+ System.arraycopy(in, 0, r, 0, len);
+ return r;
+ }
+
@Test
public void testArrayConstructor() throws IOException {
final UnionInputStream u = new UnionInputStream(
@@ -121,10 +129,12 @@ public class UnionInputStreamTest {
new ByteArrayInputStream(new byte[] { 4, 5 }));
final byte[] r = new byte[5];
- assertEquals(5, u.read(r, 0, 5));
- assertTrue(Arrays.equals(new byte[] { 1, 0, 2, 3, 4 }, r));
+ assertEquals(3, u.read(r, 0, 5));
+ assertTrue(Arrays.equals(new byte[] { 1, 0, 2, }, slice(r, 3)));
assertEquals(1, u.read(r, 0, 5));
- assertEquals(5, r[0]);
+ assertEquals(3, r[0]);
+ assertEquals(2, u.read(r, 0, 5));
+ assertTrue(Arrays.equals(new byte[] { 4, 5, }, slice(r, 2)));
assertEquals(-1, u.read(r, 0, 5));
}
@@ -143,9 +153,9 @@ public class UnionInputStreamTest {
u.add(new ByteArrayInputStream(new byte[] { 3 }));
u.add(new ByteArrayInputStream(new byte[] { 4, 5 }));
assertEquals(0, u.skip(0));
- assertEquals(4, u.skip(4));
- assertEquals(4, u.read());
- assertEquals(1, u.skip(5));
+ assertEquals(3, u.skip(3));
+ assertEquals(3, u.read());
+ assertEquals(2, u.skip(5));
assertEquals(0, u.skip(5));
assertEquals(-1, u.read());
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java
index 43ad98985d..1b78fcfc9a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java
@@ -851,11 +851,6 @@ public class TransportHttp extends HttpTransport implements WalkTransport,
}
class HttpExecuteStream extends InputStream {
- public int available() throws IOException {
- execute();
- return 0;
- }
-
public int read() throws IOException {
execute();
return -1;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/UnionInputStream.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/UnionInputStream.java
index f0183717a7..0df3775f11 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/UnionInputStream.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/UnionInputStream.java
@@ -148,8 +148,11 @@ public class UnionInputStream extends InputStream {
len -= n;
} else if (in == EOF)
return 0 < cnt ? cnt : -1;
- else
+ else {
pop();
+ if (0 < cnt)
+ break;
+ }
}
return cnt;
}
@@ -180,6 +183,8 @@ public class UnionInputStream extends InputStream {
final int r = in.read();
if (r < 0) {
pop();
+ if (0 < cnt)
+ break;
} else {
cnt += 1;
len -= 1;