151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/*
251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Copyright (c) 1996, 2009, Oracle and/or its affiliates. All rights reserved.
351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it
651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as
751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation.  Oracle designates this
851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided
951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code.
1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT
1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that
1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code).
1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version
1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation,
1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any
2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions.
2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */
2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage sun.security.ssl;
2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
2951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.*;
3051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/**
3251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * InputStream for application data as returned by SSLSocket.getInputStream().
3351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * It uses an InputRecord as internal buffer that is refilled on demand
3451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * whenever it runs out of data.
3551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
3651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @author David Brownell
3751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */
3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiclass AppInputStream extends InputStream {
3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
4051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // static dummy array we use to implement skip()
4151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private final static byte[] SKIP_ARRAY = new byte[1024];
4251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
4351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private SSLSocketImpl c;
4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    InputRecord r;
4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // One element array used to implement the single byte read() method
4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private final byte[] oneByte = new byte[1];
4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    AppInputStream(SSLSocketImpl conn) {
5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        r = new InputRecord();
5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        c = conn;
5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
5351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
5451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
5551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Return the minimum number of bytes that can be read without blocking.
5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Currently not synchronized.
5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
5851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public int available() throws IOException {
5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (c.checkEOF() || (r.isAppDataValid() == false)) {
6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return 0;
6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return r.available();
6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Read a single byte, returning -1 on non-fault EOF status.
6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public synchronized int read() throws IOException {
6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int n = read(oneByte, 0, 1);
7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (n <= 0) { // EOF
7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return -1;
7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return oneByte[0] & 0xff;
7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Read up to "len" bytes into this buffer, starting at "off".
7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * If the layer above needs more data, it asks for more, so we
7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * are responsible only for blocking to fill at most one buffer,
8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * and returning "-1" on non-fault EOF status.
8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public synchronized int read(byte b[], int off, int len)
8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throws IOException {
8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (b == null) {
8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new NullPointerException();
8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else if (off < 0 || len < 0 || len > b.length - off) {
8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new IndexOutOfBoundsException();
8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else if (len == 0) {
8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return 0;
9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
9151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
9251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (c.checkEOF()) {
9351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return -1;
9451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
9551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        try {
9651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            /*
9751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * Read data if needed ... notice that the connection guarantees
9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * that handshake, alert, and change cipher spec data streams are
9951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * handled as they arrive, so we never see them here.
10051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             */
10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            while (r.available() == 0) {
10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                c.readDataRecord(r);
10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (c.checkEOF()) {
10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    return -1;
10551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
10651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
10751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            int howmany = Math.min(len, r.available());
10951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            howmany = r.read(b, off, howmany);
11051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return howmany;
11151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } catch (Exception e) {
11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // shutdown and rethrow (wrapped) exception as appropriate
11351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            c.handleException(e);
11451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // dummy for compiler
11551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return -1;
11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
11751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
11851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
11951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
12051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
12151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Skip n bytes. This implementation is somewhat less efficient
12251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * than possible, but not badly so (redundant copy). We reuse
12351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * the read() code to keep things simpler. Note that SKIP_ARRAY
12451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * is static and may garbled by concurrent use, but we are not interested
12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * in the data anyway.
12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
12751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public synchronized long skip(long n) throws IOException {
12851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        long skipped = 0;
12951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        while (n > 0) {
13051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            int len = (int)Math.min(n, SKIP_ARRAY.length);
13151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            int r = read(SKIP_ARRAY, 0, len);
13251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (r <= 0) {
13351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                break;
13451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
13551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            n -= r;
13651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            skipped += r;
13751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
13851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return skipped;
13951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
14051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /*
14251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Socket close is already synchronized, no need to block here.
14351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
14451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void close() throws IOException {
14551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        c.close();
14651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
14751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
14851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // inherit default mark/reset behavior (throw Exceptions) from InputStream
14951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
15051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski}
151