@@ -74,8 +74,10 @@ public RecordingInputStream(int bufferSize, String backingFilename)
7474 }
7575
7676 public void open (InputStream wrappedStream ) throws IOException {
77- logger .fine (Thread .currentThread ().getName () + " opening " +
78- wrappedStream + ", " + Thread .currentThread ().getName ());
77+ if (logger .isLoggable (Level .FINE )) {
78+ logger .fine ("wrapping " + wrappedStream + " in thread "
79+ + Thread .currentThread ().getName ());
80+ }
7981 if (isOpen ()) {
8082 // error; should not be opening/wrapping in an unclosed
8183 // stream remains open
@@ -135,11 +137,11 @@ public int read(byte[] b) throws IOException {
135137
136138 public void close () throws IOException {
137139 if (logger .isLoggable (Level .FINE )) {
138- logger .fine (Thread . currentThread (). getName () + " closing " +
139- this . in + ", " + Thread .currentThread ().getName ());
140+ logger .fine ("closing " + this . in + " in thread "
141+ + Thread .currentThread ().getName ());
140142 }
141143 IOUtils .closeQuietly (this .in );
142- this .in = null ;
144+ this .in = null ;
143145 IOUtils .closeQuietly (this .recordingOutputStream );
144146 }
145147
@@ -159,20 +161,77 @@ public long readFully() throws IOException {
159161 return this .recordingOutputStream .getSize ();
160162 }
161163
164+ public void readToEndOfContent (long contentLength )
165+ throws IOException , InterruptedException {
166+ // Check we're open before proceeding.
167+ if (!isOpen ()) {
168+ // TODO: should this be a noisier exception-raising error?
169+ return ;
170+ }
171+
172+ long totalBytes = recordingOutputStream .position - recordingOutputStream .getMessageBodyBegin ();
173+ long bytesRead = -1L ;
174+ long maxToRead = -1 ;
175+ while (contentLength <= 0 || totalBytes < contentLength ) {
176+ try {
177+ // read no more than soft max
178+ maxToRead = (contentLength <= 0 )
179+ ? drainBuffer .length
180+ : Math .min (drainBuffer .length , contentLength - totalBytes );
181+ // nor more than hard max
182+ maxToRead = Math .min (maxToRead , recordingOutputStream .getRemainingLength ());
183+ // but always at least 1 (to trigger hard max exception) XXX wtf is this?
184+ maxToRead = Math .max (maxToRead , 1 );
185+
186+ bytesRead = read (drainBuffer ,0 ,(int )maxToRead );
187+ if (bytesRead == -1 ) {
188+ break ;
189+ }
190+ totalBytes += bytesRead ;
191+
192+ if (Thread .interrupted ()) {
193+ throw new InterruptedException ("Interrupted during IO" );
194+ }
195+ } catch (SocketTimeoutException e ) {
196+ // A socket timeout is just a transient problem, meaning
197+ // nothing was available in the configured timeout period,
198+ // but something else might become available later.
199+ // Take this opportunity to check the overall
200+ // timeout (below). One reason for this timeout is
201+ // servers that keep up the connection, 'keep-alive', even
202+ // though we asked them to not keep the connection open.
203+ if (logger .isLoggable (Level .FINE )) {
204+ logger .log (Level .FINE , "socket timeout" , e );
205+ }
206+ // check for interrupt
207+ if (Thread .interrupted ()) {
208+ throw new InterruptedException ("Interrupted during IO" );
209+ }
210+ // check for overall timeout
211+ recordingOutputStream .checkLimits ();
212+ } catch (SocketException se ) {
213+ throw se ;
214+ } catch (NullPointerException e ) {
215+ // [ 896757 ] NPEs in Andy's Th-Fri Crawl.
216+ // A crawl was showing NPE's in this part of the code but can
217+ // not reproduce. Adding this rethrowing catch block w/
218+ // diagnostics to help should we come across the problem in the
219+ // future.
220+ throw new NullPointerException ("Stream " + this .in + ", " +
221+ e .getMessage () + " " + Thread .currentThread ().getName ());
222+ }
223+ }
224+ }
225+
162226 /**
163227 * Read all of a stream (Or read until we timeout or have read to the max).
164228 * @param softMaxLength Maximum length to read; if zero or < 0, then no
165229 * limit. If met, return normally.
166- * @param hardMaxLength Maximum length to read; if zero or < 0, then no
167- * limit. If exceeded, throw RecorderLengthExceededException
168- * @param timeout Timeout in milliseconds for total read; if zero or
169- * negative, timeout is <code>Long.MAX_VALUE</code>. If exceeded, throw
170- * RecorderTimeoutException
171- * @param maxBytesPerMs How many bytes per millisecond.
172230 * @throws IOException failed read.
173231 * @throws RecorderLengthExceededException
174232 * @throws RecorderTimeoutException
175233 * @throws InterruptedException
234+ * @deprecated
176235 */
177236 public void readFullyOrUntil (long softMaxLength )
178237 throws IOException , RecorderLengthExceededException ,
@@ -349,6 +408,13 @@ public int getRecordedBufferLength() {
349408 return recordingOutputStream .getBufferLength ();
350409 }
351410
411+ /**
412+ * See doc on {@link RecordingOutputStream#chopAtMessageBodyBegin()}
413+ */
414+ public void chopAtMessageBodyBegin () {
415+ recordingOutputStream .chopAtMessageBodyBegin ();
416+ }
417+
352418 public void clearForReuse () throws IOException {
353419 recordingOutputStream .clearForReuse ();
354420 }
0 commit comments