//Check Queue for IOBuffer  as Folly Test.
void check_consistency(const folly::IOBufQueue& queue)
{

    if(queue.options().cacheChainLength) {
        size_t len = queue.front() ? queue.front()->computeChainDataLength() : 0;

        LOG(INFO)<<"Chain Length : "<< len;

        EXPECT_EQ(len, queue.chainLength());
    }

}
예제 #2
0
  bool parseRoutingData(folly::IOBufQueue& bufQueue,
                        RoutingData& routingData) override {
    if (bufQueue.chainLength() == 0) {
      return false;
    }

    auto buf = bufQueue.move();
    buf->coalesce();
    // Use the first byte for hashing to a worker
    routingData.routingData = buf->data()[0];
    routingData.bufQueue.append(std::move(buf));
    return true;
  }
예제 #3
0
void HandlerCallbackBase::sendReply(
    folly::IOBufQueue queue,
    apache::thrift::Stream<folly::IOBufQueue>&& stream) {
  folly::Optional<uint32_t> crc32c = checksumIfNeeded(queue);
  transform(queue);
  auto stream_ =
      std::move(stream).map([](auto&& value) mutable { return value.move(); });
  if (getEventBase()->isInEventBaseThread()) {
    req_->sendStreamReply({queue.move(), std::move(stream_)}, nullptr, crc32c);
  } else {
    getEventBase()->runInEventBaseThread([req = std::move(req_),
                                          queue = std::move(queue),
                                          stream = std::move(stream_),
                                          crc32c]() mutable {
      req->sendStreamReply({queue.move(), std::move(stream)}, nullptr, crc32c);
    });
  }
}
예제 #4
0
void
TestAsyncTransport::addReadEvent(folly::IOBufQueue& chain,
                                 int64_t delayFromPrevious) {
  while (true) {
    unique_ptr<IOBuf> cur = chain.pop_front();
    if (!cur) {
      break;
    }
    addReadEvent(cur->data(), cur->length(), delayFromPrevious);
  }
}
예제 #5
0
void Cpp2Channel::read(Context* ctx, folly::IOBufQueue& q) {
    DestructorGuard dg(this);

    if (recvCallback_ && recvCallback_->shouldSample() && !sample_) {
        sample_.reset(new RecvCallback::sample);
        sample_->readBegin = Util::currentTimeUsec();
    }

    if (!recvCallback_) {
        LOG(INFO) << "Received a message, but no recvCallback_ installed!";
        return;
    }

    if (sample_) {
        sample_->readEnd = Util::currentTimeUsec();
    }

    recvCallback_->messageReceived(q.move(), std::move(sample_));
}
예제 #6
0
/**
 * Mostly ripped from HTTP2Codec::generateHeader.  This writes out frames
 * like Chrome does, breaking on 1024 - frame header, with some of the not
 * needed cases removed.  It's specialized to write only a single continuation
 * frame with optionally malformed length
 */
void generateHeaderChrome(HPACKCodec09& headerCodec,
                          folly::IOBufQueue& writeBuf,
                          HTTPCodec::StreamID stream,
                          const HTTPMessage& msg,
                          HTTPCodec::StreamID assocStream,
                          bool eom,
                          HTTPHeaderSize* size,
                          bool malformed) {
  VLOG(4) << "generating " << ((assocStream != 0) ? "PUSH_PROMISE" : "HEADERS")
          << " for stream=" << stream;
  std::vector<proxygen::compress::Header> allHeaders;

  const string& method = msg.getMethodString();
  const string& scheme = (msg.isSecure() ? http2::kHttps : http2::kHttp);
  const string& path = msg.getURL();
  const HTTPHeaders& headers = msg.getHeaders();
  const string& host = headers.getSingleOrEmpty(HTTP_HEADER_HOST);
  allHeaders.emplace_back(http2::kMethod, method);
  allHeaders.emplace_back(http2::kScheme, scheme);
  allHeaders.emplace_back(http2::kPath, path);
  if (!host.empty()) {
    allHeaders.emplace_back(http2::kAuthority, host);
  }

  // Add the HTTP headers supplied by the caller, but skip
  // any per-hop headers that aren't supported in HTTP/2.
  msg.getHeaders().forEachWithCode(
    [&] (HTTPHeaderCode code,
         const string& name,
         const string& value) {

      // Note this code will not drop headers named by Connection.  That's the
      // caller's job

      // see HTTP/2 spec, 8.1.2
      DCHECK(name != "TE" || value == "trailers");
      if ((name.size() > 0 && name[0] != ':') &&
          code != HTTP_HEADER_HOST) {
        allHeaders.emplace_back(code, name, value);
      }
    });

  headerCodec.setEncodeHeadroom(http2::kFrameHeadersBaseMaxSize);
  auto out = headerCodec.encode(allHeaders);
  if (size) {
    *size = headerCodec.getEncodedSize();
  }

  IOBufQueue queue(IOBufQueue::cacheChainLength());
  queue.append(std::move(out));
  if (queue.chainLength() > 0) {

    auto chunk = queue.split(std::min((size_t)(1024 - 14),
                                      queue.chainLength()));

    bool endHeaders = queue.chainLength() == 0;
    CHECK(assocStream == 0);
    http2::writeHeaders(writeBuf,
                        std::move(chunk),
                        stream,
                        http2::PriorityUpdate({0, false, 16}),
                        http2::kNoPadding,
                        eom,
                        endHeaders);
    while (!endHeaders) {
      CHECK(queue.chainLength() == 1015);
      chunk = queue.split(std::min(size_t(1024 - http2::kFrameHeaderSize),
                                   queue.chainLength()));
      endHeaders = queue.chainLength() == 0;
      CHECK(endHeaders);
      VLOG(4) << "generating CONTINUATION for stream=" << stream;
      writeFrameHeaderManual(writeBuf,
                             malformed ? 1024 : chunk->computeChainDataLength(),
                             9,
                             http2::END_HEADERS,
                             stream);
      writeBuf.append(std::move(chunk));
    }
  }
}