Example #1
0
    public ResponseEvent(int rpcType, int coordinationId, ByteBuf pBody, ByteBuf dBody) {
      this.rpcType = rpcType;
      this.coordinationId = coordinationId;
      this.pBody = pBody;
      this.dBody = dBody;

      if (pBody != null) {
        pBody.retain();
      }

      if (dBody != null) {
        dBody.retain();
      }
    }
  public void setBuffer(ByteBuf bufferHandle) {
    /* clear the existing buffer */
    clear();

    this.buffer = bufferHandle;
    buffer.retain();
  }
 /**
  * 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;
   }
 }
Example #4
0
    RequestEvent(int coordinationId, C connection, int rpcType, ByteBuf pBody, ByteBuf dBody) {
      sender = new ResponseSenderImpl();
      this.connection = connection;
      this.rpcType = rpcType;
      this.pBody = pBody;
      this.dBody = dBody;
      sender.set(connection, coordinationId);

      if (pBody != null) {
        pBody.retain();
      }

      if (dBody != null) {
        dBody.retain();
      }
    }
  public ByteBuf getBuffer() {
    ByteBuf bufferHandle = this.buffer;

    /* Increment the ref count for this buffer */
    bufferHandle.retain();

    /* We are passing ownership of the buffer to the
     * caller. clear the buffer from within our selection vector
     */
    clear();

    return bufferHandle;
  }
  @Override
  public ChannelFuture goAway(
      final ChannelHandlerContext ctx,
      final int lastStreamId,
      final long errorCode,
      final ByteBuf debugData,
      ChannelPromise promise) {
    try {
      final Http2Connection connection = connection();
      if (connection.goAwaySent() && lastStreamId > connection.remote().lastStreamKnownByPeer()) {
        throw connectionError(
            PROTOCOL_ERROR,
            "Last stream identifier must not increase between "
                + "sending multiple GOAWAY frames (was '%d', is '%d').",
            connection.remote().lastStreamKnownByPeer(),
            lastStreamId);
      }
      connection.goAwaySent(lastStreamId, errorCode, debugData);

      // Need to retain before we write the buffer because if we do it after the refCnt could
      // already be 0 and
      // result in an IllegalRefCountException.
      debugData.retain();
      ChannelFuture future =
          frameWriter().writeGoAway(ctx, lastStreamId, errorCode, debugData, promise);

      if (future.isDone()) {
        processGoAwayWriteResult(ctx, lastStreamId, errorCode, debugData, future);
      } else {
        future.addListener(
            new ChannelFutureListener() {
              @Override
              public void operationComplete(ChannelFuture future) throws Exception {
                processGoAwayWriteResult(ctx, lastStreamId, errorCode, debugData, future);
              }
            });
      }

      return future;
    } catch (
        Throwable
            cause) { // Make sure to catch Throwable because we are doing a retain() in this method.
      debugData.release();
      return promise.setFailure(cause);
    }
  }
  @Override
  protected void encode(ChannelHandlerContext ctx, ByteBuf byteBuf, List<Object> out)
      throws Exception {
    if (byteBuf.isReadable()) {
      int length = byteBuf.readableBytes();

      String headerString = length + " ";

      ByteBuf header =
          ByteBufAllocator.DEFAULT.buffer(headerString.getBytes(Charset.forName("UTF8")).length);
      header.writeBytes(headerString.getBytes(Charset.forName("UTF8")));

      Unpooled.buffer();

      byteBuf.retain();
      out.add(Unpooled.wrappedBuffer(header, byteBuf));
    }
  }
  @Override
  protected void notifyListenerOnDataRead(
      ChannelHandlerContext ctx,
      int streamId,
      ByteBuf data,
      int padding,
      boolean endOfStream,
      Http2FrameListener listener)
      throws Http2Exception {
    final Http2Stream stream = connection.stream(streamId);
    final EmbeddedChannel decoder = stream == null ? null : stream.decompressor();
    if (decoder == null) {
      super.notifyListenerOnDataRead(ctx, streamId, data, padding, endOfStream, listener);
    } else {
      // call retain here as it will call release after its written to the channel
      decoder.writeInbound(data.retain());
      ByteBuf buf = nextReadableBuf(decoder);
      if (buf == null) {
        if (endOfStream) {
          super.notifyListenerOnDataRead(
              ctx, streamId, Unpooled.EMPTY_BUFFER, padding, true, listener);
        }
        // END_STREAM is not set and the data could not be decoded yet.
        // The assumption has to be there will be more data frames to complete the decode.
        // We don't have enough information here to know if this is an error.
      } else {
        for (; ; ) {
          final ByteBuf nextBuf = nextReadableBuf(decoder);
          if (nextBuf == null) {
            super.notifyListenerOnDataRead(ctx, streamId, buf, padding, endOfStream, listener);
            break;
          } else {
            super.notifyListenerOnDataRead(ctx, streamId, buf, padding, false, listener);
          }
          buf = nextBuf;
        }
      }

      if (endOfStream) {
        cleanup(stream, decoder);
      }
    }
  }
  public void send(@NotNull final FastCgiRequest fastCgiRequest, @NotNull ByteBuf content) {
    final ByteBuf notEmptyContent;
    if (content.isReadable()) {
      content.retain();
      notEmptyContent = content;
      notEmptyContent.touch();
    } else {
      notEmptyContent = null;
    }

    try {
      if (processHandler.has()) {
        fastCgiRequest.writeToServerChannel(notEmptyContent, processChannel);
      } else {
        processHandler
            .get()
            .done(
                new Consumer<OSProcessHandler>() {
                  @Override
                  public void consume(OSProcessHandler osProcessHandler) {
                    fastCgiRequest.writeToServerChannel(notEmptyContent, processChannel);
                  }
                })
            .rejected(
                new Consumer<Throwable>() {
                  @Override
                  public void consume(Throwable error) {
                    LOG.error(error);
                    handleError(fastCgiRequest, notEmptyContent);
                  }
                });
      }
    } catch (Throwable e) {
      LOG.error(e);
      handleError(fastCgiRequest, notEmptyContent);
    }
  }
  @Test
  public void test() throws Exception {
    // Preprocessor basically is split into two parts
    // Part 1 is just a direct copy
    // Part 2 negates all bytes before copying
    final AtomicReference<MessageProcessor> processor = new AtomicReference<>();
    MessageProcessorDecoder processorDecoder =
        new MessageProcessorDecoder(null) {
          @Override
          protected MessageProcessor getProcessor() {
            return processor.get();
          }
        };

    // Set up a fake ChannelHandlerContext
    FakeChannelHandlerContext fake = ChannelHandlerContextFaker.setup();
    AtomicReference<ByteBuf> ref = new AtomicReference<>();
    fake.setReference(ref);
    LinkedList<byte[]> outputList = new LinkedList<byte[]>();

    Random r = new Random();

    // Get some random bytes for data
    byte[] input = new byte[LENGTH];
    r.nextBytes(input);

    boolean breakOccured = false;
    int position = 0;

    for (int i = 0; i < input.length; ) {
      // Simulate real data read
      int burstSize = r.nextInt(512);
      // With a 1/10 chance of having an extra-large burst
      if (r.nextInt(10) == 0) {
        burstSize *= 10;
      }

      // Final burst needs to be clamped
      if (i + burstSize > input.length) {
        burstSize = input.length - i;
      }

      // And we can't negate in the middle of a burst
      if (i + burstSize > BREAK && !breakOccured) {
        burstSize = BREAK - i;
      }

      // Write info to a new ByteBuf
      final ByteBuf buf = Unpooled.buffer(burstSize);
      buf.retain();
      buf.writeBytes(input, i, burstSize);
      i += burstSize;

      // Fake a read
      processorDecoder.channelRead(fake, buf);

      final ByteBuf returned = ref.get();

      while (returned != null && true) {
        int packetSize = r.nextInt(128) + 1;
        if (r.nextInt(10) == 0) {
          packetSize *= 20;
        }

        if (packetSize > returned.readableBytes()) {
          packetSize = returned.readableBytes();
        }
        if (position + packetSize > BREAK && !breakOccured) {
          packetSize = BREAK - position;
        }
        if (position + packetSize > LENGTH) {
          packetSize = LENGTH - position;
        }

        if (packetSize == 0) {
          break;
        }

        byte[] array = new byte[packetSize];

        returned.readBytes(array);
        position += packetSize;

        if (position == BREAK) {
          processor.set(new NegatingProcessor(512));
          breakOccured = true;
        }
        outputList.add(array);
      }
    }

    // Get the output data and combine into one array
    byte[] output = new byte[LENGTH];
    int i = 0;
    for (byte[] array : outputList) {
      for (int j = 0; j < array.length; j++) {
        output[i++] = array[j];
      }
    }

    for (i = 0; i < input.length; i++) {
      byte expected = i < BREAK ? input[i] : (byte) ~input[i];
      if (output[i] != expected) {
        for (int j = Math.max(0, i - 10); j <= i + 10; j++) {
          System.out.println(
              j
                  + ") "
                  + Integer.toBinaryString(j < BREAK ? input[j] : (byte) ~input[j])
                  + " "
                  + Integer.toBinaryString(output[j]));
        }
      }

      if (i < BREAK) {
        assertTrue(
            "Input/Output mismatch at position "
                + i
                + ". Expected "
                + input[i]
                + " but got "
                + output[i]
                + ". Break is: "
                + BREAK,
            output[i] == input[i]);
      } else {
        assertTrue(
            "Input/Output mismatch at position "
                + i
                + ", after the processor change. Expected "
                + (byte) ~input[i]
                + " but got "
                + output[i]
                + ". Break is: "
                + BREAK,
            output[i] == (byte) ~input[i]);
      }
    }
  }
Example #11
0
  public ReceivedResponse request(URI uri, Duration duration, Action<? super RequestSpec> action)
      throws Throwable {
    CountDownLatch latch = new CountDownLatch(1);
    AtomicReference<ExecResult<ReceivedResponse>> result = new AtomicReference<>();

    try (ExecController execController = new DefaultExecController(2)) {
      execController
          .fork()
          .onComplete(e -> {})
          .start(
              e -> {
                HttpClient.httpClient(UnpooledByteBufAllocator.DEFAULT, Integer.MAX_VALUE)
                    .request(uri, action.prepend(s -> s.readTimeout(Duration.ofHours(1))))
                    .map(
                        response -> {
                          TypedData responseBody = response.getBody();
                          ByteBuf responseBodyBuffer = responseBody.getBuffer();
                          responseBodyBuffer =
                              Unpooled.unreleasableBuffer(responseBodyBuffer.retain());

                          return new DefaultReceivedResponse(
                              response.getStatus(),
                              response.getHeaders(),
                              new ByteBufBackedTypedData(
                                  responseBodyBuffer, responseBody.getContentType()));
                        })
                    .connect(
                        new Downstream<DefaultReceivedResponse>() {
                          @Override
                          public void success(DefaultReceivedResponse value) {
                            result.set(ExecResult.of(Result.success(value)));
                            latch.countDown();
                          }

                          @Override
                          public void error(Throwable throwable) {
                            result.set(ExecResult.of(Result.error(throwable)));
                            latch.countDown();
                          }

                          @Override
                          public void complete() {
                            result.set(ExecResult.complete());
                            latch.countDown();
                          }
                        });
              });

      try {
        if (!latch.await(duration.toNanos(), TimeUnit.NANOSECONDS)) {
          TemporalUnit unit = duration.getUnits().get(0);
          throw new IllegalStateException(
              "Request to "
                  + uri
                  + " took more than "
                  + duration.get(unit)
                  + " "
                  + unit.toString()
                  + " to complete");
        }
      } catch (InterruptedException e) {
        throw Exceptions.uncheck(e);
      }

      return result.get().getValueOrThrow();
    }
  }
 @Override
 public ByteBuf retain(int var1) {
   return a.retain(var1);
 }
 @Override
 public FullHttpMessage retain(int increment) {
   content.retain(increment);
   return this;
 }
 @Override
 public FullHttpMessage retain() {
   content.retain();
   return this;
 }
Example #15
0
 @Override
 public ByteBuf retain(int increment) {
   return buf.retain(increment);
 }
Example #16
0
 @Override
 public ByteBuf retain() {
   return buf.retain();
 }
 @Override
 public FullBinaryMemcacheResponse retain(int increment) {
   super.retain(increment);
   content.retain(increment);
   return this;
 }