mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
bug 751465 - websockets dns and proxies r=jduell r=bsmedberg
--HG-- extra : rebase_source : ad2046a95f1ec9000577cc0f67aedc0766a51ed2
This commit is contained in:
parent
ab53c3e13d
commit
e3e7849089
@ -69,7 +69,7 @@ using namespace mozilla;
|
|||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace net {
|
namespace net {
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS11(WebSocketChannel,
|
NS_IMPL_ISUPPORTS12(WebSocketChannel,
|
||||||
nsIWebSocketChannel,
|
nsIWebSocketChannel,
|
||||||
nsIHttpUpgradeListener,
|
nsIHttpUpgradeListener,
|
||||||
nsIRequestObserver,
|
nsIRequestObserver,
|
||||||
@ -79,6 +79,7 @@ NS_IMPL_ISUPPORTS11(WebSocketChannel,
|
|||||||
nsIOutputStreamCallback,
|
nsIOutputStreamCallback,
|
||||||
nsITimerCallback,
|
nsITimerCallback,
|
||||||
nsIDNSListener,
|
nsIDNSListener,
|
||||||
|
nsIProtocolProxyCallback,
|
||||||
nsIInterfaceRequestor,
|
nsIInterfaceRequestor,
|
||||||
nsIChannelEventSink)
|
nsIChannelEventSink)
|
||||||
|
|
||||||
@ -994,7 +995,7 @@ WebSocketChannel::~WebSocketChannel()
|
|||||||
MOZ_ASSERT(mCalledOnStop, "WebSocket was opened but OnStop was not called");
|
MOZ_ASSERT(mCalledOnStop, "WebSocket was opened but OnStop was not called");
|
||||||
MOZ_ASSERT(mStopped, "WebSocket was opened but never stopped");
|
MOZ_ASSERT(mStopped, "WebSocket was opened but never stopped");
|
||||||
}
|
}
|
||||||
MOZ_ASSERT(!mDNSRequest, "DNS Request still alive at destruction");
|
MOZ_ASSERT(!mCancelable, "DNS/Proxy Request still alive at destruction");
|
||||||
MOZ_ASSERT(!mConnecting, "Should not be connecting in destructor");
|
MOZ_ASSERT(!mConnecting, "Should not be connecting in destructor");
|
||||||
|
|
||||||
moz_free(mBuffer);
|
moz_free(mBuffer);
|
||||||
@ -1959,9 +1960,9 @@ WebSocketChannel::StopSession(nsresult reason)
|
|||||||
CleanupConnection();
|
CleanupConnection();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mDNSRequest) {
|
if (mCancelable) {
|
||||||
mDNSRequest->Cancel(NS_ERROR_UNEXPECTED);
|
mCancelable->Cancel(NS_ERROR_UNEXPECTED);
|
||||||
mDNSRequest = nullptr;
|
mCancelable = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
mInflateReader = nullptr;
|
mInflateReader = nullptr;
|
||||||
@ -2198,16 +2199,9 @@ WebSocketChannel::SetupRequest()
|
|||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
WebSocketChannel::ApplyForAdmission()
|
WebSocketChannel::DoAdmissionDNS()
|
||||||
{
|
{
|
||||||
LOG(("WebSocketChannel::ApplyForAdmission() %p\n", this));
|
|
||||||
|
|
||||||
// Websockets has a policy of 1 session at a time being allowed in the
|
|
||||||
// CONNECTING state per server IP address (not hostname)
|
|
||||||
|
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
nsCOMPtr<nsIDNSService> dns = do_GetService(NS_DNSSERVICE_CONTRACTID, &rv);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
nsCString hostName;
|
nsCString hostName;
|
||||||
rv = mURI->GetHost(hostName);
|
rv = mURI->GetHost(hostName);
|
||||||
@ -2217,15 +2211,39 @@ WebSocketChannel::ApplyForAdmission()
|
|||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
if (mPort == -1)
|
if (mPort == -1)
|
||||||
mPort = (mEncrypted ? kDefaultWSSPort : kDefaultWSPort);
|
mPort = (mEncrypted ? kDefaultWSSPort : kDefaultWSPort);
|
||||||
|
nsCOMPtr<nsIDNSService> dns = do_GetService(NS_DNSSERVICE_CONTRACTID, &rv);
|
||||||
// expect the callback in ::OnLookupComplete
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
LOG(("WebSocketChannel::ApplyForAdmission: checking for concurrent open\n"));
|
|
||||||
nsCOMPtr<nsIThread> mainThread;
|
nsCOMPtr<nsIThread> mainThread;
|
||||||
NS_GetMainThread(getter_AddRefs(mainThread));
|
NS_GetMainThread(getter_AddRefs(mainThread));
|
||||||
dns->AsyncResolve(hostName, 0, this, mainThread, getter_AddRefs(mDNSRequest));
|
MOZ_ASSERT(!mCancelable);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
return dns->AsyncResolve(hostName, 0, this, mainThread, getter_AddRefs(mCancelable));
|
||||||
|
}
|
||||||
|
|
||||||
return NS_OK;
|
nsresult
|
||||||
|
WebSocketChannel::ApplyForAdmission()
|
||||||
|
{
|
||||||
|
LOG(("WebSocketChannel::ApplyForAdmission() %p\n", this));
|
||||||
|
|
||||||
|
// Websockets has a policy of 1 session at a time being allowed in the
|
||||||
|
// CONNECTING state per server IP address (not hostname)
|
||||||
|
|
||||||
|
// Check to see if a proxy is being used before making DNS call
|
||||||
|
nsCOMPtr<nsIProtocolProxyService> pps =
|
||||||
|
do_GetService(NS_PROTOCOLPROXYSERVICE_CONTRACTID);
|
||||||
|
|
||||||
|
if (!pps) {
|
||||||
|
// go straight to DNS
|
||||||
|
// expect the callback in ::OnLookupComplete
|
||||||
|
LOG(("WebSocketChannel::ApplyForAdmission: checking for concurrent open\n"));
|
||||||
|
return DoAdmissionDNS();
|
||||||
|
}
|
||||||
|
|
||||||
|
MOZ_ASSERT(!mCancelable);
|
||||||
|
|
||||||
|
return pps->AsyncResolve(mURI,
|
||||||
|
nsIProtocolProxyService::RESOLVE_PREFER_HTTPS_PROXY |
|
||||||
|
nsIProtocolProxyService::RESOLVE_ALWAYS_TUNNEL,
|
||||||
|
this, getter_AddRefs(mCancelable));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called after both OnStartRequest and OnTransportAvailable have
|
// Called after both OnStartRequest and OnTransportAvailable have
|
||||||
@ -2300,26 +2318,28 @@ WebSocketChannel::ReportConnectionTelemetry()
|
|||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
WebSocketChannel::OnLookupComplete(nsICancelable *aRequest,
|
WebSocketChannel::OnLookupComplete(nsICancelable *aRequest,
|
||||||
nsIDNSRecord *aRecord,
|
nsIDNSRecord *aRecord,
|
||||||
nsresult aStatus)
|
nsresult aStatus)
|
||||||
{
|
{
|
||||||
LOG(("WebSocketChannel::OnLookupComplete() %p [%p %p %x]\n",
|
LOG(("WebSocketChannel::OnLookupComplete() %p [%p %p %x]\n",
|
||||||
this, aRequest, aRecord, aStatus));
|
this, aRequest, aRecord, aStatus));
|
||||||
|
|
||||||
NS_ABORT_IF_FALSE(NS_IsMainThread(), "not main thread");
|
NS_ABORT_IF_FALSE(NS_IsMainThread(), "not main thread");
|
||||||
NS_ABORT_IF_FALSE(aRequest == mDNSRequest || mStopped,
|
|
||||||
"wrong dns request");
|
|
||||||
|
|
||||||
if (mStopped) {
|
if (mStopped) {
|
||||||
LOG(("WebSocketChannel::OnLookupComplete: Request Already Stopped\n"));
|
LOG(("WebSocketChannel::OnLookupComplete: Request Already Stopped\n"));
|
||||||
|
mCancelable = nullptr;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
mDNSRequest = nullptr;
|
mCancelable = nullptr;
|
||||||
|
|
||||||
// These failures are not fatal - we just use the hostname as the key
|
// These failures are not fatal - we just use the hostname as the key
|
||||||
if (NS_FAILED(aStatus)) {
|
if (NS_FAILED(aStatus)) {
|
||||||
LOG(("WebSocketChannel::OnLookupComplete: No DNS Response\n"));
|
LOG(("WebSocketChannel::OnLookupComplete: No DNS Response\n"));
|
||||||
|
|
||||||
|
// set host in case we got here without calling DoAdmissionDNS()
|
||||||
|
mURI->GetHost(mAddress);
|
||||||
} else {
|
} else {
|
||||||
nsresult rv = aRecord->GetNextAddrAsString(mAddress);
|
nsresult rv = aRecord->GetNextAddrAsString(mAddress);
|
||||||
if (NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
@ -2332,6 +2352,35 @@ WebSocketChannel::OnLookupComplete(nsICancelable *aRequest,
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// nsIProtocolProxyCallback
|
||||||
|
NS_IMETHODIMP
|
||||||
|
WebSocketChannel::OnProxyAvailable(nsICancelable *aRequest, nsIURI *aURI,
|
||||||
|
nsIProxyInfo *pi, nsresult status)
|
||||||
|
{
|
||||||
|
if (mStopped) {
|
||||||
|
LOG(("WebSocketChannel::OnProxyAvailable: [%p] Request Already Stopped\n", this));
|
||||||
|
mCancelable = nullptr;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
MOZ_ASSERT(aRequest == mCancelable);
|
||||||
|
mCancelable = nullptr;
|
||||||
|
|
||||||
|
nsAutoCString type;
|
||||||
|
if (NS_SUCCEEDED(status) && pi &&
|
||||||
|
NS_SUCCEEDED(pi->GetType(type)) &&
|
||||||
|
!type.EqualsLiteral("direct")) {
|
||||||
|
LOG(("WebSocket OnProxyAvailable [%p] Proxy found skip DNS lookup\n", this));
|
||||||
|
// call DNS callback directly without DNS resolver
|
||||||
|
OnLookupComplete(nullptr, nullptr, NS_ERROR_FAILURE);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG(("WebSocketChannel::OnProxyAvailable[%] checking DNS resolution\n", this));
|
||||||
|
DoAdmissionDNS();
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
// nsIInterfaceRequestor
|
// nsIInterfaceRequestor
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include "nsIAsyncOutputStream.h"
|
#include "nsIAsyncOutputStream.h"
|
||||||
#include "nsITimer.h"
|
#include "nsITimer.h"
|
||||||
#include "nsIDNSListener.h"
|
#include "nsIDNSListener.h"
|
||||||
|
#include "nsIProtocolProxyCallback.h"
|
||||||
#include "nsIChannelEventSink.h"
|
#include "nsIChannelEventSink.h"
|
||||||
#include "nsIHttpChannelInternal.h"
|
#include "nsIHttpChannelInternal.h"
|
||||||
#include "BaseWebSocketChannel.h"
|
#include "BaseWebSocketChannel.h"
|
||||||
@ -61,6 +62,7 @@ class WebSocketChannel : public BaseWebSocketChannel,
|
|||||||
public nsIOutputStreamCallback,
|
public nsIOutputStreamCallback,
|
||||||
public nsITimerCallback,
|
public nsITimerCallback,
|
||||||
public nsIDNSListener,
|
public nsIDNSListener,
|
||||||
|
public nsIProtocolProxyCallback,
|
||||||
public nsIInterfaceRequestor,
|
public nsIInterfaceRequestor,
|
||||||
public nsIChannelEventSink
|
public nsIChannelEventSink
|
||||||
{
|
{
|
||||||
@ -73,6 +75,7 @@ public:
|
|||||||
NS_DECL_NSIOUTPUTSTREAMCALLBACK
|
NS_DECL_NSIOUTPUTSTREAMCALLBACK
|
||||||
NS_DECL_NSITIMERCALLBACK
|
NS_DECL_NSITIMERCALLBACK
|
||||||
NS_DECL_NSIDNSLISTENER
|
NS_DECL_NSIDNSLISTENER
|
||||||
|
NS_DECL_NSIPROTOCOLPROXYCALLBACK
|
||||||
NS_DECL_NSIINTERFACEREQUESTOR
|
NS_DECL_NSIINTERFACEREQUESTOR
|
||||||
NS_DECL_NSICHANNELEVENTSINK
|
NS_DECL_NSICHANNELEVENTSINK
|
||||||
|
|
||||||
@ -134,6 +137,7 @@ private:
|
|||||||
nsresult HandleExtensions();
|
nsresult HandleExtensions();
|
||||||
nsresult SetupRequest();
|
nsresult SetupRequest();
|
||||||
nsresult ApplyForAdmission();
|
nsresult ApplyForAdmission();
|
||||||
|
nsresult DoAdmissionDNS();
|
||||||
nsresult StartWebsocketData();
|
nsresult StartWebsocketData();
|
||||||
uint16_t ResultToCloseCode(nsresult resultCode);
|
uint16_t ResultToCloseCode(nsresult resultCode);
|
||||||
void ReportConnectionTelemetry();
|
void ReportConnectionTelemetry();
|
||||||
@ -165,7 +169,7 @@ private:
|
|||||||
nsCOMPtr<nsIEventTarget> mSocketThread;
|
nsCOMPtr<nsIEventTarget> mSocketThread;
|
||||||
nsCOMPtr<nsIHttpChannelInternal> mChannel;
|
nsCOMPtr<nsIHttpChannelInternal> mChannel;
|
||||||
nsCOMPtr<nsIHttpChannel> mHttpChannel;
|
nsCOMPtr<nsIHttpChannel> mHttpChannel;
|
||||||
nsCOMPtr<nsICancelable> mDNSRequest;
|
nsCOMPtr<nsICancelable> mCancelable;
|
||||||
nsCOMPtr<nsIAsyncVerifyRedirectCallback> mRedirectCallback;
|
nsCOMPtr<nsIAsyncVerifyRedirectCallback> mRedirectCallback;
|
||||||
nsCOMPtr<nsIRandomGenerator> mRandomGenerator;
|
nsCOMPtr<nsIRandomGenerator> mRandomGenerator;
|
||||||
|
|
||||||
|
@ -899,6 +899,24 @@ NS_IMETHODIMP _class::QueryInterface(REFNSIID aIID, void** aInstancePtr) \
|
|||||||
NS_INTERFACE_TABLE_ENTRY_AMBIGUOUS(_class, nsISupports, _i1) \
|
NS_INTERFACE_TABLE_ENTRY_AMBIGUOUS(_class, nsISupports, _i1) \
|
||||||
NS_INTERFACE_TABLE_END
|
NS_INTERFACE_TABLE_END
|
||||||
|
|
||||||
|
#define NS_INTERFACE_TABLE12(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, \
|
||||||
|
_i8, _i9, _i10, _i11, _i12) \
|
||||||
|
NS_INTERFACE_TABLE_BEGIN \
|
||||||
|
NS_INTERFACE_TABLE_ENTRY(_class, _i1) \
|
||||||
|
NS_INTERFACE_TABLE_ENTRY(_class, _i2) \
|
||||||
|
NS_INTERFACE_TABLE_ENTRY(_class, _i3) \
|
||||||
|
NS_INTERFACE_TABLE_ENTRY(_class, _i4) \
|
||||||
|
NS_INTERFACE_TABLE_ENTRY(_class, _i5) \
|
||||||
|
NS_INTERFACE_TABLE_ENTRY(_class, _i6) \
|
||||||
|
NS_INTERFACE_TABLE_ENTRY(_class, _i7) \
|
||||||
|
NS_INTERFACE_TABLE_ENTRY(_class, _i8) \
|
||||||
|
NS_INTERFACE_TABLE_ENTRY(_class, _i9) \
|
||||||
|
NS_INTERFACE_TABLE_ENTRY(_class, _i10) \
|
||||||
|
NS_INTERFACE_TABLE_ENTRY(_class, _i11) \
|
||||||
|
NS_INTERFACE_TABLE_ENTRY(_class, _i12) \
|
||||||
|
NS_INTERFACE_TABLE_ENTRY_AMBIGUOUS(_class, nsISupports, _i1) \
|
||||||
|
NS_INTERFACE_TABLE_END
|
||||||
|
|
||||||
#define NS_IMPL_QUERY_INTERFACE0(_class) \
|
#define NS_IMPL_QUERY_INTERFACE0(_class) \
|
||||||
NS_INTERFACE_TABLE_HEAD(_class) \
|
NS_INTERFACE_TABLE_HEAD(_class) \
|
||||||
NS_INTERFACE_TABLE0(_class) \
|
NS_INTERFACE_TABLE0(_class) \
|
||||||
@ -965,6 +983,13 @@ NS_IMETHODIMP _class::QueryInterface(REFNSIID aIID, void** aInstancePtr) \
|
|||||||
_i9, _i10, _i11) \
|
_i9, _i10, _i11) \
|
||||||
NS_INTERFACE_TABLE_TAIL
|
NS_INTERFACE_TABLE_TAIL
|
||||||
|
|
||||||
|
#define NS_IMPL_QUERY_INTERFACE12(_class, _i1, _i2, _i3, _i4, _i5, _i6, \
|
||||||
|
_i7, _i8, _i9, _i10, _i11, _i12) \
|
||||||
|
NS_INTERFACE_TABLE_HEAD(_class) \
|
||||||
|
NS_INTERFACE_TABLE12(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, \
|
||||||
|
_i9, _i10, _i11, _i12) \
|
||||||
|
NS_INTERFACE_TABLE_TAIL
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Declare that you're going to inherit from something that already
|
* Declare that you're going to inherit from something that already
|
||||||
@ -1288,6 +1313,13 @@ NS_IMETHODIMP_(nsrefcnt) Class::Release(void) \
|
|||||||
NS_IMPL_QUERY_INTERFACE11(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, \
|
NS_IMPL_QUERY_INTERFACE11(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, \
|
||||||
_i9, _i10, _i11)
|
_i9, _i10, _i11)
|
||||||
|
|
||||||
|
#define NS_IMPL_ISUPPORTS12(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, \
|
||||||
|
_i9, _i10, _i11, _i12) \
|
||||||
|
NS_IMPL_ADDREF(_class) \
|
||||||
|
NS_IMPL_RELEASE(_class) \
|
||||||
|
NS_IMPL_QUERY_INTERFACE12(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, \
|
||||||
|
_i9, _i10, _i11, _i12)
|
||||||
|
|
||||||
#define NS_IMPL_ISUPPORTS_INHERITED0(Class, Super) \
|
#define NS_IMPL_ISUPPORTS_INHERITED0(Class, Super) \
|
||||||
NS_IMPL_QUERY_INTERFACE_INHERITED0(Class, Super) \
|
NS_IMPL_QUERY_INTERFACE_INHERITED0(Class, Super) \
|
||||||
NS_IMPL_ADDREF_INHERITED(Class, Super) \
|
NS_IMPL_ADDREF_INHERITED(Class, Super) \
|
||||||
|
Loading…
Reference in New Issue
Block a user