netwerk/protocol/websocket/WebSocketChannelParent.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* vim: set sw=2 ts=8 et tw=80 : */
michael@0 3 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 6
michael@0 7 #include "WebSocketLog.h"
michael@0 8 #include "WebSocketChannelParent.h"
michael@0 9 #include "nsIAuthPromptProvider.h"
michael@0 10 #include "mozilla/ipc/InputStreamUtils.h"
michael@0 11 #include "mozilla/ipc/URIUtils.h"
michael@0 12 #include "SerializedLoadContext.h"
michael@0 13
michael@0 14 using namespace mozilla::ipc;
michael@0 15
michael@0 16 namespace mozilla {
michael@0 17 namespace net {
michael@0 18
michael@0 19 NS_IMPL_ISUPPORTS(WebSocketChannelParent,
michael@0 20 nsIWebSocketListener,
michael@0 21 nsIInterfaceRequestor)
michael@0 22
michael@0 23 WebSocketChannelParent::WebSocketChannelParent(nsIAuthPromptProvider* aAuthProvider,
michael@0 24 nsILoadContext* aLoadContext,
michael@0 25 PBOverrideStatus aOverrideStatus)
michael@0 26 : mAuthProvider(aAuthProvider)
michael@0 27 , mLoadContext(aLoadContext)
michael@0 28 , mIPCOpen(true)
michael@0 29 {
michael@0 30 // Websocket channels can't have a private browsing override
michael@0 31 MOZ_ASSERT_IF(!aLoadContext, aOverrideStatus == kPBOverride_Unset);
michael@0 32 #if defined(PR_LOGGING)
michael@0 33 if (!webSocketLog)
michael@0 34 webSocketLog = PR_NewLogModule("nsWebSocket");
michael@0 35 #endif
michael@0 36 }
michael@0 37
michael@0 38 //-----------------------------------------------------------------------------
michael@0 39 // WebSocketChannelParent::PWebSocketChannelParent
michael@0 40 //-----------------------------------------------------------------------------
michael@0 41
michael@0 42 bool
michael@0 43 WebSocketChannelParent::RecvDeleteSelf()
michael@0 44 {
michael@0 45 LOG(("WebSocketChannelParent::RecvDeleteSelf() %p\n", this));
michael@0 46 mChannel = nullptr;
michael@0 47 mAuthProvider = nullptr;
michael@0 48 return mIPCOpen ? Send__delete__(this) : true;
michael@0 49 }
michael@0 50
michael@0 51 bool
michael@0 52 WebSocketChannelParent::RecvAsyncOpen(const URIParams& aURI,
michael@0 53 const nsCString& aOrigin,
michael@0 54 const nsCString& aProtocol,
michael@0 55 const bool& aSecure,
michael@0 56 const uint32_t& aPingInterval,
michael@0 57 const bool& aClientSetPingInterval,
michael@0 58 const uint32_t& aPingTimeout,
michael@0 59 const bool& aClientSetPingTimeout)
michael@0 60 {
michael@0 61 LOG(("WebSocketChannelParent::RecvAsyncOpen() %p\n", this));
michael@0 62
michael@0 63 nsresult rv;
michael@0 64 nsCOMPtr<nsIURI> uri;
michael@0 65
michael@0 66 if (aSecure) {
michael@0 67 mChannel =
michael@0 68 do_CreateInstance("@mozilla.org/network/protocol;1?name=wss", &rv);
michael@0 69 } else {
michael@0 70 mChannel =
michael@0 71 do_CreateInstance("@mozilla.org/network/protocol;1?name=ws", &rv);
michael@0 72 }
michael@0 73 if (NS_FAILED(rv))
michael@0 74 goto fail;
michael@0 75
michael@0 76 rv = mChannel->SetNotificationCallbacks(this);
michael@0 77 if (NS_FAILED(rv))
michael@0 78 goto fail;
michael@0 79
michael@0 80 rv = mChannel->SetProtocol(aProtocol);
michael@0 81 if (NS_FAILED(rv))
michael@0 82 goto fail;
michael@0 83
michael@0 84 uri = DeserializeURI(aURI);
michael@0 85 if (!uri) {
michael@0 86 rv = NS_ERROR_FAILURE;
michael@0 87 goto fail;
michael@0 88 }
michael@0 89
michael@0 90 // only use ping values from child if they were overridden by client code.
michael@0 91 if (aClientSetPingInterval) {
michael@0 92 // IDL allows setting in seconds, so must be multiple of 1000 ms
michael@0 93 MOZ_ASSERT(aPingInterval >= 1000 && !(aPingInterval % 1000));
michael@0 94 mChannel->SetPingInterval(aPingInterval / 1000);
michael@0 95 }
michael@0 96 if (aClientSetPingTimeout) {
michael@0 97 MOZ_ASSERT(aPingTimeout >= 1000 && !(aPingTimeout % 1000));
michael@0 98 mChannel->SetPingTimeout(aPingTimeout / 1000);
michael@0 99 }
michael@0 100
michael@0 101 rv = mChannel->AsyncOpen(uri, aOrigin, this, nullptr);
michael@0 102 if (NS_FAILED(rv))
michael@0 103 goto fail;
michael@0 104
michael@0 105 return true;
michael@0 106
michael@0 107 fail:
michael@0 108 mChannel = nullptr;
michael@0 109 return SendOnStop(rv);
michael@0 110 }
michael@0 111
michael@0 112 bool
michael@0 113 WebSocketChannelParent::RecvClose(const uint16_t& code, const nsCString& reason)
michael@0 114 {
michael@0 115 LOG(("WebSocketChannelParent::RecvClose() %p\n", this));
michael@0 116 if (mChannel) {
michael@0 117 nsresult rv = mChannel->Close(code, reason);
michael@0 118 NS_ENSURE_SUCCESS(rv, true);
michael@0 119 }
michael@0 120 return true;
michael@0 121 }
michael@0 122
michael@0 123 bool
michael@0 124 WebSocketChannelParent::RecvSendMsg(const nsCString& aMsg)
michael@0 125 {
michael@0 126 LOG(("WebSocketChannelParent::RecvSendMsg() %p\n", this));
michael@0 127 if (mChannel) {
michael@0 128 nsresult rv = mChannel->SendMsg(aMsg);
michael@0 129 NS_ENSURE_SUCCESS(rv, true);
michael@0 130 }
michael@0 131 return true;
michael@0 132 }
michael@0 133
michael@0 134 bool
michael@0 135 WebSocketChannelParent::RecvSendBinaryMsg(const nsCString& aMsg)
michael@0 136 {
michael@0 137 LOG(("WebSocketChannelParent::RecvSendBinaryMsg() %p\n", this));
michael@0 138 if (mChannel) {
michael@0 139 nsresult rv = mChannel->SendBinaryMsg(aMsg);
michael@0 140 NS_ENSURE_SUCCESS(rv, true);
michael@0 141 }
michael@0 142 return true;
michael@0 143 }
michael@0 144
michael@0 145 bool
michael@0 146 WebSocketChannelParent::RecvSendBinaryStream(const InputStreamParams& aStream,
michael@0 147 const uint32_t& aLength)
michael@0 148 {
michael@0 149 LOG(("WebSocketChannelParent::RecvSendBinaryStream() %p\n", this));
michael@0 150 if (mChannel) {
michael@0 151 nsTArray<mozilla::ipc::FileDescriptor> fds;
michael@0 152 nsCOMPtr<nsIInputStream> stream = DeserializeInputStream(aStream, fds);
michael@0 153 if (!stream) {
michael@0 154 return false;
michael@0 155 }
michael@0 156 nsresult rv = mChannel->SendBinaryStream(stream, aLength);
michael@0 157 NS_ENSURE_SUCCESS(rv, true);
michael@0 158 }
michael@0 159 return true;
michael@0 160 }
michael@0 161
michael@0 162 //-----------------------------------------------------------------------------
michael@0 163 // WebSocketChannelParent::nsIRequestObserver
michael@0 164 //-----------------------------------------------------------------------------
michael@0 165
michael@0 166 NS_IMETHODIMP
michael@0 167 WebSocketChannelParent::OnStart(nsISupports *aContext)
michael@0 168 {
michael@0 169 LOG(("WebSocketChannelParent::OnStart() %p\n", this));
michael@0 170 nsAutoCString protocol, extensions;
michael@0 171 if (mChannel) {
michael@0 172 mChannel->GetProtocol(protocol);
michael@0 173 mChannel->GetExtensions(extensions);
michael@0 174 }
michael@0 175 if (!mIPCOpen || !SendOnStart(protocol, extensions)) {
michael@0 176 return NS_ERROR_FAILURE;
michael@0 177 }
michael@0 178 return NS_OK;
michael@0 179 }
michael@0 180
michael@0 181 NS_IMETHODIMP
michael@0 182 WebSocketChannelParent::OnStop(nsISupports *aContext, nsresult aStatusCode)
michael@0 183 {
michael@0 184 LOG(("WebSocketChannelParent::OnStop() %p\n", this));
michael@0 185 if (!mIPCOpen || !SendOnStop(aStatusCode)) {
michael@0 186 return NS_ERROR_FAILURE;
michael@0 187 }
michael@0 188 return NS_OK;
michael@0 189 }
michael@0 190
michael@0 191 NS_IMETHODIMP
michael@0 192 WebSocketChannelParent::OnMessageAvailable(nsISupports *aContext, const nsACString& aMsg)
michael@0 193 {
michael@0 194 LOG(("WebSocketChannelParent::OnMessageAvailable() %p\n", this));
michael@0 195 if (!mIPCOpen || !SendOnMessageAvailable(nsCString(aMsg))) {
michael@0 196 return NS_ERROR_FAILURE;
michael@0 197 }
michael@0 198 return NS_OK;
michael@0 199 }
michael@0 200
michael@0 201 NS_IMETHODIMP
michael@0 202 WebSocketChannelParent::OnBinaryMessageAvailable(nsISupports *aContext, const nsACString& aMsg)
michael@0 203 {
michael@0 204 LOG(("WebSocketChannelParent::OnBinaryMessageAvailable() %p\n", this));
michael@0 205 if (!mIPCOpen || !SendOnBinaryMessageAvailable(nsCString(aMsg))) {
michael@0 206 return NS_ERROR_FAILURE;
michael@0 207 }
michael@0 208 return NS_OK;
michael@0 209 }
michael@0 210
michael@0 211 NS_IMETHODIMP
michael@0 212 WebSocketChannelParent::OnAcknowledge(nsISupports *aContext, uint32_t aSize)
michael@0 213 {
michael@0 214 LOG(("WebSocketChannelParent::OnAcknowledge() %p\n", this));
michael@0 215 if (!mIPCOpen || !SendOnAcknowledge(aSize)) {
michael@0 216 return NS_ERROR_FAILURE;
michael@0 217 }
michael@0 218 return NS_OK;
michael@0 219 }
michael@0 220
michael@0 221 NS_IMETHODIMP
michael@0 222 WebSocketChannelParent::OnServerClose(nsISupports *aContext,
michael@0 223 uint16_t code, const nsACString & reason)
michael@0 224 {
michael@0 225 LOG(("WebSocketChannelParent::OnServerClose() %p\n", this));
michael@0 226 if (!mIPCOpen || !SendOnServerClose(code, nsCString(reason))) {
michael@0 227 return NS_ERROR_FAILURE;
michael@0 228 }
michael@0 229 return NS_OK;
michael@0 230 }
michael@0 231
michael@0 232 void
michael@0 233 WebSocketChannelParent::ActorDestroy(ActorDestroyReason why)
michael@0 234 {
michael@0 235 LOG(("WebSocketChannelParent::ActorDestroy() %p\n", this));
michael@0 236 mIPCOpen = false;
michael@0 237 }
michael@0 238
michael@0 239 //-----------------------------------------------------------------------------
michael@0 240 // WebSocketChannelParent::nsIInterfaceRequestor
michael@0 241 //-----------------------------------------------------------------------------
michael@0 242
michael@0 243 NS_IMETHODIMP
michael@0 244 WebSocketChannelParent::GetInterface(const nsIID & iid, void **result)
michael@0 245 {
michael@0 246 LOG(("WebSocketChannelParent::GetInterface() %p\n", this));
michael@0 247 if (mAuthProvider && iid.Equals(NS_GET_IID(nsIAuthPromptProvider)))
michael@0 248 return mAuthProvider->GetAuthPrompt(nsIAuthPromptProvider::PROMPT_NORMAL,
michael@0 249 iid, result);
michael@0 250
michael@0 251 // Only support nsILoadContext if child channel's callbacks did too
michael@0 252 if (iid.Equals(NS_GET_IID(nsILoadContext)) && mLoadContext) {
michael@0 253 NS_ADDREF(mLoadContext);
michael@0 254 *result = static_cast<nsILoadContext*>(mLoadContext);
michael@0 255 return NS_OK;
michael@0 256 }
michael@0 257
michael@0 258 return QueryInterface(iid, result);
michael@0 259 }
michael@0 260
michael@0 261
michael@0 262 } // namespace net
michael@0 263 } // namespace mozilla

mercurial