@Test
  public void iternext() {
    Iternext dut = new Iternext(transcoder, transcoder);

    ChannelBuffer request = ChannelBuffers.buffer(2);
    request.writeBytes(new byte[] {(byte) 0xC8, (byte) 0x51});
    ChannelBuffer actual = ChannelBuffers.buffer(request.capacity());
    dut.encode(actual);
    assertEquals(request, actual);

    ChannelBuffer response = ChannelBuffers.buffer(1 + 4 + value.length);
    assertFalse(dut.decode(response));

    response.writeByte(BinaryCommand.ESUCCESS);
    assertFalse(dut.decode(response));
    response.resetReaderIndex();

    response.writeInt(value.length);
    response.writeBytes(value);
    assertTrue(dut.decode(response));
    assertArrayEquals(value, (byte[]) dut.getReturnValue());

    // error
    response.clear();
    response.writeByte(BinaryCommand.EUNKNOWN);
    assertTrue(dut.decode(response));
    assertNull(dut.getReturnValue());
  }
  @Test
  public void setmst() {
    String host = "host";
    int port = 1978;
    long timestamp = System.currentTimeMillis();
    int opts = RDB.ROCHKCON;
    Setmst dut = new Setmst(host, port, timestamp, opts);

    ChannelBuffer request = ChannelBuffers.buffer(2 + 4 + 4 + 8 + 4 + host.getBytes().length);
    request.writeBytes(new byte[] {(byte) 0xC8, (byte) 0x78});
    request.writeInt(host.getBytes().length);
    request.writeInt(port);
    request.writeLong(timestamp);
    request.writeInt(opts);
    request.writeBytes(host.getBytes());
    ChannelBuffer actual = ChannelBuffers.buffer(request.capacity());
    dut.encode(actual);
    assertEquals(request, actual);

    ChannelBuffer response = ChannelBuffers.buffer(1);
    assertFalse(dut.decode(response));

    response.writeByte(Command.ESUCCESS);
    assertTrue(dut.decode(response));
    assertTrue(dut.getReturnValue());

    // error
    response.clear();
    response.writeByte(Command.EUNKNOWN);
    assertTrue(dut.decode(response));
    assertFalse(dut.getReturnValue());
  }
  /**
   * 自动缩小超长的帧数据缓存
   *
   * @param ctx
   * @return
   */
  protected void shrinkCumulation(ChannelHandlerContext ctx) {
    ChannelBuffer c = cumulation;
    if (this.cumulation != null) {
      if (cumulation.readableBytes() < this.minShrinkCapacity
          && cumulation.capacity() > this.minShrinkCapacity) {
        c =
            ChannelBuffers.dynamicBuffer(
                this.minShrinkCapacity, ctx.getChannel().getConfig().getBufferFactory());
        c.writeBytes(cumulation);

        this.cumulation = c;
      }
    }
  }
 public void handleJsRequest(String path, HttpRequest req, HttpResponse resp) {
   if (req.containsHeader(IF_NONE_MATCH) || req.containsHeader(IF_MODIFIED_SINCE)) {
     resp.setStatus(HttpResponseStatus.NOT_MODIFIED);
     return;
   }
   String jsName = path.substring(1);
   ChannelBuffer buf = jsBufferMap.get(jsName);
   if (buf == null) {
     tryReloadJs();
     if (jsName == null) {
       log.error("需要访问的JS名称为空。[req: " + req.getUri() + "]");
     }
     buf = jsBufferMap.get(jsName);
   }
   if (buf != null) {
     resp.setContent(buf);
     resp.setHeader(CONTENT_LENGTH, buf.capacity());
     resp.setHeader(CONTENT_TYPE, "text/javascript; charset=UTF-8");
     resp.setHeader(CONTENT_ENCODING, "gzip");
     //			resp.setHeader(EXPIRES,  System.currentTimeMillis() + expired);
     StringBuilder etagBuilder =
         new StringBuilder("W/\"")
             .append(buf.capacity())
             .append("-")
             .append(System.currentTimeMillis())
             .append("\"");
     resp.setHeader(ETAG, etagBuilder.toString());
     LogRequestParser lrp = logRequestParserThreadLocal.get();
     if (lrp == null) {
       lrp = new LogRequestParser();
     }
     lrp.cdate.setTime(System.currentTimeMillis() + expired);
     resp.setHeader(EXPIRES, lrp.sdf.format(lrp.cdate));
   } else {
     resp.setStatus(HttpResponseStatus.NOT_FOUND);
   }
 }
 /**
  * From the current context (currentBuffer and currentData), returns the next HttpChunk (if
  * possible) trying to get sizeleft bytes more into the currentBuffer. This is the Multipart
  * version.
  *
  * @param sizeleft the number of bytes to try to get from currentData
  * @return the next HttpChunk or null if not enough bytes were found
  * @throws ErrorDataEncoderException if the encoding is in error
  */
 private HttpChunk encodeNextChunkMultipart(int sizeleft) throws ErrorDataEncoderException {
   if (currentData == null) {
     return null;
   }
   ChannelBuffer buffer;
   if (currentData instanceof InternalAttribute) {
     String internal = ((InternalAttribute) currentData).toString();
     byte[] bytes;
     try {
       bytes = internal.getBytes("ASCII");
     } catch (UnsupportedEncodingException e) {
       throw new ErrorDataEncoderException(e);
     }
     buffer = ChannelBuffers.wrappedBuffer(bytes);
     currentData = null;
   } else {
     if (currentData instanceof Attribute) {
       try {
         buffer = ((Attribute) currentData).getChunk(sizeleft);
       } catch (IOException e) {
         throw new ErrorDataEncoderException(e);
       }
     } else {
       try {
         buffer = ((FileUpload) currentData).getChunk(sizeleft);
       } catch (IOException e) {
         throw new ErrorDataEncoderException(e);
       }
     }
     if (buffer.capacity() == 0) {
       // end for current InterfaceHttpData, need more data
       currentData = null;
       return null;
     }
   }
   if (currentBuffer == null) {
     currentBuffer = buffer;
   } else {
     currentBuffer = ChannelBuffers.wrappedBuffer(currentBuffer, buffer);
   }
   if (currentBuffer.readableBytes() < HttpPostBodyUtil.chunkSize) {
     currentData = null;
     return null;
   }
   buffer = fillChannelBuffer();
   return new DefaultHttpChunk(buffer);
 }
Beispiel #6
0
  /**
   * Decodes bytes from a channel buffer
   *
   * @param ctx a channel handler context
   * @param channel a channel
   * @param msg a message
   * @return a byte array
   */
  @Override
  protected Object decode(ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception {
    if (!(msg instanceof ChannelBuffer)) {
      return msg;
    }
    ChannelBuffer buf = (ChannelBuffer) msg;
    byte[] array;
    if (buf.hasArray()) {
      if (buf.arrayOffset() == 0 && buf.readableBytes() == buf.capacity()) {
        array = buf.array();
      } else {
        array = new byte[buf.readableBytes()];
        buf.getBytes(0, array);
      }
    } else {
      array = new byte[buf.readableBytes()];
      buf.getBytes(0, array);
    }

    return array;
  }
Beispiel #7
0
  @SuppressWarnings("unchecked")
  @Override
  protected Object encode(ChannelHandlerContext ctx, Channel c, Object msg) throws Exception {
    if (msg instanceof Message) {
      Message message = (Message) msg;

      Class<? extends Message> clazz = message.getClass();
      MessageCodec<Message> codec = (MessageCodec<Message>) CodecLookupService.find(clazz);
      if (codec == null) {
        throw new IOException("Unknown message type: " + clazz + ".");
      }

      ChannelBuffer opcodeBuf = ChannelBuffers.buffer(3);
      opcodeBuf.writeByte(codec.getOpcode());

      ChannelBuffer codecBuf = codec.encode(message);
      opcodeBuf.writeInt(codecBuf.capacity());

      return ChannelBuffers.wrappedBuffer(opcodeBuf, codecBuf);
    }
    return msg;
  }
  @Test
  public void protocol() {
    double num = 4;
    Adddouble dut = new Adddouble(transcoder, transcoder, key, num);

    ChannelBuffer request = ChannelBuffers.buffer(2 + 4 + 8 + 8 + key.length);
    request.writeBytes(new byte[] {(byte) 0xC8, (byte) 0x61});
    request.writeInt(key.length);
    request.writeLong(dut._integ(num));
    request.writeLong(dut._fract(num));
    request.writeBytes(key);
    ChannelBuffer actual = ChannelBuffers.buffer(request.capacity());
    dut.encode(actual);
    assertEquals(request, actual);

    ChannelBuffer response = ChannelBuffers.buffer(1 + 8 + 8);
    assertFalse(dut.decode(response));

    response.writeByte(Command.ESUCCESS);
    assertFalse(dut.decode(response));
    response.resetReaderIndex();

    response.writeLong(dut._integ(3.0 + num));
    assertFalse(dut.decode(response));
    response.resetReaderIndex();

    response.writeLong(dut._fract(3.0 + num));
    assertTrue(dut.decode(response));
    assertEquals(3.0 + num, (double) dut.getReturnValue(), 0.0);

    // error
    response.clear();
    response.writeByte(Command.EUNKNOWN);
    assertTrue(dut.decode(response));
    assertEquals(Double.NaN, (double) dut.getReturnValue(), 0.0);
  }
Beispiel #9
0
  private ChannelBuffer unwrap(
      ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer, int offset, int length)
      throws SSLException {
    ByteBuffer inNetBuf = buffer.toByteBuffer(offset, length);
    ByteBuffer outAppBuf = bufferPool.acquire();

    try {
      boolean needsWrap = false;
      loop:
      for (; ; ) {
        SSLEngineResult result;
        synchronized (handshakeLock) {
          if (!handshaken
              && !handshaking
              && !engine.getUseClientMode()
              && !engine.isInboundDone()
              && !engine.isOutboundDone()) {
            handshake();
          }

          try {
            result = engine.unwrap(inNetBuf, outAppBuf);
          } catch (SSLException e) {
            throw e;
          }

          final HandshakeStatus handshakeStatus = result.getHandshakeStatus();
          handleRenegotiation(handshakeStatus);
          switch (handshakeStatus) {
            case NEED_UNWRAP:
              if (inNetBuf.hasRemaining() && !engine.isInboundDone()) {
                break;
              } else {
                break loop;
              }
            case NEED_WRAP:
              wrapNonAppData(ctx, channel);
              break;
            case NEED_TASK:
              runDelegatedTasks();
              break;
            case FINISHED:
              setHandshakeSuccess(channel);
              needsWrap = true;
              break loop;
            case NOT_HANDSHAKING:
              needsWrap = true;
              break loop;
            default:
              throw new IllegalStateException("Unknown handshake status: " + handshakeStatus);
          }
        }
      }

      if (needsWrap) {
        // wrap() acquires pendingUnencryptedWrites first and then
        // handshakeLock.  If handshakeLock is already hold by the
        // current thread, calling wrap() will lead to a dead lock
        // i.e. pendingUnencryptedWrites -> handshakeLock vs.
        //      handshakeLock -> pendingUnencryptedLock -> handshakeLock
        //
        // There is also a same issue between pendingEncryptedWrites
        // and pendingUnencryptedWrites.
        if (!Thread.holdsLock(handshakeLock)
            && !pendingEncryptedWritesLock.isHeldByCurrentThread()) {
          wrap(ctx, channel);
        }
      }

      outAppBuf.flip();

      if (outAppBuf.hasRemaining()) {
        ChannelBuffer frame = ChannelBuffers.buffer(outAppBuf.remaining());
        frame.writeBytes(outAppBuf.array(), 0, frame.capacity());
        return frame;
      } else {
        return null;
      }
    } catch (SSLException e) {
      setHandshakeFailure(channel, e);
      throw e;
    } finally {
      bufferPool.release(outAppBuf);
    }
  }
Beispiel #10
0
  private ChannelFuture wrapNonAppData(ChannelHandlerContext ctx, Channel channel)
      throws SSLException {
    ChannelFuture future = null;
    ByteBuffer outNetBuf = bufferPool.acquire();

    SSLEngineResult result;
    try {
      for (; ; ) {
        synchronized (handshakeLock) {
          result = engine.wrap(EMPTY_BUFFER, outNetBuf);
        }

        if (result.bytesProduced() > 0) {
          outNetBuf.flip();
          ChannelBuffer msg = ChannelBuffers.buffer(outNetBuf.remaining());
          msg.writeBytes(outNetBuf.array(), 0, msg.capacity());
          outNetBuf.clear();

          future = future(channel);
          future.addListener(
              new ChannelFutureListener() {
                public void operationComplete(ChannelFuture future) throws Exception {
                  if (future.getCause() instanceof ClosedChannelException) {
                    synchronized (ignoreClosedChannelExceptionLock) {
                      ignoreClosedChannelException++;
                    }
                  }
                }
              });

          write(ctx, future, msg);
        }

        final HandshakeStatus handshakeStatus = result.getHandshakeStatus();
        handleRenegotiation(handshakeStatus);
        switch (handshakeStatus) {
          case FINISHED:
            setHandshakeSuccess(channel);
            runDelegatedTasks();
            break;
          case NEED_TASK:
            runDelegatedTasks();
            break;
          case NEED_UNWRAP:
            if (!Thread.holdsLock(handshakeLock)) {
              // unwrap shouldn't be called when this method was
              // called by unwrap - unwrap will keep running after
              // this method returns.
              unwrap(ctx, channel, ChannelBuffers.EMPTY_BUFFER, 0, 0);
            }
            break;
          case NOT_HANDSHAKING:
          case NEED_WRAP:
            break;
          default:
            throw new IllegalStateException("Unexpected handshake status: " + handshakeStatus);
        }

        if (result.bytesProduced() == 0) {
          break;
        }
      }
    } catch (SSLException e) {
      setHandshakeFailure(channel, e);
      throw e;
    } finally {
      bufferPool.release(outNetBuf);
    }

    if (future == null) {
      future = succeededFuture(channel);
    }

    return future;
  }
Beispiel #11
0
  private ChannelFuture wrap(ChannelHandlerContext context, Channel channel) throws SSLException {

    ChannelFuture future = null;
    ChannelBuffer msg;
    ByteBuffer outNetBuf = bufferPool.acquire();
    boolean success = true;
    boolean offered = false;
    boolean needsUnwrap = false;
    try {
      loop:
      for (; ; ) {
        // Acquire a lock to make sure unencrypted data is polled
        // in order and their encrypted counterpart is offered in
        // order.
        synchronized (pendingUnencryptedWrites) {
          PendingWrite pendingWrite = pendingUnencryptedWrites.peek();
          if (pendingWrite == null) {
            break;
          }

          ByteBuffer outAppBuf = pendingWrite.outAppBuf;
          if (outAppBuf == null) {
            // A write request with an empty buffer
            pendingUnencryptedWrites.remove();
            offerEncryptedWriteRequest(
                new DownstreamMessageEvent(
                    channel,
                    pendingWrite.future,
                    ChannelBuffers.EMPTY_BUFFER,
                    channel.getRemoteAddress()));
            offered = true;
          } else {
            SSLEngineResult result = null;
            try {
              synchronized (handshakeLock) {
                result = engine.wrap(outAppBuf, outNetBuf);
              }
            } finally {
              if (!outAppBuf.hasRemaining()) {
                pendingUnencryptedWrites.remove();
              }
            }

            if (result.bytesProduced() > 0) {
              outNetBuf.flip();
              msg = ChannelBuffers.buffer(outNetBuf.remaining());
              msg.writeBytes(outNetBuf.array(), 0, msg.capacity());
              outNetBuf.clear();

              if (pendingWrite.outAppBuf.hasRemaining()) {
                // pendingWrite's future shouldn't be notified if
                // only partial data is written.
                future = succeededFuture(channel);
              } else {
                future = pendingWrite.future;
              }

              MessageEvent encryptedWrite =
                  new DownstreamMessageEvent(channel, future, msg, channel.getRemoteAddress());
              offerEncryptedWriteRequest(encryptedWrite);
              offered = true;
            } else {
              final HandshakeStatus handshakeStatus = result.getHandshakeStatus();
              handleRenegotiation(handshakeStatus);
              switch (handshakeStatus) {
                case NEED_WRAP:
                  if (outAppBuf.hasRemaining()) {
                    break;
                  } else {
                    break loop;
                  }
                case NEED_UNWRAP:
                  needsUnwrap = true;
                  break loop;
                case NEED_TASK:
                  runDelegatedTasks();
                  break;
                case FINISHED:
                case NOT_HANDSHAKING:
                  if (handshakeStatus == HandshakeStatus.FINISHED) {
                    setHandshakeSuccess(channel);
                  }
                  if (result.getStatus() == Status.CLOSED) {
                    success = false;
                  }
                  break loop;
                default:
                  throw new IllegalStateException("Unknown handshake status: " + handshakeStatus);
              }
            }
          }
        }
      }
    } catch (SSLException e) {
      success = false;
      setHandshakeFailure(channel, e);
      throw e;
    } finally {
      bufferPool.release(outNetBuf);

      if (offered) {
        flushPendingEncryptedWrites(context);
      }

      if (!success) {
        IllegalStateException cause = new IllegalStateException("SSLEngine already closed");
        // Mark all remaining pending writes as failure if anything
        // wrong happened before the write requests are wrapped.
        // Please note that we do not call setFailure while a lock is
        // acquired, to avoid a potential dead lock.
        for (; ; ) {
          PendingWrite pendingWrite;
          synchronized (pendingUnencryptedWrites) {
            pendingWrite = pendingUnencryptedWrites.poll();
            if (pendingWrite == null) {
              break;
            }
          }

          pendingWrite.future.setFailure(cause);
        }
      }
    }

    if (needsUnwrap) {
      unwrap(context, channel, ChannelBuffers.EMPTY_BUFFER, 0, 0);
    }

    if (future == null) {
      future = succeededFuture(channel);
    }
    return future;
  }
  public static void main(String[] args) {
    final int payloadSize = 100;
    int CYCLE_SIZE = 50000;
    final long NUMBER_OF_ITERATIONS = 500000;

    ChannelBuffer message = ChannelBuffers.buffer(100);
    for (int i = 0; i < message.capacity(); i++) {
      message.writeByte((byte) i);
    }

    // Configure the server.
    ServerBootstrap serverBootstrap =
        new ServerBootstrap(
            new NioServerSocketChannelFactory(
                Executors.newCachedThreadPool(), Executors.newCachedThreadPool()));

    // Set up the pipeline factory.
    serverBootstrap.setPipelineFactory(
        new ChannelPipelineFactory() {
          @Override
          public ChannelPipeline getPipeline() throws Exception {
            return Channels.pipeline(new EchoServerHandler());
          }
        });

    // Bind and start to accept incoming connections.
    serverBootstrap.bind(new InetSocketAddress(9000));

    ClientBootstrap clientBootstrap =
        new ClientBootstrap(
            new NioClientSocketChannelFactory(
                Executors.newCachedThreadPool(), Executors.newCachedThreadPool()));

    //        ClientBootstrap clientBootstrap = new ClientBootstrap(
    //                new OioClientSocketChannelFactory(Executors.newCachedThreadPool()));

    // Set up the pipeline factory.
    final EchoClientHandler clientHandler = new EchoClientHandler();
    clientBootstrap.setPipelineFactory(
        new ChannelPipelineFactory() {
          @Override
          public ChannelPipeline getPipeline() throws Exception {
            return Channels.pipeline(clientHandler);
          }
        });

    // Start the connection attempt.
    ChannelFuture future = clientBootstrap.connect(new InetSocketAddress("localhost", 9000));
    future.awaitUninterruptibly();
    Channel clientChannel = future.getChannel();

    System.out.println("Warming up...");
    for (long i = 0; i < 10000; i++) {
      clientHandler.latch = new CountDownLatch(1);
      clientChannel.write(message);
      try {
        clientHandler.latch.await();
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
    System.out.println("Warmed up");

    long start = System.currentTimeMillis();
    long cycleStart = System.currentTimeMillis();
    for (long i = 1; i < NUMBER_OF_ITERATIONS; i++) {
      clientHandler.latch = new CountDownLatch(1);
      clientChannel.write(message);
      try {
        clientHandler.latch.await();
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      if ((i % CYCLE_SIZE) == 0) {
        long cycleEnd = System.currentTimeMillis();
        System.out.println(
            "Ran 50000, TPS " + (CYCLE_SIZE / ((double) (cycleEnd - cycleStart) / 1000)));
        cycleStart = cycleEnd;
      }
    }
    long end = System.currentTimeMillis();
    long seconds = (end - start) / 1000;
    System.out.println(
        "Ran ["
            + NUMBER_OF_ITERATIONS
            + "] iterations, payload ["
            + payloadSize
            + "]: took ["
            + seconds
            + "], TPS: "
            + ((double) NUMBER_OF_ITERATIONS) / seconds);

    clientChannel.close().awaitUninterruptibly();
    clientBootstrap.releaseExternalResources();
    serverBootstrap.releaseExternalResources();
  }
 /**
  * From the current context (currentBuffer and currentData), returns the next HttpChunk (if
  * possible) trying to get sizeleft bytes more into the currentBuffer. This is the UrlEncoded
  * version.
  *
  * @param sizeleft the number of bytes to try to get from currentData
  * @return the next HttpChunk or null if not enough bytes were found
  * @throws ErrorDataEncoderException if the encoding is in error
  */
 private HttpChunk encodeNextChunkUrlEncoded(int sizeleft) throws ErrorDataEncoderException {
   if (currentData == null) {
     return null;
   }
   int size = sizeleft;
   ChannelBuffer buffer;
   if (isKey) {
     // get name
     String key = currentData.getName();
     buffer = ChannelBuffers.wrappedBuffer(key.getBytes());
     isKey = false;
     if (currentBuffer == null) {
       currentBuffer =
           ChannelBuffers.wrappedBuffer(buffer, ChannelBuffers.wrappedBuffer("=".getBytes()));
       // continue
       size -= buffer.readableBytes() + 1;
     } else {
       currentBuffer =
           ChannelBuffers.wrappedBuffer(
               currentBuffer, buffer, ChannelBuffers.wrappedBuffer("=".getBytes()));
       // continue
       size -= buffer.readableBytes() + 1;
     }
     if (currentBuffer.readableBytes() >= HttpPostBodyUtil.chunkSize) {
       buffer = fillChannelBuffer();
       return new DefaultHttpChunk(buffer);
     }
   }
   try {
     buffer = ((Attribute) currentData).getChunk(size);
   } catch (IOException e) {
     throw new ErrorDataEncoderException(e);
   }
   ChannelBuffer delimiter = null;
   if (buffer.readableBytes() < size) {
     // delimiter
     isKey = true;
     delimiter = iterator.hasNext() ? ChannelBuffers.wrappedBuffer("&".getBytes()) : null;
   }
   if (buffer.capacity() == 0) {
     // end for current InterfaceHttpData, need potentially more data
     currentData = null;
     if (currentBuffer == null) {
       currentBuffer = delimiter;
     } else {
       if (delimiter != null) {
         currentBuffer = ChannelBuffers.wrappedBuffer(currentBuffer, delimiter);
       }
     }
     if (currentBuffer.readableBytes() >= HttpPostBodyUtil.chunkSize) {
       buffer = fillChannelBuffer();
       return new DefaultHttpChunk(buffer);
     }
     return null;
   }
   if (currentBuffer == null) {
     if (delimiter != null) {
       currentBuffer = ChannelBuffers.wrappedBuffer(buffer, delimiter);
     } else {
       currentBuffer = buffer;
     }
   } else {
     if (delimiter != null) {
       currentBuffer = ChannelBuffers.wrappedBuffer(currentBuffer, buffer, delimiter);
     } else {
       currentBuffer = ChannelBuffers.wrappedBuffer(currentBuffer, buffer);
     }
   }
   if (currentBuffer.readableBytes() < HttpPostBodyUtil.chunkSize) {
     // end for current InterfaceHttpData, need more data
     currentData = null;
     isKey = true;
     return null;
   }
   buffer = fillChannelBuffer();
   // size = 0
   return new DefaultHttpChunk(buffer);
 }