diff options
Diffstat (limited to 'netwerk/base/RequestContextService.cpp')
-rw-r--r-- | netwerk/base/RequestContextService.cpp | 217 |
1 files changed, 217 insertions, 0 deletions
diff --git a/netwerk/base/RequestContextService.cpp b/netwerk/base/RequestContextService.cpp new file mode 100644 index 000000000..b72e42b13 --- /dev/null +++ b/netwerk/base/RequestContextService.cpp @@ -0,0 +1,217 @@ +/* -*- 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 "nsAutoPtr.h" +#include "nsIObserverService.h" +#include "nsIUUIDGenerator.h" +#include "nsServiceManagerUtils.h" +#include "nsThreadUtils.h" +#include "RequestContextService.h" + +#include "mozilla/Atomics.h" +#include "mozilla/Services.h" + +#include "mozilla/net/PSpdyPush.h" + +namespace mozilla { +namespace net { + +// nsIRequestContext +class RequestContext final : public nsIRequestContext +{ +public: + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSIREQUESTCONTEXT + + explicit RequestContext(const nsID& id); +private: + virtual ~RequestContext(); + + nsID mID; + char mCID[NSID_LENGTH]; + Atomic<uint32_t> mBlockingTransactionCount; + nsAutoPtr<SpdyPushCache> mSpdyCache; + nsCString mUserAgentOverride; +}; + +NS_IMPL_ISUPPORTS(RequestContext, nsIRequestContext) + +RequestContext::RequestContext(const nsID& aID) + : mBlockingTransactionCount(0) +{ + mID = aID; + mID.ToProvidedString(mCID); +} + +RequestContext::~RequestContext() +{ +} + +NS_IMETHODIMP +RequestContext::GetBlockingTransactionCount(uint32_t *aBlockingTransactionCount) +{ + NS_ENSURE_ARG_POINTER(aBlockingTransactionCount); + *aBlockingTransactionCount = mBlockingTransactionCount; + return NS_OK; +} + +NS_IMETHODIMP +RequestContext::AddBlockingTransaction() +{ + mBlockingTransactionCount++; + return NS_OK; +} + +NS_IMETHODIMP +RequestContext::RemoveBlockingTransaction(uint32_t *outval) +{ + NS_ENSURE_ARG_POINTER(outval); + mBlockingTransactionCount--; + *outval = mBlockingTransactionCount; + return NS_OK; +} + +NS_IMETHODIMP +RequestContext::GetSpdyPushCache(mozilla::net::SpdyPushCache **aSpdyPushCache) +{ + *aSpdyPushCache = mSpdyCache.get(); + return NS_OK; +} + +NS_IMETHODIMP +RequestContext::SetSpdyPushCache(mozilla::net::SpdyPushCache *aSpdyPushCache) +{ + mSpdyCache = aSpdyPushCache; + return NS_OK; +} + +NS_IMETHODIMP +RequestContext::GetID(nsID *outval) +{ + NS_ENSURE_ARG_POINTER(outval); + *outval = mID; + return NS_OK; +} + +NS_IMETHODIMP +RequestContext::GetUserAgentOverride(nsACString& aUserAgentOverride) +{ + aUserAgentOverride = mUserAgentOverride; + return NS_OK; +} + +NS_IMETHODIMP +RequestContext::SetUserAgentOverride(const nsACString& aUserAgentOverride) +{ + mUserAgentOverride = aUserAgentOverride; + return NS_OK; +} + + +//nsIRequestContextService +RequestContextService *RequestContextService::sSelf = nullptr; + +NS_IMPL_ISUPPORTS(RequestContextService, nsIRequestContextService, nsIObserver) + +RequestContextService::RequestContextService() +{ + MOZ_ASSERT(!sSelf, "multiple rcs instances!"); + MOZ_ASSERT(NS_IsMainThread()); + sSelf = this; +} + +RequestContextService::~RequestContextService() +{ + MOZ_ASSERT(NS_IsMainThread()); + Shutdown(); + sSelf = nullptr; +} + +nsresult +RequestContextService::Init() +{ + MOZ_ASSERT(NS_IsMainThread()); + nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService(); + if (!obs) { + return NS_ERROR_NOT_AVAILABLE; + } + + return obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false); +} + +void +RequestContextService::Shutdown() +{ + MOZ_ASSERT(NS_IsMainThread()); + mTable.Clear(); +} + +/* static */ nsresult +RequestContextService::Create(nsISupports *aOuter, const nsIID& aIID, void **aResult) +{ + MOZ_ASSERT(NS_IsMainThread()); + if (aOuter != nullptr) { + return NS_ERROR_NO_AGGREGATION; + } + + RefPtr<RequestContextService> svc = new RequestContextService(); + nsresult rv = svc->Init(); + NS_ENSURE_SUCCESS(rv, rv); + + return svc->QueryInterface(aIID, aResult); +} + +NS_IMETHODIMP +RequestContextService::GetRequestContext(const nsID& rcID, nsIRequestContext **rc) +{ + MOZ_ASSERT(NS_IsMainThread()); + NS_ENSURE_ARG_POINTER(rc); + *rc = nullptr; + + if (!mTable.Get(rcID, rc)) { + nsCOMPtr<nsIRequestContext> newSC = new RequestContext(rcID); + mTable.Put(rcID, newSC); + newSC.swap(*rc); + } + + return NS_OK; +} + +NS_IMETHODIMP +RequestContextService::NewRequestContextID(nsID *rcID) +{ + MOZ_ASSERT(NS_IsMainThread()); + if (!mUUIDGen) { + nsresult rv; + mUUIDGen = do_GetService("@mozilla.org/uuid-generator;1", &rv); + NS_ENSURE_SUCCESS(rv, rv); + } + + return mUUIDGen->GenerateUUIDInPlace(rcID); +} + +NS_IMETHODIMP +RequestContextService::RemoveRequestContext(const nsID& rcID) +{ + MOZ_ASSERT(NS_IsMainThread()); + mTable.Remove(rcID); + return NS_OK; +} + +NS_IMETHODIMP +RequestContextService::Observe(nsISupports *subject, const char *topic, + const char16_t *data_unicode) +{ + MOZ_ASSERT(NS_IsMainThread()); + if (!strcmp(NS_XPCOM_SHUTDOWN_OBSERVER_ID, topic)) { + Shutdown(); + } + + return NS_OK; +} + +} // ::mozilla::net +} // ::mozilla |