Search in sources :

Example 51 with SocketChannel

use of java.nio.channels.SocketChannel in project http-kit by http-kit.

the class HttpClient method doWrite.

private void doWrite(SelectionKey key) {
    Request req = (Request) key.attachment();
    SocketChannel ch = (SocketChannel) key.channel();
    try {
        if (req instanceof HttpsRequest) {
            HttpsRequest httpsReq = (HttpsRequest) req;
            if (httpsReq.handshaken) {
                // will flip to OP_READ
                httpsReq.writeWrappedRequest();
            } else {
                buffer.clear();
                if (httpsReq.doHandshake(buffer) < 0) {
                    // will be a No status exception
                    req.finish();
                }
            }
        } else {
            ByteBuffer[] buffers = req.request;
            ch.write(buffers);
            if (!buffers[buffers.length - 1].hasRemaining()) {
                key.interestOps(OP_READ);
            }
        }
    } catch (IOException e) {
        if (!cleanAndRetryIfBroken(key, req)) {
            req.finish(e);
        }
    } catch (Exception e) {
        // rarely happen
        req.finish(e);
    }
}
Also used : SocketChannel(java.nio.channels.SocketChannel) IOException(java.io.IOException) ByteBuffer(java.nio.ByteBuffer) ProtocolException(org.httpkit.ProtocolException) IOException(java.io.IOException) SSLException(javax.net.ssl.SSLException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException)

Example 52 with SocketChannel

use of java.nio.channels.SocketChannel in project http-kit by http-kit.

the class HttpClient method finishConnect.

private void finishConnect(SelectionKey key, long now) {
    SocketChannel ch = (SocketChannel) key.channel();
    Request req = (Request) key.attachment();
    try {
        if (ch.finishConnect()) {
            req.isConnected = true;
            req.onProgress(now);
            key.interestOps(OP_WRITE);
            if (req instanceof HttpsRequest) {
                ((HttpsRequest) req).engine.beginHandshake();
            }
        }
    } catch (IOException e) {
        // not added to kee-alive yet;
        closeQuietly(key);
        req.finish(e);
    }
}
Also used : SocketChannel(java.nio.channels.SocketChannel) IOException(java.io.IOException)

Example 53 with SocketChannel

use of java.nio.channels.SocketChannel in project http-kit by http-kit.

the class HttpsRequest method doHandshake.

final int doHandshake(ByteBuffer peerAppData) throws IOException {
    SSLEngineResult.HandshakeStatus hs = engine.getHandshakeStatus();
    while (!handshaken) {
        switch(hs) {
            case NEED_TASK:
                Runnable runnable;
                while ((runnable = engine.getDelegatedTask()) != null) {
                    runnable.run();
                }
                break;
            case NEED_UNWRAP:
                int read = ((SocketChannel) key.channel()).read(peerNetData);
                if (read < 0) {
                    return -1;
                } else {
                    peerNetData.flip();
                    SSLEngineResult res = engine.unwrap(peerNetData, peerAppData);
                    peerNetData.compact();
                    switch(res.getStatus()) {
                        case // Not possible, peerAppData is 64k
                        BUFFER_OVERFLOW:
                            break;
                        case CLOSED:
                            return -1;
                        case // need more data from peer
                        BUFFER_UNDERFLOW:
                            return 0;
                    }
                // do not flip to write here, since TCP buffer is writable
                }
                break;
            case NEED_WRAP:
                SSLEngineResult res = engine.wrap(EMPTY_BUFFER, myNetData);
                myNetData.flip();
                ((SocketChannel) key.channel()).write(myNetData);
                if (myNetData.hasRemaining()) {
                // TODO, make sure data get written
                } else {
                    myNetData.clear();
                    if (res.getHandshakeStatus() != SSLEngineResult.HandshakeStatus.NEED_WRAP)
                        key.interestOps(SelectionKey.OP_READ);
                }
                break;
        }
        hs = engine.getHandshakeStatus();
        handshaken = hs == SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING || hs == SSLEngineResult.HandshakeStatus.FINISHED;
        if (handshaken) {
            wrapRequest();
            // TCP buffer maybe empty this time
            writeWrappedRequest();
        }
    }
    return 0;
}
Also used : SocketChannel(java.nio.channels.SocketChannel) SSLEngineResult(javax.net.ssl.SSLEngineResult)

Example 54 with SocketChannel

use of java.nio.channels.SocketChannel in project http-kit by http-kit.

the class SSLTest method main.

public static void main(String[] args) throws Exception {
    SSLEngine engine = CLIENT_CONTEXT.createSSLEngine();
    engine.setUseClientMode(true);
    // Create a nonblocking socket channel
    SocketChannel socketChannel = SocketChannel.open();
    socketChannel.configureBlocking(true);
    socketChannel.connect(new InetSocketAddress("google.com", 443));
    //        int i = 0;
    while (!socketChannel.finishConnect()) {
        //            System.out.println("----------" + i++);
        Thread.sleep(50);
    // do something until connect completed
    }
    // Create byte buffers to use for holding application and encoded data
    SSLSession session = engine.getSession();
    ByteBuffer myNetData = ByteBuffer.allocate(session.getPacketBufferSize());
    ByteBuffer peerAppData = ByteBuffer.allocate(session.getApplicationBufferSize());
    ByteBuffer peerNetData = ByteBuffer.allocate(session.getPacketBufferSize());
    peerNetData.limit(0);
    ByteBuffer myAppData = ByteBuffer.wrap(("GET / HTTP/1.1\r\nHost: \r\n\r\n").getBytes());
    engine.beginHandshake();
    SSLEngineResult.HandshakeStatus hs = engine.getHandshakeStatus();
    while (hs != SSLEngineResult.HandshakeStatus.FINISHED && hs != SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) {
        System.out.println("hs status: " + hs);
        switch(hs) {
            case NEED_TASK:
                Runnable runnable;
                while ((runnable = engine.getDelegatedTask()) != null) {
                    System.out.println("get task " + runnable);
                    runnable.run();
                }
                break;
            case NEED_UNWRAP:
                if (!peerNetData.hasRemaining()) {
                    peerNetData.clear();
                    int read = socketChannel.read(peerNetData);
                    System.out.println("read: " + read + "\t" + peerNetData);
                    peerNetData.flip();
                }
                SSLEngineResult status = engine.unwrap(peerNetData, peerAppData);
                //  peerNetData.compact();
                System.out.println("unwrap: " + status);
                switch(status.getStatus()) {
                    case BUFFER_UNDERFLOW:
                        peerNetData.compact();
                        //                            peerNetData.flip();
                        int read = socketChannel.read(peerNetData);
                        System.out.println("flip read: " + read + "\t" + peerNetData);
                        peerNetData.flip();
                        break;
                }
                break;
            case NEED_WRAP:
                myNetData.clear();
                SSLEngineResult wrapStatus = engine.wrap(myAppData, myNetData);
                System.out.println("wrap: " + wrapStatus);
                myNetData.flip();
                while (myNetData.hasRemaining()) {
                    socketChannel.write(myNetData);
                }
                break;
        }
        hs = engine.getHandshakeStatus();
    }
    // https://raw.github.com/http-kit/scale-clojure-web-app/master/results/600k/heap_usage.png
    for (int i = 0; i < 5; i++) {
        myNetData.clear();
        peerAppData.clear();
        myAppData = ByteBuffer.wrap(("GET / HTTP/1.1\r\nHost: www.google.co.jp\r\n\r\n").getBytes());
        SSLEngineResult wrapStatus = engine.wrap(myAppData, myNetData);
        //            System.out.println("---------wrap: " + wrapStatus);
        myNetData.flip();
        while (myNetData.hasRemaining()) {
            socketChannel.write(myNetData);
        }
        peerNetData.clear();
        int read = socketChannel.read(peerNetData);
        //            System.out.println("-------read: " + read + "\t" + peerNetData);
        peerNetData.flip();
        // 	Exception in thread "main" javax.net.ssl.SSLException: bad record MAC
        SSLEngineResult status = engine.unwrap(peerNetData, peerAppData);
        while (status.getStatus() != SSLEngineResult.Status.OK) {
            //                System.out.println("-------unwrap: " + status);
            peerNetData.compact();
            read = socketChannel.read(peerNetData);
            System.out.println("-------read: " + read + "\t" + peerNetData);
            peerNetData.flip();
            status = engine.unwrap(peerNetData, peerAppData);
        }
        peerAppData.flip();
        System.out.println(peerAppData);
        byte[] data = new byte[peerAppData.remaining()];
        peerAppData.get(data);
        System.out.println(new String(data));
    //  peerNetData.compact();
    }
// Do initial handshake
//        doHandleShake2(socketChannel, engine, myNetData, peerNetData);
}
Also used : SocketChannel(java.nio.channels.SocketChannel) InetSocketAddress(java.net.InetSocketAddress) ByteBuffer(java.nio.ByteBuffer)

Example 55 with SocketChannel

use of java.nio.channels.SocketChannel in project http-kit by http-kit.

the class HttpServer method doWrite.

private void doWrite(SelectionKey key) {
    ServerAtta atta = (ServerAtta) key.attachment();
    SocketChannel ch = (SocketChannel) key.channel();
    try {
        // 1. keep byte data order, 2. ensure visibility
        synchronized (atta) {
            LinkedList<ByteBuffer> toWrites = atta.toWrites;
            int size = toWrites.size();
            if (size == 1) {
                ch.write(toWrites.get(0));
            // TODO investigate why needed.
            // ws request for write, but has no data?
            } else if (size > 0) {
                ByteBuffer[] buffers = new ByteBuffer[size];
                toWrites.toArray(buffers);
                ch.write(buffers, 0, buffers.length);
            }
            Iterator<ByteBuffer> ite = toWrites.iterator();
            while (ite.hasNext()) {
                if (!ite.next().hasRemaining()) {
                    ite.remove();
                }
            }
            // all done
            if (toWrites.size() == 0) {
                if (atta.isKeepAlive()) {
                    key.interestOps(OP_READ);
                } else {
                    closeKey(key, CLOSE_NORMAL);
                }
            }
        }
    } catch (IOException e) {
        // the remote forcibly closed the connection
        closeKey(key, CLOSE_AWAY);
    }
}
Also used : ServerSocketChannel(java.nio.channels.ServerSocketChannel) SocketChannel(java.nio.channels.SocketChannel) IOException(java.io.IOException) ByteBuffer(java.nio.ByteBuffer)

Aggregations

SocketChannel (java.nio.channels.SocketChannel)662 IOException (java.io.IOException)298 ServerSocketChannel (java.nio.channels.ServerSocketChannel)285 InetSocketAddress (java.net.InetSocketAddress)202 ByteBuffer (java.nio.ByteBuffer)163 SelectionKey (java.nio.channels.SelectionKey)105 Socket (java.net.Socket)87 Test (org.junit.Test)81 ClosedChannelException (java.nio.channels.ClosedChannelException)50 Selector (java.nio.channels.Selector)42 SocketAddress (java.net.SocketAddress)35 ServerSocket (java.net.ServerSocket)31 ClosedSelectorException (java.nio.channels.ClosedSelectorException)28 CancelledKeyException (java.nio.channels.CancelledKeyException)27 ConnectException (java.net.ConnectException)26 ArrayList (java.util.ArrayList)26 SocketTimeoutException (java.net.SocketTimeoutException)23 SelectableChannel (java.nio.channels.SelectableChannel)21 SocketException (java.net.SocketException)20 HashMap (java.util.HashMap)20