2012-09-10 06:48:14 -07:00
|
|
|
/* -*- 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/. */
|
|
|
|
|
|
|
|
#ifndef WebSocket_h__
|
|
|
|
#define WebSocket_h__
|
|
|
|
|
2013-05-29 13:43:41 -07:00
|
|
|
#include "mozilla/Attributes.h"
|
2013-09-05 23:43:07 -07:00
|
|
|
#include "mozilla/dom/TypedArray.h"
|
|
|
|
#include "mozilla/dom/WebSocketBinding.h" // for BinaryType
|
2014-03-31 23:13:50 -07:00
|
|
|
#include "mozilla/DOMEventTargetHelper.h"
|
2013-09-05 23:43:07 -07:00
|
|
|
#include "mozilla/ErrorResult.h"
|
|
|
|
#include "nsAutoPtr.h"
|
2012-09-10 06:48:14 -07:00
|
|
|
#include "nsCOMPtr.h"
|
|
|
|
#include "nsCycleCollectionParticipant.h"
|
|
|
|
#include "nsIInterfaceRequestor.h"
|
|
|
|
#include "nsIObserver.h"
|
|
|
|
#include "nsIRequest.h"
|
2013-09-05 23:43:07 -07:00
|
|
|
#include "nsISupports.h"
|
|
|
|
#include "nsISupportsUtils.h"
|
|
|
|
#include "nsIWebSocketChannel.h"
|
|
|
|
#include "nsIWebSocketListener.h"
|
|
|
|
#include "nsString.h"
|
2012-09-10 06:48:14 -07:00
|
|
|
#include "nsWeakReference.h"
|
2013-09-05 23:43:07 -07:00
|
|
|
#include "nsWrapperCache.h"
|
2012-09-10 06:48:14 -07:00
|
|
|
|
|
|
|
#define DEFAULT_WS_SCHEME_PORT 80
|
|
|
|
#define DEFAULT_WSS_SCHEME_PORT 443
|
|
|
|
|
|
|
|
namespace mozilla {
|
|
|
|
namespace dom {
|
|
|
|
|
2014-08-05 10:33:55 -07:00
|
|
|
class WebSocket MOZ_FINAL : public DOMEventTargetHelper,
|
|
|
|
public nsIInterfaceRequestor,
|
|
|
|
public nsIWebSocketListener,
|
|
|
|
public nsIObserver,
|
|
|
|
public nsSupportsWeakReference,
|
|
|
|
public nsIRequest
|
2012-09-10 06:48:14 -07:00
|
|
|
{
|
|
|
|
friend class CallDispatchConnectionCloseEvents;
|
|
|
|
friend class nsAutoCloseWS;
|
|
|
|
|
|
|
|
public:
|
|
|
|
enum {
|
|
|
|
CONNECTING = 0,
|
|
|
|
OPEN = 1,
|
|
|
|
CLOSING = 2,
|
|
|
|
CLOSED = 3
|
|
|
|
};
|
|
|
|
|
|
|
|
public:
|
|
|
|
NS_DECL_ISUPPORTS_INHERITED
|
2014-03-31 23:13:50 -07:00
|
|
|
NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_INHERITED(
|
|
|
|
WebSocket, DOMEventTargetHelper)
|
2012-09-10 06:48:14 -07:00
|
|
|
NS_DECL_NSIINTERFACEREQUESTOR
|
|
|
|
NS_DECL_NSIWEBSOCKETLISTENER
|
|
|
|
NS_DECL_NSIOBSERVER
|
|
|
|
NS_DECL_NSIREQUEST
|
|
|
|
|
2013-05-23 04:41:32 -07:00
|
|
|
// EventTarget
|
|
|
|
virtual void EventListenerAdded(nsIAtom* aType) MOZ_OVERRIDE;
|
|
|
|
virtual void EventListenerRemoved(nsIAtom* aType) MOZ_OVERRIDE;
|
2012-09-10 06:48:14 -07:00
|
|
|
|
2013-05-29 13:43:41 -07:00
|
|
|
virtual void DisconnectFromOwner() MOZ_OVERRIDE;
|
2012-09-10 06:48:14 -07:00
|
|
|
|
|
|
|
// nsWrapperCache
|
|
|
|
nsPIDOMWindow* GetParentObject() { return GetOwner(); }
|
|
|
|
|
2014-04-08 15:27:18 -07:00
|
|
|
virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
|
2012-09-10 06:48:14 -07:00
|
|
|
|
|
|
|
public: // static helpers:
|
|
|
|
|
|
|
|
// Determine if preferences allow WebSocket
|
2014-02-06 10:28:14 -08:00
|
|
|
static bool PrefEnabled(JSContext* aCx = nullptr, JSObject* aGlobal = nullptr);
|
2012-09-10 06:48:14 -07:00
|
|
|
|
|
|
|
public: // WebIDL interface:
|
|
|
|
|
|
|
|
// Constructor:
|
2012-12-03 08:07:49 -08:00
|
|
|
static already_AddRefed<WebSocket> Constructor(const GlobalObject& aGlobal,
|
2012-09-10 06:48:14 -07:00
|
|
|
const nsAString& aUrl,
|
|
|
|
ErrorResult& rv);
|
|
|
|
|
2012-12-03 08:07:49 -08:00
|
|
|
static already_AddRefed<WebSocket> Constructor(const GlobalObject& aGlobal,
|
2012-09-10 06:48:14 -07:00
|
|
|
const nsAString& aUrl,
|
|
|
|
const nsAString& aProtocol,
|
|
|
|
ErrorResult& rv);
|
|
|
|
|
2012-12-03 08:07:49 -08:00
|
|
|
static already_AddRefed<WebSocket> Constructor(const GlobalObject& aGlobal,
|
2012-09-10 06:48:14 -07:00
|
|
|
const nsAString& aUrl,
|
|
|
|
const Sequence<nsString>& aProtocols,
|
|
|
|
ErrorResult& rv);
|
|
|
|
|
|
|
|
// webIDL: readonly attribute DOMString url
|
|
|
|
void GetUrl(nsAString& aResult);
|
|
|
|
|
|
|
|
// webIDL: readonly attribute unsigned short readyState;
|
2012-09-11 12:08:24 -07:00
|
|
|
uint16_t ReadyState() const { return mReadyState; }
|
2012-09-10 06:48:14 -07:00
|
|
|
|
|
|
|
// webIDL: readonly attribute unsigned long bufferedAmount;
|
2012-09-11 12:08:24 -07:00
|
|
|
uint32_t BufferedAmount() const { return mOutgoingBufferedAmount; }
|
2012-09-10 06:48:14 -07:00
|
|
|
|
|
|
|
// 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;
|
2012-09-11 12:08:24 -07:00
|
|
|
dom::BinaryType BinaryType() const { return mBinaryType; }
|
|
|
|
void SetBinaryType(dom::BinaryType aData) { mBinaryType = aData; }
|
2012-09-10 06:48:14 -07:00
|
|
|
|
|
|
|
// webIDL: void send(DOMString|Blob|ArrayBufferView data);
|
|
|
|
void Send(const nsAString& aData,
|
|
|
|
ErrorResult& aRv);
|
|
|
|
void Send(nsIDOMBlob* aData,
|
|
|
|
ErrorResult& aRv);
|
2013-08-05 10:40:01 -07:00
|
|
|
void Send(const ArrayBuffer& aData,
|
2012-09-10 06:48:14 -07:00
|
|
|
ErrorResult& aRv);
|
2013-08-05 10:40:01 -07:00
|
|
|
void Send(const ArrayBufferView& aData,
|
2012-09-10 06:48:14 -07:00
|
|
|
ErrorResult& aRv);
|
|
|
|
|
|
|
|
private: // constructor && distructor
|
2014-09-01 16:48:51 -07:00
|
|
|
WebSocket(nsPIDOMWindow* aOwnerWindow);
|
2012-09-10 06:48:14 -07:00
|
|
|
virtual ~WebSocket();
|
|
|
|
|
|
|
|
protected:
|
|
|
|
nsresult Init(JSContext* aCx,
|
|
|
|
nsIPrincipal* aPrincipal,
|
|
|
|
const nsAString& aURL,
|
|
|
|
nsTArray<nsString>& aProtocolArray);
|
|
|
|
|
|
|
|
void Send(nsIInputStream* aMsgStream,
|
|
|
|
const nsACString& aMsgString,
|
2012-09-10 11:11:19 -07:00
|
|
|
uint32_t aMsgLength,
|
2012-09-10 06:48:14 -07:00
|
|
|
bool aIsBinary,
|
|
|
|
ErrorResult& aRv);
|
|
|
|
|
|
|
|
nsresult ParseURL(const nsString& aURL);
|
|
|
|
nsresult EstablishConnection();
|
|
|
|
|
|
|
|
// These methods when called can release the WebSocket object
|
2012-12-22 00:04:08 -08:00
|
|
|
void FailConnection(uint16_t reasonCode,
|
|
|
|
const nsACString& aReasonString = EmptyCString());
|
2012-09-10 06:48:14 -07:00
|
|
|
nsresult CloseConnection(uint16_t reasonCode,
|
|
|
|
const nsACString& aReasonString = EmptyCString());
|
|
|
|
nsresult Disconnect();
|
|
|
|
|
|
|
|
nsresult ConsoleError();
|
|
|
|
nsresult PrintErrorOnConsole(const char* aBundleURI,
|
2014-01-04 07:02:17 -08:00
|
|
|
const char16_t* aError,
|
|
|
|
const char16_t** aFormatStrings,
|
2012-09-10 11:11:19 -07:00
|
|
|
uint32_t aFormatStringsLen);
|
2012-09-10 06:48:14 -07:00
|
|
|
|
|
|
|
nsresult DoOnMessageAvailable(const nsACString& aMsg,
|
|
|
|
bool isBinary);
|
|
|
|
|
|
|
|
// ConnectionCloseEvents: 'error' event if needed, then 'close' event.
|
|
|
|
// - These must not be dispatched while we are still within an incoming call
|
|
|
|
// from JS (ex: close()). Set 'sync' to false in that case to dispatch in a
|
|
|
|
// separate new event.
|
|
|
|
nsresult ScheduleConnectionCloseEvents(nsISupports* aContext,
|
|
|
|
nsresult aStatusCode,
|
|
|
|
bool sync);
|
|
|
|
// 2nd half of ScheduleConnectionCloseEvents, sometimes run in its own event.
|
|
|
|
void DispatchConnectionCloseEvents();
|
|
|
|
|
|
|
|
// These methods actually do the dispatch for various events.
|
|
|
|
nsresult CreateAndDispatchSimpleEvent(const nsString& aName);
|
|
|
|
nsresult CreateAndDispatchMessageEvent(const nsACString& aData,
|
|
|
|
bool isBinary);
|
|
|
|
nsresult CreateAndDispatchCloseEvent(bool aWasClean,
|
2012-09-10 11:11:19 -07:00
|
|
|
uint16_t aCode,
|
2012-09-10 06:48:14 -07:00
|
|
|
const nsString& aReason);
|
|
|
|
|
|
|
|
// 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();
|
|
|
|
|
|
|
|
nsresult UpdateURI();
|
|
|
|
|
|
|
|
protected: //data
|
|
|
|
|
|
|
|
nsCOMPtr<nsIWebSocketChannel> mChannel;
|
|
|
|
|
|
|
|
// related to the WebSocket constructor steps
|
|
|
|
nsString mOriginalURL;
|
|
|
|
nsString mEffectiveURL; // after redirects
|
|
|
|
bool mSecure; // if true it is using SSL and the wss scheme,
|
|
|
|
// otherwise it is using the ws scheme with no SSL
|
|
|
|
|
|
|
|
bool mKeepingAlive;
|
|
|
|
bool mCheckMustKeepAlive;
|
|
|
|
bool mOnCloseScheduled;
|
|
|
|
bool mFailed;
|
|
|
|
bool mDisconnected;
|
|
|
|
|
|
|
|
// Set attributes of DOM 'onclose' message
|
|
|
|
bool mCloseEventWasClean;
|
|
|
|
nsString mCloseEventReason;
|
|
|
|
uint16_t mCloseEventCode;
|
|
|
|
|
|
|
|
nsCString mAsciiHost; // hostname
|
|
|
|
uint32_t mPort;
|
|
|
|
nsCString mResource; // [filepath[?query]]
|
|
|
|
nsString mUTF16Origin;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIURI> mURI;
|
|
|
|
nsCString mRequestedProtocolList;
|
|
|
|
nsCString mEstablishedProtocol;
|
|
|
|
nsCString mEstablishedExtensions;
|
|
|
|
|
|
|
|
uint16_t mReadyState;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIPrincipal> mPrincipal;
|
|
|
|
|
|
|
|
uint32_t mOutgoingBufferedAmount;
|
|
|
|
|
2012-09-11 12:08:24 -07:00
|
|
|
dom::BinaryType mBinaryType;
|
2012-09-10 06:48:14 -07:00
|
|
|
|
|
|
|
// Web Socket owner information:
|
|
|
|
// - the script file name, UTF8 encoded.
|
|
|
|
// - source code line number where the Web Socket object was constructed.
|
|
|
|
// - the ID of the inner window where the script lives. Note that this may not
|
|
|
|
// be the same as the Web Socket owner window.
|
|
|
|
// These attributes are used for error reporting.
|
|
|
|
nsCString mScriptFile;
|
|
|
|
uint32_t mScriptLine;
|
|
|
|
uint64_t mInnerWindowID;
|
|
|
|
|
|
|
|
private:
|
|
|
|
WebSocket(const WebSocket& x) MOZ_DELETE; // prevent bad usage
|
|
|
|
WebSocket& operator=(const WebSocket& x) MOZ_DELETE;
|
|
|
|
};
|
|
|
|
|
|
|
|
} //namespace dom
|
|
|
|
} //namespace mozilla
|
|
|
|
|
|
|
|
#endif
|