/**
  * Adds a fragment to the block.
  *
  * @param fragment the fragment of the headers block to be added.
  * @param alloc allocator for new blocks if needed.
  * @param endOfHeaders flag indicating whether the current frame is the end of the headers. This
  *     is used for an optimization for when the first fragment is the full block. In that case,
  *     the buffer is used directly without copying.
  */
 final void addFragment(ByteBuf fragment, ByteBufAllocator alloc, boolean endOfHeaders)
     throws Http2Exception {
   if (headerBlock == null) {
     if (fragment.readableBytes() > headersDecoder.configuration().maxHeaderSize()) {
       headerSizeExceeded();
     }
     if (endOfHeaders) {
       // Optimization - don't bother copying, just use the buffer as-is. Need
       // to retain since we release when the header block is built.
       headerBlock = fragment.retain();
     } else {
       headerBlock = alloc.buffer(fragment.readableBytes());
       headerBlock.writeBytes(fragment);
     }
     return;
   }
   if (headersDecoder.configuration().maxHeaderSize() - fragment.readableBytes()
       < headerBlock.readableBytes()) {
     headerSizeExceeded();
   }
   if (headerBlock.isWritable(fragment.readableBytes())) {
     // The buffer can hold the requested bytes, just write it directly.
     headerBlock.writeBytes(fragment);
   } else {
     // Allocate a new buffer that is big enough to hold the entire header block so far.
     ByteBuf buf = alloc.buffer(headerBlock.readableBytes() + fragment.readableBytes());
     buf.writeBytes(headerBlock);
     buf.writeBytes(fragment);
     headerBlock.release();
     headerBlock = buf;
   }
 }
  @Override
  protected void doRead() {
    if (checkInputShutdown()) {
      return;
    }

    final ChannelPipeline pipeline = pipeline();

    // TODO: calculate size as in 3.x
    ByteBuf byteBuf = alloc().buffer();
    boolean closed = false;
    boolean read = false;
    boolean firedInboundBufferSuspeneded = false;
    try {
      for (; ; ) {
        int localReadAmount = doReadBytes(byteBuf);
        if (localReadAmount > 0) {
          read = true;
        } else if (localReadAmount < 0) {
          closed = true;
        }

        final int available = available();
        if (available <= 0) {
          break;
        }

        if (!byteBuf.isWritable()) {
          final int capacity = byteBuf.capacity();
          final int maxCapacity = byteBuf.maxCapacity();
          if (capacity == maxCapacity) {
            if (read) {
              read = false;
              pipeline.fireMessageReceived(byteBuf);
              byteBuf = alloc().buffer();
            }
          } else {
            final int writerIndex = byteBuf.writerIndex();
            if (writerIndex + available > maxCapacity) {
              byteBuf.capacity(maxCapacity);
            } else {
              byteBuf.ensureWritable(available);
            }
          }
        }
        if (!config().isAutoRead()) {
          // stop reading until next Channel.read() call
          // See https://github.com/netty/netty/issues/1363
          break;
        }
      }
    } catch (Throwable t) {
      if (read) {
        read = false;
        pipeline.fireMessageReceived(byteBuf);
      }

      if (t instanceof IOException) {
        closed = true;
        pipeline.fireExceptionCaught(t);
      } else {
        firedInboundBufferSuspeneded = true;
        pipeline.fireChannelReadSuspended();
        pipeline.fireExceptionCaught(t);
        unsafe().close(voidPromise());
      }
    } finally {
      if (read) {
        pipeline.fireMessageReceived(byteBuf);
      } else {
        // nothing read into the buffer so release it
        byteBuf.release();
      }
      if (closed) {
        inputShutdown = true;
        if (isOpen()) {
          if (Boolean.TRUE.equals(config().getOption(ChannelOption.ALLOW_HALF_CLOSURE))) {
            pipeline.fireUserEventTriggered(ChannelInputShutdownEvent.INSTANCE);
          } else {
            unsafe().close(unsafe().voidPromise());
          }
        }
      } else if (!firedInboundBufferSuspeneded) {
        pipeline.fireChannelReadSuspended();
      }
    }
  }
Example #3
0
 @Override
 public boolean isWritable(int size) {
   return buf.isWritable(size);
 }
Example #4
0
 @Override
 public boolean isWritable() {
   return buf.isWritable();
 }
 @Override
 public boolean isWritable(int var1) {
   return a.isWritable(var1);
 }