mirror of
				https://github.com/mozilla/gecko-dev.git
				synced 2025-11-04 10:18:41 +02:00 
			
		
		
		
	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
		
			
				
	
	
		
			192 lines
		
	
	
	
		
			6.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			192 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
 |