@Override
  public void messageReceived(final ChannelHandlerContext ctx, final MessageEvent e)
      throws Exception {

    if (!chunked) {
      final HttpRequest request = (HttpRequest) e.getMessage();

      final ChannelBuffer buffer = request.getContent();
      receivedData.write(buffer.array());
      // System.out.println("received "+buffer.array() );
      // System.out.println(buffer.array().length);
      if (!request.isChunked()) {
        processRequest(e);
      } else {
        chunked = true;
      }
      // final boolean keepAlive = isKeepAlive(request);
    } else {
      final HttpChunk chunk = (HttpChunk) e.getMessage();
      final ChannelBuffer buffer = chunk.getContent();
      receivedData.write(buffer.array());
      if (chunk.isLast()) {
        processRequest(e);
      }
    }
  }
  @Override
  protected Object decode(
      final ChannelHandlerContext ctx, final Channel channel, final ChannelBuffer buffer)
      throws Exception {

    while (buffer.readable()) {

      byte c = buffer.readByte();

      // check if last character read was DLE
      if (foundDLE) {
        foundDLE = false;

        if (c == DleStxEtxConstants.STX && !foundPacket) {

          foundPacket = true;

        } else if (c == DleStxEtxConstants.ETX && foundPacket) {

          ChannelBuffer packetRead = packet;
          resetDecodingState();
          return packetRead;

        } else if (c == DleStxEtxConstants.DLE && foundPacket) {

          // Stuffed DLE found
          packet.writeByte(DleStxEtxConstants.DLE);

        } else {

          if (log.isWarnEnabled()) {
            log.warn(
                "Incomplete packet received: {}",
                StringUtils.toHexString(
                    packet.array(), packet.readerIndex(), packet.readableBytes()));
          }
          resetDecodingState();
        }

      } else {

        if (c == DleStxEtxConstants.DLE) {
          // log.trace("Plain DLE received");
          foundDLE = true;
        } else if (foundPacket) {
          packet.writeByte(c);
        }
      }
    }

    // decoding is not yet complete, we'll need more bytes until we find DLE
    // ETX
    return null;
  }
Example #3
0
 /* (non-Javadoc)
  * @see com.e9.framework.channel.i.Message#decode(com.e9.framework.channel.i.IoBuffer)
  */
 @Override
 public void decode(IoBuffer arg0) throws Exception {
   // TODO Auto-generated method stub
   ChannelBuffer buffer = null;
   try {
     buffer = beginDecode(arg0);
     //			buffer.skipBytes(GwLength.STATUS);
   } catch (Exception e) {
     // TODO: handle exception
     throw new Exception(buffer == null ? "" : Common.toHex(buffer.array()), e);
   }
 }
  public static void send(MessageEvent event, Integer transactionId, Long connectionId)
      throws Exception {
    logger.debug("ConnectionResponse::send to " + event.getRemoteAddress());

    ChannelBuffer responseBuffer = ChannelBuffers.buffer(4 + 4 + 8);
    responseBuffer.writeInt(Action.CONNECT.getId());
    responseBuffer.writeInt(transactionId);
    responseBuffer.writeLong(connectionId);

    logger.debug("ConnectionResponse DUMP: " + Utils.getHexString(responseBuffer.array()));

    event.getChannel().write(responseBuffer, event.getRemoteAddress());
  }
Example #5
0
 /**
  * Read a PeerAddress from a Netty buffer. I did not want to include ChannelBuffer in the class
  * PeerAddress
  *
  * @param buffer The Netty buffer
  * @return A PeerAddress created from the buffer (deserialized)
  */
 private static PeerAddress readPeerAddress(final ChannelBuffer buffer) {
   if (buffer.readableBytes() < 21) return null;
   Number160 id = readID(buffer);
   // peek
   int type = buffer.getUnsignedByte(buffer.readerIndex());
   // now we know the length
   int len = PeerAddress.expectedSocketLength(type);
   if (buffer.readableBytes() < len) return null;
   PeerAddress peerAddress =
       new PeerAddress(id, buffer.array(), buffer.arrayOffset() + buffer.readerIndex());
   buffer.skipBytes(len);
   return peerAddress;
 }
Example #6
0
  /*
   * Each ControlMessage is encoded as:
   *  code (<0) ... short(2)
   * Each TaskMessage is encoded as:
   *  task (>=0) ... short(2)
   *  len ... int(4)
   *  payload ... byte[]     *
   */
  protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf)
      throws Exception {
    // Make sure that we have received at least a short
    if (buf.readableBytes() < 2) {
      // need more data
      return null;
    }

    // Mark the current buffer position before reading task/len field
    // because the whole frame might not be in the buffer yet.
    // We will reset the buffer position to the marked position if
    // there's not enough bytes in the buffer.
    buf.markReaderIndex();

    // read the short field
    short code = buf.readShort();

    // case 1: Control message
    ControlMessage ctrl_msg = ControlMessage.mkMessage(code);
    if (ctrl_msg != null) return ctrl_msg;

    // case 2: task Message
    short task = code;

    // Make sure that we have received at least an integer (length)
    if (buf.readableBytes() < 4) {
      // need more data
      buf.resetReaderIndex();
      return null;
    }

    // Read the length field.
    int length = buf.readInt();
    if (length <= 0) {
      return new TaskMessage(task, null);
    }

    // Make sure if there's enough bytes in the buffer.
    if (buf.readableBytes() < length) {
      // The whole bytes were not received yet - return null.
      buf.resetReaderIndex();
      return null;
    }

    // There's enough bytes in the buffer. Read it.
    ChannelBuffer payload = buf.readBytes(length);

    // Successfully decoded a frame.
    // Return a TaskMessage object
    return new TaskMessage(task, payload.array());
  }
Example #7
0
    @Override
    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
      ChannelBuffer buf;
      PaxosMessage msg;

      buf = (ChannelBuffer) e.getMessage();

      // Read in the message string.
      msg = new PaxosMessage();
      msg.unSerialize(buf.array());

      // Send the message upstream to the server handler.
      Channels.fireMessageReceived(ctx, msg);
    }
  public static void send(
      MessageEvent event, Integer transactionId, List<TorrentStats> torrentStatsList)
      throws Exception {
    logger.debug("ScrapeResponse::send to " + event.getRemoteAddress());

    ChannelBuffer responseBuffer = ChannelBuffers.buffer(4 + 4 + torrentStatsList.size() * 12);
    responseBuffer.writeInt(Action.SCRAPE.getId());
    responseBuffer.writeInt(transactionId);

    for (TorrentStats torrentStats : torrentStatsList) {
      responseBuffer.writeInt(torrentStats.seeders);
      responseBuffer.writeInt(torrentStats.completed);
      responseBuffer.writeInt(torrentStats.leechers);
    }

    logger.debug("ScrapeResponse DUMP: " + Utils.getHexString(responseBuffer.array()));

    event.getChannel().write(responseBuffer, event.getRemoteAddress());
  }
Example #9
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;
  }
  @Override
  public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {

    ResultCode success;
    ChannelBuffer buf = (ChannelBuffer) e.getMessage();
    TMemoryInputTransport trans = new TMemoryInputTransport(buf.array());
    TBinaryProtocol proto = new TBinaryProtocol(trans);
    TMessage msg = proto.readMessageBegin();
    if (msg.type == TMessageType.EXCEPTION) {
      proto.readMessageEnd();
    }
    TField field;
    proto.readStructBegin();
    while (true) {
      field = proto.readFieldBegin();
      if (field.type == TType.STOP) {
        break;
      }
      switch (field.id) {
        case 0: // SUCCESS
          if (field.type == TType.I32) {
            success = ResultCode.findByValue(proto.readI32());
            stats.accumulateOutcomeWithDelta(
                success.getValue() == 0 ? Outcome.SUCCESS : Outcome.GRACEFUL_FAILURE, 0);
          } else {
            TProtocolUtil.skip(proto, field.type);
          }
          break;
        default:
          TProtocolUtil.skip(proto, field.type);
      }
      proto.readFieldEnd();
    }
    proto.readStructEnd();
    proto.readMessageEnd();
  }
Example #11
0
  private void handleHttpRequest(ChannelHandlerContext ctx, HttpRequest req) throws Exception {
    // Allow only GET methods.
    if (req.getMethod() != GET) {
      sendHttpResponse(ctx, req, new DefaultHttpResponse(HTTP_1_1, FORBIDDEN));
      return;
    }

    // Send the demo page.
    if (req.getUri().equals("/")) {
      HttpResponse res = new DefaultHttpResponse(HTTP_1_1, OK);

      ChannelBuffer content = WebSocketServerIndexPage.getContent(getWebSocketLocation(req));

      res.setHeader(CONTENT_TYPE, "text/html; charset=UTF-8");
      setContentLength(res, content.readableBytes());

      res.setContent(content);
      sendHttpResponse(ctx, req, res);
      return;
    }

    // Serve the WebSocket handshake request.
    if (req.getUri().equals(WEBSOCKET_PATH)
        && Values.UPGRADE.equalsIgnoreCase(req.getHeader(CONNECTION))
        && WEBSOCKET.equalsIgnoreCase(req.getHeader(Names.UPGRADE))) {

      // Create the WebSocket handshake response.
      HttpResponse res =
          new DefaultHttpResponse(
              HTTP_1_1, new HttpResponseStatus(101, "Web Socket Protocol Handshake"));
      res.addHeader(Names.UPGRADE, WEBSOCKET);
      res.addHeader(CONNECTION, Values.UPGRADE);

      // Fill in the headers and contents depending on handshake method.
      if (req.containsHeader(SEC_WEBSOCKET_KEY1) && req.containsHeader(SEC_WEBSOCKET_KEY2)) {
        // New handshake method with a challenge:
        res.addHeader(SEC_WEBSOCKET_ORIGIN, req.getHeader(ORIGIN));
        res.addHeader(SEC_WEBSOCKET_LOCATION, getWebSocketLocation(req));
        String protocol = req.getHeader(SEC_WEBSOCKET_PROTOCOL);
        if (protocol != null) {
          res.addHeader(SEC_WEBSOCKET_PROTOCOL, protocol);
        }

        // Calculate the answer of the challenge.
        String key1 = req.getHeader(SEC_WEBSOCKET_KEY1);
        String key2 = req.getHeader(SEC_WEBSOCKET_KEY2);
        int a =
            (int)
                (Long.parseLong(key1.replaceAll("[^0-9]", ""))
                    / key1.replaceAll("[^ ]", "").length());
        int b =
            (int)
                (Long.parseLong(key2.replaceAll("[^0-9]", ""))
                    / key2.replaceAll("[^ ]", "").length());
        long c = req.getContent().readLong();
        ChannelBuffer input = ChannelBuffers.buffer(16);
        input.writeInt(a);
        input.writeInt(b);
        input.writeLong(c);
        ChannelBuffer output =
            ChannelBuffers.wrappedBuffer(MessageDigest.getInstance("MD5").digest(input.array()));
        res.setContent(output);
      } else {
        // Old handshake method with no challenge:
        res.addHeader(WEBSOCKET_ORIGIN, req.getHeader(ORIGIN));
        res.addHeader(WEBSOCKET_LOCATION, getWebSocketLocation(req));
        String protocol = req.getHeader(WEBSOCKET_PROTOCOL);
        if (protocol != null) {
          res.addHeader(WEBSOCKET_PROTOCOL, protocol);
        }
      }

      // Upgrade the connection and send the handshake response.
      ChannelPipeline p = ctx.getChannel().getPipeline();
      p.remove("aggregator");
      p.replace("decoder", "wsdecoder", new WebSocketFrameDecoder());

      ctx.getChannel().write(res);

      p.replace("encoder", "wsencoder", new WebSocketFrameEncoder());
      return;
    }

    // Send an error page otherwise.
    sendHttpResponse(ctx, req, new DefaultHttpResponse(HTTP_1_1, FORBIDDEN));
  }
Example #12
0
 @Override
 public byte[] array() {
   return buffer.array();
 }
Example #13
0
  private void websocketHandshake(final ChannelHandlerContext ctx, HttpRequest req, MessageEvent e)
      throws Exception {

    // Create the WebSocket handshake response.
    HttpResponse res =
        new DefaultHttpResponse(
            HttpVersion.HTTP_1_1, new HttpResponseStatus(101, "Web Socket Protocol Handshake"));
    res.addHeader(HttpHeaders.Names.UPGRADE, HttpHeaders.Values.WEBSOCKET);
    res.addHeader(CONNECTION, HttpHeaders.Values.UPGRADE);

    // Fill in the headers and contents depending on handshake method.
    if (req.containsHeader(SEC_WEBSOCKET_KEY1) && req.containsHeader(SEC_WEBSOCKET_KEY2)) {
      // New handshake method with a challenge:
      res.addHeader(SEC_WEBSOCKET_ORIGIN, req.getHeader(ORIGIN));
      res.addHeader(
          SEC_WEBSOCKET_LOCATION, "ws://" + req.getHeader(HttpHeaders.Names.HOST) + req.getUri());
      String protocol = req.getHeader(SEC_WEBSOCKET_PROTOCOL);
      if (protocol != null) {
        res.addHeader(SEC_WEBSOCKET_PROTOCOL, protocol);
      }

      // Calculate the answer of the challenge.
      String key1 = req.getHeader(SEC_WEBSOCKET_KEY1);
      String key2 = req.getHeader(SEC_WEBSOCKET_KEY2);
      int a =
          (int)
              (Long.parseLong(key1.replaceAll("[^0-9]", ""))
                  / key1.replaceAll("[^ ]", "").length());
      int b =
          (int)
              (Long.parseLong(key2.replaceAll("[^0-9]", ""))
                  / key2.replaceAll("[^ ]", "").length());
      long c = req.getContent().readLong();
      ChannelBuffer input = ChannelBuffers.buffer(16);
      input.writeInt(a);
      input.writeInt(b);
      input.writeLong(c);
      try {
        ChannelBuffer output =
            ChannelBuffers.wrappedBuffer(MessageDigest.getInstance("MD5").digest(input.array()));
        res.setContent(output);
      } catch (NoSuchAlgorithmException ex) {
        throw new UnexpectedException(ex);
      }
    } else {
      // Old handshake method with no challenge:
      res.addHeader(WEBSOCKET_ORIGIN, req.getHeader(ORIGIN));
      res.addHeader(
          WEBSOCKET_LOCATION, "ws://" + req.getHeader(HttpHeaders.Names.HOST) + req.getUri());
      String protocol = req.getHeader(WEBSOCKET_PROTOCOL);
      if (protocol != null) {
        res.addHeader(WEBSOCKET_PROTOCOL, protocol);
      }
    }

    // Keep the original request
    Http.Request request = parseRequest(ctx, req);

    // Route the websocket request
    request.method = "WS";
    Map<String, String> route = Router.route(request.method, request.path);
    if (!route.containsKey("action")) {
      // No route found to handle this websocket connection
      ctx.getChannel()
          .write(new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.NOT_FOUND));
      return;
    }

    // Upgrade the connection and send the handshake response.
    ChannelPipeline p = ctx.getChannel().getPipeline();
    p.remove("aggregator");
    p.replace("decoder", "wsdecoder", new WebSocketFrameDecoder());

    // Connect
    ctx.getChannel().write(res);

    p.replace("encoder", "wsencoder", new WebSocketFrameEncoder());
    req.setMethod(new HttpMethod("WEBSOCKET"));

    // Inbound
    Http.Inbound inbound =
        new Http.Inbound() {

          @Override
          public boolean isOpen() {
            return ctx.getChannel().isOpen();
          }
        };
    channels.put(ctx, inbound);

    // Outbound
    Http.Outbound outbound =
        new Http.Outbound() {

          final List<ChannelFuture> writeFutures =
              Collections.synchronizedList(new ArrayList<ChannelFuture>());
          Promise<Void> closeTask;

          synchronized void writeAndClose(ChannelFuture writeFuture) {
            if (!writeFuture.isDone()) {
              writeFutures.add(writeFuture);
              writeFuture.addListener(
                  new ChannelFutureListener() {

                    public void operationComplete(ChannelFuture cf) throws Exception {
                      writeFutures.remove(cf);
                      futureClose();
                    }
                  });
            }
          }

          void futureClose() {
            if (closeTask != null && writeFutures.isEmpty()) {
              closeTask.invoke(null);
            }
          }

          @Override
          public void send(String data) {
            if (!isOpen()) {
              throw new IllegalStateException("The outbound channel is closed");
            }
            writeAndClose(ctx.getChannel().write(new DefaultWebSocketFrame(data)));
          }

          @Override
          public void send(byte opcode, byte[] data, int offset, int length) {
            if (!isOpen()) {
              throw new IllegalStateException("The outbound channel is closed");
            }
            writeAndClose(
                ctx.getChannel()
                    .write(new DefaultWebSocketFrame(opcode, wrappedBuffer(data, offset, length))));
          }

          @Override
          public synchronized boolean isOpen() {
            return ctx.getChannel().isOpen() && closeTask == null;
          }

          @Override
          public synchronized void close() {
            closeTask = new Promise<Void>();
            closeTask.onRedeem(
                new Action<Promise<Void>>() {

                  public void invoke(Promise<Void> completed) {
                    writeFutures.clear();
                    ctx.getChannel().disconnect();
                    closeTask = null;
                  }
                });
            futureClose();
          }
        };

    Invoker.invoke(new WebSocketInvocation(route, request, inbound, outbound, ctx, e));
  }
Example #14
0
  /*
   * Each ControlMessage is encoded as: code (<0) ... short(2) Each
   * TaskMessage is encoded as: task (>=0) ... short(2) len ... int(4) payload
   * ... byte[] *
   */
  protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf)
      throws Exception {
    // Make sure that we have received at least a short
    long available = buf.readableBytes();
    // Length of control message is 10.
    // Minimum length of a task message is 6(short taskId, int length).
    if (available < 10) {
      // need more data
      return null;
    }

    Long startTime = null;
    if (isServer) {
      startTime = System.nanoTime();
    }
    try {
      // Mark the current buffer position before reading task/len field
      // because the whole frame might not be in the buffer yet.
      // We will reset the buffer position to the marked position if
      // there's not enough bytes in the buffer.
      buf.markReaderIndex();

      // read the short field
      short code = buf.readShort();
      available -= 2;

      // case 1: Control message
      ControlMessage ctrl_msg = ControlMessage.mkMessage(code);
      if (ctrl_msg != null) {
        if (available < 12) {
          // The time stamp bytes were not received yet - return null.
          buf.resetReaderIndex();
          return null;
        }
        long timeStamp = buf.readLong();
        int clientPort = buf.readInt();
        available -= 12;
        if (ctrl_msg == ControlMessage.EOB_MESSAGE) {

          long interval = System.currentTimeMillis() - timeStamp;
          if (interval > 0) {

            Histogram netTransTime = getTransmitHistogram(channel, clientPort);
            if (netTransTime != null) {
              netTransTime.update(interval);
            }
          }

          recvSpeed.update(Double.valueOf(ControlMessage.encodeLength()));
        }

        return ctrl_msg;
      }

      // case 2: task Message
      short task = code;

      // Make sure that we have received at least an integer (length)
      if (available < 8) {
        // need more data
        buf.resetReaderIndex();

        return null;
      }

      // Read the length field.
      int length = buf.readInt();
      if (length <= 0) {
        LOG.info("Receive one message whose TaskMessage's message length is {}", length);
        return new TaskMessage(task, null);
      }
      int headerLength = buf.readInt();
      if (headerLength <= 0) {
        LOG.info("Receive one message whose TaskMessage's message header length is {}", length);
      }
      // Make sure if there's enough bytes in the buffer.
      available -= 8;
      if (available < length + headerLength) {
        // The whole bytes were not received yet - return null.
        buf.resetReaderIndex();

        return null;
      }

      String component = null;
      String stream = null;
      if (headerLength > 0) {
        ChannelBuffer header = buf.readBytes(headerLength);
        String headerValue = new String(header.array());
        String splits[] = headerValue.split(" ");
        stream = splits[0];
        component = splits[1];
      }

      // There's enough bytes in the buffer. Read it.
      ChannelBuffer payload = buf.readBytes(length);

      // Successfully decoded a frame.
      // Return a TaskMessage object

      byte[] rawBytes = payload.array();
      // @@@ TESTING CODE
      // LOG.info("Receive task:{}, length: {}, data:{}",
      // task, length, JStormUtils.toPrintableString(rawBytes));

      TaskMessage ret = new TaskMessage(task, rawBytes, component, stream);
      recvSpeed.update(Double.valueOf(rawBytes.length + 6));
      return ret;
    } finally {
      if (isServer) {
        Long endTime = System.nanoTime();
        timer.update((endTime - startTime) / 1000000.0d);
      }
    }
  }