netwerk/protocol/websocket/WebSocketChannelParent.cpp

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

mercurial