Instantly share code, notes, and snippets.
Created
April 19, 2017 07:34
-
Star
(0)
0
You must be signed in to star a gist -
Fork
(0)
0
You must be signed in to fork a gist
-
Save valenting/9db7702a7f42aadf62b3697e6650d93e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# HG changeset patch | |
# User Valentin Gosu <valentin.gosu@gmail.com> | |
# Parent ec0e2532c1b00acee8852611a9e4d543ae41c9cb | |
Bug 1331680 - Add CookieStruct IPDL representation and send a list of CookieStructs to the child in OnStartRequest | |
* Added CookieStruct to NeckoChannelParams.ipdlh | |
* Added GetCookieListInternal that appends cookies to a nsTArray<nsCookie*> | |
* Change GetCookieStringInternal to use GetCookieListInternal | |
* Add CookieList[] argument to PHttpChannel::OnStartRequest to pass it to the child | |
* Add nsCookieService::GetCookieStructList to get a list of CookieStructs to send to the child | |
MozReview-Commit-ID: GJkvEz7mWW0 | |
diff --git a/netwerk/cookie/nsCookieService.cpp b/netwerk/cookie/nsCookieService.cpp | |
--- a/netwerk/cookie/nsCookieService.cpp | |
+++ b/netwerk/cookie/nsCookieService.cpp | |
@@ -3195,22 +3195,22 @@ PathMatches(nsCookie* aCookie, const nsA | |
} | |
// either the paths match exactly, or the cookie path is a prefix of | |
// the given path. | |
return true; | |
} | |
void | |
-nsCookieService::GetCookieStringInternal(nsIURI *aHostURI, | |
- bool aIsForeign, | |
- bool aHttpBound, | |
- const OriginAttributes& aOriginAttrs, | |
- bool aIsPrivate, | |
- nsCString &aCookieString) | |
+nsCookieService::GetCookieListInternal(nsIURI *aHostURI, | |
+ bool aIsForeign, | |
+ bool aHttpBound, | |
+ const OriginAttributes& aOriginAttrs, | |
+ bool aIsPrivate, | |
+ nsTArray<nsCookie*>& aCookieList) | |
{ | |
NS_ASSERTION(aHostURI, "null host!"); | |
if (!mDBState) { | |
NS_WARNING("No DBState! Profile already closed?"); | |
return; | |
} | |
@@ -3255,17 +3255,16 @@ nsCookieService::GetCookieStringInternal | |
// if it isn't, then we can't send a secure cookie over the connection. | |
// if SchemeIs fails, assume an insecure connection, to be on the safe side | |
bool isSecure; | |
if (NS_FAILED(aHostURI->SchemeIs("https", &isSecure))) { | |
isSecure = false; | |
} | |
nsCookie *cookie; | |
- AutoTArray<nsCookie*, 8> foundCookieList; | |
int64_t currentTimeInUsec = PR_Now(); | |
int64_t currentTime = currentTimeInUsec / PR_USEC_PER_SEC; | |
bool stale = false; | |
nsCookieKey key(baseDomain, aOriginAttrs); | |
EnsureReadDomain(key); | |
// perform the hash lookup | |
@@ -3296,39 +3295,39 @@ nsCookieService::GetCookieStringInternal | |
continue; | |
// check if the cookie has expired | |
if (cookie->Expiry() <= currentTime) { | |
continue; | |
} | |
// all checks passed - add to list and check if lastAccessed stamp needs updating | |
- foundCookieList.AppendElement(cookie); | |
+ aCookieList.AppendElement(cookie); | |
if (cookie->IsStale()) { | |
stale = true; | |
} | |
} | |
- int32_t count = foundCookieList.Length(); | |
+ int32_t count = aCookieList.Length(); | |
if (count == 0) | |
return; | |
// update lastAccessed timestamps. we only do this if the timestamp is stale | |
// by a certain amount, to avoid thrashing the db during pageload. | |
if (stale) { | |
// Create an array of parameters to bind to our update statement. Batching | |
// is OK here since we're updating cookies with no interleaved operations. | |
nsCOMPtr<mozIStorageBindingParamsArray> paramsArray; | |
mozIStorageAsyncStatement* stmt = mDBState->stmtUpdate; | |
if (mDBState->dbConn) { | |
stmt->NewBindingParamsArray(getter_AddRefs(paramsArray)); | |
} | |
for (int32_t i = 0; i < count; ++i) { | |
- cookie = foundCookieList.ElementAt(i); | |
+ cookie = aCookieList.ElementAt(i); | |
if (cookie->IsStale()) { | |
UpdateCookieInList(cookie, currentTimeInUsec, paramsArray); | |
} | |
} | |
// Update the database now if necessary. | |
if (paramsArray) { | |
uint32_t length; | |
@@ -3342,19 +3341,60 @@ nsCookieService::GetCookieStringInternal | |
NS_ASSERT_SUCCESS(rv); | |
} | |
} | |
} | |
// return cookies in order of path length; longest to shortest. | |
// this is required per RFC2109. if cookies match in length, | |
// then sort by creation time (see bug 236772). | |
- foundCookieList.Sort(CompareCookiesForSending()); | |
- | |
- for (int32_t i = 0; i < count; ++i) { | |
+ aCookieList.Sort(CompareCookiesForSending()); | |
+} | |
+ | |
+void | |
+nsCookieService::GetCookieStructList(nsIURI *aHostURI, | |
+ bool aIsForeign, | |
+ bool aHttpBound, | |
+ const OriginAttributes& aOriginAttrs, | |
+ bool aIsPrivate, | |
+ nsTArray<mozilla::net::CookieStruct>& aCookieList) | |
+{ | |
+ AutoTArray<nsCookie*, 8> foundCookieList; | |
+ GetCookieListInternal(aHostURI, aIsForeign, aHttpBound, aOriginAttrs, aIsPrivate, foundCookieList); | |
+ | |
+ nsCookie* cookie; | |
+ for (uint32_t i = 0; i < foundCookieList.Length(); ++i) { | |
+ cookie = foundCookieList.ElementAt(i); | |
+ CookieStruct* cookieStruct = aCookieList.AppendElement(); | |
+ cookieStruct->name() = cookie->Name(); | |
+ cookieStruct->value() = cookie->Value(); | |
+ cookieStruct->host() = cookie->Host(); | |
+ cookieStruct->path() = cookie->Path(); | |
+ cookieStruct->expiry() = cookie->Expiry(); | |
+ cookieStruct->lastAccessed() = cookie->LastAccessed(); | |
+ cookieStruct->creationTime() = cookie->CreationTime(); | |
+ cookieStruct->isSession() = cookie->IsSession(); | |
+ cookieStruct->isSecure() = cookie->IsSecure(); | |
+ cookieStruct->isHttpOnly() = cookie->IsHttpOnly(); | |
+ } | |
+} | |
+ | |
+void | |
+nsCookieService::GetCookieStringInternal(nsIURI *aHostURI, | |
+ bool aIsForeign, | |
+ bool aHttpBound, | |
+ const OriginAttributes& aOriginAttrs, | |
+ bool aIsPrivate, | |
+ nsCString &aCookieString) | |
+{ | |
+ AutoTArray<nsCookie*, 8> foundCookieList; | |
+ GetCookieListInternal(aHostURI, aIsForeign, aHttpBound, aOriginAttrs, aIsPrivate, foundCookieList); | |
+ | |
+ nsCookie* cookie; | |
+ for (uint32_t i = 0; i < foundCookieList.Length(); ++i) { | |
cookie = foundCookieList.ElementAt(i); | |
// check if we have anything to write | |
if (!cookie->Name().IsEmpty() || !cookie->Value().IsEmpty()) { | |
// if we've already added a cookie to the return list, append a "; " so | |
// that subsequent cookies are delimited in the final list. | |
if (!aCookieString.IsEmpty()) { | |
aCookieString.AppendLiteral("; "); | |
@@ -3365,18 +3405,19 @@ nsCookieService::GetCookieStringInternal | |
aCookieString += cookie->Name() + NS_LITERAL_CSTRING("=") + cookie->Value(); | |
} else { | |
// just write value | |
aCookieString += cookie->Value(); | |
} | |
} | |
} | |
- if (!aCookieString.IsEmpty()) | |
+ if (!aCookieString.IsEmpty()) { | |
COOKIE_LOGSUCCESS(GET_COOKIE, aHostURI, aCookieString, nullptr, false); | |
+ } | |
} | |
// processes a single cookie, and returns true if there are more cookies | |
// to be processed | |
bool | |
nsCookieService::SetCookieInternal(nsIURI *aHostURI, | |
const nsCookieKey &aKey, | |
bool aRequireHostMatch, | |
diff --git a/netwerk/cookie/nsCookieService.h b/netwerk/cookie/nsCookieService.h | |
--- a/netwerk/cookie/nsCookieService.h | |
+++ b/netwerk/cookie/nsCookieService.h | |
@@ -26,16 +26,17 @@ | |
#include "mozIStorageCompletionCallback.h" | |
#include "mozIStorageStatementCallback.h" | |
#include "mozIStorageFunction.h" | |
#include "nsIVariant.h" | |
#include "nsIFile.h" | |
#include "mozilla/BasePrincipal.h" | |
#include "mozilla/MemoryReporting.h" | |
#include "mozilla/Maybe.h" | |
+#include "mozilla/net/NeckoChannelParams.h" | |
using mozilla::OriginAttributes; | |
class nsICookiePermission; | |
class nsIEffectiveTLDService; | |
class nsIIDNService; | |
class nsIPrefBranch; | |
class nsIObserverService; | |
@@ -262,16 +263,18 @@ class nsCookieService final : public nsI | |
/** | |
* Start watching the observer service for messages indicating that an app has | |
* been uninstalled. When an app is uninstalled, we get the cookie service | |
* (thus instantiating it, if necessary) and clear all the cookies for that | |
* app. | |
*/ | |
static void AppClearDataObserverInit(); | |
+ void GetCookieStructList(nsIURI *aHostURI, bool aIsForeign, bool aHttpBound, const OriginAttributes& aOriginAttrs, bool aIsPrivate, nsTArray<mozilla::net::CookieStruct>& aCookieList); | |
+ | |
protected: | |
virtual ~nsCookieService(); | |
void PrefChanged(nsIPrefBranch *aPrefBranch); | |
void InitDBStates(); | |
OpenDBResult TryInitDB(bool aDeleteExistingDB); | |
nsresult CreateTableWorker(const char* aName); | |
nsresult CreateIndex(); | |
@@ -290,16 +293,17 @@ class nsCookieService final : public nsI | |
void CancelAsyncRead(bool aPurgeReadSet); | |
void EnsureReadDomain(const nsCookieKey &aKey); | |
void EnsureReadComplete(); | |
nsresult NormalizeHost(nsCString &aHost); | |
nsresult GetBaseDomain(nsIURI *aHostURI, nsCString &aBaseDomain, bool &aRequireHostMatch); | |
nsresult GetBaseDomainFromHost(const nsACString &aHost, nsCString &aBaseDomain); | |
nsresult GetCookieStringCommon(nsIURI *aHostURI, nsIChannel *aChannel, bool aHttpBound, char** aCookie); | |
void GetCookieStringInternal(nsIURI *aHostURI, bool aIsForeign, bool aHttpBound, const OriginAttributes& aOriginAttrs, bool aIsPrivate, nsCString &aCookie); | |
+ void GetCookieListInternal(nsIURI *aHostURI, bool aIsForeign, bool aHttpBound, const OriginAttributes& aOriginAttrs, bool aIsPrivate, nsTArray<nsCookie*>& aCookieList); | |
nsresult SetCookieStringCommon(nsIURI *aHostURI, const char *aCookieHeader, const char *aServerTime, nsIChannel *aChannel, bool aFromHttp); | |
void SetCookieStringInternal(nsIURI *aHostURI, bool aIsForeign, nsDependentCString &aCookieHeader, const nsCString &aServerTime, bool aFromHttp, const OriginAttributes &aOriginAttrs, bool aIsPrivate, nsIChannel* aChannel); | |
bool SetCookieInternal(nsIURI *aHostURI, const nsCookieKey& aKey, bool aRequireHostMatch, CookieStatus aStatus, nsDependentCString &aCookieHeader, int64_t aServerTime, bool aFromHttp, nsIChannel* aChannel); | |
void AddInternal(const nsCookieKey& aKey, nsCookie *aCookie, int64_t aCurrentTimeInUsec, nsIURI *aHostURI, const char *aCookieHeader, bool aFromHttp); | |
void RemoveCookieFromList(const nsListIter &aIter, mozIStorageBindingParamsArray *aParamsArray = nullptr); | |
void AddCookieToList(const nsCookieKey& aKey, nsCookie *aCookie, DBState *aDBState, mozIStorageBindingParamsArray *aParamsArray, bool aWriteToDB = true); | |
void UpdateCookieInList(nsCookie *aCookie, int64_t aLastAccessed, mozIStorageBindingParamsArray *aParamsArray); | |
static bool GetTokenValue(nsASingleFragmentCString::const_char_iterator &aIter, nsASingleFragmentCString::const_char_iterator &aEndIter, nsDependentCSubstring &aTokenString, nsDependentCSubstring &aTokenValue, bool &aEqualsFound); | |
diff --git a/netwerk/ipc/NeckoChannelParams.ipdlh b/netwerk/ipc/NeckoChannelParams.ipdlh | |
--- a/netwerk/ipc/NeckoChannelParams.ipdlh | |
+++ b/netwerk/ipc/NeckoChannelParams.ipdlh | |
@@ -184,16 +184,32 @@ struct HttpChannelDiverterArgs | |
}; | |
union ChannelDiverterArgs | |
{ | |
HttpChannelDiverterArgs; | |
PFTPChannel; | |
}; | |
+// For OnStartRequest Parent -> Child | |
+ | |
+struct CookieStruct | |
+{ | |
+ nsCString name; | |
+ nsCString value; | |
+ nsCString host; | |
+ nsCString path; | |
+ int64_t expiry; | |
+ int64_t lastAccessed; | |
+ int64_t creationTime; | |
+ bool isSession; | |
+ bool isSecure; | |
+ bool isHttpOnly; | |
+}; | |
+ | |
//----------------------------------------------------------------------------- | |
// RTSP IPDL structs | |
//----------------------------------------------------------------------------- | |
struct RtspChannelConnectArgs | |
{ | |
URIParams uri; | |
uint32_t channelId; | |
diff --git a/netwerk/protocol/http/HttpChannelChild.cpp b/netwerk/protocol/http/HttpChannelChild.cpp | |
--- a/netwerk/protocol/http/HttpChannelChild.cpp | |
+++ b/netwerk/protocol/http/HttpChannelChild.cpp | |
@@ -413,17 +413,18 @@ HttpChannelChild::RecvOnStartRequest(con | |
const uint32_t& cacheExpirationTime, | |
const nsCString& cachedCharset, | |
const nsCString& securityInfoSerialization, | |
const NetAddr& selfAddr, | |
const NetAddr& peerAddr, | |
const int16_t& redirectCount, | |
const uint32_t& cacheKey, | |
const nsCString& altDataType, | |
- const int64_t& altDataLen) | |
+ const int64_t& altDataLen, | |
+ nsTArray<CookieStruct>&& cookieList) | |
{ | |
LOG(("HttpChannelChild::RecvOnStartRequest [this=%p]\n", this)); | |
// mFlushedForDiversion and mDivertingToParent should NEVER be set at this | |
// stage, as they are set in the listener's OnStartRequest. | |
MOZ_RELEASE_ASSERT(!mFlushedForDiversion, | |
"mFlushedForDiversion should be unset before OnStartRequest!"); | |
MOZ_RELEASE_ASSERT(!mDivertingToParent, | |
"mDivertingToParent should be unset before OnStartRequest!"); | |
diff --git a/netwerk/protocol/http/HttpChannelChild.h b/netwerk/protocol/http/HttpChannelChild.h | |
--- a/netwerk/protocol/http/HttpChannelChild.h | |
+++ b/netwerk/protocol/http/HttpChannelChild.h | |
@@ -125,17 +125,18 @@ protected: | |
const uint32_t& cacheExpirationTime, | |
const nsCString& cachedCharset, | |
const nsCString& securityInfoSerialization, | |
const NetAddr& selfAddr, | |
const NetAddr& peerAddr, | |
const int16_t& redirectCount, | |
const uint32_t& cacheKey, | |
const nsCString& altDataType, | |
- const int64_t& altDataLen) override; | |
+ const int64_t& altDataLen, | |
+ nsTArray<CookieStruct>&& cookieList) override; | |
mozilla::ipc::IPCResult RecvOnTransportAndData(const nsresult& channelStatus, | |
const nsresult& status, | |
const uint64_t& offset, | |
const uint32_t& count, | |
const nsCString& data) override; | |
mozilla::ipc::IPCResult RecvOnStopRequest(const nsresult& statusCode, const ResourceTimingStruct& timing) override; | |
mozilla::ipc::IPCResult RecvOnProgress(const int64_t& progress, const int64_t& progressMax) override; | |
mozilla::ipc::IPCResult RecvOnStatus(const nsresult& status) override; | |
diff --git a/netwerk/protocol/http/HttpChannelParent.cpp b/netwerk/protocol/http/HttpChannelParent.cpp | |
--- a/netwerk/protocol/http/HttpChannelParent.cpp | |
+++ b/netwerk/protocol/http/HttpChannelParent.cpp | |
@@ -1213,30 +1213,33 @@ HttpChannelParent::OnStartRequest(nsIReq | |
} | |
nsAutoCString altDataType; | |
chan->GetAlternativeDataType(altDataType); | |
int64_t altDataLen = chan->GetAltDataLength(); | |
// !!! We need to lock headers and please don't forget to unlock them !!! | |
requestHead->Enter(); | |
+ | |
+ AutoTArray<CookieStruct, 10> cookieList; // TODO: initialize and use it | |
nsresult rv = NS_OK; | |
if (mIPCClosed || | |
!SendOnStartRequest(channelStatus, | |
responseHead ? *responseHead : nsHttpResponseHead(), | |
!!responseHead, | |
requestHead->Headers(), | |
isFromCache, | |
mCacheEntry ? true : false, | |
expirationTime, cachedCharset, secInfoSerialization, | |
chan->GetSelfAddr(), chan->GetPeerAddr(), | |
redirectCount, | |
cacheKeyValue, | |
altDataType, | |
- altDataLen)) | |
+ altDataLen, | |
+ cookieList)) | |
{ | |
rv = NS_ERROR_UNEXPECTED; | |
} | |
requestHead->Exit(); | |
return rv; | |
} | |
NS_IMETHODIMP | |
diff --git a/netwerk/protocol/http/PHttpChannel.ipdl b/netwerk/protocol/http/PHttpChannel.ipdl | |
--- a/netwerk/protocol/http/PHttpChannel.ipdl | |
+++ b/netwerk/protocol/http/PHttpChannel.ipdl | |
@@ -104,17 +104,18 @@ child: | |
uint32_t cacheExpirationTime, | |
nsCString cachedCharset, | |
nsCString securityInfoSerialization, | |
NetAddr selfAddr, | |
NetAddr peerAddr, | |
int16_t redirectCount, | |
uint32_t cacheKey, | |
nsCString altDataType, | |
- int64_t altDataLength); | |
+ int64_t altDataLength, | |
+ CookieStruct[] cookieList); | |
// Combines a single OnDataAvailable and its associated OnProgress & | |
// OnStatus calls into one IPDL message | |
async OnTransportAndData(nsresult channelStatus, | |
nsresult transportStatus, | |
uint64_t offset, | |
uint32_t count, | |
nsCString data); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment