Bug 1562315 - Respect again=false indicated by http2 session when calling through TLSFilterTransaction, r=dragana

Differential Revision: https://phabricator.services.mozilla.com/D37391

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Honza Bambas 2019-07-09 13:52:27 +00:00
parent c052688204
commit f38f54b139
2 changed files with 44 additions and 10 deletions

View File

@ -355,31 +355,61 @@ nsresult TLSFilterTransaction::ReadSegments(nsAHttpSegmentReader* aReader,
return NS_SUCCEEDED(rv) ? mReadSegmentReturnValue : rv; return NS_SUCCEEDED(rv) ? mReadSegmentReturnValue : rv;
} }
nsresult TLSFilterTransaction::WriteSegments(nsAHttpSegmentWriter* aWriter, nsresult TLSFilterTransaction::WriteSegmentsAgain(nsAHttpSegmentWriter* aWriter,
uint32_t aCount, uint32_t aCount,
uint32_t* outCountWritten) { uint32_t* outCountWritten,
bool* again) {
MOZ_ASSERT(OnSocketThread(), "not on socket thread"); MOZ_ASSERT(OnSocketThread(), "not on socket thread");
LOG(("TLSFilterTransaction::WriteSegments %p max=%d\n", this, aCount)); LOG(("TLSFilterTransaction::WriteSegmentsAgain %p max=%d\n", this, aCount));
if (!mTransaction) { if (!mTransaction) {
return mCloseReason; return mCloseReason;
} }
bool againBeforeWriteSegmentsCall = *again;
mSegmentWriter = aWriter; mSegmentWriter = aWriter;
nsresult rv = mTransaction->WriteSegments(this, aCount, outCountWritten); nsresult rv =
if (NS_SUCCEEDED(rv) && NS_FAILED(mFilterReadCode) && !(*outCountWritten)) { mTransaction->WriteSegmentsAgain(this, aCount, outCountWritten, again);
if (NS_SUCCEEDED(rv) && !(*outCountWritten)) {
if (NS_FAILED(mFilterReadCode)) {
// nsPipe turns failures into silent OK.. undo that! // nsPipe turns failures into silent OK.. undo that!
rv = mFilterReadCode; rv = mFilterReadCode;
if (Connection() && (mFilterReadCode == NS_BASE_STREAM_WOULD_BLOCK)) { if (Connection() && (mFilterReadCode == NS_BASE_STREAM_WOULD_BLOCK)) {
Unused << Connection()->ResumeRecv(); Unused << Connection()->ResumeRecv();
} }
} }
if (againBeforeWriteSegmentsCall && !*again) {
LOG(
("TLSFilterTransaction %p called trans->WriteSegments which dropped "
"the 'again' flag",
this));
// The transaction (=h2 session) wishes to break the loop. There is a
// pending close of the transaction that is being handled by the current
// input stream of the session. After cancellation of that transaction
// the state of the stream will change and move the state machine of the
// session forward on the next call of WriteSegmentsAgain. But if there
// are no data on the socket to read to call this code again, the session
// and the stream will just hang in an intermediate state, blocking. Hence
// forcing receive to finish the stream cleanup.
if (Connection()) {
Unused << Connection()->ForceRecv();
}
}
}
LOG(("TLSFilterTransaction %p called trans->WriteSegments rv=%" PRIx32 LOG(("TLSFilterTransaction %p called trans->WriteSegments rv=%" PRIx32
" %d\n", " %d\n",
this, static_cast<uint32_t>(rv), *outCountWritten)); this, static_cast<uint32_t>(rv), *outCountWritten));
return rv; return rv;
} }
nsresult TLSFilterTransaction::WriteSegments(nsAHttpSegmentWriter* aWriter,
uint32_t aCount,
uint32_t* outCountWritten) {
bool again = false;
return WriteSegmentsAgain(aWriter, aCount, outCountWritten, &again);
}
nsresult TLSFilterTransaction::GetTransactionSecurityInfo( nsresult TLSFilterTransaction::GetTransactionSecurityInfo(
nsISupports** outSecInfo) { nsISupports** outSecInfo) {
if (!mSecInfo) { if (!mSecInfo) {

View File

@ -144,6 +144,10 @@ class TLSFilterTransaction final : public nsAHttpTransaction,
NullHttpTransaction* QueryNullTransaction() override; NullHttpTransaction* QueryNullTransaction() override;
nsHttpTransaction* QueryHttpTransaction() override; nsHttpTransaction* QueryHttpTransaction() override;
SpdyConnectTransaction* QuerySpdyConnectTransaction() override; SpdyConnectTransaction* QuerySpdyConnectTransaction() override;
MOZ_MUST_USE nsresult WriteSegmentsAgain(nsAHttpSegmentWriter* writer,
uint32_t count,
uint32_t* countWritten,
bool* again) override;
private: private:
MOZ_MUST_USE nsresult StartTimerCallback(); MOZ_MUST_USE nsresult StartTimerCallback();