From cca9142903097dbe4643944bbb4dbe5e2b87d922 Mon Sep 17 00:00:00 2001 From: jwilson Date: Sat, 22 Feb 2014 00:45:10 -0500 Subject: [PATCH] Deadlines are per-stream, not per-operation. --- .../com/squareup/okhttp/internal/Util.java | 7 +-- .../okhttp/internal/bytes/BufferedSink.java | 59 +++++++++--------- .../okhttp/internal/bytes/BufferedSource.java | 49 ++++++++------- .../okhttp/internal/bytes/DeflaterSink.java | 29 +++++---- .../okhttp/internal/bytes/GzipSource.java | 37 +++++++----- .../okhttp/internal/bytes/InflaterSource.java | 17 ++++-- .../okhttp/internal/bytes/OkBuffer.java | 15 +++-- .../okhttp/internal/bytes/OkBuffers.java | 27 +++++++-- .../squareup/okhttp/internal/bytes/Sink.java | 15 +++-- .../okhttp/internal/bytes/Source.java | 13 +++- .../okhttp/internal/spdy/HpackDraft05.java | 3 +- .../okhttp/internal/spdy/Http20Draft09.java | 15 +++-- .../internal/spdy/NameValueBlockReader.java | 19 +++--- .../squareup/okhttp/internal/spdy/Spdy3.java | 5 +- .../okhttp/internal/spdy/SpdyConnection.java | 3 +- .../okhttp/internal/spdy/SpdyStream.java | 19 +++--- .../internal/bytes/BufferedSinkTest.java | 10 ++-- .../internal/bytes/DeflaterSinkTest.java | 16 ++--- .../okhttp/internal/bytes/GzipSourceTest.java | 2 +- .../internal/bytes/InflaterSourceTest.java | 6 +- .../okhttp/internal/bytes/OkBufferTest.java | 60 +++++++++---------- .../internal/spdy/SpdyConnectionTest.java | 24 ++++---- .../java/com/squareup/okhttp/Connection.java | 3 +- .../okhttp/internal/http/HttpConnection.java | 35 +++++++---- .../okhttp/internal/http/SpdyTransport.java | 11 +++- 25 files changed, 295 insertions(+), 204 deletions(-) diff --git a/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/Util.java b/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/Util.java index 999b0fe61..99aa917d5 100644 --- a/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/Util.java +++ b/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/Util.java @@ -16,7 +16,6 @@ package com.squareup.okhttp.internal; -import com.squareup.okhttp.internal.bytes.Deadline; import com.squareup.okhttp.internal.bytes.OkBuffer; import com.squareup.okhttp.internal.bytes.Sink; import com.squareup.okhttp.internal.bytes.Source; @@ -115,7 +114,7 @@ public final class Util { public static void closeQuietly(Source source) { if (source != null) { try { - source.close(Deadline.NONE); + source.close(); } catch (RuntimeException rethrown) { throw rethrown; } catch (Exception ignored) { @@ -130,7 +129,7 @@ public final class Util { public static void closeQuietly(Sink sink) { if (sink != null) { try { - sink.close(Deadline.NONE); + sink.close(); } catch (RuntimeException rethrown) { throw rethrown; } catch (Exception ignored) { @@ -277,7 +276,7 @@ public final class Util { long startNanos = System.nanoTime(); OkBuffer skipBuffer = new OkBuffer(); while (NANOSECONDS.toMillis(System.nanoTime() - startNanos) < timeoutMillis) { - long read = in.read(skipBuffer, 2048, Deadline.NONE); + long read = in.read(skipBuffer, 2048); if (read == -1) return true; // Successfully exhausted the stream. skipBuffer.clear(); } diff --git a/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/bytes/BufferedSink.java b/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/bytes/BufferedSink.java index 3d5f00e4b..2b5a670e2 100644 --- a/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/bytes/BufferedSink.java +++ b/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/bytes/BufferedSink.java @@ -36,53 +36,53 @@ public final class BufferedSink implements Sink { this(sink, new OkBuffer()); } - @Override public void write(OkBuffer source, long byteCount, Deadline deadline) + @Override public void write(OkBuffer source, long byteCount) throws IOException { if (closed) throw new IllegalStateException("closed"); - buffer.write(source, byteCount, deadline); - emitCompleteSegments(deadline); + buffer.write(source, byteCount); + emitCompleteSegments(); } - public void write(ByteString byteString, Deadline deadline) throws IOException { + public void write(ByteString byteString) throws IOException { if (closed) throw new IllegalStateException("closed"); buffer.write(byteString); - emitCompleteSegments(deadline); + emitCompleteSegments(); } - public void writeUtf8(String string, Deadline deadline) throws IOException { + public void writeUtf8(String string) throws IOException { if (closed) throw new IllegalStateException("closed"); buffer.writeUtf8(string); - emitCompleteSegments(deadline); + emitCompleteSegments(); } - public void write(byte[] data, int offset, int byteCount, Deadline deadline) throws IOException { + public void write(byte[] data, int offset, int byteCount) throws IOException { if (closed) throw new IllegalStateException("closed"); buffer.write(data, offset, byteCount); - emitCompleteSegments(deadline); + emitCompleteSegments(); } - public void writeByte(int b, Deadline deadline) throws IOException { + public void writeByte(int b) throws IOException { if (closed) throw new IllegalStateException("closed"); buffer.writeByte(b); - emitCompleteSegments(deadline); + emitCompleteSegments(); } - public void writeShort(int s, Deadline deadline) throws IOException { + public void writeShort(int s) throws IOException { if (closed) throw new IllegalStateException("closed"); buffer.writeShort(s); - emitCompleteSegments(deadline); + emitCompleteSegments(); } - public void writeInt(int i, Deadline deadline) throws IOException { + public void writeInt(int i) throws IOException { if (closed) throw new IllegalStateException("closed"); buffer.writeInt(i); - emitCompleteSegments(deadline); + emitCompleteSegments(); } - void emitCompleteSegments(Deadline deadline) throws IOException { + void emitCompleteSegments() throws IOException { long byteCount = buffer.completeSegmentByteCount(); if (byteCount == 0) return; - sink.write(buffer, byteCount, deadline); + sink.write(buffer, byteCount); } /** Returns an output stream that writes to this sink. */ @@ -91,21 +91,21 @@ public final class BufferedSink implements Sink { @Override public void write(int b) throws IOException { if (closed) throw new IllegalStateException("closed"); buffer.writeByte((byte) b); - emitCompleteSegments(Deadline.NONE); + emitCompleteSegments(); } @Override public void write(byte[] data, int offset, int byteCount) throws IOException { if (closed) throw new IllegalStateException("closed"); buffer.write(data, offset, byteCount); - emitCompleteSegments(Deadline.NONE); + emitCompleteSegments(); } @Override public void flush() throws IOException { - BufferedSink.this.flush(Deadline.NONE); + BufferedSink.this.flush(); } @Override public void close() throws IOException { - BufferedSink.this.close(Deadline.NONE); + BufferedSink.this.close(); } @Override public String toString() { @@ -114,20 +114,25 @@ public final class BufferedSink implements Sink { }; } - @Override public void flush(Deadline deadline) throws IOException { + @Override public void flush() throws IOException { if (closed) throw new IllegalStateException("closed"); if (buffer.byteCount > 0) { - sink.write(buffer, buffer.byteCount, deadline); + sink.write(buffer, buffer.byteCount); } - sink.flush(deadline); + sink.flush(); } - @Override public void close(Deadline deadline) throws IOException { - flush(deadline); - sink.close(deadline); + @Override public void close() throws IOException { + flush(); + sink.close(); closed = true; } + @Override public Sink deadline(Deadline deadline) { + sink.deadline(deadline); + return this; + } + @Override public String toString() { return "BufferedSink(" + sink + ")"; } diff --git a/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/bytes/BufferedSource.java b/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/bytes/BufferedSource.java index 35e333398..c3bdea1b4 100644 --- a/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/bytes/BufferedSource.java +++ b/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/bytes/BufferedSource.java @@ -39,18 +39,18 @@ public final class BufferedSource implements Source { this(source, new OkBuffer()); } - @Override public long read(OkBuffer sink, long byteCount, Deadline deadline) + @Override public long read(OkBuffer sink, long byteCount) throws IOException { if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount); if (closed) throw new IllegalStateException("closed"); if (buffer.byteCount == 0) { - long read = source.read(buffer, Segment.SIZE, deadline); + long read = source.read(buffer, Segment.SIZE); if (read == -1) return -1; } long toRead = Math.min(byteCount, buffer.byteCount); - return buffer.read(sink, toRead, deadline); + return buffer.read(sink, toRead); } /** @@ -58,8 +58,8 @@ public final class BufferedSource implements Source { * will block until there are bytes to read or the source is definitely * exhausted. */ - public boolean exhausted(Deadline deadline) throws IOException { - return buffer.byteCount() == 0 && source.read(buffer, Segment.SIZE, deadline) == -1; + public boolean exhausted() throws IOException { + return buffer.byteCount() == 0 && source.read(buffer, Segment.SIZE) == -1; } /** @@ -67,39 +67,39 @@ public final class BufferedSource implements Source { * an {@link EOFException} if the source is exhausted before the required * bytes can be read. */ - void require(long byteCount, Deadline deadline) throws IOException { + void require(long byteCount) throws IOException { while (buffer.byteCount < byteCount) { - if (source.read(buffer, Segment.SIZE, deadline) == -1) throw new EOFException(); + if (source.read(buffer, Segment.SIZE) == -1) throw new EOFException(); } } public byte readByte() throws IOException { - require(1, Deadline.NONE); + require(1); return buffer.readByte(); } public ByteString readByteString(int byteCount) throws IOException { - require(byteCount, Deadline.NONE); + require(byteCount); return buffer.readByteString(byteCount); } public short readShort() throws IOException { - require(2, Deadline.NONE); + require(2); return buffer.readShort(); } public int readShortLe() throws IOException { - require(2, Deadline.NONE); + require(2); return buffer.readShortLe(); } public int readInt() throws IOException { - require(4, Deadline.NONE); + require(4); return buffer.readInt(); } public int readIntLe() throws IOException { - require(4, Deadline.NONE); + require(4); return buffer.readIntLe(); } @@ -108,9 +108,9 @@ public final class BufferedSource implements Source { * buffer} as a buffer. Throws an {@link EOFException} if the source is * exhausted before the requested bytes can be skipped. */ - public void skip(long byteCount, Deadline deadline) throws IOException { + public void skip(long byteCount) throws IOException { while (byteCount > 0) { - if (buffer.byteCount == 0 && source.read(buffer, Segment.SIZE, deadline) == -1) { + if (buffer.byteCount == 0 && source.read(buffer, Segment.SIZE) == -1) { throw new EOFException(); } long toSkip = Math.min(byteCount, buffer.byteCount()); @@ -123,12 +123,12 @@ public final class BufferedSource implements Source { * Returns the index of {@code b} in the buffer, refilling it if necessary * until it is found. This reads an unbounded number of bytes into the buffer. */ - public long seek(byte b, Deadline deadline) throws IOException { + public long seek(byte b) throws IOException { long start = 0; long index; while ((index = buffer.indexOf(b, start)) == -1) { start = buffer.byteCount; - if (source.read(buffer, Segment.SIZE, deadline) == -1) throw new EOFException(); + if (source.read(buffer, Segment.SIZE) == -1) throw new EOFException(); } return index; } @@ -138,7 +138,7 @@ public final class BufferedSource implements Source { return new InputStream() { @Override public int read() throws IOException { if (buffer.byteCount == 0) { - long count = source.read(buffer, Segment.SIZE, Deadline.NONE); + long count = source.read(buffer, Segment.SIZE); if (count == -1) return -1; } return buffer.readByte() & 0xff; @@ -148,7 +148,7 @@ public final class BufferedSource implements Source { checkOffsetAndCount(data.length, offset, byteCount); if (buffer.byteCount == 0) { - long count = source.read(buffer, Segment.SIZE, Deadline.NONE); + long count = source.read(buffer, Segment.SIZE); if (count == -1) return -1; } @@ -172,7 +172,7 @@ public final class BufferedSource implements Source { } @Override public void close() throws IOException { - BufferedSource.this.close(Deadline.NONE); + BufferedSource.this.close(); } @Override public String toString() { @@ -181,10 +181,15 @@ public final class BufferedSource implements Source { }; } - @Override public void close(Deadline deadline) throws IOException { + @Override public Source deadline(Deadline deadline) { + source.deadline(deadline); + return this; + } + + @Override public void close() throws IOException { if (closed) return; closed = true; - source.close(deadline); + source.close(); buffer.clear(); } diff --git a/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/bytes/DeflaterSink.java b/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/bytes/DeflaterSink.java index 2413d4885..cc81de974 100644 --- a/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/bytes/DeflaterSink.java +++ b/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/bytes/DeflaterSink.java @@ -44,7 +44,7 @@ public final class DeflaterSink implements Sink { this.deflater = deflater; } - @Override public void write(OkBuffer source, long byteCount, Deadline deadline) + @Override public void write(OkBuffer source, long byteCount) throws IOException { checkOffsetAndCount(source.byteCount, 0, byteCount); while (byteCount > 0) { @@ -54,7 +54,7 @@ public final class DeflaterSink implements Sink { deflater.setInput(head.data, head.pos, toDeflate); // Deflate those bytes into sink. - deflate(deadline, false); + deflate(false); // Mark those bytes as read. source.byteCount -= toDeflate; @@ -69,7 +69,7 @@ public final class DeflaterSink implements Sink { } @IgnoreJRERequirement - private void deflate(Deadline deadline, boolean syncFlush) throws IOException { + private void deflate(boolean syncFlush) throws IOException { while (true) { Segment s = sink.buffer.writableSegment(1); @@ -84,18 +84,27 @@ public final class DeflaterSink implements Sink { if (deflated == 0) return; s.limit += deflated; sink.buffer.byteCount += deflated; - sink.emitCompleteSegments(deadline); + sink.emitCompleteSegments(); } } - @Override public void flush(Deadline deadline) throws IOException { - deflate(deadline, true); - sink.flush(deadline); + @Override public void flush() throws IOException { + deflate(true); + sink.flush(); } - @Override public void close(Deadline deadline) throws IOException { + @Override public void close() throws IOException { deflater.finish(); - deflate(deadline, false); - sink.close(deadline); + deflate(false); + sink.close(); + } + + @Override public Sink deadline(Deadline deadline) { + sink.deadline(deadline); + return this; + } + + @Override public String toString() { + return "DeflaterSink(" + sink + ")"; } } diff --git a/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/bytes/GzipSource.java b/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/bytes/GzipSource.java index 7ece47593..bd0fc5ce7 100644 --- a/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/bytes/GzipSource.java +++ b/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/bytes/GzipSource.java @@ -58,20 +58,20 @@ public final class GzipSource implements Source { this.inflaterSource = new InflaterSource(this.source, inflater); } - @Override public long read(OkBuffer sink, long byteCount, Deadline deadline) throws IOException { + @Override public long read(OkBuffer sink, long byteCount) throws IOException { if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount); if (byteCount == 0) return 0; // If we haven't consumed the header, we must consume it before anything else. if (section == SECTION_HEADER) { - consumeHeader(deadline); + consumeHeader(); section = SECTION_BODY; } // Attempt to read at least a byte of the body. If we do, we're done. if (section == SECTION_BODY) { long offset = sink.byteCount; - long result = inflaterSource.read(sink, byteCount, deadline); + long result = inflaterSource.read(sink, byteCount); if (result != -1) { updateCrc(sink, offset, result); return result; @@ -83,40 +83,40 @@ public final class GzipSource implements Source { // trailer before returning a -1 exhausted result; that way if you read to // the end of a GzipSource you guarantee that the CRC has been checked. if (section == SECTION_TRAILER) { - consumeTrailer(deadline); + consumeTrailer(); section = SECTION_DONE; } return -1; } - private void consumeHeader(Deadline deadline) throws IOException { + private void consumeHeader() throws IOException { // Read the 10-byte header. We peek at the flags byte first so we know if we // need to CRC the entire header. Then we read the magic ID1ID2 sequence. // We can skip everything else in the first 10 bytes. // +---+---+---+---+---+---+---+---+---+---+ // |ID1|ID2|CM |FLG| MTIME |XFL|OS | (more-->) // +---+---+---+---+---+---+---+---+---+---+ - source.require(10, deadline); + source.require(10); byte flags = source.buffer.getByte(3); boolean fhcrc = ((flags >> FHCRC) & 1) == 1; if (fhcrc) updateCrc(source.buffer, 0, 10); short id1id2 = source.readShort(); checkEqual("ID1ID2", (short) 0x1f8b, id1id2); - source.skip(8, deadline); + source.skip(8); // Skip optional extra fields. // +---+---+=================================+ // | XLEN |...XLEN bytes of "extra field"...| (more-->) // +---+---+=================================+ if (((flags >> FEXTRA) & 1) == 1) { - source.require(2, deadline); + source.require(2); if (fhcrc) updateCrc(source.buffer, 0, 2); int xlen = source.buffer.readShortLe() & 0xffff; - source.require(xlen, deadline); + source.require(xlen); if (fhcrc) updateCrc(source.buffer, 0, xlen); - source.skip(xlen, deadline); + source.skip(xlen); } // Skip an optional 0-terminated name. @@ -124,7 +124,7 @@ public final class GzipSource implements Source { // |...original file name, zero-terminated...| (more-->) // +=========================================+ if (((flags >> FNAME) & 1) == 1) { - long index = source.seek((byte) 0, deadline); + long index = source.seek((byte) 0); if (fhcrc) updateCrc(source.buffer, 0, index + 1); source.buffer.skip(index + 1); } @@ -134,9 +134,9 @@ public final class GzipSource implements Source { // |...file comment, zero-terminated...| (more-->) // +===================================+ if (((flags >> FCOMMENT) & 1) == 1) { - long index = source.seek((byte) 0, deadline); + long index = source.seek((byte) 0); if (fhcrc) updateCrc(source.buffer, 0, index + 1); - source.skip(index + 1, deadline); + source.skip(index + 1); } // Confirm the optional header CRC. @@ -149,7 +149,7 @@ public final class GzipSource implements Source { } } - private void consumeTrailer(Deadline deadline) throws IOException { + private void consumeTrailer() throws IOException { // Read the eight-byte trailer. Confirm the body's CRC and size. // +---+---+---+---+---+---+---+---+ // | CRC32 | ISIZE | @@ -158,8 +158,13 @@ public final class GzipSource implements Source { checkEqual("ISIZE", source.readIntLe(), inflater.getTotalOut()); } - @Override public void close(Deadline deadline) throws IOException { - inflaterSource.close(deadline); + @Override public Source deadline(Deadline deadline) { + source.deadline(deadline); + return this; + } + + @Override public void close() throws IOException { + inflaterSource.close(); } /** Updates the CRC with the given bytes. */ diff --git a/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/bytes/InflaterSource.java b/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/bytes/InflaterSource.java index 790dcfd25..b31cc03aa 100644 --- a/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/bytes/InflaterSource.java +++ b/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/bytes/InflaterSource.java @@ -53,13 +53,13 @@ public final class InflaterSource implements Source { } @Override public long read( - OkBuffer sink, long byteCount, Deadline deadline) throws IOException { + OkBuffer sink, long byteCount) throws IOException { if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount); if (closed) throw new IllegalStateException("closed"); if (byteCount == 0) return 0; while (true) { - boolean sourceExhausted = refill(deadline); + boolean sourceExhausted = refill(); // Decompress the inflater's compressed data into the sink. try { @@ -86,14 +86,14 @@ public final class InflaterSource implements Source { * it needs input). Returns true if the inflater required input but the source * was exhausted. */ - public boolean refill(Deadline deadline) throws IOException { + public boolean refill() throws IOException { if (!inflater.needsInput()) return false; releaseInflatedBytes(); if (inflater.getRemaining() != 0) throw new IllegalStateException("?"); // TODO: possible? // If there are compressed bytes in the source, assign them to the inflater. - if (source.exhausted(deadline)) return true; + if (source.exhausted()) return true; // Assign buffer bytes to the inflater. Segment head = source.buffer.head; @@ -110,10 +110,15 @@ public final class InflaterSource implements Source { source.buffer.skip(toRelease); } - @Override public void close(Deadline deadline) throws IOException { + @Override public Source deadline(Deadline deadline) { + source.deadline(deadline); + return this; + } + + @Override public void close() throws IOException { if (closed) return; inflater.end(); closed = true; - source.close(deadline); + source.close(); } } diff --git a/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/bytes/OkBuffer.java b/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/bytes/OkBuffer.java index 9ed0dfa7c..a8ab472c2 100644 --- a/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/bytes/OkBuffer.java +++ b/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/bytes/OkBuffer.java @@ -334,7 +334,7 @@ public final class OkBuffer implements Source, Sink, Cloneable { return tail; } - @Override public void write(OkBuffer source, long byteCount, Deadline deadline) { + @Override public void write(OkBuffer source, long byteCount) { // Move bytes from the head of the source buffer to the tail of this buffer // while balancing two conflicting goals: don't waste CPU and don't waste // memory. @@ -425,13 +425,18 @@ public final class OkBuffer implements Source, Sink, Cloneable { } } - @Override public long read(OkBuffer sink, long byteCount, Deadline deadline) throws IOException { + @Override public long read(OkBuffer sink, long byteCount) throws IOException { if (this.byteCount == 0) return -1L; if (byteCount > this.byteCount) byteCount = this.byteCount; - sink.write(this, byteCount, deadline); + sink.write(this, byteCount); return byteCount; } + @Override public OkBuffer deadline(Deadline deadline) { + // All operations are in memory so this class doesn't need to honor deadlines. + return this; + } + /** * Returns the index of {@code b} in this, or -1 if this buffer does not * contain {@code b}. @@ -465,10 +470,10 @@ public final class OkBuffer implements Source, Sink, Cloneable { return -1L; } - @Override public void flush(Deadline deadline) { + @Override public void flush() { } - @Override public void close(Deadline deadline) { + @Override public void close() { } /** For testing. This returns the sizes of the segments in this buffer. */ diff --git a/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/bytes/OkBuffers.java b/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/bytes/OkBuffers.java index b18692aa6..6e5be4cc6 100644 --- a/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/bytes/OkBuffers.java +++ b/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/bytes/OkBuffers.java @@ -50,7 +50,9 @@ public final class OkBuffers { /** Returns a sink that writes to {@code out}. */ public static Sink sink(final OutputStream out) { return new Sink() { - @Override public void write(OkBuffer source, long byteCount, Deadline deadline) + private Deadline deadline = Deadline.NONE; + + @Override public void write(OkBuffer source, long byteCount) throws IOException { checkOffsetAndCount(source.byteCount, 0, byteCount); while (byteCount > 0) { @@ -70,14 +72,20 @@ public final class OkBuffers { } } - @Override public void flush(Deadline deadline) throws IOException { + @Override public void flush() throws IOException { out.flush(); } - @Override public void close(Deadline deadline) throws IOException { + @Override public void close() throws IOException { out.close(); } + @Override public Sink deadline(Deadline deadline) { + if (deadline == null) throw new IllegalArgumentException("deadline == null"); + this.deadline = deadline; + return this; + } + @Override public String toString() { return "sink(" + out + ")"; } @@ -87,8 +95,9 @@ public final class OkBuffers { /** Returns a source that reads from {@code in}. */ public static Source source(final InputStream in) { return new Source() { - @Override public long read( - OkBuffer sink, long byteCount, Deadline deadline) throws IOException { + private Deadline deadline = Deadline.NONE; + + @Override public long read(OkBuffer sink, long byteCount) throws IOException { if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount); deadline.throwIfReached(); Segment tail = sink.writableSegment(1); @@ -100,10 +109,16 @@ public final class OkBuffers { return bytesRead; } - @Override public void close(Deadline deadline) throws IOException { + @Override public void close() throws IOException { in.close(); } + @Override public Source deadline(Deadline deadline) { + if (deadline == null) throw new IllegalArgumentException("deadline == null"); + this.deadline = deadline; + return this; + } + @Override public String toString() { return "source(" + in + ")"; } diff --git a/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/bytes/Sink.java b/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/bytes/Sink.java index 1531366be..d559290b0 100644 --- a/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/bytes/Sink.java +++ b/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/bytes/Sink.java @@ -15,22 +15,29 @@ */ package com.squareup.okhttp.internal.bytes; +import java.io.Closeable; import java.io.IOException; /** * An alternative to OutputStream. */ -public interface Sink { +public interface Sink extends Closeable { /** Removes {@code byteCount} bytes from {@code source} and appends them to this. */ - void write(OkBuffer source, long byteCount, Deadline deadline) throws IOException; + void write(OkBuffer source, long byteCount) throws IOException; /** Pushes all buffered bytes to their final destination. */ - void flush(Deadline deadline) throws IOException; + void flush() throws IOException; /** * Pushes all buffered bytes to their final destination and releases the * resources held by this sink. It is an error to write a closed sink. It is * safe to close a sink more than once. */ - void close(Deadline deadline) throws IOException; + @Override void close() throws IOException; + + /** + * Sets the deadline for all operations on this sink. + * @return this sink. + */ + Sink deadline(Deadline deadline); } diff --git a/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/bytes/Source.java b/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/bytes/Source.java index 5b9a87a00..52f28a3dc 100644 --- a/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/bytes/Source.java +++ b/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/bytes/Source.java @@ -15,22 +15,29 @@ */ package com.squareup.okhttp.internal.bytes; +import java.io.Closeable; import java.io.IOException; /** * An alternative to InputStream. */ -public interface Source { +public interface Source extends Closeable { /** * Removes at least 1, and up to {@code byteCount} bytes from this and appends * them to {@code sink}. Returns the number of bytes read, or -1 if this * source is exhausted. */ - long read(OkBuffer sink, long byteCount, Deadline deadline) throws IOException; + long read(OkBuffer sink, long byteCount) throws IOException; + + /** + * Sets the deadline for all operations on this source. + * @return this source. + */ + Source deadline(Deadline deadline); /** * Closes this source and releases the resources held by this source. It is an * error to read a closed source. It is safe to close a source more than once. */ - void close(Deadline deadline) throws IOException; + @Override void close() throws IOException; } diff --git a/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/spdy/HpackDraft05.java b/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/spdy/HpackDraft05.java index 6b15ffe69..36e42f050 100644 --- a/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/spdy/HpackDraft05.java +++ b/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/spdy/HpackDraft05.java @@ -3,7 +3,6 @@ package com.squareup.okhttp.internal.spdy; import com.squareup.okhttp.internal.BitArray; import com.squareup.okhttp.internal.bytes.BufferedSource; import com.squareup.okhttp.internal.bytes.ByteString; -import com.squareup.okhttp.internal.bytes.Deadline; import com.squareup.okhttp.internal.bytes.Source; import java.io.IOException; import java.io.OutputStream; @@ -180,7 +179,7 @@ final class HpackDraft05 { * set of emitted headers. */ void readHeaders() throws IOException { - while (!source.exhausted(Deadline.NONE)) { + while (!source.exhausted()) { int b = source.readByte() & 0xff; if (b == 0x80) { // 10000000 clearReferenceSet(); diff --git a/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/spdy/Http20Draft09.java b/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/spdy/Http20Draft09.java index 608642376..27f66ee24 100644 --- a/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/spdy/Http20Draft09.java +++ b/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/spdy/Http20Draft09.java @@ -145,7 +145,7 @@ public final class Http20Draft09 implements Variant { default: // Implementations MUST ignore frames of unsupported or unrecognized types. - source.skip(length, Deadline.NONE); + source.skip(length); } return true; } @@ -282,7 +282,7 @@ public final class Http20Draft09 implements Variant { } @Override public void close() throws IOException { - source.close(Deadline.NONE); + source.close(); } } @@ -491,7 +491,7 @@ public final class Http20Draft09 implements Variant { this.source = source; } - @Override public long read(OkBuffer sink, long byteCount, Deadline deadline) + @Override public long read(OkBuffer sink, long byteCount) throws IOException { while (left == 0) { if ((flags & FLAG_END_HEADERS) != 0) return -1; @@ -499,13 +499,18 @@ public final class Http20Draft09 implements Variant { // TODO: test case for empty continuation header? } - long read = source.read(sink, Math.min(byteCount, left), deadline); + long read = source.read(sink, Math.min(byteCount, left)); if (read == -1) return -1; left -= read; return read; } - @Override public void close(Deadline deadline) throws IOException { + @Override public Source deadline(Deadline deadline) { + source.deadline(deadline); + return this; + } + + @Override public void close() throws IOException { } private void readContinuationHeader() throws IOException { diff --git a/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/spdy/NameValueBlockReader.java b/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/spdy/NameValueBlockReader.java index 405f6fce8..60e8f9bc0 100644 --- a/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/spdy/NameValueBlockReader.java +++ b/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/spdy/NameValueBlockReader.java @@ -36,17 +36,22 @@ class NameValueBlockReader { // block. We cut the inflater off at its source because we can't predict the // ratio of compressed bytes to uncompressed bytes. Source throttleSource = new Source() { - @Override public long read(OkBuffer sink, long byteCount, Deadline deadline) + @Override public long read(OkBuffer sink, long byteCount) throws IOException { if (compressedLimit == 0) return -1; // Out of data for the current block. - long read = source.read(sink, Math.min(byteCount, compressedLimit), deadline); + long read = source.read(sink, Math.min(byteCount, compressedLimit)); if (read == -1) return -1; compressedLimit -= read; return read; } - @Override public void close(Deadline deadline) throws IOException { - source.close(deadline); + @Override public void close() throws IOException { + source.close(); + } + + @Override public Source deadline(Deadline deadline) { + source.deadline(deadline); + return this; } }; @@ -96,12 +101,12 @@ class NameValueBlockReader { // deflate compression is that sometimes there are bytes remaining in the // stream after we've consumed all of the content. if (compressedLimit > 0) { - inflaterSource.refill(Deadline.NONE); + inflaterSource.refill(); if (compressedLimit != 0) throw new IOException("compressedLimit > 0: " + compressedLimit); } } - public void close(Deadline deadline) throws IOException { - source.close(deadline); + public void close() throws IOException { + source.close(); } } diff --git a/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/spdy/Spdy3.java b/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/spdy/Spdy3.java index 27ce0428f..477baa28e 100644 --- a/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/spdy/Spdy3.java +++ b/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/spdy/Spdy3.java @@ -20,7 +20,6 @@ import com.squareup.okhttp.internal.Platform; import com.squareup.okhttp.internal.Util; import com.squareup.okhttp.internal.bytes.BufferedSource; import com.squareup.okhttp.internal.bytes.ByteString; -import com.squareup.okhttp.internal.bytes.Deadline; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; @@ -179,7 +178,7 @@ final class Spdy3 implements Variant { return true; default: - source.skip(length, Deadline.NONE); + source.skip(length); return true; } } else { @@ -282,7 +281,7 @@ final class Spdy3 implements Variant { } @Override public void close() throws IOException { - headerBlockReader.close(Deadline.NONE); + headerBlockReader.close(); } } diff --git a/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/spdy/SpdyConnection.java b/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/spdy/SpdyConnection.java index aa1a2ba48..f5c16781d 100644 --- a/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/spdy/SpdyConnection.java +++ b/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/spdy/SpdyConnection.java @@ -20,7 +20,6 @@ import com.squareup.okhttp.internal.NamedRunnable; import com.squareup.okhttp.internal.Util; import com.squareup.okhttp.internal.bytes.BufferedSource; import com.squareup.okhttp.internal.bytes.ByteString; -import com.squareup.okhttp.internal.bytes.Deadline; import com.squareup.okhttp.internal.bytes.OkBuffers; import java.io.Closeable; import java.io.IOException; @@ -531,7 +530,7 @@ public final class SpdyConnection implements Closeable { SpdyStream dataStream = getStream(streamId); if (dataStream == null) { writeSynResetLater(streamId, ErrorCode.INVALID_STREAM); - source.skip(length, Deadline.NONE); + source.skip(length); return; } dataStream.receiveData(source, length); diff --git a/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/spdy/SpdyStream.java b/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/spdy/SpdyStream.java index b23bfb64a..b61db2abb 100644 --- a/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/spdy/SpdyStream.java +++ b/okhttp-protocols/src/main/java/com/squareup/okhttp/internal/spdy/SpdyStream.java @@ -355,7 +355,7 @@ public final class SpdyStream { this.maxByteCount = maxByteCount; } - @Override public long read(OkBuffer sink, long byteCount, Deadline deadline) + @Override public long read(OkBuffer sink, long byteCount) throws IOException { if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount); @@ -366,7 +366,7 @@ public final class SpdyStream { if (readBuffer.byteCount() == 0) return -1; // This source is exhausted. // Move bytes from the read buffer into the caller's buffer. - read = readBuffer.read(sink, Math.min(byteCount, readBuffer.byteCount()), deadline); + read = readBuffer.read(sink, Math.min(byteCount, readBuffer.byteCount())); // Flow control: notify the peer that we're ready for more data! unacknowledgedBytesRead += read; @@ -430,26 +430,26 @@ public final class SpdyStream { // If the peer sends more data than we can handle, discard it and close the connection. if (flowControlError) { - in.skip(byteCount, Deadline.NONE); + in.skip(byteCount); closeLater(ErrorCode.FLOW_CONTROL_ERROR); return; } // Discard data received after the stream is finished. It's probably a benign race. if (finished) { - in.skip(byteCount, Deadline.NONE); + in.skip(byteCount); return; } // Fill the receive buffer without holding any locks. - long read = in.read(receiveBuffer, byteCount, Deadline.NONE); + long read = in.read(receiveBuffer, byteCount); if (read == -1) throw new EOFException(); byteCount -= read; // Move the received data to the read buffer to the reader can read it. synchronized (SpdyStream.this) { boolean wasEmpty = readBuffer.byteCount() == 0; - readBuffer.write(receiveBuffer, receiveBuffer.byteCount(), Deadline.NONE); + readBuffer.write(receiveBuffer, receiveBuffer.byteCount()); if (wasEmpty) { SpdyStream.this.notifyAll(); } @@ -457,7 +457,12 @@ public final class SpdyStream { } } - @Override public void close(Deadline deadline) throws IOException { + @Override public Source deadline(Deadline deadline) { + // TODO: honor deadlines. + return this; + } + + @Override public void close() throws IOException { synchronized (SpdyStream.this) { closed = true; readBuffer.clear(); diff --git a/okhttp-protocols/src/test/java/com/squareup/okhttp/internal/bytes/BufferedSinkTest.java b/okhttp-protocols/src/test/java/com/squareup/okhttp/internal/bytes/BufferedSinkTest.java index f5508b347..d45785ffd 100644 --- a/okhttp-protocols/src/test/java/com/squareup/okhttp/internal/bytes/BufferedSinkTest.java +++ b/okhttp-protocols/src/test/java/com/squareup/okhttp/internal/bytes/BufferedSinkTest.java @@ -24,29 +24,29 @@ public final class BufferedSinkTest { @Test public void bytesEmittedToSinkWithFlush() throws Exception { OkBuffer sink = new OkBuffer(); BufferedSink bufferedSink = new BufferedSink(sink); - bufferedSink.writeUtf8("abc", Deadline.NONE); - bufferedSink.flush(Deadline.NONE); + bufferedSink.writeUtf8("abc"); + bufferedSink.flush(); assertEquals(3, sink.byteCount()); } @Test public void bytesNotEmittedToSinkWithoutFlush() throws Exception { OkBuffer sink = new OkBuffer(); BufferedSink bufferedSink = new BufferedSink(sink); - bufferedSink.writeUtf8("abc", Deadline.NONE); + bufferedSink.writeUtf8("abc"); assertEquals(0, sink.byteCount()); } @Test public void completeSegmentsEmitted() throws Exception { OkBuffer sink = new OkBuffer(); BufferedSink bufferedSink = new BufferedSink(sink); - bufferedSink.writeUtf8(repeat('a', Segment.SIZE * 3), Deadline.NONE); + bufferedSink.writeUtf8(repeat('a', Segment.SIZE * 3)); assertEquals(Segment.SIZE * 3, sink.byteCount()); } @Test public void incompleteSegmentsNotEmitted() throws Exception { OkBuffer sink = new OkBuffer(); BufferedSink bufferedSink = new BufferedSink(sink); - bufferedSink.writeUtf8(repeat('a', Segment.SIZE * 3 - 1), Deadline.NONE); + bufferedSink.writeUtf8(repeat('a', Segment.SIZE * 3 - 1)); assertEquals(Segment.SIZE * 2, sink.byteCount()); } diff --git a/okhttp-protocols/src/test/java/com/squareup/okhttp/internal/bytes/DeflaterSinkTest.java b/okhttp-protocols/src/test/java/com/squareup/okhttp/internal/bytes/DeflaterSinkTest.java index e1d22b9a6..6c1867828 100644 --- a/okhttp-protocols/src/test/java/com/squareup/okhttp/internal/bytes/DeflaterSinkTest.java +++ b/okhttp-protocols/src/test/java/com/squareup/okhttp/internal/bytes/DeflaterSinkTest.java @@ -33,8 +33,8 @@ public final class DeflaterSinkTest { data.writeUtf8(original); OkBuffer sink = new OkBuffer(); DeflaterSink deflaterSink = new DeflaterSink(sink, new Deflater()); - deflaterSink.write(data, data.byteCount(), Deadline.NONE); - deflaterSink.close(Deadline.NONE); + deflaterSink.write(data, data.byteCount()); + deflaterSink.close(); OkBuffer inflated = inflate(sink); assertEquals(original, inflated.readUtf8((int) inflated.byteCount())); } @@ -45,8 +45,8 @@ public final class DeflaterSinkTest { data.writeUtf8(original); OkBuffer sink = new OkBuffer(); DeflaterSink deflaterSink = new DeflaterSink(sink, new Deflater()); - deflaterSink.write(data, data.byteCount(), Deadline.NONE); - deflaterSink.flush(Deadline.NONE); + deflaterSink.write(data, data.byteCount()); + deflaterSink.flush(); OkBuffer inflated = inflate(sink); assertEquals(original, inflated.readUtf8((int) inflated.byteCount())); } @@ -57,8 +57,8 @@ public final class DeflaterSinkTest { data.writeUtf8(original); OkBuffer sink = new OkBuffer(); DeflaterSink deflaterSink = new DeflaterSink(sink, new Deflater()); - deflaterSink.write(data, data.byteCount(), Deadline.NONE); - deflaterSink.close(Deadline.NONE); + deflaterSink.write(data, data.byteCount()); + deflaterSink.close(); OkBuffer inflated = inflate(sink); assertEquals(original, inflated.readUtf8((int) inflated.byteCount())); } @@ -69,8 +69,8 @@ public final class DeflaterSinkTest { data.write(original); OkBuffer sink = new OkBuffer(); DeflaterSink deflaterSink = new DeflaterSink(sink, new Deflater()); - deflaterSink.write(data, data.byteCount(), Deadline.NONE); - deflaterSink.close(Deadline.NONE); + deflaterSink.write(data, data.byteCount()); + deflaterSink.close(); OkBuffer inflated = inflate(sink); assertEquals(original, inflated.readByteString((int) inflated.byteCount())); } diff --git a/okhttp-protocols/src/test/java/com/squareup/okhttp/internal/bytes/GzipSourceTest.java b/okhttp-protocols/src/test/java/com/squareup/okhttp/internal/bytes/GzipSourceTest.java index d4b59b6c0..1f0a6da5a 100644 --- a/okhttp-protocols/src/test/java/com/squareup/okhttp/internal/bytes/GzipSourceTest.java +++ b/okhttp-protocols/src/test/java/com/squareup/okhttp/internal/bytes/GzipSourceTest.java @@ -176,7 +176,7 @@ public class GzipSourceTest { private OkBuffer gunzip(OkBuffer gzipped) throws IOException { OkBuffer result = new OkBuffer(); GzipSource source = new GzipSource(gzipped); - while (source.read(result, Integer.MAX_VALUE, Deadline.NONE) != -1) { + while (source.read(result, Integer.MAX_VALUE) != -1) { } return result; } diff --git a/okhttp-protocols/src/test/java/com/squareup/okhttp/internal/bytes/InflaterSourceTest.java b/okhttp-protocols/src/test/java/com/squareup/okhttp/internal/bytes/InflaterSourceTest.java index 481f024fc..7a56d59c4 100644 --- a/okhttp-protocols/src/test/java/com/squareup/okhttp/internal/bytes/InflaterSourceTest.java +++ b/okhttp-protocols/src/test/java/com/squareup/okhttp/internal/bytes/InflaterSourceTest.java @@ -88,8 +88,8 @@ public final class InflaterSourceTest { private OkBuffer deflate(OkBuffer buffer) throws IOException { OkBuffer result = new OkBuffer(); Sink sink = OkBuffers.sink(new DeflaterOutputStream(new BufferedSink(result).outputStream())); - sink.write(buffer, buffer.byteCount(), Deadline.NONE); - sink.close(Deadline.NONE); + sink.write(buffer, buffer.byteCount()); + sink.close(); return result; } @@ -103,7 +103,7 @@ public final class InflaterSourceTest { private OkBuffer inflate(OkBuffer deflated) throws IOException { OkBuffer result = new OkBuffer(); InflaterSource source = new InflaterSource(deflated, new Inflater()); - while (source.read(result, Integer.MAX_VALUE, Deadline.NONE) != -1) { + while (source.read(result, Integer.MAX_VALUE) != -1) { } return result; } diff --git a/okhttp-protocols/src/test/java/com/squareup/okhttp/internal/bytes/OkBufferTest.java b/okhttp-protocols/src/test/java/com/squareup/okhttp/internal/bytes/OkBufferTest.java index 97703b95c..7d9540ca0 100644 --- a/okhttp-protocols/src/test/java/com/squareup/okhttp/internal/bytes/OkBufferTest.java +++ b/okhttp-protocols/src/test/java/com/squareup/okhttp/internal/bytes/OkBufferTest.java @@ -152,7 +152,7 @@ public final class OkBufferTest { for (String s : contents) { OkBuffer source = new OkBuffer(); source.writeUtf8(s); - buffer.write(source, source.byteCount(), Deadline.NONE); + buffer.write(source, source.byteCount()); expected.append(s); } List segmentSizes = buffer.segmentSizes(); @@ -169,7 +169,7 @@ public final class OkBufferTest { OkBuffer source = new OkBuffer(); source.writeUtf8(repeat('a', Segment.SIZE * 2)); - sink.write(source, writeSize, Deadline.NONE); + sink.write(source, writeSize); assertEquals(asList(Segment.SIZE - 10, writeSize), sink.segmentSizes()); assertEquals(asList(Segment.SIZE - writeSize, Segment.SIZE), source.segmentSizes()); @@ -184,7 +184,7 @@ public final class OkBufferTest { OkBuffer source = new OkBuffer(); source.writeUtf8(repeat('a', Segment.SIZE * 2)); - sink.write(source, writeSize, Deadline.NONE); + sink.write(source, writeSize); assertEquals(asList(Segment.SIZE - 10, writeSize), sink.segmentSizes()); assertEquals(asList(Segment.SIZE - writeSize, Segment.SIZE), source.segmentSizes()); @@ -196,7 +196,7 @@ public final class OkBufferTest { OkBuffer source = new OkBuffer(); source.writeUtf8(repeat('a', Segment.SIZE * 2)); - sink.write(source, 20, Deadline.NONE); + sink.write(source, 20); assertEquals(asList(30), sink.segmentSizes()); assertEquals(asList(Segment.SIZE - 20, Segment.SIZE), source.segmentSizes()); @@ -211,7 +211,7 @@ public final class OkBufferTest { OkBuffer source = new OkBuffer(); source.writeUtf8(repeat('a', Segment.SIZE * 2)); - sink.write(source, 20, Deadline.NONE); + sink.write(source, 20); assertEquals(asList(30), sink.segmentSizes()); assertEquals(asList(Segment.SIZE - 20, Segment.SIZE), source.segmentSizes()); @@ -225,7 +225,7 @@ public final class OkBufferTest { OkBuffer source = new OkBuffer(); - assertEquals(-1, source.read(sink, 10, Deadline.NONE)); + assertEquals(-1, source.read(sink, 10)); assertEquals(10, sink.byteCount()); assertEquals(0, source.byteCount()); } @@ -238,7 +238,7 @@ public final class OkBufferTest { // Either 0 or -1 is reasonable here. For consistency with Android's // ByteArrayInputStream we return 0. - assertEquals(-1, source.read(sink, 0, Deadline.NONE)); + assertEquals(-1, source.read(sink, 0)); assertEquals(10, sink.byteCount()); assertEquals(0, source.byteCount()); } @@ -250,7 +250,7 @@ public final class OkBufferTest { OkBuffer source = new OkBuffer(); source.writeUtf8(repeat('b', 15)); - assertEquals(10, source.read(sink, 10, Deadline.NONE)); + assertEquals(10, source.read(sink, 10)); assertEquals(20, sink.byteCount()); assertEquals(5, source.byteCount()); assertEquals(repeat('a', 10) + repeat('b', 10), sink.readUtf8(20)); @@ -263,7 +263,7 @@ public final class OkBufferTest { OkBuffer source = new OkBuffer(); source.writeUtf8(repeat('b', 20)); - assertEquals(20, source.read(sink, 25, Deadline.NONE)); + assertEquals(20, source.read(sink, 25)); assertEquals(30, sink.byteCount()); assertEquals(0, source.byteCount()); assertEquals(repeat('a', 10) + repeat('b', 20), sink.readUtf8(30)); @@ -336,9 +336,9 @@ public final class OkBufferTest { ByteArrayOutputStream out = new ByteArrayOutputStream(); Sink sink = OkBuffers.sink(out); - sink.write(data, 3, Deadline.NONE); + sink.write(data, 3); assertEquals("abb", out.toString("UTF-8")); - sink.write(data, data.byteCount(), Deadline.NONE); + sink.write(data, data.byteCount()); assertEquals("a" + repeat('b', 9998) + "c", out.toString("UTF-8")); } @@ -365,9 +365,9 @@ public final class OkBufferTest { @Test public void bufferedSinkEmitsTailWhenItIsComplete() throws IOException { OkBuffer sink = new OkBuffer(); BufferedSink bufferedSink = new BufferedSink(sink); - bufferedSink.writeUtf8(repeat('a', Segment.SIZE - 1), Deadline.NONE); + bufferedSink.writeUtf8(repeat('a', Segment.SIZE - 1)); assertEquals(0, sink.byteCount()); - bufferedSink.writeByte(0, Deadline.NONE); + bufferedSink.writeByte(0); assertEquals(Segment.SIZE, sink.byteCount()); assertEquals(0, bufferedSink.buffer.byteCount()); } @@ -375,14 +375,14 @@ public final class OkBufferTest { @Test public void bufferedSinkEmitZero() throws IOException { OkBuffer sink = new OkBuffer(); BufferedSink bufferedSink = new BufferedSink(sink); - bufferedSink.writeUtf8("", Deadline.NONE); + bufferedSink.writeUtf8(""); assertEquals(0, sink.byteCount()); } @Test public void bufferedSinkEmitMultipleSegments() throws IOException { OkBuffer sink = new OkBuffer(); BufferedSink bufferedSink = new BufferedSink(sink); - bufferedSink.writeUtf8(repeat('a', Segment.SIZE * 4 - 1), Deadline.NONE); + bufferedSink.writeUtf8(repeat('a', Segment.SIZE * 4 - 1)); assertEquals(Segment.SIZE * 3, sink.byteCount()); assertEquals(Segment.SIZE - 1, bufferedSink.buffer.byteCount()); } @@ -390,9 +390,9 @@ public final class OkBufferTest { @Test public void bufferedSinkFlush() throws IOException { OkBuffer sink = new OkBuffer(); BufferedSink bufferedSink = new BufferedSink(sink); - bufferedSink.writeByte('a', Deadline.NONE); + bufferedSink.writeByte('a'); assertEquals(0, sink.byteCount()); - bufferedSink.flush(Deadline.NONE); + bufferedSink.flush(); assertEquals(0, bufferedSink.buffer.byteCount()); assertEquals(1, sink.byteCount()); } @@ -406,25 +406,25 @@ public final class OkBufferTest { OkBuffer sink = new OkBuffer(); // Source: b...bc. Sink: abb. - assertEquals(3, source.read(sink, 3, Deadline.NONE)); + assertEquals(3, source.read(sink, 3)); assertEquals("abb", sink.readUtf8(3)); // Source: b...bc. Sink: b...b. - assertEquals(Segment.SIZE, source.read(sink, 20000, Deadline.NONE)); + assertEquals(Segment.SIZE, source.read(sink, 20000)); assertEquals(repeat('b', Segment.SIZE), sink.readUtf8((int) sink.byteCount())); // Source: b...bc. Sink: b...bc. - assertEquals(Segment.SIZE - 1, source.read(sink, 20000, Deadline.NONE)); + assertEquals(Segment.SIZE - 1, source.read(sink, 20000)); assertEquals(repeat('b', Segment.SIZE - 2) + "c", sink.readUtf8((int) sink.byteCount())); // Source and sink are empty. - assertEquals(-1, source.read(sink, 1, Deadline.NONE)); + assertEquals(-1, source.read(sink, 1)); } @Test public void sourceFromInputStreamBounds() throws Exception { Source source = OkBuffers.source(new ByteArrayInputStream(new byte[100])); try { - source.read(new OkBuffer(), -1, Deadline.NONE); + source.read(new OkBuffer(), -1); fail(); } catch (IllegalArgumentException expected) { } @@ -615,7 +615,7 @@ public final class OkBufferTest { OkBuffer sink = new OkBuffer(); OkBuffer source = new OkBuffer(); source.writeUtf8("abcd"); - sink.write(source, 2, Deadline.NONE); + sink.write(source, 2); assertEquals("ab", sink.readUtf8(2)); } @@ -626,7 +626,7 @@ public final class OkBufferTest { BufferedSource bufferedSource = new BufferedSource(source); bufferedSource.buffer.writeUtf8("aa"); - bufferedSource.require(2, Deadline.NONE); + bufferedSource.require(2); assertEquals(2, bufferedSource.buffer.byteCount()); assertEquals(2, source.byteCount()); } @@ -638,7 +638,7 @@ public final class OkBufferTest { BufferedSource bufferedSource = new BufferedSource(source); bufferedSource.buffer.writeUtf8("a"); - bufferedSource.require(2, Deadline.NONE); + bufferedSource.require(2); assertEquals("ab", bufferedSource.buffer.readUtf8(2)); } @@ -649,7 +649,7 @@ public final class OkBufferTest { BufferedSource bufferedSource = new BufferedSource(source); try { - bufferedSource.require(2, Deadline.NONE); + bufferedSource.require(2); fail(); } catch (EOFException expected) { } @@ -662,7 +662,7 @@ public final class OkBufferTest { BufferedSource bufferedSource = new BufferedSource(source); - bufferedSource.require(2, Deadline.NONE); + bufferedSource.require(2); assertEquals(Segment.SIZE, source.byteCount()); assertEquals(Segment.SIZE, bufferedSource.buffer.byteCount()); } @@ -673,7 +673,7 @@ public final class OkBufferTest { BufferedSource bufferedSource = new BufferedSource(source); try { - bufferedSource.skip(2, Deadline.NONE); + bufferedSource.skip(2); fail(); } catch (EOFException expected) { } @@ -684,7 +684,7 @@ public final class OkBufferTest { source.writeUtf8(repeat('a', Segment.SIZE)); source.writeUtf8(repeat('b', Segment.SIZE)); BufferedSource bufferedSource = new BufferedSource(source); - bufferedSource.skip(2, Deadline.NONE); + bufferedSource.skip(2); assertEquals(Segment.SIZE, source.byteCount()); assertEquals(Segment.SIZE - 2, bufferedSource.buffer.byteCount()); } @@ -696,7 +696,7 @@ public final class OkBufferTest { BufferedSource bufferedSource = new BufferedSource(source); bufferedSource.buffer.writeUtf8("aa"); - bufferedSource.skip(2, Deadline.NONE); + bufferedSource.skip(2); assertEquals(0, bufferedSource.buffer.byteCount()); assertEquals(2, source.byteCount()); } diff --git a/okhttp-protocols/src/test/java/com/squareup/okhttp/internal/spdy/SpdyConnectionTest.java b/okhttp-protocols/src/test/java/com/squareup/okhttp/internal/spdy/SpdyConnectionTest.java index 287bfb1d9..ae892840e 100644 --- a/okhttp-protocols/src/test/java/com/squareup/okhttp/internal/spdy/SpdyConnectionTest.java +++ b/okhttp-protocols/src/test/java/com/squareup/okhttp/internal/spdy/SpdyConnectionTest.java @@ -18,7 +18,6 @@ package com.squareup.okhttp.internal.spdy; import com.squareup.okhttp.internal.Util; import com.squareup.okhttp.internal.bytes.BufferedSource; import com.squareup.okhttp.internal.bytes.ByteString; -import com.squareup.okhttp.internal.bytes.Deadline; import com.squareup.okhttp.internal.bytes.OkBuffer; import com.squareup.okhttp.internal.bytes.Source; import java.io.IOException; @@ -33,7 +32,6 @@ import org.junit.Test; import static com.squareup.okhttp.internal.Util.UTF_8; import static com.squareup.okhttp.internal.Util.headerEntries; import static com.squareup.okhttp.internal.spdy.ErrorCode.CANCEL; -import static com.squareup.okhttp.internal.spdy.ErrorCode.FLOW_CONTROL_ERROR; import static com.squareup.okhttp.internal.spdy.ErrorCode.INTERNAL_ERROR; import static com.squareup.okhttp.internal.spdy.ErrorCode.INVALID_STREAM; import static com.squareup.okhttp.internal.spdy.ErrorCode.PROTOCOL_ERROR; @@ -551,9 +549,9 @@ public final class SpdyConnectionTest { SpdyStream stream = connection.newStream(headerEntries("a", "android"), false, true); Source in = stream.getSource(); OutputStream out = stream.getOutputStream(); - in.close(Deadline.NONE); + in.close(); try { - in.read(new OkBuffer(), 1, Deadline.NONE); + in.read(new OkBuffer(), 1); fail(); } catch (IOException expected) { assertEquals("stream closed", expected.getMessage()); @@ -594,9 +592,9 @@ public final class SpdyConnectionTest { SpdyStream stream = connection.newStream(headerEntries("a", "android"), true, true); Source source = stream.getSource(); OutputStream out = stream.getOutputStream(); - source.close(Deadline.NONE); + source.close(); try { - source.read(new OkBuffer(), 1, Deadline.NONE); + source.read(new OkBuffer(), 1); fail(); } catch (IOException expected) { assertEquals("stream closed", expected.getMessage()); @@ -662,7 +660,7 @@ public final class SpdyConnectionTest { assertEquals(headerEntries("a", "android"), stream.getResponseHeaders()); connection.ping().roundTripTime(); // Ensure that the 2nd SYN REPLY has been received. try { - stream.getSource().read(new OkBuffer(), 1, Deadline.NONE); + stream.getSource().read(new OkBuffer(), 1); fail(); } catch (IOException expected) { assertEquals("stream was reset: STREAM_IN_USE", expected.getMessage()); @@ -918,7 +916,7 @@ public final class SpdyConnectionTest { assertEquals("stream was reset: CANCEL", expected.getMessage()); } try { - stream.getSource().read(new OkBuffer(), 1, Deadline.NONE); + stream.getSource().read(new OkBuffer(), 1); fail(); } catch (IOException expected) { assertEquals("stream was reset: CANCEL", expected.getMessage()); @@ -963,7 +961,7 @@ public final class SpdyConnectionTest { Source source = stream.getSource(); long startNanos = System.nanoTime(); try { - source.read(new OkBuffer(), 1, Deadline.NONE); + source.read(new OkBuffer(), 1); fail(); } catch (IOException expected) { } @@ -1067,10 +1065,10 @@ public final class SpdyConnectionTest { assertEquals(headerEntries("a", "android"), stream.getResponseHeaders()); Source in = stream.getSource(); OkBuffer buffer = new OkBuffer(); - while (in.read(buffer, 1024, Deadline.NONE) != -1) { + while (in.read(buffer, 1024) != -1) { if (buffer.byteCount() == 3 * windowUpdateThreshold) break; } - assertEquals(-1, in.read(buffer, 1, Deadline.NONE)); + assertEquals(-1, in.read(buffer, 1)); // Verify the peer received what was expected. assertEquals(21, peer.frameCount()); @@ -1110,7 +1108,7 @@ public final class SpdyConnectionTest { // Play it back. SpdyConnection connection = connection(peer, variant); SpdyStream client = connection.newStream(headerEntries("b", "banana"), false, true); - assertEquals(-1, client.getSource().read(new OkBuffer(), 1, Deadline.NONE)); + assertEquals(-1, client.getSource().read(new OkBuffer(), 1)); // Verify the peer received what was expected. MockSpdyPeer.InFrame synStream = peer.takeFrame(); @@ -1462,7 +1460,7 @@ public final class SpdyConnectionTest { private void assertStreamData(String expected, Source source) throws IOException { OkBuffer buffer = new OkBuffer(); - while (source.read(buffer, Long.MAX_VALUE, Deadline.NONE) != -1) { + while (source.read(buffer, Long.MAX_VALUE) != -1) { } String actual = buffer.readUtf8((int) buffer.byteCount()); assertEquals(expected, actual); diff --git a/okhttp/src/main/java/com/squareup/okhttp/Connection.java b/okhttp/src/main/java/com/squareup/okhttp/Connection.java index b8d2f262b..1b81e5eff 100644 --- a/okhttp/src/main/java/com/squareup/okhttp/Connection.java +++ b/okhttp/src/main/java/com/squareup/okhttp/Connection.java @@ -19,7 +19,6 @@ package com.squareup.okhttp; import com.squareup.okhttp.internal.Platform; import com.squareup.okhttp.internal.bytes.BufferedSource; import com.squareup.okhttp.internal.bytes.ByteString; -import com.squareup.okhttp.internal.bytes.Deadline; import com.squareup.okhttp.internal.bytes.OkBuffers; import com.squareup.okhttp.internal.http.HttpAuthenticator; import com.squareup.okhttp.internal.http.HttpConnection; @@ -215,7 +214,7 @@ public final class Connection implements Closeable { int readTimeout = socket.getSoTimeout(); try { socket.setSoTimeout(1); - if (source.source.read(source.buffer, 1, Deadline.NONE) == -1) { + if (source.source.read(source.buffer, 1) == -1) { return false; // Stream is exhausted; socket is closed. } return true; diff --git a/okhttp/src/main/java/com/squareup/okhttp/internal/http/HttpConnection.java b/okhttp/src/main/java/com/squareup/okhttp/internal/http/HttpConnection.java index de5ae153d..eadfb42d8 100644 --- a/okhttp/src/main/java/com/squareup/okhttp/internal/http/HttpConnection.java +++ b/okhttp/src/main/java/com/squareup/okhttp/internal/http/HttpConnection.java @@ -174,7 +174,7 @@ public final class HttpConnection { } private String readLine() throws IOException { - long newline = source.seek((byte) '\n', Deadline.NONE); + long newline = source.seek((byte) '\n'); if (newline > 0 && source.buffer.getByte(newline - 1) == '\r') { // Read everything until '\r\n', then skip the '\r\n'. @@ -483,13 +483,13 @@ public final class HttpConnection { } } - @Override public long read(OkBuffer sink, long byteCount, Deadline deadline) + @Override public long read(OkBuffer sink, long byteCount) throws IOException { if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount); if (closed) throw new IllegalStateException("closed"); if (bytesRemaining == 0) return -1; - long read = source.read(sink, Math.min(bytesRemaining, byteCount), deadline); + long read = source.read(sink, Math.min(bytesRemaining, byteCount)); if (read == -1) { unexpectedEndOfInput(); // the server didn't supply the promised content length throw new ProtocolException("unexpected end of stream"); @@ -503,7 +503,12 @@ public final class HttpConnection { return read; } - @Override public void close(Deadline deadline) throws IOException { + @Override public Source deadline(Deadline deadline) { + source.deadline(deadline); + return this; + } + + @Override public void close() throws IOException { if (closed) return; if (bytesRemaining != 0 && !discard(this, DISCARD_STREAM_TIMEOUT_MILLIS)) { @@ -527,7 +532,7 @@ public final class HttpConnection { } @Override public long read( - OkBuffer sink, long byteCount, Deadline deadline) throws IOException { + OkBuffer sink, long byteCount) throws IOException { if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount); if (closed) throw new IllegalStateException("closed"); if (!hasMoreChunks) return -1; @@ -537,7 +542,7 @@ public final class HttpConnection { if (!hasMoreChunks) return -1; } - long read = source.read(sink, Math.min(byteCount, bytesRemainingInChunk), deadline); + long read = source.read(sink, Math.min(byteCount, bytesRemainingInChunk)); if (read == -1) { unexpectedEndOfInput(); // the server didn't supply the promised chunk length throw new IOException("unexpected end of stream"); @@ -571,7 +576,12 @@ public final class HttpConnection { } } - @Override public void close(Deadline deadline) throws IOException { + @Override public Source deadline(Deadline deadline) { + source.deadline(deadline); + return this; + } + + @Override public void close() throws IOException { if (closed) return; if (hasMoreChunks && !discard(this, DISCARD_STREAM_TIMEOUT_MILLIS)) { unexpectedEndOfInput(); @@ -588,13 +598,13 @@ public final class HttpConnection { super(cacheRequest); } - @Override public long read(OkBuffer sink, long byteCount, Deadline deadline) + @Override public long read(OkBuffer sink, long byteCount) throws IOException { if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount); if (closed) throw new IllegalStateException("closed"); if (inputExhausted) return -1; - long read = source.read(sink, byteCount, deadline); + long read = source.read(sink, byteCount); if (read == -1) { inputExhausted = true; endOfInput(); @@ -604,7 +614,12 @@ public final class HttpConnection { return read; } - @Override public void close(Deadline deadline) throws IOException { + @Override public Source deadline(Deadline deadline) { + source.deadline(deadline); + return this; + } + + @Override public void close() throws IOException { if (closed) return; // TODO: discard unknown length streams for best caching? if (!inputExhausted) { diff --git a/okhttp/src/main/java/com/squareup/okhttp/internal/http/SpdyTransport.java b/okhttp/src/main/java/com/squareup/okhttp/internal/http/SpdyTransport.java index b4c1e62f8..e159fb5dd 100644 --- a/okhttp/src/main/java/com/squareup/okhttp/internal/http/SpdyTransport.java +++ b/okhttp/src/main/java/com/squareup/okhttp/internal/http/SpdyTransport.java @@ -257,13 +257,13 @@ public final class SpdyTransport implements Transport { this.cacheRequest = cacheRequest; } - @Override public long read(OkBuffer sink, long byteCount, Deadline deadline) + @Override public long read(OkBuffer sink, long byteCount) throws IOException { if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount); if (closed) throw new IllegalStateException("closed"); if (inputExhausted) return -1; - long read = source.read(sink, byteCount, deadline); + long read = source.read(sink, byteCount); if (read == -1) { inputExhausted = true; if (cacheRequest != null) { @@ -279,7 +279,12 @@ public final class SpdyTransport implements Transport { return read; } - @Override public void close(Deadline deadline) throws IOException { + @Override public Source deadline(Deadline deadline) { + source.deadline(deadline); + return this; + } + + @Override public void close() throws IOException { if (closed) return; if (!inputExhausted && cacheBody != null) {