/* this stream eof */ boolean eof = false; boolean needData = true; InputStream () { bbuf = allocate (BufType.APPLICATION); } public int read (byte[] buf, int off, int len) throws IOException { if (closed) { throw new IOException ("SSL stream is closed"); } if (eof) { return 0; } int available=0; if (!needData) { available = bbuf.remaining(); needData = (available==0); } if (needData) { bbuf.clear(); WrapperResult r = recvData (bbuf); bbuf = r.buf== bbuf? bbuf: r.buf; if ((available=bbuf.remaining()) == 0) { eof = true; return 0; } else { needData = false; } } /* copy as much as possible from buf into users buf */ if (len > available) { len = available; } bbuf.get (buf, off, len); return len; } public int available () throws IOException { return bbuf.remaining(); } public boolean markSupported () { return false; /* not possible with SSLEngine */ } public void reset () throws IOException { throw new IOException ("mark/reset not supported"); } public long skip (long s) throws IOException { int n = (int)s; if (closed) { throw new IOException ("SSL stream is closed"); } if (eof) { return 0; } int ret = n; while (n > 0) { if (bbuf.remaining() >= n) { bbuf.position (bbuf.position()+n); return ret; } else { n -= bbuf.remaining(); bbuf.clear(); WrapperResult r = recvData (bbuf); bbuf = r.buf==bbuf? bbuf: r.buf; } } return ret; /* not reached */ } /** * close the SSL connection. All data must have been consumed * before this is called. Otherwise an exception will be thrown. * [Note. May need to revisit this. not quite the normal close() symantics */ public void close () throws IOException { eof = true; engine.closeInbound (); } public int read (byte[] buf) throws IOException { return read (buf, 0, buf.length); } byte single[] = new byte [1]; public int read () throws IOException { int n = read (single, 0, 1); if (n == 0) { return -1; } else { return single[0] & 0xFF; } } } /** * represents an SSL output stream. plain text data written to this stream * is encrypted by the stream. Multiple HTTPS responses can be sent on * one stream. closing this stream initiates an SSL closure */ class OutputStream extends java.io.OutputStream { ByteBuffer buf; boolean closed = false; byte single[] = new byte[1]; OutputStream() { buf = allocate(BufType.APPLICATION); } public void write(int b) throws IOException { single[0] = (byte)b; write (single, 0, 1); } public void write(byte b[]) throws IOException { write (b, 0, b.length); } public void write(byte b[], int off, int len) throws IOException { if (closed) { throw new IOException ("output stream is closed"); } while (len > 0) { int l = len > buf.capacity() ? buf.capacity() : len; buf.clear(); buf.put (b, off, l); len -= l; off += l; buf.flip(); WrapperResult r = sendData (buf); if (r.result.getStatus() == Status.CLOSED) { closed = true; if (len > 0) { throw new IOException ("output stream is closed"); } } } } public void flush() throws IOException { /* no-op */ } public void close() throws IOException { WrapperResult r=null; engine.closeOutbound(); closed = true; HandshakeStatus stat = HandshakeStatus.NEED_WRAP; buf.clear(); while (stat == HandshakeStatus.NEED_WRAP) { r = wrapper.wrapAndSend (buf); stat = r.result.getHandshakeStatus(); } assert r.result.getStatus() == Status.CLOSED; } }}Lines 501–662 of 662. Previous lines
/* this stream eof */ boolean eof = false; boolean needData = true; InputStream () { bbuf = allocate (BufType.APPLICATION); } public int read (byte[] buf, int off, int len) throws IOException { if (closed) { throw new IOException ("SSL stream is closed"); } if (eof) { return 0; } int available=0; if (!needData) { available = bbuf.remaining(); needData = (available==0); } if (needData) { bbuf.clear(); WrapperResult r = recvData (bbuf); bbuf = r.buf== bbuf? bbuf: r.buf; if ((available=bbuf.remaining()) == 0) { eof = true; return 0; } else { needData = false; } } /* copy as much as possible from buf into users buf */ if (len > available) { len = available; } bbuf.get (buf, off, len); return len; } public int available () throws IOException { return bbuf.remaining(); } public boolean markSupported () { return false; /* not possible with SSLEngine */ } public void reset () throws IOException { throw new IOException ("mark/reset not supported"); } public long skip (long s) throws IOException { int n = (int)s; if (closed) { throw new IOException ("SSL stream is closed"); } if (eof) { return 0; } int ret = n; while (n > 0) { if (bbuf.remaining() >= n) { bbuf.position (bbuf.position()+n); return ret; } else { n -= bbuf.remaining(); bbuf.clear(); WrapperResult r = recvData (bbuf); bbuf = r.buf==bbuf? bbuf: r.buf; } } return ret; /* not reached */ } /** * close the SSL connection. All data must have been consumed * before this is called. Otherwise an exception will be thrown. * [Note. May need to revisit this. not quite the normal close() symantics */ public void close () throws IOException { eof = true; engine.closeInbound (); } public int read (byte[] buf) throws IOException { return read (buf, 0, buf.length); } byte single[] = new byte [1]; public int read () throws IOException { int n = read (single, 0, 1); if (n == 0) { return -1; } else { return single[0] & 0xFF; } } } /** * represents an SSL output stream. plain text data written to this stream * is encrypted by the stream. Multiple HTTPS responses can be sent on * one stream. closing this stream initiates an SSL closure */ class OutputStream extends java.io.OutputStream { ByteBuffer buf; boolean closed = false; byte single[] = new byte[1]; OutputStream() { buf = allocate(BufType.APPLICATION); } public void write(int b) throws IOException { single[0] = (byte)b; write (single, 0, 1); } public void write(byte b[]) throws IOException { write (b, 0, b.length); } public void write(byte b[], int off, int len) throws IOException { if (closed) { throw new IOException ("output stream is closed"); } while (len > 0) { int l = len > buf.capacity() ? buf.capacity() : len; buf.clear(); buf.put (b, off, l); len -= l; off += l; buf.flip(); WrapperResult r = sendData (buf); if (r.result.getStatus() == Status.CLOSED) { closed = true; if (len > 0) { throw new IOException ("output stream is closed"); } } } } public void flush() throws IOException { /* no-op */ } public void close() throws IOException { WrapperResult r=null; engine.closeOutbound(); closed = true; HandshakeStatus stat = HandshakeStatus.NEED_WRAP; buf.clear(); while (stat == HandshakeStatus.NEED_WRAP) { r = wrapper.wrapAndSend (buf); stat = r.result.getHandshakeStatus(); } assert r.result.getStatus() == Status.CLOSED; } } }