Home | History | Annotate | Download | only in server
      1 /*
      2  * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  *
      8  *   - Redistributions of source code must retain the above copyright
      9  *     notice, this list of conditions and the following disclaimer.
     10  *
     11  *   - Redistributions in binary form must reproduce the above copyright
     12  *     notice, this list of conditions and the following disclaimer in the
     13  *     documentation and/or other materials provided with the distribution.
     14  *
     15  *   - Neither the name of Oracle nor the names of its
     16  *     contributors may be used to endorse or promote products derived
     17  *     from this software without specific prior written permission.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
     20  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     21  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     26  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
     27  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
     28  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     29  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 /*
     33  * This source code is provided to illustrate the usage of a given feature
     34  * or technique and has been deliberately simplified. Additional steps
     35  * required for a production-quality application, such as security checks,
     36  * input validation and proper error handling, might not be present in
     37  * this sample code.
     38  */
     39 
     40 
     41 import java.io.*;
     42 import java.nio.*;
     43 import java.nio.channels.*;
     44 
     45 /**
     46  * A helper class for properly sizing inbound byte buffers and
     47  * redirecting I/O calls to the proper SocketChannel call.
     48  * <P>
     49  * Many of these calls may seem unnecessary until you consider
     50  * that they are placeholders for the secure variant, which is much
     51  * more involved.  See ChannelIOSecure for more information.
     52  *
     53  * @author Brad R. Wetmore
     54  * @author Mark Reinhold
     55  */
     56 class ChannelIO {
     57 
     58     protected SocketChannel sc;
     59 
     60     /*
     61      * All of the inbound request data lives here until we determine
     62      * that we've read everything, then we pass that data back to the
     63      * caller.
     64      */
     65     protected ByteBuffer requestBB;
     66     static private int requestBBSize = 4096;
     67 
     68     protected ChannelIO(SocketChannel sc, boolean blocking)
     69             throws IOException {
     70         this.sc = sc;
     71         sc.configureBlocking(blocking);
     72     }
     73 
     74     static ChannelIO getInstance(SocketChannel sc, boolean blocking)
     75             throws IOException {
     76         ChannelIO cio = new ChannelIO(sc, blocking);
     77         cio.requestBB = ByteBuffer.allocate(requestBBSize);
     78 
     79         return cio;
     80     }
     81 
     82     SocketChannel getSocketChannel() {
     83         return sc;
     84     }
     85 
     86     /*
     87      * Return a ByteBuffer with "remaining" space to work.  If you have to
     88      * reallocate the ByteBuffer, copy the existing info into the new buffer.
     89      */
     90     protected void resizeRequestBB(int remaining) {
     91         if (requestBB.remaining() < remaining) {
     92             // Expand buffer for large request
     93             ByteBuffer bb = ByteBuffer.allocate(requestBB.capacity() * 2);
     94             requestBB.flip();
     95             bb.put(requestBB);
     96             requestBB = bb;
     97         }
     98     }
     99 
    100     /*
    101      * Perform any handshaking processing.
    102      * <P>
    103      * This variant is for Servers without SelectionKeys (e.g.
    104      * blocking).
    105      * <P>
    106      * return true when we're done with handshaking.
    107      */
    108     boolean doHandshake() throws IOException {
    109         return true;
    110     }
    111 
    112     /*
    113      * Perform any handshaking processing.
    114      * <P>
    115      * This variant is for Servers with SelectionKeys, so that
    116      * we can register for selectable operations (e.g. selectable
    117      * non-blocking).
    118      * <P>
    119      * return true when we're done with handshaking.
    120      */
    121     boolean doHandshake(SelectionKey sk) throws IOException {
    122         return true;
    123     }
    124 
    125     /*
    126      * Resize (if necessary) the inbound data buffer, and then read more
    127      * data into the read buffer.
    128      */
    129     int read() throws IOException {
    130         /*
    131          * Allocate more space if less than 5% remains
    132          */
    133         resizeRequestBB(requestBBSize/20);
    134         return sc.read(requestBB);
    135     }
    136 
    137     /*
    138      * All data has been read, pass back the request in one buffer.
    139      */
    140     ByteBuffer getReadBuf() {
    141         return requestBB;
    142     }
    143 
    144     /*
    145      * Write the src buffer into the socket channel.
    146      */
    147     int write(ByteBuffer src) throws IOException {
    148         return sc.write(src);
    149     }
    150 
    151     /*
    152      * Perform a FileChannel.TransferTo on the socket channel.
    153      */
    154     long transferTo(FileChannel fc, long pos, long len) throws IOException {
    155         return fc.transferTo(pos, len, sc);
    156     }
    157 
    158     /*
    159      * Flush any outstanding data to the network if possible.
    160      * <P>
    161      * This isn't really necessary for the insecure variant, but needed
    162      * for the secure one where intermediate buffering must take place.
    163      * <P>
    164      * Return true if successful.
    165      */
    166     boolean dataFlush() throws IOException {
    167         return true;
    168     }
    169 
    170     /*
    171      * Start any connection shutdown processing.
    172      * <P>
    173      * This isn't really necessary for the insecure variant, but needed
    174      * for the secure one where intermediate buffering must take place.
    175      * <P>
    176      * Return true if successful, and the data has been flushed.
    177      */
    178     boolean shutdown() throws IOException {
    179         return true;
    180     }
    181 
    182     /*
    183      * Close the underlying connection.
    184      */
    185     void close() throws IOException {
    186         sc.close();
    187     }
    188 
    189 }
    190