in proxygen/lib/http/session/HTTPTransaction.cpp [1264:1325]
size_t HTTPTransaction::sendBodyNow(std::unique_ptr<folly::IOBuf> body,
size_t bodyLen,
bool sendEom) {
static const std::string noneStr = "None";
DCHECK(body);
DCHECK_GT(bodyLen, 0);
size_t nbytes = 0;
if (useFlowControl_) {
// Because of how sendBodyNow is embedded in HTTPTransaction code flow,
// calling INVARIANT here is not safe
CHECK(sendWindow_.reserve(bodyLen));
}
VLOG(4) << "Sending " << bodyLen
<< " bytes of body. eom=" << ((sendEom) ? "yes" : "no")
<< " send_window is "
<< (useFlowControl_
? folly::to<std::string>(
sendWindow_.getSize(), " / ", sendWindow_.getCapacity())
: noneStr)
<< " trailers=" << ((trailers_) ? "yes" : "no") << " " << *this;
DCHECK_LT(bodyLen, std::numeric_limits<int64_t>::max());
transport_.notifyEgressBodyBuffered(-static_cast<int64_t>(bodyLen));
if (sendEom && !trailers_) {
if (!validateEgressStateTransition(
HTTPTransactionEgressSM::Event::eomFlushed)) {
return 0;
}
} else if (ingressErrorSeen_ && isExpectingWindowUpdate()) {
// I don't know how we got here but we're in trouble. We need a window
// update to continue but we've already seen an ingress error.
HTTPException ex(HTTPException::Direction::INGRESS_AND_EGRESS,
folly::to<std::string>("window blocked with ingress error,"
" streamID=",
id_));
ex.setProxygenError(kErrorEOF);
ex.setCodecStatusCode(ErrorCode::FLOW_CONTROL_ERROR);
onError(ex);
return 0;
}
updateReadTimeout();
nbytes = transport_.sendBody(this,
std::move(body),
sendEom && !trailers_,
enableLastByteFlushedTracking_);
bodyBytesEgressed_ += bodyLen;
for (auto it = egressBodyOffsetsToTrack_.begin();
it != egressBodyOffsetsToTrack_.end() && it->first < bodyBytesEgressed_;
it = egressBodyOffsetsToTrack_.begin()) {
transport_.trackEgressBodyOffset(it->first, it->second);
egressBodyOffsetsToTrack_.erase(it);
}
if (sendEom && trailers_) {
nbytes += sendEOMNow();
}
if (isPrioritySampled()) {
updateTransactionBytesSent(bodyLen);
}
if (egressLimitBytesPerMs_ > 0) {
numLimitedBytesEgressed_ += nbytes;
}
return nbytes;
}