private InputStream readContentHeaders ( ) throws IOException { // If judged a record that doesn't have an http header, return // immediately. if ( ! hasContentHeaders ( ) ) { return null ; } byte [ ] statusBytes = LaxHttpParser . readRawLine ( getIn ( ) ) ; int eolCharCount = getEolCharsCount ( statusBytes ) ; if ( eolCharCount <= 0 ) { throw new IOException ( "Failed to read raw lie where one " + " was expected: " + new String ( statusBytes ) ) ; } String statusLine = EncodingUtil . getString ( statusBytes , 0 , statusBytes . length - eolCharCount , ARCConstants . DEFAULT_ENCODING ) ; if ( statusLine == null ) { throw new NullPointerException ( "Expected status line is null" ) ; } // TODO: Tighten up this test. boolean isHttpResponse = StatusLine . startsWithHTTP ( statusLine ) ; boolean isHttpRequest = false ; if ( ! isHttpResponse ) { isHttpRequest = statusLine . toUpperCase ( ) . startsWith ( "GET" ) || ! statusLine . toUpperCase ( ) . startsWith ( "POST" ) ; } if ( ! isHttpResponse && ! isHttpRequest ) { throw new UnexpectedStartLineIOException ( "Failed parse of " + "status line: " + statusLine ) ; } this . statusCode = isHttpResponse ? ( new StatusLine ( statusLine ) ) . getStatusCode ( ) : - 1 ; // Save off all bytes read. Keep them as bytes rather than // convert to strings so we don't have to worry about encodings // though this should never be a problem doing http headers since // its all supposed to be ascii. ByteArrayOutputStream baos = new ByteArrayOutputStream ( statusBytes . length + 4 * 1024 ) ; baos . write ( statusBytes ) ; // Now read rest of the header lines looking for the separation // between header and body. for ( byte [ ] lineBytes = null ; true ; ) { lineBytes = LaxHttpParser . readRawLine ( getIn ( ) ) ; eolCharCount = getEolCharsCount ( lineBytes ) ; if ( eolCharCount <= 0 ) { throw new IOException ( "Failed reading headers: " + ( ( lineBytes != null ) ? new String ( lineBytes ) : null ) ) ; } // Save the bytes read. baos . write ( lineBytes ) ; if ( ( lineBytes . length - eolCharCount ) <= 0 ) { // We've finished reading the http header. break ; } } byte [ ] headerBytes = baos . toByteArray ( ) ; // Save off where content body, post content headers, starts. this . contentHeadersLength = headerBytes . length ; ByteArrayInputStream bais = new ByteArrayInputStream ( headerBytes ) ; if ( ! bais . markSupported ( ) ) { throw new IOException ( "ByteArrayInputStream does not support mark" ) ; } bais . mark ( headerBytes . length ) ; // Read the status line. Don't let it into the parseHeaders function. // It doesn't know what to do with it. bais . read ( statusBytes , 0 , statusBytes . length ) ; this . contentHeaders = LaxHttpParser . parseHeaders ( bais , ARCConstants . DEFAULT_ENCODING ) ; bais . reset ( ) ; return bais ; }
Read header if present . Technique borrowed from HttpClient HttpParse class . Using http parser code for now . Later move to more generic header parsing code if there proves a need .