Unverified Commit 77dedbef authored by Zhangyi Chen's avatar Zhangyi Chen Committed by GitHub

Merge pull request #632 from zyearn/fix_h2_big_response_not_sending

fix h2 big response not sending bug
parents 45938762 e1d1d9af
...@@ -1522,26 +1522,26 @@ H2UnsentRequest::AppendAndDestroySelf(butil::IOBuf* out, Socket* socket) { ...@@ -1522,26 +1522,26 @@ H2UnsentRequest::AppendAndDestroySelf(butil::IOBuf* out, Socket* socket) {
<< " h2req=" << (StreamUserData*)this; << " h2req=" << (StreamUserData*)this;
return butil::Status(EH2RUNOUTSTREAMS, "Fail to allocate stream_id"); return butil::Status(EH2RUNOUTSTREAMS, "Fail to allocate stream_id");
} }
H2StreamContext* sctx = _sctx.release();
sctx->Init(ctx, id);
const int rc = ctx->TryToInsertStream(id, sctx);
if (rc < 0) {
delete sctx;
return butil::Status(EINTERNAL, "Fail to insert existing stream_id");
} else if (rc > 0) {
delete sctx;
return butil::Status(ELOGOFF, "the connection just issued GOAWAY");
}
_stream_id = sctx->stream_id();
_sctx->Init(ctx, id);
// flow control // flow control
if (!_cntl->request_attachment().empty()) { if (!_cntl->request_attachment().empty()) {
const int64_t data_size = _cntl->request_attachment().size(); const int64_t data_size = _cntl->request_attachment().size();
if (!sctx->ConsumeWindowSize(data_size)) { if (!_sctx->ConsumeWindowSize(data_size)) {
return butil::Status(ELIMIT, "remote_window_left is not enough, data_size=%" PRId64, data_size); return butil::Status(ELIMIT, "remote_window_left is not enough, data_size=%" PRId64, data_size);
} }
} }
const int rc = ctx->TryToInsertStream(id, _sctx.get());
if (rc < 0) {
return butil::Status(EINTERNAL, "Fail to insert existing stream_id");
} else if (rc > 0) {
return butil::Status(ELOGOFF, "the connection just issued GOAWAY");
}
_stream_id = _sctx->stream_id();
// After calling TryToInsertStream, the ownership of _sctx is transferred to ctx
_sctx.release();
HPacker& hpacker = ctx->hpacker(); HPacker& hpacker = ctx->hpacker();
butil::IOBufAppender appender; butil::IOBufAppender appender;
HPackOptions options; HPackOptions options;
...@@ -1672,8 +1672,15 @@ H2UnsentResponse::AppendAndDestroySelf(butil::IOBuf* out, Socket* socket) { ...@@ -1672,8 +1672,15 @@ H2UnsentResponse::AppendAndDestroySelf(butil::IOBuf* out, Socket* socket) {
// NOTE: Currently the stream context is definitely removed and updating // NOTE: Currently the stream context is definitely removed and updating
// window size is useless, however it's not true when progressive request // window size is useless, however it's not true when progressive request
// is supported. // is supported.
// TODO(zhujiashun): Instead of just returning error to client, a better
// solution to handle not enough window size is to wait until WINDOW_UPDATE
// is received, and then retry those failed response again.
if (!MinusWindowSize(&ctx->_remote_window_left, _data.size())) { if (!MinusWindowSize(&ctx->_remote_window_left, _data.size())) {
return butil::Status(ELIMIT, "Remote window size is not enough"); char rstbuf[FRAME_HEAD_SIZE + 4];
SerializeFrameHead(rstbuf, 4, H2_FRAME_RST_STREAM, 0, _stream_id);
SaveUint32(rstbuf + FRAME_HEAD_SIZE, H2_FLOW_CONTROL_ERROR);
out->append(rstbuf, sizeof(rstbuf));
return butil::Status::OK();
} }
HPacker& hpacker = ctx->hpacker(); HPacker& hpacker = ctx->hpacker();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment