/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set sw=2 ts=8 et tw=80 : */ /* 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"
// Log on level :5, instead of default :4. #undef LOG #define LOG(args) LOG5(args) #undef LOG_ENABLED #define LOG_ENABLED() LOG5_ENABLED()
// Because WeakPtr isn't thread-safe we must ensure that the object is destroyed // on the socket thread, so any Release() called on a different thread is // dispatched to the socket thread. bool Http2PushedStreamWrapper::DispatchRelease() { if (OnSocketThread()) { returnfalse;
}
Http2PushedStream::Http2PushedStream(
Http2PushTransactionBuffer* aTransaction, Http2Session* aSession,
Http2StreamBase* aAssociatedStream, uint32_t aID,
uint64_t aCurrentForegroundTabOuterContentWindowId)
: Http2StreamBase((aTransaction->QueryHttpTransaction())
? aTransaction->QueryHttpTransaction()->BrowserId()
: 0,
aSession, 0, aCurrentForegroundTabOuterContentWindowId),
mAssociatedTransaction(aAssociatedStream->Transaction()),
mBufferedPush(aTransaction),
mTransaction(aTransaction) {
LOG3(("Http2PushedStream ctor this=%p 0x%X\n", this, aID));
mStreamID = aID;
MOZ_ASSERT(!(aID & 1)); // must be even to be a pushed stream
mBufferedPush->SetPushStream(this);
mRequestContext = aAssociatedStream->RequestContext();
mLastRead = TimeStamp::Now();
mPriorityDependency = aAssociatedStream->PriorityDependency(); if (mPriorityDependency == Http2Session::kUrgentStartGroupID ||
mPriorityDependency == Http2Session::kLeaderGroupID) {
mPriorityDependency = Http2Session::kFollowerGroupID;
} // Cache this for later use in case of tab switch.
mDefaultPriorityDependency = mPriorityDependency;
SetPriorityDependency(aAssociatedStream->RFC7540Priority() + 1,
mPriorityDependency); // Assume we are on the same tab as our associated stream, for priority // purposes. It's possible this could change when we get paired with a sink, // but it's unlikely and doesn't much matter anyway.
mTransactionBrowserId = aAssociatedStream->TransactionBrowserId();
}
if (rv == NS_BASE_STREAM_CLOSED) {
mPushCompleted = true;
rv = NS_OK; // this is what a normal HTTP transaction would do
} if (rv != NS_BASE_STREAM_WOULD_BLOCK && NS_FAILED(rv)) mStatus = rv; return rv;
}
mozilla::OriginAttributes originAttributes; switch (mUpstreamState) { case GENERATING_HEADERS: { // The request headers for this has been processed, so we need to verify // that :authority, :scheme, and :path MUST be present. :method MUST NOT // be present
mSocketTransport->GetOriginAttributes(&originAttributes);
RefPtr<Http2Session> session = Session();
CreatePushHashKey(mHeaderScheme, mHeaderHost, originAttributes,
session->Serial(), mHeaderPath, mOrigin, mHashKey);
// the write side of a pushed transaction just involves manipulating a // little state
SetSentFin(true);
Http2StreamBase::mRequestHeadersDone = 1;
Http2StreamBase::mOpenGenerated = 1;
Http2StreamBase::ChangeState(UPSTREAM_COMPLETE);
} break;
case UPSTREAM_COMPLETE: // Let's just clear the stream's transmit buffer by pushing it into // the session. This is probably a window adjustment.
LOG3(("Http2Push::ReadSegments 0x%X \n", mStreamID));
mSegmentReader = reader;
rv = TransmitFrame(nullptr, nullptr, true);
mSegmentReader = nullptr; break;
case GENERATING_BODY: case SENDING_BODY: case SENDING_FIN_STREAM: default: break;
}
return rv;
}
void Http2PushedStream::AdjustInitialWindow() {
LOG3(("Http2PushStream %p 0x%X AdjustInitialWindow", this, mStreamID)); if (mConsumerStream) {
LOG3(
("Http2PushStream::AdjustInitialWindow %p 0x%X " "calling super consumer %p 0x%X\n", this, mStreamID, mConsumerStream, mConsumerStream->StreamID()));
Http2StreamBase::AdjustInitialWindow(); // Http2PushedStream::ReadSegments is needed to call TransmitFrame() // and actually get this information into the session bytestream
RefPtr<Http2Session> session = Session();
session->TransactionHasDataToWrite(this);
} // Otherwise, when we get hooked up, the initial window will get bumped // anyway, so we're good to go.
}
void Http2PushedStream::CurrentBrowserIdChanged(uint64_t id) { if (mConsumerStream) { // Pass through to our sink, who will handle things appropriately.
mConsumerStream->CurrentBrowserIdChanged(id); return;
}
if (mPriorityDependency != oldDependency) {
session->SendPriorityFrame(mStreamID, mPriorityDependency, mPriorityWeight);
}
}
// ConvertPushHeaders is used to convert the pushed request headers // into HTTP/1 format and report some telemetry
nsresult Http2PushedStream::ConvertPushHeaders(Http2Decompressor* decompressor,
nsACString& aHeadersIn,
nsACString& aHeadersOut) {
nsresult rv = decompressor->DecodeHeaderBlock( reinterpret_cast<const uint8_t*>(aHeadersIn.BeginReading()),
aHeadersIn.Length(), aHeadersOut, true); if (NS_FAILED(rv)) {
LOG3(("Http2PushedStream::ConvertPushHeaders %p Error\n", this)); return rv;
}
////////////////////////////////////////// // Http2PushTransactionBuffer // This is the nsAHttpTransction owned by the stream when the pushed // stream has not yet been matched with a pull request //////////////////////////////////////////
// If all the data has been consumed then reset the buffer if (mBufferedHTTP1Consumed == mBufferedHTTP1Used) {
mBufferedHTTP1Consumed = 0;
mBufferedHTTP1Used = 0;
}
return NS_OK;
}
} // namespace net
} // namespace mozilla
¤ Dauer der Verarbeitung: 0.18 Sekunden
(vorverarbeitet)
¤
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.