mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 23:02:20 +00:00
40a377c3dc
Enforce all subprotocol character checks as per RFC 6455 with a new method. (See bug for full check details.) Differential Revision: https://phabricator.services.mozilla.com/D171219
193 lines
6.1 KiB
C++
193 lines
6.1 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim: set ts=8 sts=2 et sw=2 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/. */
|
|
|
|
#ifndef WebSocket_h__
|
|
#define WebSocket_h__
|
|
|
|
#include "mozilla/Attributes.h"
|
|
#include "mozilla/CheckedInt.h"
|
|
#include "mozilla/dom/TypedArray.h"
|
|
#include "mozilla/dom/WebSocketBinding.h" // for BinaryType
|
|
#include "mozilla/DOMEventTargetHelper.h"
|
|
#include "mozilla/Mutex.h"
|
|
#include "nsCOMPtr.h"
|
|
#include "nsCycleCollectionParticipant.h"
|
|
#include "nsISupports.h"
|
|
#include "nsISupportsUtils.h"
|
|
#include "nsString.h"
|
|
#include "nsWrapperCache.h"
|
|
|
|
#define DEFAULT_WS_SCHEME_PORT 80
|
|
#define DEFAULT_WSS_SCHEME_PORT 443
|
|
|
|
class nsIInputStream;
|
|
class nsITransportProvider;
|
|
|
|
namespace mozilla {
|
|
class ErrorResult;
|
|
|
|
namespace dom {
|
|
|
|
class Blob;
|
|
class StringOrStringSequence;
|
|
class WebSocketImpl;
|
|
|
|
class WebSocket final : public DOMEventTargetHelper {
|
|
friend class WebSocketImpl;
|
|
|
|
public:
|
|
enum { CONNECTING = 0, OPEN = 1, CLOSING = 2, CLOSED = 3 };
|
|
|
|
public:
|
|
NS_DECL_ISUPPORTS_INHERITED
|
|
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(WebSocket, DOMEventTargetHelper)
|
|
virtual bool IsCertainlyAliveForCC() const override;
|
|
|
|
// EventTarget
|
|
using EventTarget::EventListenerAdded;
|
|
virtual void EventListenerAdded(nsAtom* aType) override;
|
|
|
|
using EventTarget::EventListenerRemoved;
|
|
virtual void EventListenerRemoved(nsAtom* aType) override;
|
|
|
|
virtual void DisconnectFromOwner() override;
|
|
|
|
mozilla::Maybe<EventCallbackDebuggerNotificationType>
|
|
GetDebuggerNotificationType() const override;
|
|
|
|
// nsWrapperCache
|
|
virtual JSObject* WrapObject(JSContext* cx,
|
|
JS::Handle<JSObject*> aGivenProto) override;
|
|
|
|
public: // static helpers:
|
|
// Determine if preferences allow WebSocket
|
|
static bool PrefEnabled(JSContext* aCx = nullptr,
|
|
JSObject* aGlobal = nullptr);
|
|
|
|
public: // WebIDL interface:
|
|
// Constructor:
|
|
static already_AddRefed<WebSocket> Constructor(
|
|
const GlobalObject& aGlobal, const nsAString& aUrl,
|
|
const StringOrStringSequence& aProtocols, ErrorResult& rv);
|
|
|
|
static already_AddRefed<WebSocket> CreateServerWebSocket(
|
|
const GlobalObject& aGlobal, const nsAString& aUrl,
|
|
const Sequence<nsString>& aProtocols,
|
|
nsITransportProvider* aTransportProvider,
|
|
const nsAString& aNegotiatedExtensions, ErrorResult& rv);
|
|
|
|
static already_AddRefed<WebSocket> ConstructorCommon(
|
|
const GlobalObject& aGlobal, const nsAString& aUrl,
|
|
const Sequence<nsString>& aProtocols,
|
|
nsITransportProvider* aTransportProvider,
|
|
const nsACString& aNegotiatedExtensions, ErrorResult& rv);
|
|
|
|
// webIDL: readonly attribute DOMString url
|
|
void GetUrl(nsAString& aResult);
|
|
|
|
// webIDL: readonly attribute unsigned short readyState;
|
|
uint16_t ReadyState();
|
|
|
|
// webIDL: readonly attribute unsigned long long bufferedAmount;
|
|
uint64_t BufferedAmount() const;
|
|
|
|
// webIDL: attribute Function? onopen;
|
|
IMPL_EVENT_HANDLER(open)
|
|
|
|
// webIDL: attribute Function? onerror;
|
|
IMPL_EVENT_HANDLER(error)
|
|
|
|
// webIDL: attribute Function? onclose;
|
|
IMPL_EVENT_HANDLER(close)
|
|
|
|
// webIDL: readonly attribute DOMString extensions;
|
|
void GetExtensions(nsAString& aResult);
|
|
|
|
// webIDL: readonly attribute DOMString protocol;
|
|
void GetProtocol(nsAString& aResult);
|
|
|
|
// webIDL: void close(optional unsigned short code,
|
|
// optional DOMString reason):
|
|
void Close(const Optional<uint16_t>& aCode,
|
|
const Optional<nsAString>& aReason, ErrorResult& aRv);
|
|
|
|
// webIDL: attribute Function? onmessage;
|
|
IMPL_EVENT_HANDLER(message)
|
|
|
|
// webIDL: attribute DOMString binaryType;
|
|
dom::BinaryType BinaryType() const;
|
|
void SetBinaryType(dom::BinaryType aData);
|
|
|
|
// webIDL: void send(DOMString|Blob|ArrayBufferView data);
|
|
void Send(const nsAString& aData, ErrorResult& aRv);
|
|
void Send(Blob& aData, ErrorResult& aRv);
|
|
void Send(const ArrayBuffer& aData, ErrorResult& aRv);
|
|
void Send(const ArrayBufferView& aData, ErrorResult& aRv);
|
|
|
|
private: // constructor && destructor
|
|
explicit WebSocket(nsIGlobalObject* aGlobal);
|
|
virtual ~WebSocket();
|
|
|
|
void SetReadyState(uint16_t aReadyState);
|
|
|
|
// These methods actually do the dispatch for various events.
|
|
nsresult CreateAndDispatchSimpleEvent(const nsAString& aName);
|
|
nsresult CreateAndDispatchMessageEvent(const nsACString& aData,
|
|
bool aIsBinary);
|
|
nsresult CreateAndDispatchCloseEvent(bool aWasClean, uint16_t aCode,
|
|
const nsAString& aReason);
|
|
|
|
static bool IsValidProtocolString(const nsString& aValue);
|
|
|
|
// if there are "strong event listeners" (see comment in WebSocket.cpp) or
|
|
// outgoing not sent messages then this method keeps the object alive
|
|
// when js doesn't have strong references to it.
|
|
void UpdateMustKeepAlive();
|
|
// ATTENTION, when calling this method the object can be released
|
|
// (and possibly collected).
|
|
void DontKeepAliveAnyMore();
|
|
|
|
private:
|
|
WebSocket(const WebSocket& x) = delete; // prevent bad usage
|
|
WebSocket& operator=(const WebSocket& x) = delete;
|
|
|
|
void Send(nsIInputStream* aMsgStream, const nsACString& aMsgString,
|
|
uint32_t aMsgLength, bool aIsBinary, ErrorResult& aRv);
|
|
|
|
void AssertIsOnTargetThread() const;
|
|
|
|
// Raw pointer because this WebSocketImpl is created, managed and destroyed by
|
|
// WebSocket.
|
|
WebSocketImpl* mImpl;
|
|
|
|
bool mIsMainThread;
|
|
|
|
bool mKeepingAlive;
|
|
bool mCheckMustKeepAlive;
|
|
|
|
CheckedUint64 mOutgoingBufferedAmount;
|
|
|
|
// related to the WebSocket constructor steps
|
|
nsString mURI;
|
|
nsString mEffectiveURL; // after redirects
|
|
nsCString mEstablishedExtensions;
|
|
nsCString mEstablishedProtocol;
|
|
|
|
dom::BinaryType mBinaryType;
|
|
|
|
// This mutex protects mReadyState that is the only variable that is used in
|
|
// different threads.
|
|
mozilla::Mutex mMutex;
|
|
|
|
// This value should not be used directly but use ReadyState() instead.
|
|
uint16_t mReadyState MOZ_GUARDED_BY(mMutex);
|
|
};
|
|
|
|
} // namespace dom
|
|
} // namespace mozilla
|
|
|
|
#endif
|