summaryrefslogtreecommitdiffstats
path: root/netwerk/protocol/websocket/BaseWebSocketChannel.h
blob: ee05e5bf4cd3bcb16f153a2f86f72aa64cc1593f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/* -*- 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 mozilla_net_BaseWebSocketChannel_h
#define mozilla_net_BaseWebSocketChannel_h

#include "mozilla/DataMutex.h"
#include "nsIWebSocketChannel.h"
#include "nsIWebSocketListener.h"
#include "nsIProtocolHandler.h"
#include "nsIThread.h"
#include "nsIThreadRetargetableRequest.h"
#include "nsCOMPtr.h"
#include "nsString.h"

namespace mozilla {
namespace net {

const static int32_t kDefaultWSPort = 80;
const static int32_t kDefaultWSSPort = 443;

class BaseWebSocketChannel : public nsIWebSocketChannel,
                             public nsIProtocolHandler,
                             public nsIThreadRetargetableRequest {
 public:
  BaseWebSocketChannel();

  NS_DECL_NSIPROTOCOLHANDLER
  NS_DECL_NSITHREADRETARGETABLEREQUEST

  NS_IMETHOD QueryInterface(const nsIID& uuid, void** result) override = 0;
  NS_IMETHOD_(MozExternalRefCountType) AddRef(void) override = 0;
  NS_IMETHOD_(MozExternalRefCountType) Release(void) override = 0;

  // Partial implementation of nsIWebSocketChannel
  //
  NS_IMETHOD GetOriginalURI(nsIURI** aOriginalURI) override;
  NS_IMETHOD GetURI(nsIURI** aURI) override;
  NS_IMETHOD GetNotificationCallbacks(
      nsIInterfaceRequestor** aNotificationCallbacks) override;
  NS_IMETHOD SetNotificationCallbacks(
      nsIInterfaceRequestor* aNotificationCallbacks) override;
  NS_IMETHOD GetLoadGroup(nsILoadGroup** aLoadGroup) override;
  NS_IMETHOD SetLoadGroup(nsILoadGroup* aLoadGroup) override;
  NS_IMETHOD SetLoadInfo(nsILoadInfo* aLoadInfo) override;
  NS_IMETHOD GetLoadInfo(nsILoadInfo** aLoadInfo) override;
  NS_IMETHOD GetExtensions(nsACString& aExtensions) override;
  NS_IMETHOD GetProtocol(nsACString& aProtocol) override;
  NS_IMETHOD SetProtocol(const nsACString& aProtocol) override;
  NS_IMETHOD GetPingInterval(uint32_t* aSeconds) override;
  NS_IMETHOD SetPingInterval(uint32_t aSeconds) override;
  NS_IMETHOD GetPingTimeout(uint32_t* aSeconds) override;
  NS_IMETHOD SetPingTimeout(uint32_t aSeconds) override;
  NS_IMETHOD InitLoadInfoNative(nsINode* aLoadingNode,
                                nsIPrincipal* aLoadingPrincipal,
                                nsIPrincipal* aTriggeringPrincipal,
                                nsICookieJarSettings* aCookieJarSettings,
                                uint32_t aSecurityFlags,
                                nsContentPolicyType aContentPolicyType,
                                uint32_t aSandboxFlags) override;
  NS_IMETHOD InitLoadInfo(nsINode* aLoadingNode,
                          nsIPrincipal* aLoadingPrincipal,
                          nsIPrincipal* aTriggeringPrincipal,
                          uint32_t aSecurityFlags,
                          nsContentPolicyType aContentPolicyType) override;
  NS_IMETHOD GetSerial(uint32_t* aSerial) override;
  NS_IMETHOD SetSerial(uint32_t aSerial) override;
  NS_IMETHOD SetServerParameters(
      nsITransportProvider* aProvider,
      const nsACString& aNegotiatedExtensions) override;
  NS_IMETHOD GetHttpChannelId(uint64_t* aHttpChannelId) override;

  // Off main thread URI access.
  virtual void GetEffectiveURL(nsAString& aEffectiveURL) const = 0;
  virtual bool IsEncrypted() const = 0;

  already_AddRefed<nsISerialEventTarget> GetTargetThread();
  bool IsOnTargetThread();

  class ListenerAndContextContainer final {
   public:
    NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ListenerAndContextContainer)

    ListenerAndContextContainer(nsIWebSocketListener* aListener,
                                nsISupports* aContext);

    nsCOMPtr<nsIWebSocketListener> mListener;
    nsCOMPtr<nsISupports> mContext;

   private:
    ~ListenerAndContextContainer();
  };

 protected:
  virtual ~BaseWebSocketChannel();
  nsCOMPtr<nsIURI> mOriginalURI;
  nsCOMPtr<nsIURI> mURI;
  RefPtr<ListenerAndContextContainer> mListenerMT;
  nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
  nsCOMPtr<nsILoadGroup> mLoadGroup;
  nsCOMPtr<nsILoadInfo> mLoadInfo;
  nsCOMPtr<nsITransportProvider> mServerTransportProvider;

  // Used to ensure atomicity of mTargetThread.
  // Set before AsyncOpen via RetargetDeliveryTo or in AsyncOpen, never changed
  // after AsyncOpen
  DataMutex<nsCOMPtr<nsISerialEventTarget>> mTargetThread{
      "BaseWebSocketChannel::EventTargetMutex"};

  nsCString mProtocol;
  nsCString mOrigin;

  nsCString mNegotiatedExtensions;

  uint32_t mWasOpened : 1;
  uint32_t mClientSetPingInterval : 1;
  uint32_t mClientSetPingTimeout : 1;

  Atomic<bool> mEncrypted;
  bool mPingForced;
  bool mIsServerSide;

  Atomic<uint32_t> mPingInterval; /* milliseconds */
  uint32_t mPingResponseTimeout;  /* milliseconds */

  uint32_t mSerial;

  uint64_t mHttpChannelId;
};

}  // namespace net
}  // namespace mozilla

#endif  // mozilla_net_BaseWebSocketChannel_h