mirror of
https://github.com/roytam1/basilisk55.git
synced 2026-05-26 15:02:46 +00:00
ported from UXP:
- Allow matroska and avc (h.264) content in matroska/webm containers for video element and MSE. (18f9b185) - Alow AAC audio codec data in matroska/webm streams. Allow CRC32 elements in matroska cluster elements. (6b6aa59f) - Truncate Buffer/Texture on GL_OOM. (3f9e299b) - Bug 1550498 (b0a8ed21) - Don't allow cross-origin POST redirects on 308 codes. (8b7daa53) - Bug 1548822 (b7807cd0) - Do not allow the ^ character to appear in the hostname. (f046b917) - Add CheckedInt check for GL texture uploads. (227b2360) - Implement a threadsafe & revised version of http2PushedStream. (17a4b4f6d) - Convert dom/base/nsImageLoadingContent.cpp to use AsyncOpen2 and followups along with it (1445670 and 1373780 part 2 and 3) (deae241f) and ported part of tenfourfox changes: - #559: M1550498 M1548822 M1540759(partial) M1528481(+WeakPtr for Http2Stream) M1555523 M1552541 (46496870) - #559: M1547266 (97b8db0b)
This commit is contained in:
@@ -22,6 +22,7 @@
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsITabChild.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIImageLoadingContent.h"
|
||||
#include "nsILoadContext.h"
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsContentUtils.h"
|
||||
@@ -145,6 +146,16 @@ nsContentPolicy::CheckPolicy(CPMethod policyMethod,
|
||||
decision);
|
||||
|
||||
if (NS_SUCCEEDED(rv) && NS_CP_REJECTED(*decision)) {
|
||||
// If we are blocking an image, we have to let the
|
||||
// ImageLoadingContent know that we blocked the load.
|
||||
if (externalType == nsIContentPolicy::TYPE_IMAGE ||
|
||||
externalType == nsIContentPolicy::TYPE_IMAGESET) {
|
||||
nsCOMPtr<nsIImageLoadingContent> img =
|
||||
do_QueryInterface(requestingContext);
|
||||
if (img) {
|
||||
img->SetBlockedRequest(*decision);
|
||||
}
|
||||
}
|
||||
/* policy says no, no point continuing to check */
|
||||
return NS_OK;
|
||||
}
|
||||
@@ -193,6 +204,16 @@ nsContentPolicy::CheckPolicy(CPMethod policyMethod,
|
||||
decision);
|
||||
|
||||
if (NS_SUCCEEDED(rv) && NS_CP_REJECTED(*decision)) {
|
||||
// If we are blocking an image, we have to let the
|
||||
// ImageLoadingContent know that we blocked the load.
|
||||
if (externalType == nsIContentPolicy::TYPE_IMAGE ||
|
||||
externalType == nsIContentPolicy::TYPE_IMAGESET) {
|
||||
nsCOMPtr<nsIImageLoadingContent> img =
|
||||
do_QueryInterface(requestingContext);
|
||||
if (img) {
|
||||
img->SetBlockedRequest(*decision);
|
||||
}
|
||||
}
|
||||
/* policy says no, no point continuing to check */
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -8516,12 +8516,9 @@ nsContentUtils::InternalContentPolicyTypeToExternalOrWorker(nsContentPolicyType
|
||||
bool
|
||||
nsContentUtils::IsPreloadType(nsContentPolicyType aType)
|
||||
{
|
||||
if (aType == nsIContentPolicy::TYPE_INTERNAL_SCRIPT_PRELOAD ||
|
||||
aType == nsIContentPolicy::TYPE_INTERNAL_IMAGE_PRELOAD ||
|
||||
aType == nsIContentPolicy::TYPE_INTERNAL_STYLESHEET_PRELOAD) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return (aType == nsIContentPolicy::TYPE_INTERNAL_SCRIPT_PRELOAD ||
|
||||
aType == nsIContentPolicy::TYPE_INTERNAL_IMAGE_PRELOAD ||
|
||||
aType == nsIContentPolicy::TYPE_INTERNAL_STYLESHEET_PRELOAD);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
||||
+14
-8
@@ -9363,19 +9363,23 @@ already_AddRefed<nsIURI>
|
||||
nsDocument::ResolvePreloadImage(nsIURI *aBaseURI,
|
||||
const nsAString& aSrcAttr,
|
||||
const nsAString& aSrcsetAttr,
|
||||
const nsAString& aSizesAttr)
|
||||
const nsAString& aSizesAttr,
|
||||
bool *aIsImgSet)
|
||||
{
|
||||
nsString sourceURL;
|
||||
bool isImgSet;
|
||||
if (mPreloadPictureDepth == 1 && !mPreloadPictureFoundSource.IsVoid()) {
|
||||
// We're in a <picture> element and found a URI from a source previous to
|
||||
// this image, use it.
|
||||
sourceURL = mPreloadPictureFoundSource;
|
||||
isImgSet = true;
|
||||
} else {
|
||||
// Otherwise try to use this <img> as a source
|
||||
HTMLImageElement::SelectSourceForTagWithAttrs(this, false, aSrcAttr,
|
||||
aSrcsetAttr, aSizesAttr,
|
||||
NullString(), NullString(),
|
||||
sourceURL);
|
||||
isImgSet = !aSrcsetAttr.IsEmpty();
|
||||
}
|
||||
|
||||
// Empty sources are not loaded by <img> (i.e. not resolved to the baseURI)
|
||||
@@ -9393,6 +9397,8 @@ nsDocument::ResolvePreloadImage(nsIURI *aBaseURI,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
*aIsImgSet = isImgSet;
|
||||
|
||||
// We don't clear mPreloadPictureFoundSource because subsequent <img> tags in
|
||||
// this this <picture> share the same <sources> (though this is not valid per
|
||||
// spec)
|
||||
@@ -9401,16 +9407,12 @@ nsDocument::ResolvePreloadImage(nsIURI *aBaseURI,
|
||||
|
||||
void
|
||||
nsDocument::MaybePreLoadImage(nsIURI* uri, const nsAString &aCrossOriginAttr,
|
||||
ReferrerPolicy aReferrerPolicy)
|
||||
ReferrerPolicy aReferrerPolicy, bool aIsImgSet)
|
||||
{
|
||||
// Early exit if the img is already present in the img-cache
|
||||
// which indicates that the "real" load has already started and
|
||||
// that we shouldn't preload it.
|
||||
int16_t blockingStatus;
|
||||
if (nsContentUtils::IsImageInCache(uri, static_cast<nsIDocument *>(this)) ||
|
||||
!nsContentUtils::CanLoadImage(uri, static_cast<nsIDocument *>(this),
|
||||
this, NodePrincipal(), &blockingStatus,
|
||||
nsIContentPolicy::TYPE_INTERNAL_IMAGE_PRELOAD)) {
|
||||
if (nsContentUtils::IsImageInCache(uri, static_cast<nsIDocument *>(this))) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -9429,6 +9431,10 @@ nsDocument::MaybePreLoadImage(nsIURI* uri, const nsAString &aCrossOriginAttr,
|
||||
MOZ_CRASH("Unknown CORS mode!");
|
||||
}
|
||||
|
||||
nsContentPolicyType policyType =
|
||||
aIsImgSet ? nsIContentPolicy::TYPE_IMAGESET :
|
||||
nsIContentPolicy::TYPE_INTERNAL_IMAGE_PRELOAD;
|
||||
|
||||
// Image not in cache - trigger preload
|
||||
RefPtr<imgRequestProxy> request;
|
||||
nsresult rv =
|
||||
@@ -9442,7 +9448,7 @@ nsDocument::MaybePreLoadImage(nsIURI* uri, const nsAString &aCrossOriginAttr,
|
||||
loadFlags,
|
||||
NS_LITERAL_STRING("img"),
|
||||
getter_AddRefs(request),
|
||||
nsIContentPolicy::TYPE_INTERNAL_IMAGE_PRELOAD);
|
||||
policyType);
|
||||
|
||||
// Pin image-reference to avoid evicting it from the img-cache before
|
||||
// the "real" load occurs. Unpinned in DispatchContentLoadedEvents and
|
||||
|
||||
@@ -963,11 +963,13 @@ public:
|
||||
ResolvePreloadImage(nsIURI *aBaseURI,
|
||||
const nsAString& aSrcAttr,
|
||||
const nsAString& aSrcsetAttr,
|
||||
const nsAString& aSizesAttr) override;
|
||||
const nsAString& aSizesAttr,
|
||||
bool *aIsImgSet) override;
|
||||
|
||||
virtual void MaybePreLoadImage(nsIURI* uri,
|
||||
const nsAString &aCrossOriginAttr,
|
||||
ReferrerPolicy aReferrerPolicy) override;
|
||||
ReferrerPolicy aReferrerPolicy,
|
||||
bool aIsImgSet) override;
|
||||
virtual void ForgetImagePreload(nsIURI* aURI) override;
|
||||
|
||||
virtual void MaybePreconnect(nsIURI* uri,
|
||||
|
||||
@@ -2407,11 +2407,13 @@ nsGlobalWindow::WouldReuseInnerWindow(nsIDocument* aNewDocument)
|
||||
}
|
||||
|
||||
bool equal;
|
||||
if (NS_SUCCEEDED(mDoc->NodePrincipal()->Equals(aNewDocument->NodePrincipal(),
|
||||
&equal)) &&
|
||||
equal) {
|
||||
if (NS_SUCCEEDED(
|
||||
BasePrincipal::Cast(mDoc->NodePrincipal())->
|
||||
EqualsConsideringDomain(aNewDocument->NodePrincipal(),
|
||||
&equal))) {
|
||||
// Return the result. If true (bug 1552541):
|
||||
// The origin is the same.
|
||||
return true;
|
||||
return equal;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -2309,21 +2309,27 @@ public:
|
||||
* nesting and possible sources, which are used to inform URL selection
|
||||
* responsive <picture> or <img srcset> images. Unset attributes are expected
|
||||
* to be marked void.
|
||||
* If this image is for <picture> or <img srcset>, aIsImgSet will be set to
|
||||
* true, false otherwise.
|
||||
*/
|
||||
virtual already_AddRefed<nsIURI>
|
||||
ResolvePreloadImage(nsIURI *aBaseURI,
|
||||
const nsAString& aSrcAttr,
|
||||
const nsAString& aSrcsetAttr,
|
||||
const nsAString& aSizesAttr) = 0;
|
||||
const nsAString& aSizesAttr,
|
||||
bool *aIsImgSet) = 0;
|
||||
/**
|
||||
* Called by nsParser to preload images. Can be removed and code moved
|
||||
* to nsPreloadURIs::PreloadURIs() in file nsParser.cpp whenever the
|
||||
* parser-module is linked with gklayout-module. aCrossOriginAttr should
|
||||
* be a void string if the attr is not present.
|
||||
* aIsImgSet is the value got from calling ResolvePreloadImage, it is true
|
||||
* when this image is for loading <picture> or <img srcset> images.
|
||||
*/
|
||||
virtual void MaybePreLoadImage(nsIURI* uri,
|
||||
const nsAString& aCrossOriginAttr,
|
||||
ReferrerPolicyEnum aReferrerPolicy) = 0;
|
||||
ReferrerPolicyEnum aReferrerPolicy,
|
||||
bool aIsImgSet) = 0;
|
||||
|
||||
/**
|
||||
* Called by images to forget an image preload when they start doing
|
||||
|
||||
@@ -103,6 +103,15 @@ interface nsIImageLoadingContent : imgINotificationObserver
|
||||
*/
|
||||
imgIRequest getRequest(in long aRequestType);
|
||||
|
||||
/**
|
||||
* Call this function when the request was blocked by any of the
|
||||
* security policies enforced.
|
||||
*
|
||||
* @param aContentDecision the decision returned from nsIContentPolicy
|
||||
* (any of the types REJECT_*)
|
||||
*/
|
||||
void setBlockedRequest(in int16_t aContentDecision);
|
||||
|
||||
/**
|
||||
* @return true if the current request's size is available.
|
||||
*/
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
|
||||
#include "mozAutoDocUpdate.h"
|
||||
#include "mozilla/AsyncEventDispatcher.h"
|
||||
#include "mozilla/AutoRestore.h"
|
||||
#include "mozilla/EventStates.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/ImageTracker.h"
|
||||
@@ -95,6 +96,7 @@ nsImageLoadingContent::nsImageLoadingContent()
|
||||
mStateChangerDepth(0),
|
||||
mCurrentRequestRegistered(false),
|
||||
mPendingRequestRegistered(false),
|
||||
mIsStartingImageLoad(false),
|
||||
mFrameCreateCalled(false)
|
||||
{
|
||||
if (!nsContentUtils::GetImgLoaderForChannel(nullptr, nullptr)) {
|
||||
@@ -790,6 +792,11 @@ nsImageLoadingContent::LoadImage(nsIURI* aNewURI,
|
||||
nsIDocument* aDocument,
|
||||
nsLoadFlags aLoadFlags)
|
||||
{
|
||||
MOZ_ASSERT(!mIsStartingImageLoad, "some evil code is reentering LoadImage.");
|
||||
if (mIsStartingImageLoad) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Pending load/error events need to be canceled in some situations. This
|
||||
// is not documented in the spec, but can cause site compat problems if not
|
||||
// done. See bug 1309461 and https://github.com/whatwg/html/issues/1872.
|
||||
@@ -819,6 +826,21 @@ nsImageLoadingContent::LoadImage(nsIURI* aNewURI,
|
||||
}
|
||||
}
|
||||
|
||||
AutoRestore<bool> guard(mIsStartingImageLoad);
|
||||
mIsStartingImageLoad = true;
|
||||
|
||||
// Data documents, or documents from DOMParser shouldn't perform image loading.
|
||||
if (aDocument->IsLoadedAsData()) {
|
||||
// This is the only codepath on which we can reach SetBlockedRequest while
|
||||
// our pending request exists. Just clear it out here if we do have one.
|
||||
ClearPendingRequest(NS_BINDING_ABORTED,
|
||||
Some(OnNonvisible::DISCARD_IMAGES));
|
||||
SetBlockedRequest(nsIContentPolicy::REJECT_REQUEST);
|
||||
FireEvent(NS_LITERAL_STRING("error"));
|
||||
FireEvent(NS_LITERAL_STRING("loadend"));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// URI equality check.
|
||||
//
|
||||
// We skip the equality check if our current image was blocked, since in that
|
||||
@@ -849,23 +871,8 @@ nsImageLoadingContent::LoadImage(nsIURI* aNewURI,
|
||||
"Principal mismatch?");
|
||||
#endif
|
||||
|
||||
// Are we blocked?
|
||||
int16_t cpDecision = nsIContentPolicy::REJECT_REQUEST;
|
||||
nsContentPolicyType policyType = PolicyTypeForLoad(aImageLoadType);
|
||||
|
||||
nsContentUtils::CanLoadImage(aNewURI,
|
||||
static_cast<nsIImageLoadingContent*>(this),
|
||||
aDocument,
|
||||
aDocument->NodePrincipal(),
|
||||
&cpDecision,
|
||||
policyType);
|
||||
if (!NS_CP_ACCEPTED(cpDecision)) {
|
||||
FireEvent(NS_LITERAL_STRING("error"));
|
||||
FireEvent(NS_LITERAL_STRING("loadend"));
|
||||
SetBlockedRequest(aNewURI, cpDecision);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsLoadFlags loadFlags = aLoadFlags;
|
||||
int32_t corsmode = GetCORSMode();
|
||||
if (corsmode == CORS_ANONYMOUS) {
|
||||
@@ -883,7 +890,6 @@ nsImageLoadingContent::LoadImage(nsIURI* aNewURI,
|
||||
referrerPolicy = imgReferrerPolicy;
|
||||
}
|
||||
|
||||
// Not blocked. Do the load.
|
||||
RefPtr<imgRequestProxy>& req = PrepareNextRequest(aImageLoadType);
|
||||
nsCOMPtr<nsIContent> content =
|
||||
do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
|
||||
@@ -937,7 +943,6 @@ nsImageLoadingContent::LoadImage(nsIURI* aNewURI,
|
||||
|
||||
FireEvent(NS_LITERAL_STRING("error"));
|
||||
FireEvent(NS_LITERAL_STRING("loadend"));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@@ -1217,46 +1222,42 @@ nsImageLoadingContent::PrepareNextRequest(ImageLoadType aImageLoadType)
|
||||
mMostRecentRequestChange = now;
|
||||
}
|
||||
|
||||
// If we don't have a usable current request, get rid of any half-baked
|
||||
// request that might be sitting there and make this one current.
|
||||
if (!HaveSize(mCurrentRequest))
|
||||
return PrepareCurrentRequest(aImageLoadType);
|
||||
|
||||
// Otherwise, make it pending.
|
||||
return PreparePendingRequest(aImageLoadType);
|
||||
// We only want to cancel the existing current request if size is not
|
||||
// available. bz says the web depends on this behavior.
|
||||
// Otherwise, we get rid of any half-baked request that might be sitting there
|
||||
// and make this one current.
|
||||
// TODO: Bug 583491
|
||||
// Investigate/Cleanup NS_ERROR_IMAGE_SRC_CHANGED use in nsImageFrame.cpp
|
||||
return HaveSize(mCurrentRequest) ?
|
||||
PreparePendingRequest(aImageLoadType) :
|
||||
PrepareCurrentRequest(aImageLoadType);
|
||||
}
|
||||
|
||||
void
|
||||
nsImageLoadingContent::SetBlockedRequest(nsIURI* aURI, int16_t aContentDecision)
|
||||
nsresult
|
||||
nsImageLoadingContent::SetBlockedRequest(int16_t aContentDecision)
|
||||
{
|
||||
// If this is not calling from LoadImage, for example, from ServiceWorker,
|
||||
// bail out.
|
||||
if (!mIsStartingImageLoad) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Sanity
|
||||
MOZ_ASSERT(!NS_CP_ACCEPTED(aContentDecision), "Blocked but not?");
|
||||
|
||||
// We do some slightly illogical stuff here to maintain consistency with
|
||||
// old behavior that people probably depend on. Even in the case where the
|
||||
// new image is blocked, the old one should really be canceled with the
|
||||
// reason "image source changed". However, apparently there's some abuse
|
||||
// over in nsImageFrame where the displaying of the "broken" icon for the
|
||||
// next image depends on the cancel reason of the previous image. ugh.
|
||||
// XXX(seth): So shouldn't we fix nsImageFrame?!
|
||||
ClearPendingRequest(NS_ERROR_IMAGE_BLOCKED,
|
||||
Some(OnNonvisible::DISCARD_IMAGES));
|
||||
|
||||
// For the blocked case, we only want to cancel the existing current request
|
||||
// if size is not available. bz says the web depends on this behavior.
|
||||
if (!HaveSize(mCurrentRequest)) {
|
||||
// We should never have a pending request after we got blocked.
|
||||
MOZ_ASSERT(!mPendingRequest, "mPendingRequest should be null.");
|
||||
|
||||
if (HaveSize(mCurrentRequest)) {
|
||||
// PreparePendingRequest set mPendingRequestFlags, now since we've decided
|
||||
// to block it, we reset it back to 0.
|
||||
mPendingRequestFlags = 0;
|
||||
} else {
|
||||
mImageBlockingStatus = aContentDecision;
|
||||
uint32_t keepFlags = mCurrentRequestFlags & REQUEST_IS_IMAGESET;
|
||||
ClearCurrentRequest(NS_ERROR_IMAGE_BLOCKED,
|
||||
Some(OnNonvisible::DISCARD_IMAGES));
|
||||
|
||||
// We still want to remember what URI we were and if it was an imageset,
|
||||
// despite not having an actual request. These are both cleared as part of
|
||||
// ClearCurrentRequest() before a new request is started.
|
||||
mCurrentURI = aURI;
|
||||
mCurrentRequestFlags = keepFlags;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
RefPtr<imgRequestProxy>&
|
||||
@@ -1267,7 +1268,7 @@ nsImageLoadingContent::PrepareCurrentRequest(ImageLoadType aImageLoadType)
|
||||
mImageBlockingStatus = nsIContentPolicy::ACCEPT;
|
||||
|
||||
// Get rid of anything that was there previously.
|
||||
ClearCurrentRequest(NS_ERROR_IMAGE_SRC_CHANGED,
|
||||
ClearCurrentRequest(NS_BINDING_ABORTED,
|
||||
Some(OnNonvisible::DISCARD_IMAGES));
|
||||
|
||||
if (mNewRequestsWillNeedAnimationReset) {
|
||||
@@ -1286,7 +1287,7 @@ RefPtr<imgRequestProxy>&
|
||||
nsImageLoadingContent::PreparePendingRequest(ImageLoadType aImageLoadType)
|
||||
{
|
||||
// Get rid of anything that was there previously.
|
||||
ClearPendingRequest(NS_ERROR_IMAGE_SRC_CHANGED,
|
||||
ClearPendingRequest(NS_BINDING_ABORTED,
|
||||
Some(OnNonvisible::DISCARD_IMAGES));
|
||||
|
||||
if (mNewRequestsWillNeedAnimationReset) {
|
||||
|
||||
@@ -302,18 +302,11 @@ protected:
|
||||
*/
|
||||
RefPtr<imgRequestProxy>& PrepareNextRequest(ImageLoadType aImageLoadType);
|
||||
|
||||
/**
|
||||
* Called when we would normally call PrepareNextRequest(), but the request was
|
||||
* blocked.
|
||||
*/
|
||||
void SetBlockedRequest(nsIURI* aURI, int16_t aContentDecision);
|
||||
|
||||
/**
|
||||
* Returns a COMPtr reference to the current/pending image requests, cleaning
|
||||
* up and canceling anything that was there before. Note that if you just want
|
||||
* to get rid of one of the requests, you should call
|
||||
* Clear*Request(NS_BINDING_ABORTED) instead, since it passes a more appropriate
|
||||
* aReason than Prepare*Request() does (NS_ERROR_IMAGE_SRC_CHANGED).
|
||||
* Clear*Request(NS_BINDING_ABORTED) instead.
|
||||
*
|
||||
* @param aImageLoadType The ImageLoadType for this request
|
||||
*/
|
||||
@@ -455,6 +448,14 @@ private:
|
||||
bool mCurrentRequestRegistered;
|
||||
bool mPendingRequestRegistered;
|
||||
|
||||
// This member is used in SetBlockedRequest, if it's true, then this call is
|
||||
// triggered from LoadImage.
|
||||
// If this is false, it means this call is from other places like
|
||||
// ServiceWorker, then we will ignore call to SetBlockedRequest for now.
|
||||
//
|
||||
// Also we use this variable to check if some evil code is reentering LoadImage.
|
||||
bool mIsStartingImageLoad;
|
||||
|
||||
// True when FrameCreate has been called but FrameDestroy has not.
|
||||
bool mFrameCreateCalled;
|
||||
};
|
||||
|
||||
@@ -134,6 +134,7 @@ WebGLBuffer::BufferData(GLenum target, size_t size, const void* data, GLenum usa
|
||||
if (error) {
|
||||
MOZ_ASSERT(error == LOCAL_GL_OUT_OF_MEMORY);
|
||||
mContext->ErrorOutOfMemory("%s: Error from driver: 0x%04x", funcName, error);
|
||||
mByteLength = 0;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -215,6 +215,16 @@ WebGLRenderbuffer::RenderbufferStorage(const char* funcName, uint32_t samples,
|
||||
if (error) {
|
||||
const char* errorName = mContext->ErrorName(error);
|
||||
mContext->GenerateWarning("%s generated error %s", funcName, errorName);
|
||||
if (error == LOCAL_GL_OUT_OF_MEMORY) {
|
||||
// Truncate.
|
||||
mSamples = 0;
|
||||
mFormat = nullptr;
|
||||
mWidth = 0;
|
||||
mHeight = 0;
|
||||
mImageDataStatus = WebGLImageDataStatus::NoImageData;
|
||||
|
||||
InvalidateStatusOfAttachedFBs(funcName);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1222,6 +1222,12 @@ WebGLTexture::TexParameter(TexTarget texTarget, GLenum pname, const FloatOrInt&
|
||||
mContext->gl->fTexParameterf(texTarget.get(), pname, clamped.f);
|
||||
}
|
||||
|
||||
void WebGLTexture::Truncate(const char* funcName) {
|
||||
for (auto& cur : mImageInfoArr) {
|
||||
SetImageInfo(funcName, &cur, ImageInfo());
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLTexture)
|
||||
|
||||
@@ -387,6 +387,7 @@ public:
|
||||
bool* const out_initFailed);
|
||||
|
||||
bool IsMipmapCubeComplete() const;
|
||||
void Truncate(const char* funcName);
|
||||
|
||||
bool IsCubeMap() const { return (mTarget == LOCAL_GL_TEXTURE_CUBE_MAP); }
|
||||
|
||||
|
||||
@@ -1170,6 +1170,7 @@ WebGLTexture::TexStorage(const char* funcName, TexTarget target, GLsizei levels,
|
||||
if (error == LOCAL_GL_OUT_OF_MEMORY) {
|
||||
mContext->ErrorOutOfMemory("%s: Ran out of memory during texture allocation.",
|
||||
funcName);
|
||||
Truncate(funcName);
|
||||
return;
|
||||
}
|
||||
if (error) {
|
||||
@@ -1302,6 +1303,7 @@ WebGLTexture::TexImage(const char* funcName, TexImageTarget target, GLint level,
|
||||
if (glError == LOCAL_GL_OUT_OF_MEMORY) {
|
||||
mContext->ErrorOutOfMemory("%s: Driver ran out of memory during upload.",
|
||||
funcName);
|
||||
Truncate(funcName);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1390,6 +1392,7 @@ WebGLTexture::TexSubImage(const char* funcName, TexImageTarget target, GLint lev
|
||||
if (glError == LOCAL_GL_OUT_OF_MEMORY) {
|
||||
mContext->ErrorOutOfMemory("%s: Driver ran out of memory during upload.",
|
||||
funcName);
|
||||
Truncate(funcName);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1506,6 +1509,7 @@ WebGLTexture::CompressedTexImage(const char* funcName, TexImageTarget target, GL
|
||||
blob->mAvailBytes, blob->mPtr);
|
||||
if (error == LOCAL_GL_OUT_OF_MEMORY) {
|
||||
mContext->ErrorOutOfMemory("%s: Ran out of memory during upload.", funcName);
|
||||
Truncate(funcName);
|
||||
return;
|
||||
}
|
||||
if (error) {
|
||||
@@ -1656,6 +1660,7 @@ WebGLTexture::CompressedTexSubImage(const char* funcName, TexImageTarget target,
|
||||
blob->mAvailBytes, blob->mPtr);
|
||||
if (error == LOCAL_GL_OUT_OF_MEMORY) {
|
||||
mContext->ErrorOutOfMemory("%s: Ran out of memory during upload.", funcName);
|
||||
Truncate(funcName);
|
||||
return;
|
||||
}
|
||||
if (error) {
|
||||
@@ -1998,7 +2003,7 @@ WebGLTexture::ValidateCopyTexImageForFeedback(const char* funcName, uint32_t lev
|
||||
|
||||
static bool
|
||||
DoCopyTexOrSubImage(WebGLContext* webgl, const char* funcName, bool isSubImage,
|
||||
const WebGLTexture* tex, TexImageTarget target, GLint level,
|
||||
WebGLTexture* tex, TexImageTarget target, GLint level,
|
||||
GLint xWithinSrc, GLint yWithinSrc,
|
||||
uint32_t srcTotalWidth, uint32_t srcTotalHeight,
|
||||
const webgl::FormatUsageInfo* srcUsage,
|
||||
@@ -2075,6 +2080,7 @@ DoCopyTexOrSubImage(WebGLContext* webgl, const char* funcName, bool isSubImage,
|
||||
|
||||
if (error == LOCAL_GL_OUT_OF_MEMORY) {
|
||||
webgl->ErrorOutOfMemory("%s: Ran out of memory during texture copy.", funcName);
|
||||
tex->Truncate(funcName);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -186,7 +186,8 @@ bool
|
||||
MP4Decoder::IsH264(const nsACString& aMimeType)
|
||||
{
|
||||
return aMimeType.EqualsLiteral("video/mp4") ||
|
||||
aMimeType.EqualsLiteral("video/avc");
|
||||
aMimeType.EqualsLiteral("video/avc") ||
|
||||
aMimeType.EqualsLiteral("video/webm; codecs=avc1");
|
||||
}
|
||||
|
||||
/* static */
|
||||
|
||||
@@ -701,6 +701,10 @@ ContainerParser::CreateForMIMEType(const MediaContainerType& aType)
|
||||
return new WebMContainerParser(aType);
|
||||
}
|
||||
|
||||
if (aType.Type() == MEDIAMIMETYPE("video/x-matroska")) {
|
||||
return new WebMContainerParser(aType);
|
||||
}
|
||||
|
||||
#ifdef MOZ_FMP4
|
||||
if (aType.Type() == MEDIAMIMETYPE("video/mp4")
|
||||
|| aType.Type() == MEDIAMIMETYPE("audio/mp4")) {
|
||||
|
||||
@@ -113,7 +113,8 @@ MediaSource::IsTypeSupported(const nsAString& aType, DecoderDoctorDiagnostics* a
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
if (mimeType == MEDIAMIMETYPE("video/webm")) {
|
||||
if (mimeType == MEDIAMIMETYPE("video/webm") ||
|
||||
mimeType == MEDIAMIMETYPE("video/x-matroska")) {
|
||||
if (!(Preferences::GetBool("media.mediasource.webm.enabled", false) ||
|
||||
IsWebMForced(aDiagnostics))) {
|
||||
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
|
||||
|
||||
@@ -814,6 +814,7 @@ TrackBuffersManager::CreateDemuxerforMIMEType()
|
||||
ShutdownDemuxers();
|
||||
|
||||
if (mType.Type() == MEDIAMIMETYPE("video/webm") ||
|
||||
mType.Type() == MEDIAMIMETYPE("video/x-matroska") ||
|
||||
mType.Type() == MEDIAMIMETYPE("audio/webm")) {
|
||||
mInputDemuxer = new WebMDemuxer(mCurrentInputBuffer, true /* IsMediaSource*/ );
|
||||
return;
|
||||
|
||||
@@ -60,6 +60,15 @@ WebMDecoder::IsSupportedType(const MediaContainerType& aContainerType)
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (IsH264CodecString(codec)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (IsAACCodecString(codec)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Some unsupported codec.
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -326,6 +326,20 @@ WebMDemuxer::ReadMetadata()
|
||||
case NESTEGG_CODEC_AV1:
|
||||
mInfo.mVideo.mMimeType = "video/webm; codecs=av1";
|
||||
break;
|
||||
case NESTEGG_CODEC_AVC1: {
|
||||
mInfo.mVideo.mMimeType = "video/webm; codecs=avc1";
|
||||
|
||||
unsigned char* data = 0;
|
||||
size_t length = 0;
|
||||
r = nestegg_track_codec_data(context, track, 0, &data, &length);
|
||||
if (r == -1) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mInfo.mVideo.mExtraData = new MediaByteBuffer(length);
|
||||
mInfo.mVideo.mExtraData->AppendElements(data, length);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
NS_WARNING("Unknown WebM video codec");
|
||||
return NS_ERROR_FAILURE;
|
||||
@@ -409,6 +423,8 @@ WebMDemuxer::ReadMetadata()
|
||||
mInfo.mAudio.mMimeType = "audio/opus";
|
||||
OpusDataDecoder::AppendCodecDelay(mInfo.mAudio.mCodecSpecificConfig,
|
||||
media::TimeUnit::FromNanoseconds(params.codec_delay).ToMicroseconds());
|
||||
} else if (mAudioCodec == NESTEGG_CODEC_AAC) {
|
||||
mInfo.mAudio.mMimeType = "audio/mp4a-latm";
|
||||
}
|
||||
mSeekPreroll = params.seek_preroll;
|
||||
mInfo.mAudio.mRate = params.rate;
|
||||
@@ -678,6 +694,9 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl
|
||||
isKeyframe = AOMDecoder::IsKeyframe(sample);
|
||||
break;
|
||||
#endif
|
||||
case NESTEGG_CODEC_AVC1:
|
||||
isKeyframe = nestegg_packet_has_keyframe(holder->Packet());
|
||||
break;
|
||||
default:
|
||||
NS_WARNING("Cannot detect keyframes in unknown WebM video codec");
|
||||
return NS_ERROR_FAILURE;
|
||||
@@ -698,7 +717,7 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl
|
||||
dimensions = AOMDecoder::GetFrameSize(sample);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (mLastSeenFrameSize.isSome()
|
||||
&& (dimensions != mLastSeenFrameSize.value())) {
|
||||
mInfo.mVideo.mDisplay = dimensions;
|
||||
@@ -774,6 +793,11 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl
|
||||
if (aType == TrackInfo::kVideoTrack) {
|
||||
sample->mTrackInfo = mSharedVideoTrackInfo;
|
||||
}
|
||||
|
||||
if (mVideoCodec == NESTEGG_CODEC_AVC1) {
|
||||
sample->mExtraData = mInfo.mVideo.mExtraData;
|
||||
}
|
||||
|
||||
aSamples->Push(sample);
|
||||
}
|
||||
return NS_OK;
|
||||
|
||||
@@ -1381,7 +1381,7 @@ nsPluginStreamListenerPeer::AsyncOnChannelRedirect(nsIChannel *oldChannel, nsICh
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Don't allow cross-origin 307 POST redirects.
|
||||
// Don't allow cross-origin 307/308 POST redirects.
|
||||
nsCOMPtr<nsIHttpChannel> oldHttpChannel(do_QueryInterface(oldChannel));
|
||||
if (oldHttpChannel) {
|
||||
uint32_t responseStatus;
|
||||
@@ -1389,7 +1389,7 @@ nsPluginStreamListenerPeer::AsyncOnChannelRedirect(nsIChannel *oldChannel, nsICh
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
if (responseStatus == 307) {
|
||||
if (responseStatus == 307 || responseStatus == 308) {
|
||||
nsAutoCString method;
|
||||
rv = oldHttpChannel->GetRequestMethod(method);
|
||||
if (NS_FAILED(rv)) {
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "nsMixedContentBlocker.h"
|
||||
#include "nsCDefaultURIFixup.h"
|
||||
#include "nsIURIFixup.h"
|
||||
#include "nsIImageLoadingContent.h"
|
||||
#include "nsINestedURI.h"
|
||||
|
||||
#include "mozilla/dom/Element.h"
|
||||
@@ -732,6 +733,8 @@ nsContentSecurityManager::CheckChannel(nsIChannel* aChannel)
|
||||
// within nsCorsListenerProxy
|
||||
rv = DoCheckLoadURIChecks(uri, loadInfo);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
// TODO: Bug 1371237
|
||||
// consider calling SetBlockedRequest in nsContentSecurityManager::CheckChannel
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
||||
@@ -178,7 +178,22 @@ TexSubImage2DWithoutUnpackSubimage(GLContext* gl,
|
||||
// isn't supported. We make a copy of the texture data we're using,
|
||||
// such that we're using the whole row of data in the copy. This turns
|
||||
// out to be more efficient than uploading row-by-row; see bug 698197.
|
||||
unsigned char* newPixels = new (fallible) unsigned char[width*height*pixelsize];
|
||||
|
||||
// Width and height are never more than 16384. At 16Ki*16Ki, 4Bpp is 1GiB, but
|
||||
// if we allow 8Bpp (16-bit channels, or higher) here, that's 2GiB+, which would
|
||||
// overflow on 32-bit.
|
||||
MOZ_ASSERT(width <= 16384);
|
||||
MOZ_ASSERT(height <= 16384);
|
||||
MOZ_ASSERT(pixelsize < 8);
|
||||
|
||||
const auto size = CheckedInt<size_t>(width) * height * pixelsize;
|
||||
if (!size.isValid()) {
|
||||
// This should never happen, but we use a defensive check.
|
||||
MOZ_ASSERT_UNREACHABLE("Unacceptable size calculated.!");
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned char* newPixels = new (fallible) unsigned char[size.value()];
|
||||
|
||||
if (newPixels) {
|
||||
unsigned char* rowDest = newPixels;
|
||||
@@ -303,7 +318,22 @@ TexImage2DHelper(GLContext* gl,
|
||||
GLsizei paddedWidth = RoundUpPow2((uint32_t)width);
|
||||
GLsizei paddedHeight = RoundUpPow2((uint32_t)height);
|
||||
|
||||
GLvoid* paddedPixels = new unsigned char[paddedWidth * paddedHeight * pixelsize];
|
||||
// Width and height are never more than 16384. At 16Ki*16Ki, 4Bpp
|
||||
// is 1GiB, but if we allow 8Bpp (or higher) here, that's 2GiB,
|
||||
// which would overflow on 32-bit.
|
||||
MOZ_ASSERT(width <= 16384);
|
||||
MOZ_ASSERT(height <= 16384);
|
||||
MOZ_ASSERT(pixelsize < 8);
|
||||
|
||||
const auto size =
|
||||
CheckedInt<size_t>(paddedWidth) * paddedHeight * pixelsize;
|
||||
if (!size.isValid()) {
|
||||
// This should never happen, but we use a defensive check.
|
||||
MOZ_ASSERT_UNREACHABLE("Unacceptable size calculated.!");
|
||||
return;
|
||||
}
|
||||
|
||||
GLvoid* paddedPixels = new unsigned char[size.value()];
|
||||
|
||||
// Pad out texture data to be in a POT sized buffer for uploading to
|
||||
// a POT sized texture
|
||||
@@ -483,13 +513,17 @@ UploadImageDataToTexture(GLContext* gl,
|
||||
surfaceFormat = SurfaceFormat::A8;
|
||||
break;
|
||||
default:
|
||||
NS_ASSERTION(false, "Unhandled image surface format!");
|
||||
MOZ_ASSERT_UNREACHABLE(false, "Unhandled image surface format!");
|
||||
}
|
||||
|
||||
if (aOutUploadSize) {
|
||||
*aOutUploadSize = 0;
|
||||
}
|
||||
|
||||
if (surfaceFormat == gfx::SurfaceFormat::UNKNOWN) {
|
||||
return gfx::SurfaceFormat::UNKNOWN;
|
||||
}
|
||||
|
||||
if (aNeedInit || !CanUploadSubTextures(gl)) {
|
||||
// If the texture needs initialized, or we are unable to
|
||||
// upload sub textures, then initialize and upload the entire
|
||||
|
||||
@@ -1697,6 +1697,7 @@ imgLoader::ValidateRequestWithNewChannel(imgRequest* request,
|
||||
|
||||
rv = newChannel->AsyncOpen2(listener);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
req->CancelAndForgetObserver(rv);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -72,6 +72,8 @@ extern "C" {
|
||||
#define NESTEGG_CODEC_VP9 2 /**< Track uses Google On2 VP9 codec. */
|
||||
#define NESTEGG_CODEC_OPUS 3 /**< Track uses Xiph Opus codec. */
|
||||
#define NESTEGG_CODEC_AV1 4 /**< Track uses AOMedia AV1 codec. */
|
||||
#define NESTEGG_CODEC_AVC1 5 /**< Track uses AVC1 'h264' */
|
||||
#define NESTEGG_CODEC_AAC 6 /**< Track uses AAC 'mp4a' */
|
||||
#define NESTEGG_CODEC_UNKNOWN INT_MAX /**< Track uses unknown codec. */
|
||||
|
||||
#define NESTEGG_VIDEO_MONO 0 /**< Track is mono video. */
|
||||
|
||||
@@ -157,6 +157,8 @@ enum ebml_type_enum {
|
||||
#define TRACK_ID_AV1 "V_AV1"
|
||||
#define TRACK_ID_VORBIS "A_VORBIS"
|
||||
#define TRACK_ID_OPUS "A_OPUS"
|
||||
#define TRACK_ID_AVC1 "V_MPEG4/ISO/AVC"
|
||||
#define TRACK_ID_AAC "A_AAC"
|
||||
|
||||
/* Track Encryption */
|
||||
#define CONTENT_ENC_ALGO_AES 5
|
||||
@@ -2401,6 +2403,12 @@ nestegg_track_codec_id(nestegg * ctx, unsigned int track)
|
||||
if (strcmp(codec_id, TRACK_ID_OPUS) == 0)
|
||||
return NESTEGG_CODEC_OPUS;
|
||||
|
||||
if (strcmp(codec_id, TRACK_ID_AVC1) == 0)
|
||||
return NESTEGG_CODEC_AVC1;
|
||||
|
||||
if (strcmp(codec_id, TRACK_ID_AAC) == 0)
|
||||
return NESTEGG_CODEC_AAC;
|
||||
|
||||
return NESTEGG_CODEC_UNKNOWN;
|
||||
}
|
||||
|
||||
@@ -2421,7 +2429,8 @@ nestegg_track_codec_data_count(nestegg * ctx, unsigned int track,
|
||||
|
||||
codec_id = nestegg_track_codec_id(ctx, track);
|
||||
|
||||
if (codec_id == NESTEGG_CODEC_OPUS) {
|
||||
if (codec_id == NESTEGG_CODEC_OPUS ||
|
||||
codec_id == NESTEGG_CODEC_AAC) {
|
||||
*count = 1;
|
||||
return 0;
|
||||
}
|
||||
@@ -2459,7 +2468,9 @@ nestegg_track_codec_data(nestegg * ctx, unsigned int track, unsigned int item,
|
||||
return -1;
|
||||
|
||||
if (nestegg_track_codec_id(ctx, track) != NESTEGG_CODEC_VORBIS &&
|
||||
nestegg_track_codec_id(ctx, track) != NESTEGG_CODEC_OPUS)
|
||||
nestegg_track_codec_id(ctx, track) != NESTEGG_CODEC_OPUS &&
|
||||
nestegg_track_codec_id(ctx, track) != NESTEGG_CODEC_AVC1 &&
|
||||
nestegg_track_codec_id(ctx, track) != NESTEGG_CODEC_AAC)
|
||||
return -1;
|
||||
|
||||
if (ne_get_binary(entry->codec_private, &codec_private) != 0)
|
||||
@@ -2772,6 +2783,19 @@ nestegg_read_packet(nestegg * ctx, nestegg_packet ** pkt)
|
||||
if (r != 1)
|
||||
return r;
|
||||
|
||||
/* Some files have a crc32 element, since it also has to be first it
|
||||
conflicts with the timecode spec. Just ignore it */
|
||||
if (id == ID_CRC32) {
|
||||
ctx->log(ctx, NESTEGG_LOG_DEBUG,
|
||||
"read_packet: skipping crc element in a cluster");
|
||||
r = ne_io_read_skip(ctx->io, size);
|
||||
if (r != 1)
|
||||
return r;
|
||||
r = ne_read_element(ctx, &id, &size);
|
||||
if (r != 1)
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Timecode must be the first element in a Cluster, per spec. */
|
||||
if (id != ID_TIMECODE)
|
||||
return -1;
|
||||
|
||||
@@ -521,7 +521,7 @@ nsStandardURL::ValidIPv6orHostname(const char *host, uint32_t length)
|
||||
}
|
||||
|
||||
const char *end = host + length;
|
||||
if (end != net_FindCharInSet(host, end, CONTROL_CHARACTERS " #/:?@[\\]*<>|\"")) {
|
||||
if (end != net_FindCharInSet(host, end, CONTROL_CHARACTERS " #/:?@[\\]*<>|\"^")) {
|
||||
// We still allow % because it is in the ID of addons.
|
||||
// Any percent encoded ASCII characters that are not allowed in the
|
||||
// hostname are not percent decoded, and will be parsed just fine.
|
||||
|
||||
@@ -30,8 +30,8 @@ class CallChannelOnPush final : public Runnable {
|
||||
Http2PushedStream *pushStream)
|
||||
: mAssociatedChannel(associatedChannel)
|
||||
, mPushedURI(pushedURI)
|
||||
, mPushedStream(pushStream)
|
||||
{
|
||||
mPushedStreamWrapper = new Http2PushedStreamWrapper(pushStream);
|
||||
}
|
||||
|
||||
NS_IMETHOD Run() override
|
||||
@@ -40,21 +40,95 @@ class CallChannelOnPush final : public Runnable {
|
||||
RefPtr<nsHttpChannel> channel;
|
||||
CallQueryInterface(mAssociatedChannel, channel.StartAssignment());
|
||||
MOZ_ASSERT(channel);
|
||||
if (channel && NS_SUCCEEDED(channel->OnPush(mPushedURI, mPushedStream))) {
|
||||
if (channel &&
|
||||
NS_SUCCEEDED(channel->OnPush(mPushedURI, mPushedStreamWrapper))) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
LOG3(("Http2PushedStream Orphan %p failed OnPush\n", this));
|
||||
mPushedStream->OnPushFailed();
|
||||
mPushedStreamWrapper->OnPushFailed();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIHttpChannelInternal> mAssociatedChannel;
|
||||
const nsCString mPushedURI;
|
||||
Http2PushedStream *mPushedStream;
|
||||
RefPtr<Http2PushedStreamWrapper> mPushedStreamWrapper;
|
||||
};
|
||||
|
||||
// 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 (PR_GetCurrentThread() == gSocketThread) {
|
||||
return false;
|
||||
}
|
||||
|
||||
gSocketTransportService->Dispatch(
|
||||
NewNonOwningRunnableMethod(this, &Http2PushedStreamWrapper::Release),
|
||||
NS_DISPATCH_NORMAL);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF(Http2PushedStreamWrapper)
|
||||
NS_IMETHODIMP_(MozExternalRefCountType)
|
||||
Http2PushedStreamWrapper::Release() {
|
||||
nsrefcnt count = mRefCnt - 1;
|
||||
if (DispatchRelease()) {
|
||||
// Redispatched to the socket thread.
|
||||
return count;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(0 != mRefCnt, "dup release");
|
||||
count = --mRefCnt;
|
||||
NS_LOG_RELEASE(this, count, "Http2PushedStreamWrapper");
|
||||
|
||||
if (0 == count) {
|
||||
mRefCnt = 1;
|
||||
delete (this);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(Http2PushedStreamWrapper)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
Http2PushedStreamWrapper::Http2PushedStreamWrapper(
|
||||
Http2PushedStream* aPushStream) {
|
||||
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread, "not on socket thread");
|
||||
mStream = aPushStream;
|
||||
mRequestString = aPushStream->GetRequestString();
|
||||
}
|
||||
|
||||
Http2PushedStreamWrapper::~Http2PushedStreamWrapper() {
|
||||
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread, "not on socket thread");
|
||||
}
|
||||
|
||||
Http2PushedStream* Http2PushedStreamWrapper::GetStream() {
|
||||
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread, "not on socket thread");
|
||||
if (mStream) {
|
||||
Http2Stream* stream = mStream;
|
||||
return static_cast<Http2PushedStream*>(stream);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Http2PushedStreamWrapper::OnPushFailed() {
|
||||
if (PR_GetCurrentThread() == gSocketThread) {
|
||||
if (mStream) {
|
||||
Http2Stream* stream = mStream;
|
||||
static_cast<Http2PushedStream*>(stream)->OnPushFailed();
|
||||
}
|
||||
} else {
|
||||
gSocketTransportService->Dispatch(
|
||||
NewRunnableMethod(this, &Http2PushedStreamWrapper::OnPushFailed),
|
||||
NS_DISPATCH_NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////
|
||||
// Http2PushedStream
|
||||
//////////////////////////////////////////
|
||||
|
||||
@@ -123,6 +123,24 @@ private:
|
||||
uint32_t mBufferedHTTP1Consumed;
|
||||
};
|
||||
|
||||
class Http2PushedStreamWrapper : public nsISupports {
|
||||
public:
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
bool DispatchRelease();
|
||||
|
||||
explicit Http2PushedStreamWrapper(Http2PushedStream* aPushStream);
|
||||
|
||||
nsCString& GetRequestString() { return mRequestString; }
|
||||
Http2PushedStream* GetStream();
|
||||
void OnPushFailed();
|
||||
|
||||
private:
|
||||
virtual ~Http2PushedStreamWrapper();
|
||||
|
||||
nsCString mRequestString;
|
||||
WeakPtr<Http2Stream> mStream;
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
||||
|
||||
@@ -387,12 +387,24 @@ Http2Session::AddStream(nsAHttpTransaction *aHttpTransaction,
|
||||
|
||||
if (mClosed || mShouldGoAway) {
|
||||
nsHttpTransaction *trans = aHttpTransaction->QueryHttpTransaction();
|
||||
if (trans && !trans->GetPushedStream()) {
|
||||
LOG3(("Http2Session::AddStream %p atrans=%p trans=%p session unusable - resched.\n",
|
||||
this, aHttpTransaction, trans));
|
||||
aHttpTransaction->SetConnection(nullptr);
|
||||
gHttpHandler->InitiateTransaction(trans, trans->Priority());
|
||||
return true;
|
||||
if (trans) {
|
||||
RefPtr<Http2PushedStreamWrapper> pushedStreamWrapper;
|
||||
pushedStreamWrapper = trans->GetPushedStream();
|
||||
if (!pushedStreamWrapper || !pushedStreamWrapper->GetStream()) {
|
||||
LOG3(
|
||||
("Http2Session::AddStream %p atrans=%p trans=%p session unusable - "
|
||||
"resched.\n", this, aHttpTransaction, trans));
|
||||
aHttpTransaction->SetConnection(nullptr);
|
||||
nsresult rv =
|
||||
gHttpHandler->InitiateTransaction(trans, trans->Priority());
|
||||
if (NS_FAILED(rv)) {
|
||||
LOG3(
|
||||
("Http2Session::AddStream %p atrans=%p trans=%p failed to "
|
||||
"initiate transaction (%08x).\n",
|
||||
this, aHttpTransaction, trans, static_cast<uint32_t>(rv)));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1726,8 +1738,9 @@ Http2Session::RecvPushPromise(Http2Session *self)
|
||||
RefPtr<Http2PushTransactionBuffer> transactionBuffer =
|
||||
new Http2PushTransactionBuffer();
|
||||
transactionBuffer->SetConnection(self);
|
||||
Http2PushedStream *pushedStream =
|
||||
new Http2PushedStream(transactionBuffer, self, associatedStream, promisedID);
|
||||
nsAutoPtr<Http2PushedStream> pushedStream(
|
||||
new Http2PushedStream(transactionBuffer, self, associatedStream, promisedID)
|
||||
);
|
||||
|
||||
rv = pushedStream->ConvertPushHeaders(&self->mDecompressor,
|
||||
self->mDecompressBuffer,
|
||||
@@ -1736,7 +1749,6 @@ Http2Session::RecvPushPromise(Http2Session *self)
|
||||
if (rv == NS_ERROR_NOT_IMPLEMENTED) {
|
||||
LOG3(("Http2Session::PushPromise Semantics not Implemented\n"));
|
||||
self->GenerateRstStream(REFUSED_STREAM_ERROR, promisedID);
|
||||
delete pushedStream;
|
||||
self->ResetDownstreamState();
|
||||
return NS_OK;
|
||||
}
|
||||
@@ -1745,7 +1757,6 @@ Http2Session::RecvPushPromise(Http2Session *self)
|
||||
// This means the decompression completed ok, but there was a problem with
|
||||
// the decoded headers. Reset the stream and go away.
|
||||
self->GenerateRstStream(PROTOCOL_ERROR, promisedID);
|
||||
delete pushedStream;
|
||||
self->ResetDownstreamState();
|
||||
return NS_OK;
|
||||
} else if (NS_FAILED(rv)) {
|
||||
@@ -1754,14 +1765,17 @@ Http2Session::RecvPushPromise(Http2Session *self)
|
||||
return rv;
|
||||
}
|
||||
|
||||
WeakPtr<Http2Stream> pushedWeak = pushedStream.forget();
|
||||
|
||||
// Ownership of the pushed stream is by the transaction hash, just as it
|
||||
// is for a client initiated stream. Errors that aren't fatal to the
|
||||
// whole session must call cleanupStream() after this point in order
|
||||
// to remove the stream from that hash.
|
||||
self->mStreamTransactionHash.Put(transactionBuffer, pushedStream);
|
||||
self->mPushedStreams.AppendElement(pushedStream);
|
||||
self->mStreamTransactionHash.Put(transactionBuffer, pushedWeak);
|
||||
self->mPushedStreams.AppendElement(
|
||||
static_cast<Http2PushedStream*>(pushedWeak.get()));
|
||||
|
||||
if (self->RegisterStreamID(pushedStream, promisedID) == kDeadStreamID) {
|
||||
if (self->RegisterStreamID(pushedWeak, promisedID) == kDeadStreamID) {
|
||||
LOG3(("Http2Session::RecvPushPromise registerstreamid failed\n"));
|
||||
self->mGoAwayReason = INTERNAL_ERROR;
|
||||
return NS_ERROR_FAILURE;
|
||||
@@ -1773,23 +1787,24 @@ Http2Session::RecvPushPromise(Http2Session *self)
|
||||
// Fake the request side of the pushed HTTP transaction. Sets up hash
|
||||
// key and origin
|
||||
uint32_t notUsed;
|
||||
pushedStream->ReadSegments(nullptr, 1, ¬Used);
|
||||
pushedWeak->ReadSegments(nullptr, 1, ¬Used);
|
||||
|
||||
nsAutoCString key;
|
||||
if (!pushedStream->GetHashKey(key)) {
|
||||
if (!static_cast<Http2PushedStream*>(pushedWeak.get())->GetHashKey(key)) {
|
||||
LOG3(("Http2Session::RecvPushPromise one of :authority :scheme :path missing from push\n"));
|
||||
self->CleanupStream(pushedStream, NS_ERROR_FAILURE, PROTOCOL_ERROR);
|
||||
self->CleanupStream(pushedWeak, NS_ERROR_FAILURE, PROTOCOL_ERROR);
|
||||
self->ResetDownstreamState();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// does the pushed origin belong on this connection?
|
||||
RefPtr<nsStandardURL> associatedURL, pushedURL;
|
||||
rv = Http2Stream::MakeOriginURL(associatedStream->Origin(), associatedURL);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = Http2Stream::MakeOriginURL(pushedStream->Origin(), pushedURL);
|
||||
rv = Http2Stream::MakeOriginURL(pushedWeak->Origin(), pushedURL);
|
||||
}
|
||||
LOG3(("Http2Session::RecvPushPromise %p checking %s == %s", self,
|
||||
associatedStream->Origin().get(), pushedStream->Origin().get()));
|
||||
associatedStream->Origin().get(), pushedWeak->Origin().get()));
|
||||
bool match = false;
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = associatedURL->Equals(pushedURL, &match);
|
||||
@@ -1797,36 +1812,38 @@ Http2Session::RecvPushPromise(Http2Session *self)
|
||||
if (NS_FAILED(rv)) {
|
||||
// Fallback to string equality of origins. This won't be guaranteed to be as
|
||||
// liberal as we want it to be, but it will at least be safe
|
||||
match = associatedStream->Origin().Equals(pushedStream->Origin());
|
||||
match = associatedStream->Origin().Equals(pushedWeak->Origin());
|
||||
}
|
||||
if (!match) {
|
||||
LOG3(("Http2Session::RecvPushPromise %p pushed stream mismatched origin "
|
||||
"associated origin %s .. pushed origin %s\n", self,
|
||||
associatedStream->Origin().get(), pushedStream->Origin().get()));
|
||||
self->CleanupStream(pushedStream, NS_ERROR_FAILURE, REFUSED_STREAM_ERROR);
|
||||
associatedStream->Origin().get(), pushedWeak->Origin().get()));
|
||||
self->CleanupStream(pushedWeak, NS_ERROR_FAILURE, REFUSED_STREAM_ERROR);
|
||||
self->ResetDownstreamState();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (pushedStream->TryOnPush()) {
|
||||
if (static_cast<Http2PushedStream*>(pushedWeak.get())->TryOnPush()) {
|
||||
LOG3(("Http2Session::RecvPushPromise %p channel implements nsIHttpPushListener "
|
||||
"stream %p will not be placed into session cache.\n", self, pushedStream));
|
||||
"stream %p will not be placed into session cache.\n", self, pushedWeak.get()));
|
||||
} else {
|
||||
LOG3(("Http2Session::RecvPushPromise %p place stream into session cache\n", self));
|
||||
if (!cache->RegisterPushedStreamHttp2(key, pushedStream)) {
|
||||
if (!cache->RegisterPushedStreamHttp2(
|
||||
key, static_cast<Http2PushedStream*>(pushedWeak.get()))) {
|
||||
// This only happens if they've already pushed us this item.
|
||||
LOG3(("Http2Session::RecvPushPromise registerPushedStream Failed\n"));
|
||||
self->CleanupStream(pushedStream, NS_ERROR_FAILURE, INTERNAL_ERROR);
|
||||
self->CleanupStream(pushedWeak, NS_ERROR_FAILURE, INTERNAL_ERROR);
|
||||
self->ResetDownstreamState();
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
pushedStream->SetHTTPState(Http2Stream::RESERVED_BY_REMOTE);
|
||||
pushedWeak->SetHTTPState(Http2Stream::RESERVED_BY_REMOTE);
|
||||
static_assert(Http2Stream::kWorstPriority >= 0,
|
||||
"kWorstPriority out of range");
|
||||
uint8_t priorityWeight = (nsISupportsPriority::PRIORITY_LOWEST + 1) -
|
||||
(Http2Stream::kWorstPriority - Http2Stream::kNormalPriority);
|
||||
pushedStream->SetPriority(Http2Stream::kWorstPriority);
|
||||
pushedWeak->SetPriority(Http2Stream::kWorstPriority);
|
||||
self->GeneratePriority(promisedID, priorityWeight);
|
||||
self->ResetDownstreamState();
|
||||
return NS_OK;
|
||||
|
||||
@@ -443,12 +443,14 @@ Http2Stream::ParseHttpRequestHeaders(const char *buf,
|
||||
requestContext->GetSpdyPushCache(&cache);
|
||||
}
|
||||
|
||||
RefPtr<Http2PushedStreamWrapper> pushedStreamWrapper;
|
||||
Http2PushedStream *pushedStream = nullptr;
|
||||
|
||||
// If a push stream is attached to the transaction via onPush, match only with that
|
||||
// one. This occurs when a push was made with in conjunction with a nsIHttpPushListener
|
||||
nsHttpTransaction *trans = mTransaction->QueryHttpTransaction();
|
||||
if (trans && (pushedStream = trans->TakePushedStream())) {
|
||||
if (trans && (pushedStreamWrapper = trans->TakePushedStream()) &&
|
||||
(pushedStream = pushedStreamWrapper->GetStream())) {
|
||||
if (pushedStream->mSession == mSession) {
|
||||
LOG3(("Pushed Stream match based on OnPush correlation %p", pushedStream));
|
||||
} else {
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "nsAHttpTransaction.h"
|
||||
#include "nsISupportsPriority.h"
|
||||
#include "SimpleBuffer.h"
|
||||
#include "mozilla/WeakPtr.h"
|
||||
|
||||
class nsIInputStream;
|
||||
class nsIOutputStream;
|
||||
@@ -28,8 +29,10 @@ class Http2Decompressor;
|
||||
class Http2Stream
|
||||
: public nsAHttpSegmentReader
|
||||
, public nsAHttpSegmentWriter
|
||||
, public SupportsWeakPtr<Http2Stream>
|
||||
{
|
||||
public:
|
||||
MOZ_DECLARE_WEAKREFERENCE_TYPENAME(Http2Stream)
|
||||
NS_DECL_NSAHTTPSEGMENTREADER
|
||||
NS_DECL_NSAHTTPSEGMENTWRITER
|
||||
|
||||
|
||||
@@ -543,13 +543,14 @@ HttpChannelChild::DoOnStartRequest(nsIRequest* aRequest, nsISupports* aContext)
|
||||
{
|
||||
LOG(("HttpChannelChild::DoOnStartRequest [this=%p]\n", this));
|
||||
|
||||
// In theory mListener should not be null, but in practice sometimes it is.
|
||||
MOZ_ASSERT(mListener);
|
||||
if (!mListener) {
|
||||
Cancel(NS_ERROR_FAILURE);
|
||||
return;
|
||||
nsresult rv;
|
||||
if (MOZ_LIKELY(mListener)) {
|
||||
nsCOMPtr<nsIStreamListener> listener(mListener);
|
||||
rv = listener->OnStartRequest(aRequest, aContext);
|
||||
} else {
|
||||
rv = NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
nsresult rv = mListener->OnStartRequest(aRequest, aContext);
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
Cancel(rv);
|
||||
return;
|
||||
@@ -804,9 +805,12 @@ HttpChannelChild::DoOnDataAvailable(nsIRequest* aRequest, nsISupports* aContext,
|
||||
if (mCanceled)
|
||||
return;
|
||||
|
||||
nsresult rv = mListener->OnDataAvailable(aRequest, aContext, aStream, offset, count);
|
||||
if (NS_FAILED(rv)) {
|
||||
Cancel(rv);
|
||||
if (MOZ_LIKELY(mListener)) {
|
||||
nsCOMPtr<nsIStreamListener> listener(mListener);
|
||||
nsresult rv = listener->OnDataAvailable(aRequest, aContext, aStream, offset, count);
|
||||
if (NS_FAILED(rv)) {
|
||||
Cancel(rv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -985,11 +989,11 @@ HttpChannelChild::DoOnStopRequest(nsIRequest* aRequest, nsresult aChannelStatus,
|
||||
MOZ_ASSERT(!mOnStopRequestCalled,
|
||||
"We should not call OnStopRequest twice");
|
||||
|
||||
// In theory mListener should not be null, but in practice sometimes it is.
|
||||
MOZ_ASSERT(mListener);
|
||||
if (mListener) {
|
||||
mListener->OnStopRequest(aRequest, aContext, mStatus);
|
||||
if (MOZ_LIKELY(mListener)) {
|
||||
nsCOMPtr<nsIStreamListener> listener(mListener);
|
||||
listener->OnStopRequest(aRequest, aContext, mStatus);
|
||||
}
|
||||
|
||||
mOnStopRequestCalled = true;
|
||||
|
||||
mListener = nullptr;
|
||||
|
||||
@@ -912,6 +912,9 @@ nsCORSListenerProxy::UpdateChannel(nsIChannel* aChannel,
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
// TODO: Bug 1353683
|
||||
// consider calling SetBlockedRequest in nsCORSListenerProxy::UpdateChannel
|
||||
//
|
||||
// Check that the uri is ok to load
|
||||
rv = nsContentUtils::GetSecurityManager()->
|
||||
CheckLoadURIWithPrincipal(mRequestingPrincipal, uri,
|
||||
|
||||
@@ -6915,7 +6915,8 @@ nsHttpChannel::OnStopRequest(nsIRequest *request, nsISupports *ctxt, nsresult st
|
||||
if (mListener) {
|
||||
MOZ_ASSERT(!mOnStartRequestCalled,
|
||||
"We should not call OnStartRequest twice.");
|
||||
mListener->OnStartRequest(this, mListenerContext);
|
||||
nsCOMPtr<nsIStreamListener> listener(mListener);
|
||||
listener->OnStartRequest(this, mListenerContext);
|
||||
mOnStartRequestCalled = true;
|
||||
} else {
|
||||
NS_WARNING("OnStartRequest skipped because of null listener");
|
||||
@@ -8100,7 +8101,7 @@ nsHttpChannel::AwaitingCacheCallbacks()
|
||||
}
|
||||
|
||||
void
|
||||
nsHttpChannel::SetPushedStream(Http2PushedStream *stream)
|
||||
nsHttpChannel::SetPushedStream(Http2PushedStreamWrapper *stream)
|
||||
{
|
||||
MOZ_ASSERT(stream);
|
||||
MOZ_ASSERT(!mPushedStream);
|
||||
@@ -8108,7 +8109,8 @@ nsHttpChannel::SetPushedStream(Http2PushedStream *stream)
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHttpChannel::OnPush(const nsACString &url, Http2PushedStream *pushedStream)
|
||||
nsHttpChannel::OnPush(const nsACString &url,
|
||||
Http2PushedStreamWrapper *pushedStream)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
LOG(("nsHttpChannel::OnPush [this=%p]\n", this));
|
||||
|
||||
@@ -128,7 +128,8 @@ public:
|
||||
nsIURI *aProxyURI,
|
||||
const nsID& aChannelId) override;
|
||||
|
||||
nsresult OnPush(const nsACString &uri, Http2PushedStream *pushedStream);
|
||||
nsresult OnPush(const nsACString &uri,
|
||||
Http2PushedStreamWrapper *pushedStream);
|
||||
|
||||
static bool IsRedirectStatus(uint32_t status);
|
||||
|
||||
@@ -456,7 +457,7 @@ private:
|
||||
nsresult OpenCacheInputStream(nsICacheEntry* cacheEntry, bool startBuffering,
|
||||
bool checkingAppCacheEntry);
|
||||
|
||||
void SetPushedStream(Http2PushedStream *stream);
|
||||
void SetPushedStream(Http2PushedStreamWrapper *stream);
|
||||
|
||||
void MaybeWarnAboutAppCache();
|
||||
|
||||
@@ -592,7 +593,7 @@ private:
|
||||
// Needed for accurate DNS timing
|
||||
RefPtr<nsDNSPrefetch> mDNSPrefetch;
|
||||
|
||||
Http2PushedStream *mPushedStream;
|
||||
RefPtr<Http2PushedStreamWrapper> mPushedStream;
|
||||
// True if the channel's principal was found on a phishing, malware, or
|
||||
// tracking (if tracking protection is enabled) blocklist
|
||||
bool mLocalBlocklist;
|
||||
|
||||
@@ -376,8 +376,12 @@ nsHttpConnectionMgr::VerifyTraffic()
|
||||
nsresult
|
||||
nsHttpConnectionMgr::DoShiftReloadConnectionCleanup(nsHttpConnectionInfo *aCI)
|
||||
{
|
||||
RefPtr<nsHttpConnectionInfo> ci;
|
||||
if (aCI) {
|
||||
ci = aCI->Clone();
|
||||
}
|
||||
return PostEvent(&nsHttpConnectionMgr::OnMsgDoShiftReloadConnectionCleanup,
|
||||
0, aCI);
|
||||
0, ci);
|
||||
}
|
||||
|
||||
class SpeculativeConnectArgs : public ARefBase
|
||||
@@ -507,9 +511,13 @@ nsHttpConnectionMgr::UpdateParam(nsParamName name, uint16_t value)
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHttpConnectionMgr::ProcessPendingQ(nsHttpConnectionInfo *ci)
|
||||
nsHttpConnectionMgr::ProcessPendingQ(nsHttpConnectionInfo* aCI)
|
||||
{
|
||||
LOG(("nsHttpConnectionMgr::ProcessPendingQ [ci=%s]\n", ci->HashKey().get()));
|
||||
LOG(("nsHttpConnectionMgr::ProcessPendingQ [ci=%s]\n", aCI->HashKey().get()));
|
||||
RefPtr<nsHttpConnectionInfo> ci;
|
||||
if (aCI) {
|
||||
ci = aCI->Clone();
|
||||
}
|
||||
return PostEvent(&nsHttpConnectionMgr::OnMsgProcessPendingQ, 0, ci);
|
||||
}
|
||||
|
||||
@@ -1863,13 +1871,17 @@ nsHttpConnectionMgr::ProcessNewTransaction(nsHttpTransaction *trans)
|
||||
|
||||
trans->SetPendingTime();
|
||||
|
||||
Http2PushedStream *pushedStream = trans->GetPushedStream();
|
||||
if (pushedStream) {
|
||||
LOG((" ProcessNewTransaction %p tied to h2 session push %p\n",
|
||||
trans, pushedStream->Session()));
|
||||
return pushedStream->Session()->
|
||||
AddStream(trans, trans->Priority(), false, nullptr) ?
|
||||
NS_OK : NS_ERROR_UNEXPECTED;
|
||||
RefPtr<Http2PushedStreamWrapper> pushedStreamWrapper =
|
||||
trans->GetPushedStream();
|
||||
if (pushedStreamWrapper) {
|
||||
Http2PushedStream* pushedStream = pushedStreamWrapper->GetStream();
|
||||
if (pushedStream) {
|
||||
LOG((" ProcessNewTransaction %p tied to h2 session push %p\n",
|
||||
trans, pushedStream->Session()));
|
||||
return pushedStream->Session()->
|
||||
AddStream(trans, trans->Priority(), false, nullptr) ?
|
||||
NS_OK : NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
@@ -2361,7 +2361,7 @@ nsHttpHandler::SpeculativeConnectInternal(nsIURI *aURI,
|
||||
originAttributes.StripAttributes(OriginAttributes::STRIP_ADDON_ID);
|
||||
}
|
||||
|
||||
auto *ci =
|
||||
RefPtr<nsHttpConnectionInfo> ci =
|
||||
new nsHttpConnectionInfo(host, port, EmptyCString(), username, nullptr,
|
||||
originAttributes, usingSSL);
|
||||
ci->SetAnonymous(anonymous);
|
||||
|
||||
@@ -235,7 +235,8 @@ public:
|
||||
uint32_t caps = 0)
|
||||
{
|
||||
TickleWifi(callbacks);
|
||||
return mConnMgr->SpeculativeConnect(ci, callbacks, caps);
|
||||
RefPtr<nsHttpConnectionInfo> clone = ci->Clone();
|
||||
return mConnMgr->SpeculativeConnect(clone, callbacks, caps);
|
||||
}
|
||||
|
||||
// Alternate Services Maps are main thread only
|
||||
|
||||
@@ -136,14 +136,16 @@ public:
|
||||
|
||||
nsHttpTransaction *QueryHttpTransaction() override { return this; }
|
||||
|
||||
Http2PushedStream *GetPushedStream() { return mPushedStream; }
|
||||
Http2PushedStream *TakePushedStream()
|
||||
{
|
||||
Http2PushedStream *r = mPushedStream;
|
||||
mPushedStream = nullptr;
|
||||
return r;
|
||||
already_AddRefed<Http2PushedStreamWrapper> GetPushedStream() {
|
||||
//return do_AddRef(mPushedStream); // XXX: add this support to RefPtr.h
|
||||
RefPtr<Http2PushedStreamWrapper> ref(mPushedStream);
|
||||
return ref.forget();
|
||||
}
|
||||
void SetPushedStream(Http2PushedStream *push) { mPushedStream = push; }
|
||||
already_AddRefed<Http2PushedStreamWrapper> TakePushedStream() {
|
||||
return mPushedStream.forget();
|
||||
}
|
||||
|
||||
void SetPushedStream(Http2PushedStreamWrapper* push) { mPushedStream = push; }
|
||||
uint32_t InitialRwin() const { return mInitialRwin; };
|
||||
bool ChannelPipeFull() { return mWaitingOnPipeOut; }
|
||||
|
||||
@@ -269,7 +271,7 @@ private:
|
||||
// so far been skipped.
|
||||
uint32_t mInvalidResponseBytesRead;
|
||||
|
||||
Http2PushedStream *mPushedStream;
|
||||
RefPtr<Http2PushedStreamWrapper> mPushedStream;
|
||||
uint32_t mInitialRwin;
|
||||
|
||||
nsHttpChunkedDecoder *mChunkedDecoder;
|
||||
|
||||
@@ -956,8 +956,9 @@ nsHtml5TreeOpExecutor::PreloadImage(const nsAString& aURL,
|
||||
const nsAString& aImageReferrerPolicy)
|
||||
{
|
||||
nsCOMPtr<nsIURI> baseURI = BaseURIForPreload();
|
||||
bool isImgSet = false;
|
||||
nsCOMPtr<nsIURI> uri = mDocument->ResolvePreloadImage(baseURI, aURL, aSrcset,
|
||||
aSizes);
|
||||
aSizes, &isImgSet);
|
||||
if (uri && ShouldPreloadURI(uri)) {
|
||||
// use document wide referrer policy
|
||||
mozilla::net::ReferrerPolicy referrerPolicy = mSpeculationReferrerPolicy;
|
||||
@@ -971,7 +972,7 @@ nsHtml5TreeOpExecutor::PreloadImage(const nsAString& aURL,
|
||||
}
|
||||
}
|
||||
|
||||
mDocument->MaybePreLoadImage(uri, aCrossOrigin, referrerPolicy);
|
||||
mDocument->MaybePreLoadImage(uri, aCrossOrigin, referrerPolicy, isImgSet);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user