protected void connect(SelectionKey key) { NetCtx atta = NetCtx.fromKey(key); NetRequest req = (NetRequest)atta.getInput(); try { boolean connected = atta.getChannel().finishConnect(); if (connected) { // TODO key.interestOps(OP_WRITE|OP_READ); // TODO if TLS enabled, begin handshake here ... req.sendRequest(key, this); } } catch (IOException e) { // TODO notify client that connection failed, or retry log.error("Cannot finish connect for " + req, e); } }
@Override public HttpEncoder finish(SelectionKey key) { finishHeaders(key); ByteBuffer bb = ByteBuffer.wrap(buf.get(), 0, buf.length()); BufHandler out = output != null ? output : NetCtx.fromKey(key).getOutput(); out.submit(key, true, bb, body, keepAlive() ? NetCtx.FLUSH : NetCtx.CLOSE); state |= FINISHED; return this; }
@Override public boolean submit(SelectionKey key, boolean copyOnSchedule, ByteBuffer... buffers) { // TODO make this thing fully streaming, do not use ByteArrayOutputStream, make it thread safe for (int i = 0; i < buffers.length; i++) { ByteBuffer buf = buffers[i]; while (buf.hasRemaining()) { byte b = buf.get(); os.write(b); if (b == '\n') { byte[] a = os.toByteArray(); os.reset(); ByteBuffer bb = ByteBuffer.wrap(a); BufHandler out = NetCtx.fromKey(key).getOutput(); //out.submit(key, true, bb, a[0] == 'q' ? NetAtta.CLOSE : NetAtta.NULL); if (isClose()) { out.submit(key, true, bb, NetCtx.CLOSE); } else { out.submit(key, true, bb); } return !(buf.hasRemaining() || i < buffers.length-1); } } } return true; }
@Override public void submit(SelectionKey key, HttpMessage message) { reqs.add(message); NetCtx ctx = NetCtx.fromKey(key); assertNotNull("NetContext not passed", ctx); assertNotNull("Output not passed", ctx.getOutput()); if (!replies.isEmpty()) { HttpMessage msg = replies.pollFirst(); HttpMessageHandler mh = new HttpMessageHandler(config,null); mh.submit(key, msg); } }
@Override public RingHandler request(SelectionKey key, String httpVersion, HttpMethod method, String uri, String query) { NetCtx ctx = NetCtx.fromKey(key); request = PersistentArrayMap.EMPTY.asTransient() .assoc(SERVER_PORT, ctx.getServerPort()) .assoc(SERVER_NAME, ctx.getServerName()) .assoc(REMOTE_ADDR, ctx.getRemoteAddr()) .assoc(PROTOCOL, httpVersion) .assoc(URI, uri) .assoc(QUERY_STRING, query) .assoc(REQUEST_METHOD, getMethod(method)) .assoc(SCHEME, ctx.getTlsContext() != null ? HTTPS : HTTP); headers = PersistentArrayMap.EMPTY.asTransient(); // TODO SSL_CLIENT_CERT return this; }