/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// HttpLog.h should generally be included first #include"HttpLog.h" #include"Http3WebTransportSession.h" #include"Http3WebTransportStream.h" #include"Http3Session.h" #include"Http3Stream.h" #include"nsHttpRequestHead.h" #include"nsHttpTransaction.h" #include"nsIClassOfService.h" #include"nsISocketTransport.h" #include"nsSocketTransportService2.h" #include"nsIOService.h" #include"nsHttpHandler.h"
// XXX some streams return NS_BASE_STREAM_CLOSED to indicate EOF. if (rv == NS_BASE_STREAM_CLOSED && !mTransaction->IsDone()) {
rv = NS_OK;
transactionBytes = 0;
}
if (NS_FAILED(rv)) { // if the transaction didn't want to write any more data, then // wait for the transaction to call ResumeSend. if (rv == NS_BASE_STREAM_WOULD_BLOCK) {
rv = NS_OK;
}
again = false;
} elseif (NS_FAILED(mSocketOutCondition)) { if (mSocketOutCondition != NS_BASE_STREAM_WOULD_BLOCK) {
rv = mSocketOutCondition;
}
again = false;
} elseif (!transactionBytes) {
mTransaction->OnTransportStatus(nullptr, NS_NET_STATUS_WAITING_FOR, 0);
mSendState = PROCESSING_DATAGRAM;
rv = NS_OK;
again = false;
} // write more to the socket until error or end-of-request...
} while (again && gHttpHandler->Active()); return rv;
}
mFlatHttpRequestHeaders.Append(buf, avail); // We can use the simple double crlf because firefox is the // only client we are parsing
int32_t endHeader = mFlatHttpRequestHeaders.Find("\r\n\r\n");
if (endHeader == kNotFound) { // We don't have all the headers yet
LOG3(
("Http3WebTransportSession::ConsumeHeaders %p " "Need more header bytes. Len = %zu", this, mFlatHttpRequestHeaders.Length()));
*countUsed = avail; returnfalse;
}
if (mRecvState == CLOSE_PENDING) {
mSession->CloseWebTransport(mStreamId, mStatus, mReason);
mRecvState = RECV_DONE; // This will closed the steam because the stream is Done(). return NS_OK;
}
do {
mSocketInCondition = NS_OK;
countWrittenSingle = 0;
rv = mTransaction->WriteSegmentsAgain( this, nsIOService::gDefaultSegmentSize, &countWrittenSingle, &again);
LOG(("Http3WebTransportSession::WriteSegments rv=0x%" PRIx32 " countWrittenSingle=%" PRIu32 " socketin=%" PRIx32 " [this=%p]", static_cast<uint32_t>(rv), countWrittenSingle, static_cast<uint32_t>(mSocketInCondition), this)); if (mTransaction->IsDone()) { // An HTTP transaction used for setting up a WebTransport session will // receive only response headers and afterward, it will be marked as // done. At this point, the session negotiation has finished and the // WebTransport session transfers into the ACTIVE state.
mRecvState = ACTIVE;
}
if (NS_FAILED(rv)) { // if the transaction didn't want to take any more data, then // wait for the transaction to call ResumeRecv. if (rv == NS_BASE_STREAM_WOULD_BLOCK) {
rv = NS_OK;
}
again = false;
} elseif (NS_FAILED(mSocketInCondition)) { if (mSocketInCondition != NS_BASE_STREAM_WOULD_BLOCK) {
rv = mSocketInCondition;
}
again = false;
} // read more from the socket until error...
} while (again && gHttpHandler->Active());
LOG(("Http3WebTransportSession::OnWriteSegment [this=%p, state=%d", this,
mRecvState));
nsresult rv = NS_OK; switch (mRecvState) { case BEFORE_HEADERS: {
*countWritten = 0;
rv = NS_BASE_STREAM_WOULD_BLOCK;
} break; case READING_HEADERS: case READING_INTERIM_HEADERS: { // SetResponseHeaders should have been previously called.
MOZ_ASSERT(!mFlatResponseHeaders.IsEmpty(), "Headers empty!");
*countWritten = (mFlatResponseHeaders.Length() > count)
? count
: mFlatResponseHeaders.Length();
memcpy(buf, mFlatResponseHeaders.Elements(), *countWritten);
mFlatResponseHeaders.RemoveElementsAt(0, *countWritten); if (mFlatResponseHeaders.Length() == 0) { if (mRecvState == READING_INTERIM_HEADERS) { // neqo makes sure that fin cannot be received before the final // headers are received.
mRecvState = BEFORE_HEADERS;
} else {
mRecvState = ACTIVE;
}
}
if (*countWritten == 0) {
rv = NS_BASE_STREAM_WOULD_BLOCK;
} else {
mTransaction->OnTransportStatus(nullptr, NS_NET_STATUS_RECEIVING_FROM,
0);
}
} break; case ACTIVE: case CLOSE_PENDING: case RECV_DONE:
rv = NS_ERROR_UNEXPECTED;
}
// Remember the error received from lower layers. A stream pipe may overwrite // it. // If rv == NS_OK this will reset mSocketInCondition.
mSocketInCondition = rv;
RefPtr<Http3WebTransportStream> stream =
aBidi ? new Http3WebTransportStream(mSession, mStreamId,
WebTransportStreamType::BiDi,
std::move(aCallback))
: new Http3WebTransportStream(mSession, mStreamId,
WebTransportStreamType::UniDi,
std::move(aCallback));
mSession->StreamHasDataToWrite(stream); // Put the newly created stream in to |mStreams| to keep it alive.
mStreams.AppendElement(std::move(stream));
}
// This is called by Http3Session::TryActivatingWebTransportStream. When called, // this means a WebTransport stream is successfully activated and the stream // will be managed by Http3Session. void Http3WebTransportSession::RemoveWebTransportStream(
Http3WebTransportStream* aStream) {
LOG(
("Http3WebTransportSession::RemoveWebTransportStream " "this=%p aStream=%p", this, aStream));
DebugOnly<bool> existed = mStreams.RemoveElement(aStream);
MOZ_ASSERT(existed);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.