Bug 504553 - Patch 1 - WebSockets in Workers: Dispatch WebSocketChannel::StartWebsocketConnect to target thread, r=jduell
--- a/content/base/src/WebSocket.cpp
+++ b/content/base/src/WebSocket.cpp
@@ -1,16 +1,17 @@
/* -*- 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/. */
#include "WebSocket.h"
#include "mozilla/dom/WebSocketBinding.h"
+#include "mozilla/net/WebSocketChannel.h"
#include "jsapi.h"
#include "jsfriendapi.h"
#include "js/OldDebugAPI.h"
#include "mozilla/DOMEventTargetHelper.h"
#include "mozilla/dom/File.h"
#include "mozilla/dom/ScriptSettings.h"
#include "nsIScriptGlobalObject.h"
@@ -36,17 +37,18 @@
#include "nsIScriptError.h"
#include "nsNetUtil.h"
#include "nsILoadGroup.h"
#include "mozilla/Preferences.h"
#include "xpcpublic.h"
#include "nsContentPolicyUtils.h"
#include "nsWrapperCacheInlines.h"
#include "nsIObserverService.h"
-#include "nsIWebSocketChannel.h"
+
+using namespace mozilla::net;
namespace mozilla {
namespace dom {
#define UTF_8_REPLACEMENT_CHAR static_cast<char16_t>(0xFFFD)
class CallDispatchConnectionCloseEvents: public nsRunnable
{
@@ -1119,29 +1121,22 @@ WebSocket::DontKeepAliveAnyMore()
}
mCheckMustKeepAlive = false;
}
nsresult
WebSocket::UpdateURI()
{
// Check for Redirections
- nsCOMPtr<nsIURI> uri;
- nsresult rv = mChannel->GetURI(getter_AddRefs(uri));
- NS_ENSURE_SUCCESS(rv, rv);
+ nsRefPtr<BaseWebSocketChannel> channel;
+ channel = static_cast<BaseWebSocketChannel*>(mChannel.get());
+ MOZ_ASSERT(channel);
- nsAutoCString spec;
- rv = uri->GetSpec(spec);
- NS_ENSURE_SUCCESS(rv, rv);
- CopyUTF8toUTF16(spec, mEffectiveURL);
-
- bool isWSS = false;
- rv = uri->SchemeIs("wss", &isWSS);
- NS_ENSURE_SUCCESS(rv, rv);
- mSecure = isWSS ? true : false;
+ channel->GetEffectiveURL(mEffectiveURL);
+ mSecure = channel->IsEncrypted();
return NS_OK;
}
void
WebSocket::EventListenerAdded(nsIAtom* aType)
{
UpdateMustKeepAlive();
--- a/netwerk/protocol/websocket/BaseWebSocketChannel.h
+++ b/netwerk/protocol/websocket/BaseWebSocketChannel.h
@@ -48,16 +48,20 @@ class BaseWebSocketChannel : public nsIW
NS_IMETHOD GetExtensions(nsACString &aExtensions);
NS_IMETHOD GetProtocol(nsACString &aProtocol);
NS_IMETHOD SetProtocol(const nsACString &aProtocol);
NS_IMETHOD GetPingInterval(uint32_t *aSeconds);
NS_IMETHOD SetPingInterval(uint32_t aSeconds);
NS_IMETHOD GetPingTimeout(uint32_t *aSeconds);
NS_IMETHOD SetPingTimeout(uint32_t aSeconds);
+ // Off main thread URI access.
+ virtual void GetEffectiveURL(nsAString& aEffectiveURL) const = 0;
+ virtual bool IsEncrypted() const = 0;
+
protected:
nsCOMPtr<nsIURI> mOriginalURI;
nsCOMPtr<nsIURI> mURI;
nsCOMPtr<nsIWebSocketListener> mListener;
nsCOMPtr<nsISupports> mContext;
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
nsCOMPtr<nsILoadGroup> mLoadGroup;
nsCOMPtr<nsILoadInfo> mLoadInfo;
--- a/netwerk/protocol/websocket/PWebSocket.ipdl
+++ b/netwerk/protocol/websocket/PWebSocket.ipdl
@@ -36,17 +36,18 @@ parent:
SendMsg(nsCString aMsg);
SendBinaryMsg(nsCString aMsg);
SendBinaryStream(InputStreamParams aStream, uint32_t aLength);
DeleteSelf();
child:
// Forwarded notifications corresponding to the nsIWebSocketListener interface
- OnStart(nsCString aProtocol, nsCString aExtensions);
+ OnStart(nsCString aProtocol, nsCString aExtensions,
+ nsString aEffectiveURL, bool aEncrypted);
OnStop(nsresult aStatusCode);
OnMessageAvailable(nsCString aMsg);
OnBinaryMessageAvailable(nsCString aMsg);
OnAcknowledge(uint32_t aSize);
OnServerClose(uint16_t code, nsCString aReason);
__delete__();
--- a/netwerk/protocol/websocket/WebSocketChannel.cpp
+++ b/netwerk/protocol/websocket/WebSocketChannel.cpp
@@ -203,32 +203,28 @@ public:
MOZ_COUNT_DTOR(FailDelayManager);
for (uint32_t i = 0; i < mEntries.Length(); i++) {
delete mEntries[i];
}
}
void Add(nsCString &address, int32_t port)
{
- NS_ABORT_IF_FALSE(NS_IsMainThread(), "not main thread");
-
if (mDelaysDisabled)
return;
FailDelay *record = new FailDelay(address, port);
mEntries.AppendElement(record);
}
// Element returned may not be valid after next main thread event: don't keep
// pointer to it around
FailDelay* Lookup(nsCString &address, int32_t port,
uint32_t *outIndex = nullptr)
{
- NS_ABORT_IF_FALSE(NS_IsMainThread(), "not main thread");
-
if (mDelaysDisabled)
return nullptr;
FailDelay *result = nullptr;
TimeStamp rightNow = TimeStamp::Now();
// We also remove expired entries during search: iterate from end to make
// indexing simpler
@@ -288,18 +284,16 @@ public:
// delay interval has passed: connect.
ws->BeginOpen();
}
// Remove() also deletes all expired entries as it iterates: better for
// battery life than using a periodic timer.
void Remove(nsCString &address, int32_t port)
{
- NS_ABORT_IF_FALSE(NS_IsMainThread(), "not main thread");
-
TimeStamp rightNow = TimeStamp::Now();
// iterate from end, to make deletion indexing easier
for (int32_t i = mEntries.Length() - 1; i >= 0; --i) {
FailDelay *entry = mEntries[i];
if ((entry->mAddress.Equals(address) && entry->mPort == port) ||
entry->IsExpired(rightNow)) {
mEntries.RemoveElementAt(i);
@@ -338,17 +332,16 @@ public:
delete sManager;
sManager = nullptr;
}
// Determine if we will open connection immediately (returns true), or
// delay/queue the connection (returns false)
static void ConditionallyConnect(WebSocketChannel *ws)
{
- NS_ABORT_IF_FALSE(NS_IsMainThread(), "not main thread");
NS_ABORT_IF_FALSE(ws->mConnecting == NOT_CONNECTING, "opening state");
StaticMutexAutoLock lock(sLock);
if (!sManager) {
return;
}
// If there is already another WS channel connecting to this IP address,
@@ -363,17 +356,16 @@ public:
ws->mConnecting = CONNECTING_QUEUED;
} else {
sManager->mFailures.DelayOrBegin(ws);
}
}
static void OnConnected(WebSocketChannel *aChannel)
{
- NS_ABORT_IF_FALSE(NS_IsMainThread(), "not main thread");
NS_ABORT_IF_FALSE(aChannel->mConnecting == CONNECTING_IN_PROGRESS,
"Channel completed connect, but not connecting?");
StaticMutexAutoLock lock(sLock);
if (!sManager) {
return;
}
@@ -390,18 +382,16 @@ public:
// host may have different port
sManager->ConnectNext(aChannel->mAddress);
}
// Called every time a websocket channel ends its session (including going away
// w/o ever successfully creating a connection)
static void OnStopSession(WebSocketChannel *aChannel, nsresult aReason)
{
- NS_ABORT_IF_FALSE(NS_IsMainThread(), "not main thread");
-
StaticMutexAutoLock lock(sLock);
if (!sManager) {
return;
}
if (NS_FAILED(aReason)) {
// Have we seen this failure before?
FailDelay *knownFailure = sManager->mFailures.Lookup(aChannel->mAddress,
@@ -568,17 +558,17 @@ public:
nsCString &aData,
int32_t aLen)
: mChannel(aChannel),
mData(aData),
mLen(aLen) {}
NS_IMETHOD Run()
{
- MOZ_ASSERT(NS_GetCurrentThread() == mChannel->mTargetThread);
+ MOZ_ASSERT(mChannel->IsOnTargetThread());
if (mLen < 0)
mChannel->mListener->OnMessageAvailable(mChannel->mContext, mData);
else
mChannel->mListener->OnBinaryMessageAvailable(mChannel->mContext, mData);
return NS_OK;
}
@@ -602,17 +592,17 @@ public:
CallOnStop(WebSocketChannel *aChannel,
nsresult aReason)
: mChannel(aChannel),
mReason(aReason) {}
NS_IMETHOD Run()
{
- MOZ_ASSERT(NS_GetCurrentThread() == mChannel->mTargetThread);
+ MOZ_ASSERT(mChannel->IsOnTargetThread());
nsWSAdmissionManager::OnStopSession(mChannel, mReason);
if (mChannel->mListener) {
mChannel->mListener->OnStop(mChannel->mContext, mReason);
mChannel->mListener = nullptr;
mChannel->mContext = nullptr;
}
@@ -640,17 +630,17 @@ public:
uint16_t aCode,
nsCString &aReason)
: mChannel(aChannel),
mCode(aCode),
mReason(aReason) {}
NS_IMETHOD Run()
{
- MOZ_ASSERT(NS_GetCurrentThread() == mChannel->mTargetThread);
+ MOZ_ASSERT(mChannel->IsOnTargetThread());
mChannel->mListener->OnServerClose(mChannel->mContext, mCode, mReason);
return NS_OK;
}
private:
~CallOnServerClose() {}
@@ -671,17 +661,17 @@ public:
CallAcknowledge(WebSocketChannel *aChannel,
uint32_t aSize)
: mChannel(aChannel),
mSize(aSize) {}
NS_IMETHOD Run()
{
- MOZ_ASSERT(NS_GetCurrentThread() == mChannel->mTargetThread);
+ MOZ_ASSERT(mChannel->IsOnTargetThread());
LOG(("WebSocketChannel::CallAcknowledge: Size %u\n", mSize));
mChannel->mListener->OnAcknowledge(mChannel->mContext, mSize);
return NS_OK;
}
private:
~CallAcknowledge() {}
@@ -1173,16 +1163,38 @@ WebSocketChannel::Observe(nsISupports *s
}
void
WebSocketChannel::Shutdown()
{
nsWSAdmissionManager::Shutdown();
}
+bool
+WebSocketChannel::IsOnTargetThread()
+{
+ MOZ_ASSERT(mTargetThread);
+ bool isOnTargetThread = false;
+ nsresult rv = mTargetThread->IsOnCurrentThread(&isOnTargetThread);
+ MOZ_ASSERT(NS_SUCCEEDED(rv));
+ return NS_FAILED(rv) ? false : isOnTargetThread;
+}
+
+void
+WebSocketChannel::GetEffectiveURL(nsAString& aEffectiveURL) const
+{
+ aEffectiveURL = mEffectiveURL;
+}
+
+bool
+WebSocketChannel::IsEncrypted() const
+{
+ return mEncrypted;
+}
+
void
WebSocketChannel::BeginOpen()
{
LOG(("WebSocketChannel::BeginOpen() %p\n", this));
NS_ABORT_IF_FALSE(NS_IsMainThread(), "not main thread");
nsresult rv;
@@ -2367,30 +2379,37 @@ WebSocketChannel::ApplyForAdmission()
}
// Called after both OnStartRequest and OnTransportAvailable have
// executed. This essentially ends the handshake and starts the websockets
// protocol state machine.
nsresult
WebSocketChannel::StartWebsocketData()
{
+ if (!IsOnTargetThread()) {
+ return mTargetThread->Dispatch(
+ NS_NewRunnableMethod(this, &WebSocketChannel::StartWebsocketData),
+ NS_DISPATCH_NORMAL);
+ }
+
LOG(("WebSocketChannel::StartWebsocketData() %p", this));
NS_ABORT_IF_FALSE(!mDataStarted, "StartWebsocketData twice");
mDataStarted = 1;
// We're now done CONNECTING, which means we can now open another,
// perhaps parallel, connection to the same host if one
// is pending
nsWSAdmissionManager::OnConnected(this);
LOG(("WebSocketChannel::StartWebsocketData Notifying Listener %p\n",
mListener.get()));
- if (mListener)
+ if (mListener) {
mListener->OnStart(mContext);
+ }
// Start keepalive ping timer, if we're using keepalive.
if (mPingInterval) {
nsresult rv;
mPingTimer = do_CreateInstance("@mozilla.org/timer;1", &rv);
if (NS_FAILED(rv)) {
NS_WARNING("unable to create ping timer. Carrying on.");
} else {
@@ -2969,17 +2988,17 @@ WebSocketChannel::SendBinaryStream(nsIIn
return SendMsgCommon(nullptr, true, aLength, aStream);
}
nsresult
WebSocketChannel::SendMsgCommon(const nsACString *aMsg, bool aIsBinary,
uint32_t aLength, nsIInputStream *aStream)
{
- NS_ABORT_IF_FALSE(NS_GetCurrentThread() == mTargetThread, "not target thread");
+ NS_ABORT_IF_FALSE(IsOnTargetThread(), "not target thread");
if (mRequestedClose) {
LOG(("WebSocketChannel:: Error: send when closed\n"));
return NS_ERROR_UNEXPECTED;
}
if (mStopped) {
LOG(("WebSocketChannel:: Error: send when stopped\n"));
@@ -3185,16 +3204,23 @@ WebSocketChannel::OnStartRequest(nsIRequ
mProtocol.Truncate();
}
}
rv = HandleExtensions();
if (NS_FAILED(rv))
return rv;
+ // Update mEffectiveURL for off main thread URI access.
+ nsCOMPtr<nsIURI> uri = mURI ? mURI : mOriginalURI;
+ nsAutoCString spec;
+ rv = uri->GetSpec(spec);
+ MOZ_ASSERT(NS_SUCCEEDED(rv));
+ CopyUTF8toUTF16(spec, mEffectiveURL);
+
mGotUpgradeOK = 1;
if (mRecvdHttpUpgradeTransport)
return StartWebsocketData();
return NS_OK;
}
NS_IMETHODIMP
--- a/netwerk/protocol/websocket/WebSocketChannel.h
+++ b/netwerk/protocol/websocket/WebSocketChannel.h
@@ -13,16 +13,17 @@
#include "nsIAsyncInputStream.h"
#include "nsIAsyncOutputStream.h"
#include "nsITimer.h"
#include "nsIDNSListener.h"
#include "nsIObserver.h"
#include "nsIProtocolProxyCallback.h"
#include "nsIChannelEventSink.h"
#include "nsIHttpChannelInternal.h"
+#include "nsIStringStream.h"
#include "BaseWebSocketChannel.h"
#ifdef MOZ_WIDGET_GONK
#include "nsINetworkManager.h"
#include "nsProxyRelease.h"
#endif
#include "nsCOMPtr.h"
@@ -91,16 +92,21 @@ public:
NS_IMETHOD Close(uint16_t aCode, const nsACString & aReason);
NS_IMETHOD SendMsg(const nsACString &aMsg);
NS_IMETHOD SendBinaryMsg(const nsACString &aMsg);
NS_IMETHOD SendBinaryStream(nsIInputStream *aStream, uint32_t length);
NS_IMETHOD GetSecurityInfo(nsISupports **aSecurityInfo);
WebSocketChannel();
static void Shutdown();
+ bool IsOnTargetThread();
+
+ // Off main thread URI access.
+ void GetEffectiveURL(nsAString& aEffectiveURL) const MOZ_OVERRIDE;
+ bool IsEncrypted() const MOZ_OVERRIDE;
enum {
// Non Control Frames
kContinuation = 0x0,
kText = 0x1,
kBinary = 0x2,
// Control Frames
@@ -180,16 +186,17 @@ private:
// Used as key for connection managment: Initially set to hostname from URI,
// then to IP address (unless we're leaving DNS resolution to a proxy server)
nsCString mAddress;
int32_t mPort; // WS server port
// Used for off main thread access to the URI string.
nsCString mHost;
+ nsString mEffectiveURL;
nsCOMPtr<nsISocketTransport> mTransport;
nsCOMPtr<nsIAsyncInputStream> mSocketIn;
nsCOMPtr<nsIAsyncOutputStream> mSocketOut;
nsCOMPtr<nsITimer> mCloseTimer;
uint32_t mCloseTimeout; /* milliseconds */
--- a/netwerk/protocol/websocket/WebSocketChannelChild.cpp
+++ b/netwerk/protocol/websocket/WebSocketChannelChild.cpp
@@ -44,23 +44,23 @@ NS_IMETHODIMP_(MozExternalRefCountType)
NS_INTERFACE_MAP_BEGIN(WebSocketChannelChild)
NS_INTERFACE_MAP_ENTRY(nsIWebSocketChannel)
NS_INTERFACE_MAP_ENTRY(nsIProtocolHandler)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWebSocketChannel)
NS_INTERFACE_MAP_ENTRY(nsIThreadRetargetableRequest)
NS_INTERFACE_MAP_END
-WebSocketChannelChild::WebSocketChannelChild(bool aSecure)
+WebSocketChannelChild::WebSocketChannelChild(bool aEncrypted)
: mIPCOpen(false)
{
NS_ABORT_IF_FALSE(NS_IsMainThread(), "not main thread");
LOG(("WebSocketChannelChild::WebSocketChannelChild() %p\n", this));
- BaseWebSocketChannel::mEncrypted = aSecure;
+ mEncrypted = aEncrypted;
mEventQ = new ChannelEventQueue(static_cast<nsIWebSocketChannel*>(this));
}
WebSocketChannelChild::~WebSocketChannelChild()
{
LOG(("WebSocketChannelChild::~WebSocketChannelChild() %p\n", this));
}
@@ -75,16 +75,28 @@ WebSocketChannelChild::AddIPDLReference(
void
WebSocketChannelChild::ReleaseIPDLReference()
{
NS_ABORT_IF_FALSE(mIPCOpen, "Attempt to release nonexistent IPDL reference");
mIPCOpen = false;
Release();
}
+void
+WebSocketChannelChild::GetEffectiveURL(nsAString& aEffectiveURL) const
+{
+ aEffectiveURL = mEffectiveURL;
+}
+
+bool
+WebSocketChannelChild::IsEncrypted() const
+{
+ return mEncrypted;
+}
+
class WrappedChannelEvent : public nsRunnable
{
public:
explicit WrappedChannelEvent(ChannelEvent *aChannelEvent)
: mChannelEvent(aChannelEvent)
{
MOZ_RELEASE_ASSERT(aChannelEvent);
}
@@ -108,53 +120,67 @@ WebSocketChannelChild::DispatchToTargetT
NS_DISPATCH_NORMAL);
}
class StartEvent : public ChannelEvent
{
public:
StartEvent(WebSocketChannelChild* aChild,
const nsCString& aProtocol,
- const nsCString& aExtensions)
+ const nsCString& aExtensions,
+ const nsString& aEffectiveURL,
+ bool aEncrypted)
: mChild(aChild)
, mProtocol(aProtocol)
, mExtensions(aExtensions)
+ , mEffectiveURL(aEffectiveURL)
+ , mEncrypted(aEncrypted)
{}
void Run()
{
- mChild->OnStart(mProtocol, mExtensions);
+ mChild->OnStart(mProtocol, mExtensions, mEffectiveURL, mEncrypted);
}
private:
WebSocketChannelChild* mChild;
nsCString mProtocol;
nsCString mExtensions;
+ nsString mEffectiveURL;
+ bool mEncrypted;
};
bool
WebSocketChannelChild::RecvOnStart(const nsCString& aProtocol,
- const nsCString& aExtensions)
+ const nsCString& aExtensions,
+ const nsString& aEffectiveURL,
+ const bool& aEncrypted)
{
if (mEventQ->ShouldEnqueue()) {
- mEventQ->Enqueue(new StartEvent(this, aProtocol, aExtensions));
+ mEventQ->Enqueue(new StartEvent(this, aProtocol, aExtensions,
+ aEffectiveURL, aEncrypted));
} else if (mTargetThread) {
- DispatchToTargetThread(new StartEvent(this, aProtocol, aExtensions));
+ DispatchToTargetThread(new StartEvent(this, aProtocol, aExtensions,
+ aEffectiveURL, aEncrypted));
} else {
- OnStart(aProtocol, aExtensions);
+ OnStart(aProtocol, aExtensions, aEffectiveURL, aEncrypted);
}
return true;
}
void
WebSocketChannelChild::OnStart(const nsCString& aProtocol,
- const nsCString& aExtensions)
+ const nsCString& aExtensions,
+ const nsString& aEffectiveURL,
+ const bool& aEncrypted)
{
LOG(("WebSocketChannelChild::RecvOnStart() %p\n", this));
SetProtocol(aProtocol);
mNegotiatedExtensions = aExtensions;
+ mEffectiveURL = aEffectiveURL;
+ mEncrypted = aEncrypted;
if (mListener) {
AutoEventEnqueuer ensureSerialDispatch(mEventQ);;
mListener->OnStart(mContext);
}
}
class StopEvent : public ChannelEvent
--- a/netwerk/protocol/websocket/WebSocketChannelChild.h
+++ b/netwerk/protocol/websocket/WebSocketChannelChild.h
@@ -35,38 +35,45 @@ class WebSocketChannelChild : public Bas
NS_IMETHOD SendBinaryMsg(const nsACString &aMsg);
NS_IMETHOD SendBinaryStream(nsIInputStream *aStream, uint32_t aLength);
nsresult SendBinaryStream(OptionalInputStreamParams *aStream, uint32_t aLength);
NS_IMETHOD GetSecurityInfo(nsISupports **aSecurityInfo);
void AddIPDLReference();
void ReleaseIPDLReference();
+ // Off main thread URI access.
+ void GetEffectiveURL(nsAString& aEffectiveURL) const MOZ_OVERRIDE;
+ bool IsEncrypted() const MOZ_OVERRIDE;
+
private:
~WebSocketChannelChild();
- bool RecvOnStart(const nsCString& aProtocol, const nsCString& aExtensions) MOZ_OVERRIDE;
+ bool RecvOnStart(const nsCString& aProtocol, const nsCString& aExtensions,
+ const nsString& aEffectiveURL, const bool& aSecure) MOZ_OVERRIDE;
bool RecvOnStop(const nsresult& aStatusCode) MOZ_OVERRIDE;
bool RecvOnMessageAvailable(const nsCString& aMsg) MOZ_OVERRIDE;
bool RecvOnBinaryMessageAvailable(const nsCString& aMsg) MOZ_OVERRIDE;
bool RecvOnAcknowledge(const uint32_t& aSize) MOZ_OVERRIDE;
bool RecvOnServerClose(const uint16_t& aCode, const nsCString &aReason) MOZ_OVERRIDE;
- void OnStart(const nsCString& aProtocol, const nsCString& aExtensions);
+ void OnStart(const nsCString& aProtocol, const nsCString& aExtensions,
+ const nsString& aEffectiveURL, const bool& aSecure);
void OnStop(const nsresult& aStatusCode);
void OnMessageAvailable(const nsCString& aMsg);
void OnBinaryMessageAvailable(const nsCString& aMsg);
void OnAcknowledge(const uint32_t& aSize);
void OnServerClose(const uint16_t& aCode, const nsCString& aReason);
void AsyncOpenFailed();
void DispatchToTargetThread(ChannelEvent *aChannelEvent);
bool IsOnTargetThread();
nsRefPtr<ChannelEventQueue> mEventQ;
+ nsString mEffectiveURL;
bool mIPCOpen;
friend class StartEvent;
friend class StopEvent;
friend class MessageEvent;
friend class AcknowledgeEvent;
friend class ServerCloseEvent;
friend class AsyncOpenFailedEvent;
--- a/netwerk/protocol/websocket/WebSocketChannelParent.cpp
+++ b/netwerk/protocol/websocket/WebSocketChannelParent.cpp
@@ -7,16 +7,17 @@
#include "WebSocketLog.h"
#include "WebSocketChannelParent.h"
#include "nsIAuthPromptProvider.h"
#include "mozilla/ipc/InputStreamUtils.h"
#include "mozilla/ipc/URIUtils.h"
#include "SerializedLoadContext.h"
#include "nsIOService.h"
#include "mozilla/net/NeckoCommon.h"
+#include "mozilla/net/WebSocketChannel.h"
using namespace mozilla::ipc;
namespace mozilla {
namespace net {
NS_IMPL_ISUPPORTS(WebSocketChannelParent,
nsIWebSocketListener,
@@ -184,21 +185,30 @@ WebSocketChannelParent::RecvSendBinarySt
// WebSocketChannelParent::nsIRequestObserver
//-----------------------------------------------------------------------------
NS_IMETHODIMP
WebSocketChannelParent::OnStart(nsISupports *aContext)
{
LOG(("WebSocketChannelParent::OnStart() %p\n", this));
nsAutoCString protocol, extensions;
+ nsString effectiveURL;
+ bool encrypted = false;
if (mChannel) {
mChannel->GetProtocol(protocol);
mChannel->GetExtensions(extensions);
+
+ nsRefPtr<WebSocketChannel> channel;
+ channel = static_cast<WebSocketChannel*>(mChannel.get());
+ MOZ_ASSERT(channel);
+
+ channel->GetEffectiveURL(effectiveURL);
+ encrypted = channel->IsEncrypted();
}
- if (!mIPCOpen || !SendOnStart(protocol, extensions)) {
+ if (!mIPCOpen || !SendOnStart(protocol, extensions, effectiveURL, encrypted)) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
NS_IMETHODIMP
WebSocketChannelParent::OnStop(nsISupports *aContext, nsresult aStatusCode)
{