Changeset 201967 in webkit


Ignore:
Timestamp:
Jun 11, 2016 4:09:54 AM (8 years ago)
Author:
Antti Koivisto
Message:

Vary:Cookie validation doesn't work in private browsing
https://bugs.webkit.org/show_bug.cgi?id=158616
Source/WebCore:

rdar://problem/26755067

Reviewed by Darin Adler.

This wasn't implemented because there was no way to get NetworkStorageSession from
a SessionID on WebCore side.

The patch adds a simple WebCore level weak map that allows getting NetworkStorageSessions
from SessionID. This seemed like the cleanest way to do this without a big refactoring
around the currently WebKit2 level SessionTracker.

  • CMakeLists.txt:
  • WebCore.xcodeproj/project.pbxproj:
  • platform/network/CacheValidation.cpp:

(WebCore::headerValueForVary):

Get NetworkStorageSession from SessionID for cookies

(WebCore::verifyVaryingRequestHeaders):

  • platform/network/NetworkStorageSession.cpp: Added.

Add platform independent .cpp for NetworkStorageSession.
Implement a weak map for SessionID -> NetworkStorageSession.

(WebCore::sessionsMap):
(WebCore::NetworkStorageSession::NetworkStorageSession):
(WebCore::NetworkStorageSession::~NetworkStorageSession):
(WebCore::NetworkStorageSession::forSessionID):

Get NetworkStorageSession for sessionID.

  • platform/network/NetworkStorageSession.h:

(WebCore::NetworkStorageSession::sessionID):
(WebCore::NetworkStorageSession::credentialStorage):

  • platform/network/cf/NetworkStorageSessionCFNet.cpp:

(WebCore::NetworkStorageSession::NetworkStorageSession):

Call to common constructor.

(WebCore::defaultNetworkStorageSession):

  • platform/network/soup/NetworkStorageSessionSoup.cpp:

(WebCore::NetworkStorageSession::NetworkStorageSession):

Call to common constructor.

(WebCore::defaultSession):
(WebCore::NetworkStorageSession::~NetworkStorageSession): Deleted.

LayoutTests:

Reviewed by Darin Adler.

  • http/tests/cache/disk-cache/disk-cache-vary-cookie-expected.txt:
  • http/tests/cache/disk-cache/disk-cache-vary-cookie.html:

Exapand the existing test to cover memory cache and private browsing.

Location:
trunk
Files:
1 added
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r201958 r201967  
     12016-06-10  Antti Koivisto  <antti@apple.com>
     2
     3        Vary:Cookie validation doesn't work in private browsing
     4        https://bugs.webkit.org/show_bug.cgi?id=158616
     5
     6        Reviewed by Darin Adler.
     7
     8        * http/tests/cache/disk-cache/disk-cache-vary-cookie-expected.txt:
     9        * http/tests/cache/disk-cache/disk-cache-vary-cookie.html:
     10
     11        Exapand the existing test to cover memory cache and private browsing.
     12
    1132016-06-10  Benjamin Poulain  <bpoulain@apple.com>
    214
  • trunk/LayoutTests/http/tests/cache/disk-cache/disk-cache-vary-cookie-expected.txt

    r181894 r201967  
    1 Test that Vary: Cookie in response is handled by the disk cache.
     1Test that Vary: Cookie in response is handled by caches.
    22
    33On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
    44
    55
     6Testing disk cache
    67Setting cookie and loading
    78response headers: {"Cache-control":"max-age=100"}
     
    3233response source: Disk cache
    3334
     35Testing memory cache
     36Setting cookie and loading
     37response headers: {"Cache-control":"max-age=100"}
     38response source: Network
     39
     40response headers: {"Vary":"Cookie","Cache-control":"max-age=100"}
     41response source: Network
     42
     43Loading again
     44response headers: {"Cache-control":"max-age=100"}
     45response source: Memory cache
     46
     47response headers: {"Vary":"Cookie","Cache-control":"max-age=100"}
     48response source: Memory cache
     49
     50Changing cookie and loading
     51response headers: {"Cache-control":"max-age=100"}
     52response source: Memory cache
     53
     54response headers: {"Vary":"Cookie","Cache-control":"max-age=100"}
     55response source: Network
     56
     57Loading again
     58response headers: {"Cache-control":"max-age=100"}
     59response source: Memory cache
     60
     61response headers: {"Vary":"Cookie","Cache-control":"max-age=100"}
     62response source: Memory cache
     63
     64Testing memory cache in private browsing
     65Setting cookie and loading
     66response headers: {"Cache-control":"max-age=100"}
     67response source: Network
     68
     69response headers: {"Vary":"Cookie","Cache-control":"max-age=100"}
     70response source: Network
     71
     72Loading again
     73response headers: {"Cache-control":"max-age=100"}
     74response source: Memory cache
     75
     76response headers: {"Vary":"Cookie","Cache-control":"max-age=100"}
     77response source: Memory cache
     78
     79Changing cookie and loading
     80response headers: {"Cache-control":"max-age=100"}
     81response source: Memory cache
     82
     83response headers: {"Vary":"Cookie","Cache-control":"max-age=100"}
     84response source: Network
     85
     86Loading again
     87response headers: {"Cache-control":"max-age=100"}
     88response source: Memory cache
     89
     90response headers: {"Vary":"Cookie","Cache-control":"max-age=100"}
     91response source: Memory cache
     92
    3493PASS successfullyParsed is true
    3594
  • trunk/LayoutTests/http/tests/cache/disk-cache/disk-cache-vary-cookie.html

    r183261 r201967  
    44<script>
    55
    6 var tests =
    7 [
    8   { responseHeaders: {'Cache-control': 'max-age=100'} },
    9   { responseHeaders: {'Vary': 'Cookie', 'Cache-control': 'max-age=100'} },
    10 ];
    116
    12 description("Test that Vary: Cookie in response is handled by the disk cache.");
     7description("Test that Vary: Cookie in response is handled by caches.");
    138
    14 debug("Setting cookie and loading");
    15 document.cookie = "cookie=value";
    16 loadResources(tests, function () {
    17     printResults(tests);
    18     debug("Loading again");
    19     loadResources(tests, function () {
     9function testCookies(testDiskCache, completionHandler)
     10{
     11    var tests = [
     12      { responseHeaders: {'Cache-control': 'max-age=100'} },
     13      { responseHeaders: {'Vary': 'Cookie', 'Cache-control': 'max-age=100'} },
     14    ];
     15
     16    var options = { "ClearMemoryCache" : testDiskCache };
     17    debug("Setting cookie and loading");
     18    document.cookie = "cookie=" + Math.floor((Math.random() * 1000000000000));
     19    loadResourcesWithOptions(tests, options, function () {
    2020        printResults(tests);
    21         debug("Changing cookie and loading");
    22         document.cookie = "cookie=othervalue";
    23         loadResources(tests, function () {
     21        debug("Loading again");
     22        loadResourcesWithOptions(tests, options, function () {
    2423            printResults(tests);
    25             debug("Loading again");
    26             loadResources(tests, function () {
    27                printResults(tests);
    28                finishJSTest();
     24            debug("Changing cookie and loading");
     25            document.cookie = "cookie" + Math.floor((Math.random() * 1000000000000));
     26            loadResourcesWithOptions(tests, options, function () {
     27                printResults(tests);
     28                debug("Loading again");
     29                loadResourcesWithOptions(tests, options, function () {
     30                   printResults(tests);
     31                   completionHandler();
     32                });
    2933            });
     34        });
     35    });
     36}
     37
     38debug("Testing disk cache");
     39testCookies(true, function () {
     40    debug("Testing memory cache");
     41    testCookies(false, function () {
     42        debug("Testing memory cache in private browsing");
     43        testRunner.setPrivateBrowsingEnabled(true);
     44        testCookies(false, function () {
     45            finishJSTest();
    3046        });
    3147    });
  • trunk/Source/WebCore/CMakeLists.txt

    r201946 r201967  
    23392339    platform/network/MIMEHeader.cpp
    23402340    platform/network/NetworkStateNotifier.cpp
     2341    platform/network/NetworkStorageSession.cpp
    23412342    platform/network/ParsedContentRange.cpp
    23422343    platform/network/ParsedContentType.cpp
  • trunk/Source/WebCore/ChangeLog

    r201963 r201967  
     12016-06-10  Antti Koivisto  <antti@apple.com>
     2
     3        Vary:Cookie validation doesn't work in private browsing
     4        https://bugs.webkit.org/show_bug.cgi?id=158616
     5        rdar://problem/26755067
     6
     7        Reviewed by Darin Adler.
     8
     9        This wasn't implemented because there was no way to get NetworkStorageSession from
     10        a SessionID on WebCore side.
     11
     12        The patch adds a simple WebCore level weak map that allows getting NetworkStorageSessions
     13        from SessionID. This seemed like the cleanest way to do this without a big refactoring
     14        around the currently WebKit2 level SessionTracker.
     15
     16        * CMakeLists.txt:
     17        * WebCore.xcodeproj/project.pbxproj:
     18        * platform/network/CacheValidation.cpp:
     19        (WebCore::headerValueForVary):
     20
     21            Get NetworkStorageSession from SessionID for cookies
     22
     23        (WebCore::verifyVaryingRequestHeaders):
     24        * platform/network/NetworkStorageSession.cpp: Added.
     25
     26            Add platform independent .cpp for NetworkStorageSession.
     27            Implement a weak map for SessionID -> NetworkStorageSession.
     28
     29        (WebCore::sessionsMap):
     30        (WebCore::NetworkStorageSession::NetworkStorageSession):
     31        (WebCore::NetworkStorageSession::~NetworkStorageSession):
     32        (WebCore::NetworkStorageSession::forSessionID):
     33
     34            Get NetworkStorageSession for sessionID.
     35
     36        * platform/network/NetworkStorageSession.h:
     37        (WebCore::NetworkStorageSession::sessionID):
     38        (WebCore::NetworkStorageSession::credentialStorage):
     39        * platform/network/cf/NetworkStorageSessionCFNet.cpp:
     40        (WebCore::NetworkStorageSession::NetworkStorageSession):
     41
     42            Call to common constructor.
     43
     44        (WebCore::defaultNetworkStorageSession):
     45        * platform/network/soup/NetworkStorageSessionSoup.cpp:
     46        (WebCore::NetworkStorageSession::NetworkStorageSession):
     47
     48            Call to common constructor.
     49
     50        (WebCore::defaultSession):
     51        (WebCore::NetworkStorageSession::~NetworkStorageSession): Deleted.
     52
    1532016-06-10  Ada Chan  <adachan@apple.com>
    254
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r201963 r201967  
    67346734                E4F9EEF2156D9FFA00D23E7E /* StyleSheetContents.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4F9EEF0156D84C400D23E7E /* StyleSheetContents.cpp */; };
    67356735                E4F9EEF3156DA00700D23E7E /* StyleSheetContents.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F9EEF1156D84C400D23E7E /* StyleSheetContents.h */; settings = {ATTRIBUTES = (Private, ); }; };
     6736                E4FD02041D0AF2C100D8E57E /* NetworkStorageSession.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4FD02031D0AF2C100D8E57E /* NetworkStorageSession.cpp */; };
    67366737                E51A81DF17298D7700BFCA61 /* JSPerformance.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E51A81DE17298D7700BFCA61 /* JSPerformance.cpp */; };
    67376738                E526AF3F1727F8F200E41781 /* Performance.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E526AF3E1727F8F200E41781 /* Performance.cpp */; };
     
    1481914820                E4F9EEF0156D84C400D23E7E /* StyleSheetContents.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StyleSheetContents.cpp; sourceTree = "<group>"; };
    1482014821                E4F9EEF1156D84C400D23E7E /* StyleSheetContents.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleSheetContents.h; sourceTree = "<group>"; };
     14822                E4FD02031D0AF2C100D8E57E /* NetworkStorageSession.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NetworkStorageSession.cpp; sourceTree = "<group>"; };
    1482114823                E51A81DE17298D7700BFCA61 /* JSPerformance.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSPerformance.cpp; sourceTree = "<group>"; };
    1482214824                E526AF3E1727F8F200E41781 /* Performance.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Performance.cpp; sourceTree = "<group>"; };
     
    1780717809                                1A7FA61A0DDA3BBE0028F8A5 /* NetworkStateNotifier.cpp */,
    1780817810                                1A7FA6180DDA3B3A0028F8A5 /* NetworkStateNotifier.h */,
     17811                                E4FD02031D0AF2C100D8E57E /* NetworkStorageSession.cpp */,
    1780917812                                E13EF3421684ECF40034C83F /* NetworkStorageSession.h */,
    1781017813                                CDCD41E51C3DDB0900965D99 /* ParsedContentRange.cpp */,
     
    3219132194                                A3E2643014748991005A8588 /* WorkerEventQueue.cpp in Sources */,
    3219232195                                2E4346480F546A8200B0F1BA /* WorkerGlobalScope.cpp in Sources */,
     32196                                E4FD02041D0AF2C100D8E57E /* NetworkStorageSession.cpp in Sources */,
    3219332197                                418C395A1C8DD6990051C8A3 /* WorkerGlobalScopeFetch.cpp in Sources */,
    3219432198                                5185FCB31BB4C4E80012898F /* WorkerGlobalScopeIndexedDatabase.cpp in Sources */,
  • trunk/Source/WebCore/platform/network/CacheValidation.cpp

    r201805 r201967  
    339339    // is a blocking operation. This should be sufficient to cover reasonable cases.
    340340    if (headerName == httpHeaderNameString(HTTPHeaderName::Cookie)) {
    341         if (sessionID != SessionID::defaultSessionID()) {
    342             // FIXME: Don't know how to get the cookie. There should be a global way to get NetworkStorageSession from sessionID.
    343             return "";
    344         }
    345         auto& session = NetworkStorageSession::defaultStorageSession();
     341        auto& session = NetworkStorageSession::forSessionID(sessionID);
    346342        auto* cookieStrategy = platformStrategies() ? platformStrategies()->cookiesStrategy() : nullptr;
    347343        if (!cookieStrategy)
     
    375371        if (varyingRequestHeader.first == "*")
    376372            return false;
    377         if (sessionID != SessionID::defaultSessionID() && varyingRequestHeader.first == httpHeaderNameString(HTTPHeaderName::Cookie)) {
    378             // FIXME: See the comment in headerValueForVary.
    379             return false;
    380         }
    381373        String headerValue = headerValueForVary(request, varyingRequestHeader.first, sessionID);
    382374        if (headerValue != varyingRequestHeader.second)
  • trunk/Source/WebCore/platform/network/NetworkStorageSession.h

    r198083 r201967  
    3838namespace WebCore {
    3939
    40 class NetworkingContext;
    4140class ResourceRequest;
    4241class SoupNetworkSession;
     
    5049    WEBCORE_EXPORT static void switchToNewTestingSession();
    5150
     51    static NetworkStorageSession& forSessionID(SessionID);
     52
     53    WEBCORE_EXPORT ~NetworkStorageSession();
     54
    5255    SessionID sessionID() const { return m_sessionID; }
    5356    CredentialStorage& credentialStorage() { return m_credentialStorage; }
    5457
    5558#if PLATFORM(COCOA) || USE(CFNETWORK)
    56     NetworkStorageSession(SessionID, RetainPtr<CFURLStorageSessionRef>);
     59    NetworkStorageSession(SessionID, RetainPtr<CFURLStorageSessionRef>&&);
    5760
    5861    // May be null, in which case a Foundation default should be used.
     
    6164#elif USE(SOUP)
    6265    NetworkStorageSession(SessionID, std::unique_ptr<SoupNetworkSession>);
    63     ~NetworkStorageSession();
    6466
    6567    SoupNetworkSession& soupNetworkSession() const;
    6668    void setSoupNetworkSession(std::unique_ptr<SoupNetworkSession>);
    67 #else
    68     NetworkStorageSession(SessionID, NetworkingContext*);
    69     ~NetworkStorageSession();
    70 
    71     NetworkingContext* context() const;
    7269#endif
    7370
    7471private:
     72    explicit NetworkStorageSession(SessionID);
     73
     74    static void replaceDefaultSession(std::unique_ptr<NetworkStorageSession>);
     75
    7576    SessionID m_sessionID;
    7677
     
    7980#elif USE(SOUP)
    8081    std::unique_ptr<SoupNetworkSession> m_session;
    81 #else
    82     RefPtr<NetworkingContext> m_context;
    8382#endif
    8483
  • trunk/Source/WebCore/platform/network/cf/NetworkStorageSessionCFNet.cpp

    r198083 r201967  
    4242namespace WebCore {
    4343
    44 NetworkStorageSession::NetworkStorageSession(SessionID sessionID, RetainPtr<CFURLStorageSessionRef> platformSession)
    45     : m_sessionID(sessionID)
    46     , m_platformSession(platformSession)
     44NetworkStorageSession::NetworkStorageSession(SessionID sessionID, RetainPtr<CFURLStorageSessionRef>&& platformSession)
     45    : NetworkStorageSession(sessionID)
    4746{
    48 }
    49 
    50 static std::unique_ptr<NetworkStorageSession>& defaultNetworkStorageSession()
    51 {
    52     ASSERT(isMainThread());
    53     static NeverDestroyed<std::unique_ptr<NetworkStorageSession>> session;
    54     return session;
     47    m_platformSession = WTFMove(platformSession);
    5548}
    5649
     
    6053    String sessionName = String::format("WebKit Test-%u", static_cast<uint32_t>(getCurrentProcessID()));
    6154#if PLATFORM(COCOA)
    62     defaultNetworkStorageSession() = std::make_unique<NetworkStorageSession>(SessionID::defaultSessionID(), adoptCF(wkCreatePrivateStorageSession(sessionName.createCFString().get())));
     55    replaceDefaultSession(std::make_unique<NetworkStorageSession>(SessionID::defaultSessionID(), adoptCF(wkCreatePrivateStorageSession(sessionName.createCFString().get()))));
    6356#else
    64     defaultNetworkStorageSession() = std::make_unique<NetworkStorageSession>(SessionID::defaultSessionID(), adoptCF(wkCreatePrivateStorageSession(sessionName.createCFString().get(), defaultNetworkStorageSession()->platformSession())));
     57    replaceDefaultSession(std::make_unique<NetworkStorageSession>(SessionID::defaultSessionID(), adoptCF(wkCreatePrivateStorageSession(sessionName.createCFString().get(), defaultNetworkStorageSession()->platformSession()))));
    6558#endif
    66 }
    67 
    68 NetworkStorageSession& NetworkStorageSession::defaultStorageSession()
    69 {
    70     if (!defaultNetworkStorageSession())
    71         defaultNetworkStorageSession() = std::make_unique<NetworkStorageSession>(SessionID::defaultSessionID(), nullptr);
    72     return *defaultNetworkStorageSession();
    7359}
    7460
     
    8066    auto session = std::make_unique<NetworkStorageSession>(sessionID, adoptCF(wkCreatePrivateStorageSession(cfIdentifier.get())));
    8167#else
    82     auto session = std::make_unique<NetworkStorageSession>(sessionID, adoptCF(wkCreatePrivateStorageSession(cfIdentifier.get(), defaultNetworkStorageSession()->platformSession())));
     68    auto session = std::make_unique<NetworkStorageSession>(sessionID, adoptCF(wkCreatePrivateStorageSession(cfIdentifier.get(), defaultStorageSession().platformSession())));
    8369#endif
    8470
  • trunk/Source/WebCore/platform/network/soup/NetworkStorageSessionSoup.cpp

    r198083 r201967  
    3838
    3939NetworkStorageSession::NetworkStorageSession(SessionID sessionID, std::unique_ptr<SoupNetworkSession> session)
    40     : m_sessionID(sessionID)
    41     , m_session(WTFMove(session))
     40    : NetworkStorageSession(sessionID)
    4241{
    43 }
    44 
    45 NetworkStorageSession::~NetworkStorageSession()
    46 {
    47 }
    48 
    49 static std::unique_ptr<NetworkStorageSession>& defaultSession()
    50 {
    51     ASSERT(isMainThread());
    52     static NeverDestroyed<std::unique_ptr<NetworkStorageSession>> session;
    53     return session;
    54 }
    55 
    56 NetworkStorageSession& NetworkStorageSession::defaultStorageSession()
    57 {
    58     if (!defaultSession())
    59         defaultSession() = std::make_unique<NetworkStorageSession>(SessionID::defaultSessionID(), nullptr);
    60     return *defaultSession();
     42    m_session = WTFMove(session);
    6143}
    6244
     
    6951void NetworkStorageSession::switchToNewTestingSession()
    7052{
    71     defaultSession() = std::make_unique<NetworkStorageSession>(SessionID::defaultSessionID(), SoupNetworkSession::createTestingSession());
     53    replaceDefaultSession(std::make_unique<NetworkStorageSession>(SessionID::defaultSessionID(), SoupNetworkSession::createTestingSession()));
    7254}
    7355
Note: See TracChangeset for help on using the changeset viewer.