diff --git a/netwerk/protocol/http/HttpBaseChannel.cpp b/netwerk/protocol/http/HttpBaseChannel.cpp index b64f09e8fb91..f32fb093e36a 100644 --- a/netwerk/protocol/http/HttpBaseChannel.cpp +++ b/netwerk/protocol/http/HttpBaseChannel.cpp @@ -1365,6 +1365,15 @@ HttpBaseChannel::IsNoCacheResponse(bool *value) return NS_OK; } +NS_IMETHODIMP +HttpBaseChannel::IsPrivateResponse(bool *value) +{ + if (!mResponseHead) + return NS_ERROR_NOT_AVAILABLE; + *value = mResponseHead->Private(); + return NS_OK; +} + NS_IMETHODIMP HttpBaseChannel::GetResponseStatus(uint32_t *aValue) { diff --git a/netwerk/protocol/http/HttpBaseChannel.h b/netwerk/protocol/http/HttpBaseChannel.h index 54fe7feb831a..6ab06ed56814 100644 --- a/netwerk/protocol/http/HttpBaseChannel.h +++ b/netwerk/protocol/http/HttpBaseChannel.h @@ -153,6 +153,7 @@ public: NS_IMETHOD SetRedirectionLimit(uint32_t value) MOZ_OVERRIDE; NS_IMETHOD IsNoStoreResponse(bool *value) MOZ_OVERRIDE; NS_IMETHOD IsNoCacheResponse(bool *value) MOZ_OVERRIDE; + NS_IMETHOD IsPrivateResponse(bool *value) MOZ_OVERRIDE; NS_IMETHOD GetResponseStatus(uint32_t *aValue) MOZ_OVERRIDE; NS_IMETHOD GetResponseStatusText(nsACString& aValue) MOZ_OVERRIDE; NS_IMETHOD GetRequestSucceeded(bool *aValue) MOZ_OVERRIDE; diff --git a/netwerk/protocol/http/NullHttpChannel.cpp b/netwerk/protocol/http/NullHttpChannel.cpp index 0b6c0398b0a8..00397d09e49a 100644 --- a/netwerk/protocol/http/NullHttpChannel.cpp +++ b/netwerk/protocol/http/NullHttpChannel.cpp @@ -193,6 +193,12 @@ NullHttpChannel::IsNoCacheResponse(bool *_retval) return NS_ERROR_NOT_IMPLEMENTED; } +NS_IMETHODIMP +NullHttpChannel::IsPrivateResponse(bool *_retval) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + NS_IMETHODIMP NullHttpChannel::RedirectTo(nsIURI *aNewURI) { diff --git a/netwerk/protocol/http/PHttpChannelParams.h b/netwerk/protocol/http/PHttpChannelParams.h index 8c3edb429c1c..6c29deb58150 100644 --- a/netwerk/protocol/http/PHttpChannelParams.h +++ b/netwerk/protocol/http/PHttpChannelParams.h @@ -145,6 +145,7 @@ struct ParamTraits WriteParam(aMsg, aParam.mContentLength); WriteParam(aMsg, aParam.mContentType); WriteParam(aMsg, aParam.mContentCharset); + WriteParam(aMsg, aParam.mCacheControlPrivate); WriteParam(aMsg, aParam.mCacheControlNoStore); WriteParam(aMsg, aParam.mCacheControlNoCache); WriteParam(aMsg, aParam.mPragmaNoCache); @@ -159,6 +160,7 @@ struct ParamTraits !ReadParam(aMsg, aIter, &aResult->mContentLength) || !ReadParam(aMsg, aIter, &aResult->mContentType) || !ReadParam(aMsg, aIter, &aResult->mContentCharset) || + !ReadParam(aMsg, aIter, &aResult->mCacheControlPrivate) || !ReadParam(aMsg, aIter, &aResult->mCacheControlNoStore) || !ReadParam(aMsg, aIter, &aResult->mCacheControlNoCache) || !ReadParam(aMsg, aIter, &aResult->mPragmaNoCache)) diff --git a/netwerk/protocol/http/nsHttpResponseHead.cpp b/netwerk/protocol/http/nsHttpResponseHead.cpp index 8d848d845453..fb828bfe512c 100644 --- a/netwerk/protocol/http/nsHttpResponseHead.cpp +++ b/netwerk/protocol/http/nsHttpResponseHead.cpp @@ -624,6 +624,7 @@ nsHttpResponseHead::Reset() mVersion = NS_HTTP_VERSION_1_1; mStatus = 200; mContentLength = UINT64_MAX; + mCacheControlPrivate = false; mCacheControlNoStore = false; mCacheControlNoCache = false; mPragmaNoCache = false; @@ -792,11 +793,16 @@ nsHttpResponseHead::ParseCacheControl(const char *val) { if (!(val && *val)) { // clear flags + mCacheControlPrivate = false; mCacheControlNoCache = false; mCacheControlNoStore = false; return; } + // search header value for occurrence of "private" + if (nsHttp::FindToken(val, "private", HTTP_HEADER_VALUE_SEPS)) + mCacheControlPrivate = true; + // search header value for occurrence(s) of "no-cache" but ignore // occurrence(s) of "no-cache=blah" if (nsHttp::FindToken(val, "no-cache", HTTP_HEADER_VALUE_SEPS)) diff --git a/netwerk/protocol/http/nsHttpResponseHead.h b/netwerk/protocol/http/nsHttpResponseHead.h index 663d762ff8b7..279535fb531f 100644 --- a/netwerk/protocol/http/nsHttpResponseHead.h +++ b/netwerk/protocol/http/nsHttpResponseHead.h @@ -23,6 +23,7 @@ public: nsHttpResponseHead() : mVersion(NS_HTTP_VERSION_1_1) , mStatus(200) , mContentLength(UINT64_MAX) + , mCacheControlPrivate(false) , mCacheControlNoStore(false) , mCacheControlNoCache(false) , mPragmaNoCache(false) {} @@ -37,6 +38,7 @@ public: int64_t ContentLength() const { return mContentLength; } const nsAFlatCString &ContentType() const { return mContentType; } const nsAFlatCString &ContentCharset() const { return mContentCharset; } + bool Private() const { return mCacheControlPrivate; } bool NoStore() const { return mCacheControlNoStore; } bool NoCache() const { return (mCacheControlNoCache || mPragmaNoCache); } /** @@ -128,6 +130,7 @@ private: int64_t mContentLength; nsCString mContentType; nsCString mContentCharset; + bool mCacheControlPrivate; bool mCacheControlNoStore; bool mCacheControlNoCache; bool mPragmaNoCache; diff --git a/netwerk/protocol/http/nsIHttpChannel.idl b/netwerk/protocol/http/nsIHttpChannel.idl index 03d39e85fec3..51d4a23996a7 100644 --- a/netwerk/protocol/http/nsIHttpChannel.idl +++ b/netwerk/protocol/http/nsIHttpChannel.idl @@ -14,7 +14,7 @@ interface nsIHttpHeaderVisitor; * the inspection of the resulting HTTP response status and headers when they * become available. */ -[scriptable, uuid(82083578-fb78-4f9a-953c-cecbae500697)] +[scriptable, uuid(a8bed710-653c-4ea4-9747-a629cc482cf8)] interface nsIHttpChannel : nsIChannel { /************************************************************************** @@ -299,6 +299,15 @@ interface nsIHttpChannel : nsIChannel */ boolean isNoCacheResponse(); + /** + * Returns true if the server sent a "Cache-Control: private" response + * header. + * + * @throws NS_ERROR_NOT_AVAILABLE if called before the response + * has been received (before onStartRequest). + */ + boolean isPrivateResponse(); + /** * Instructs the channel to immediately redirect to a new destination. * Can only be called on channels not yet opened. diff --git a/netwerk/protocol/viewsource/nsViewSourceChannel.cpp b/netwerk/protocol/viewsource/nsViewSourceChannel.cpp index 0d933118ace0..9f290ddca391 100644 --- a/netwerk/protocol/viewsource/nsViewSourceChannel.cpp +++ b/netwerk/protocol/viewsource/nsViewSourceChannel.cpp @@ -768,6 +768,13 @@ nsViewSourceChannel::IsNoCacheResponse(bool *_retval) mHttpChannel->IsNoCacheResponse(_retval); } +NS_IMETHODIMP +nsViewSourceChannel::IsPrivateResponse(bool *_retval) +{ + return !mHttpChannel ? NS_ERROR_NULL_POINTER : + mHttpChannel->IsPrivateResponse(_retval); +} + NS_IMETHODIMP nsViewSourceChannel::RedirectTo(nsIURI *uri) { diff --git a/netwerk/test/httpserver/test/test_basic_functionality.js b/netwerk/test/httpserver/test/test_basic_functionality.js index 824412fef81b..9151bed4bcdd 100644 --- a/netwerk/test/httpserver/test/test_basic_functionality.js +++ b/netwerk/test/httpserver/test/test_basic_functionality.js @@ -59,6 +59,7 @@ function commonCheck(ch) do_check_true(ch.contentLength > -1); do_check_eq(ch.getResponseHeader("connection"), "close"); do_check_false(ch.isNoStoreResponse()); + do_check_false(ch.isPrivateResponse()); } function start_objHandler(ch, cx)