Merge remote-tracking branch 'origin/tracking' into custom

This commit is contained in:
roytam1 2022-09-02 11:00:51 +08:00
commit 64173440fc
8 changed files with 1209 additions and 615 deletions

File diff suppressed because it is too large Load diff

View file

@ -35,221 +35,81 @@ namespace dom {
struct EventSourceInit;
class EventSourceImpl;
class EventSource final : public DOMEventTargetHelper
, public nsIObserver
, public nsIStreamListener
, public nsIChannelEventSink
, public nsIInterfaceRequestor
, public nsSupportsWeakReference
{
friend class EventSourceImpl;
public:
explicit EventSource(nsPIDOMWindowInner* aOwnerWindow);
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_INHERITED(
EventSource, DOMEventTargetHelper)
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(EventSource, DOMEventTargetHelper)
virtual bool IsCertainlyAliveForCC() const override;
NS_DECL_NSIOBSERVER
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSIREQUESTOBSERVER
NS_DECL_NSICHANNELEVENTSINK
NS_DECL_NSIINTERFACEREQUESTOR
// EventTarget
void DisconnectFromOwner() override
{
DOMEventTargetHelper::DisconnectFromOwner();
Close();
}
// nsWrapperCache
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
// WebIDL
nsPIDOMWindowInner*
GetParentObject() const
{
return GetOwner();
}
static already_AddRefed<EventSource>
Constructor(const GlobalObject& aGlobal, const nsAString& aURL,
const EventSourceInit& aEventSourceInitDict,
ErrorResult& aRv);
const EventSourceInit& aEventSourceInitDict, ErrorResult& aRv);
void GetUrl(nsAString& aURL) const
{
AssertIsOnTargetThread();
aURL = mOriginalURL;
}
bool WithCredentials() const
{
AssertIsOnTargetThread();
return mWithCredentials;
}
enum {
CONNECTING = 0U,
OPEN = 1U,
CLOSED = 2U
};
uint16_t ReadyState() const
{
AssertIsOnTargetThread();
return mReadyState;
}
IMPL_EVENT_HANDLER(open)
IMPL_EVENT_HANDLER(message)
IMPL_EVENT_HANDLER(error)
void Close();
virtual void DisconnectFromOwner() override;
protected:
virtual ~EventSource();
MOZ_IS_CLASS_INIT
nsresult Init(nsISupports* aOwner,
const nsAString& aURL,
bool aWithCredentials);
nsresult GetBaseURI(nsIURI **aBaseURI);
void SetupHttpChannel();
nsresult SetupReferrerPolicy();
nsresult InitChannelAndRequestEventSource();
nsresult ResetConnection();
nsresult DispatchFailConnection();
nsresult SetReconnectionTimeout();
void AnnounceConnection();
void DispatchAllMessageEvents();
void ReestablishConnection();
void FailConnection();
nsresult Thaw();
nsresult Freeze();
static void TimerCallback(nsITimer *aTimer, void *aClosure);
nsresult PrintErrorOnConsole(const char *aBundleURI,
const char16_t *aError,
const char16_t **aFormatStrings,
uint32_t aFormatStringsLen);
nsresult ConsoleError();
static nsresult StreamReaderFunc(nsIInputStream *aInputStream,
void *aClosure,
const char *aFromRawSegment,
uint32_t aToOffset,
uint32_t aCount,
uint32_t *aWriteCount);
nsresult SetFieldAndClear();
nsresult ClearFields();
nsresult ResetEvent();
nsresult DispatchCurrentMessageEvent();
nsresult ParseCharacter(char16_t aChr);
nsresult CheckHealthOfRequestCallback(nsIRequest *aRequestCallback);
nsresult OnRedirectVerifyCallback(nsresult result);
nsCOMPtr<nsIURI> mSrc;
nsString mLastEventID;
uint32_t mReconnectionTime; // in ms
struct Message {
nsString mEventName;
nsString mLastEventID;
nsString mData;
};
nsDeque mMessagesToDispatch;
Message mCurrentMessage;
/**
* A simple state machine used to manage the event-source's line buffer
*
* PARSE_STATE_OFF -> PARSE_STATE_BEGIN_OF_STREAM
*
* PARSE_STATE_BEGIN_OF_STREAM -> PARSE_STATE_BOM_WAS_READ |
* PARSE_STATE_CR_CHAR |
* PARSE_STATE_BEGIN_OF_LINE |
* PARSE_STATE_COMMENT |
* PARSE_STATE_FIELD_NAME
*
* PARSE_STATE_BOM_WAS_READ -> PARSE_STATE_CR_CHAR |
* PARSE_STATE_BEGIN_OF_LINE |
* PARSE_STATE_COMMENT |
* PARSE_STATE_FIELD_NAME
*
* PARSE_STATE_CR_CHAR -> PARSE_STATE_CR_CHAR |
* PARSE_STATE_COMMENT |
* PARSE_STATE_FIELD_NAME |
* PARSE_STATE_BEGIN_OF_LINE
*
* PARSE_STATE_COMMENT -> PARSE_STATE_CR_CHAR |
* PARSE_STATE_BEGIN_OF_LINE
*
* PARSE_STATE_FIELD_NAME -> PARSE_STATE_CR_CHAR |
* PARSE_STATE_BEGIN_OF_LINE |
* PARSE_STATE_FIRST_CHAR_OF_FIELD_VALUE
*
* PARSE_STATE_FIRST_CHAR_OF_FIELD_VALUE -> PARSE_STATE_FIELD_VALUE |
* PARSE_STATE_CR_CHAR |
* PARSE_STATE_BEGIN_OF_LINE
*
* PARSE_STATE_FIELD_VALUE -> PARSE_STATE_CR_CHAR |
* PARSE_STATE_BEGIN_OF_LINE
*
* PARSE_STATE_BEGIN_OF_LINE -> PARSE_STATE_CR_CHAR |
* PARSE_STATE_COMMENT |
* PARSE_STATE_FIELD_NAME |
* PARSE_STATE_BEGIN_OF_LINE
*
* Whenever the parser find an empty line or the end-of-file
* it dispatches the stacked event.
*
*/
enum ParserStatus {
PARSE_STATE_OFF,
PARSE_STATE_BEGIN_OF_STREAM,
PARSE_STATE_BOM_WAS_READ,
PARSE_STATE_CR_CHAR,
PARSE_STATE_COMMENT,
PARSE_STATE_FIELD_NAME,
PARSE_STATE_FIRST_CHAR_OF_FIELD_VALUE,
PARSE_STATE_FIELD_VALUE,
PARSE_STATE_BEGIN_OF_LINE
};
ParserStatus mStatus;
bool mFrozen;
bool mErrorLoadOnRedirect;
bool mGoingToDispatchAllMessages;
bool mWithCredentials;
bool mWaitingForOnStopRequest;
// used while reading the input streams
nsCOMPtr<nsIUnicodeDecoder> mUnicodeDecoder;
nsresult mLastConvertionResult;
nsString mLastFieldName;
nsString mLastFieldValue;
nsCOMPtr<nsILoadGroup> mLoadGroup;
nsCOMPtr<nsIHttpChannel> mHttpChannel;
nsCOMPtr<nsITimer> mTimer;
uint16_t mReadyState;
nsString mOriginalURL;
nsCOMPtr<nsIPrincipal> mPrincipal;
nsString mOrigin;
// Event Source owner information:
// - the script file name
// - source code line number and column number where the Event Source object
// was constructed.
// - the ID of the inner window where the script lives. Note that this may not
// be the same as the Event Source owner window.
// These attributes are used for error reporting.
nsString mScriptFile;
uint32_t mScriptLine;
uint32_t mScriptColumn;
uint64_t mInnerWindowID;
private:
EventSource(const EventSource& x); // prevent bad usage
EventSource& operator=(const EventSource& x);
EventSource(nsPIDOMWindowInner* aOwnerWindow, bool aWithCredentials);
virtual ~EventSource();
// prevent bad usage
EventSource(const EventSource& x) = delete;
EventSource& operator=(const EventSource& x) = delete;
void AssertIsOnTargetThread() const
{
MOZ_ASSERT(NS_IsMainThread() == mIsMainThread);
}
nsresult CreateAndDispatchSimpleEvent(const nsAString& aName);
// Raw pointer because this EventSourceImpl is created, managed and destroyed
// by EventSource.
EventSourceImpl* mImpl;
nsString mOriginalURL;
uint16_t mReadyState;
bool mWithCredentials;
bool mIsMainThread;
// This is used to keep EventSourceImpl instance when there is a connection.
bool mKeepingAlive;
void UpdateMustKeepAlive();
void UpdateDontKeepAlive();
};
} // namespace dom

View file

@ -1402,32 +1402,6 @@ WebSocket::ConstructorCommon(const GlobalObject& aGlobal,
NS_IMPL_CYCLE_COLLECTION_CLASS(WebSocket)
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(WebSocket)
bool isBlack = tmp->IsBlack();
if (isBlack || tmp->mKeepingAlive) {
if (tmp->mListenerManager) {
tmp->mListenerManager->MarkForCC();
}
if (!isBlack && tmp->PreservingWrapper()) {
// This marks the wrapper black.
tmp->GetWrapper();
}
return true;
}
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(WebSocket)
return tmp->IsBlack();
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_END
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(WebSocket)
return tmp->IsBlack();
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(WebSocket,
DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(WebSocket,
DOMEventTargetHelper)
if (tmp->mImpl) {
@ -1444,6 +1418,12 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(WebSocket,
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
bool
WebSocket::IsCertainlyAliveForCC() const
{
return mKeepingAlive;
}
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(WebSocket)
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)

View file

@ -45,8 +45,8 @@ public:
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_INHERITED(
WebSocket, DOMEventTargetHelper)
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(WebSocket, DOMEventTargetHelper)
virtual bool IsCertainlyAliveForCC() const override;
// EventTarget
virtual void EventListenerAdded(nsIAtom* aType) override;

View file

@ -52,11 +52,12 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(DOMEventTargetHelper)
if (tmp->IsBlack() || tmp->IsCertainlyAliveForCC()) {
bool isBlack = tmp->IsBlack();
if (isBlack || tmp->IsCertainlyAliveForCC()) {
if (tmp->mListenerManager) {
tmp->mListenerManager->MarkForCC();
}
if (!tmp->IsBlack() && tmp->PreservingWrapper()) {
if (!isBlack && tmp->PreservingWrapper()) {
// This marks the wrapper black.
tmp->GetWrapper();
}

View file

@ -11,7 +11,8 @@
* and create derivative works of this document.
*/
[Constructor(USVString url, optional EventSourceInit eventSourceInitDict)]
[Exposed=(Window,DedicatedWorker,SharedWorker),
Constructor(USVString url, optional EventSourceInit eventSourceInitDict)]
interface EventSource : EventTarget {
[Constant]
readonly attribute DOMString url;

View file

@ -310,30 +310,7 @@ XMLHttpRequestMainThread::SetRequestObserver(nsIRequestObserver* aObserver)
mRequestObserver = aObserver;
}
NS_IMPL_CYCLE_COLLECTION_CLASS(XMLHttpRequestMainThread)
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(XMLHttpRequestMainThread)
bool isBlack = tmp->IsBlack();
if (isBlack || tmp->mWaitingForOnStopRequest) {
if (tmp->mListenerManager) {
tmp->mListenerManager->MarkForCC();
}
if (!isBlack && tmp->PreservingWrapper()) {
// This marks the wrapper black.
tmp->GetWrapper();
}
return true;
}
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(XMLHttpRequestMainThread)
return tmp->
IsBlackAndDoesNotNeedTracing(static_cast<DOMEventTargetHelper*>(tmp));
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_END
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(XMLHttpRequestMainThread)
return tmp->IsBlack();
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END
NS_IMPL_CYCLE_COLLECTION_CLASS(XMLHttpRequestMainThread)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(XMLHttpRequestMainThread,
XMLHttpRequestEventTarget)
@ -380,6 +357,12 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(XMLHttpRequestMainThread,
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mResultJSON)
NS_IMPL_CYCLE_COLLECTION_TRACE_END
bool
XMLHttpRequestMainThread::IsCertainlyAliveForCC() const
{
return mWaitingForOnStopRequest;
}
// QueryInterface implementation for XMLHttpRequestMainThread
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(XMLHttpRequestMainThread)
NS_INTERFACE_MAP_ENTRY(nsIXMLHttpRequest)

View file

@ -525,8 +525,10 @@ public:
void SetRequestObserver(nsIRequestObserver* aObserver);
NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_INHERITED(XMLHttpRequestMainThread,
XMLHttpRequest)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(XMLHttpRequestMainThread,
XMLHttpRequest)
virtual bool IsCertainlyAliveForCC() const override;
bool AllowUploadProgress();
virtual void DisconnectFromOwner() override;