private void readPingFrame(
     ChannelHandlerContext ctx, ByteBuf payload, Http2FrameObserver observer)
     throws Http2Exception {
   ByteBuf data = payload.readSlice(payload.readableBytes());
   if (flags.ack()) {
     observer.onPingAckRead(ctx, data);
   } else {
     observer.onPingRead(ctx, data);
   }
 }
 private void readSettingsFrame(
     ChannelHandlerContext ctx, ByteBuf payload, Http2FrameObserver observer)
     throws Http2Exception {
   if (flags.ack()) {
     observer.onSettingsAckRead(ctx);
   } else {
     int numSettings = payloadLength / SETTING_ENTRY_LENGTH;
     Http2Settings settings = new Http2Settings();
     for (int index = 0; index < numSettings; ++index) {
       short id = payload.readUnsignedByte();
       long value = payload.readUnsignedInt();
       switch (id) {
         case SETTINGS_HEADER_TABLE_SIZE:
           if (value < 0 || value > Integer.MAX_VALUE) {
             throw protocolError("Invalid value for HEADER_TABLE_SIZE: %d", value);
           }
           settings.maxHeaderTableSize((int) value);
           break;
         case SETTINGS_COMPRESS_DATA:
           if (value != 0 && value != 1) {
             throw protocolError("Invalid value for COMPRESS_DATA: %d", value);
           }
           settings.allowCompressedData(value == 1);
           break;
         case SETTINGS_ENABLE_PUSH:
           if (value != 0 && value != 1) {
             throw protocolError("Invalid value for ENABLE_PUSH: %d", value);
           }
           settings.pushEnabled(value == 1);
           break;
         case SETTINGS_INITIAL_WINDOW_SIZE:
           if (value < 0 || value > Integer.MAX_VALUE) {
             throw protocolError("Invalid value for INITIAL_WINDOW_SIZE: %d", value);
           }
           settings.initialWindowSize((int) value);
           break;
         case SETTINGS_MAX_CONCURRENT_STREAMS:
           if (value < 0 || value > Integer.MAX_VALUE) {
             throw protocolError("Invalid value for MAX_CONCURRENT_STREAMS: %d", value);
           }
           settings.maxConcurrentStreams((int) value);
           break;
         default:
           throw protocolError("Unsupport setting: %d", id);
       }
     }
     observer.onSettingsRead(ctx, settings);
   }
 }
 private static void readGoAwayFrame(
     ChannelHandlerContext ctx, ByteBuf payload, Http2FrameObserver observer)
     throws Http2Exception {
   int lastStreamId = readUnsignedInt(payload);
   long errorCode = payload.readUnsignedInt();
   ByteBuf debugData = payload.readSlice(payload.readableBytes());
   observer.onGoAwayRead(ctx, lastStreamId, errorCode, debugData);
 }
 private void readPriorityFrame(
     ChannelHandlerContext ctx, ByteBuf payload, Http2FrameObserver observer)
     throws Http2Exception {
   long word1 = payload.readUnsignedInt();
   boolean exclusive = (word1 & 0x80000000L) > 0;
   int streamDependency = (int) (word1 & 0x7FFFFFFFL);
   short weight = (short) (payload.readUnsignedByte() + 1);
   observer.onPriorityRead(ctx, streamId, streamDependency, weight, exclusive);
 }
  private void processPayloadState(
      ChannelHandlerContext ctx, ByteBuf in, Http2FrameObserver observer) throws Http2Exception {
    if (in.readableBytes() < payloadLength) {
      // Wait until the entire payload has been read.
      return;
    }

    // Get a view of the buffer for the size of the payload.
    ByteBuf payload = in.readSlice(payloadLength);

    // Read the payload and fire the frame event to the observer.
    switch (frameType) {
      case DATA:
        readDataFrame(ctx, payload, observer);
        break;
      case HEADERS:
        readHeadersFrame(ctx, payload, observer);
        break;
      case PRIORITY:
        readPriorityFrame(ctx, payload, observer);
        break;
      case RST_STREAM:
        readRstStreamFrame(ctx, payload, observer);
        break;
      case SETTINGS:
        readSettingsFrame(ctx, payload, observer);
        break;
      case PUSH_PROMISE:
        readPushPromiseFrame(ctx, payload, observer);
        break;
      case PING:
        readPingFrame(ctx, payload, observer);
        break;
      case GO_AWAY:
        readGoAwayFrame(ctx, payload, observer);
        break;
      case WINDOW_UPDATE:
        readWindowUpdateFrame(ctx, payload, observer);
        break;
      case CONTINUATION:
        readContinuationFrame(payload, observer);
        break;
      case ALT_SVC:
        readAltSvcFrame(ctx, payload, observer);
        break;
      case BLOCKED:
        observer.onBlockedRead(ctx, streamId);
        break;
      default:
        // Should never happen.
        throw protocolError("Unsupported frame type: %s", frameType);
    }

    // Go back to reading the next frame header.
    state = State.FRAME_HEADER;
  }
 private void readAltSvcFrame(
     ChannelHandlerContext ctx, ByteBuf payload, Http2FrameObserver observer)
     throws Http2Exception {
   long maxAge = payload.readUnsignedInt();
   int port = payload.readUnsignedShort();
   payload.skipBytes(1);
   short protocolIdLength = payload.readUnsignedByte();
   ByteBuf protocolId = payload.readSlice(protocolIdLength);
   short hostLength = payload.readUnsignedByte();
   String host = payload.toString(payload.readerIndex(), hostLength, UTF_8);
   payload.skipBytes(hostLength);
   String origin = null;
   if (payload.isReadable()) {
     origin = payload.toString(UTF_8);
     payload.skipBytes(payload.readableBytes());
   }
   observer.onAltSvcRead(ctx, streamId, maxAge, port, protocolId, host, origin);
 }
  private void readDataFrame(
      ChannelHandlerContext ctx, ByteBuf payload, Http2FrameObserver observer)
      throws Http2Exception {
    int dataPadding = flags.readPaddingLength(payload);

    // Determine how much data there is to read by removing the trailing
    // padding.
    int dataLength = payload.readableBytes() - dataPadding;
    if (dataLength < 0) {
      throw protocolError("Frame payload too small for padding.");
    }

    ByteBuf data = payload.readSlice(dataLength);
    observer.onDataRead(
        ctx,
        streamId,
        data,
        dataPadding,
        flags.endOfStream(),
        flags.endOfSegment(),
        flags.compressed());
    payload.skipBytes(payload.readableBytes());
  }
 private void readWindowUpdateFrame(
     ChannelHandlerContext ctx, ByteBuf payload, Http2FrameObserver observer)
     throws Http2Exception {
   int windowSizeIncrement = readUnsignedInt(payload);
   observer.onWindowUpdateRead(ctx, streamId, windowSizeIncrement);
 }
 private void readRstStreamFrame(
     ChannelHandlerContext ctx, ByteBuf payload, Http2FrameObserver observer)
     throws Http2Exception {
   long errorCode = payload.readUnsignedInt();
   observer.onRstStreamRead(ctx, streamId, errorCode);
 }