⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 220459 in webkit


Ignore:
Timestamp:
Aug 9, 2017, 9:30:41 AM (9 years ago)
Author:
dbates@webkit.org
Message:

REGRESSION (r219013): OAuth flows are broken when redirecting back to application after authentication
https://bugs.webkit.org/show_bug.cgi?id=175247
<rdar://problem/33679804>

Reviewed by Brady Eidson.

Source/WebCore:

Add SPI so that Safari can differentiate between a form submission and a redirected form submission
and have PolicyCheck notify the frame loader client if the navigation was in response to receiving a
redirect response. This is the WebKit portion to fix an issue when a native app makes use of an OAuth
OAuth flow that bounces to Safari for user login and then bounce back to the app. Microsoft Graph's
OAuth flow is one example.

Safari was differentiating between a form submission and a redirected form submission based on the
nullity of WKNavigationAction.sourceFrame because in both cases the navigation type was WKNavigationTypeFormSubmitted.
The navigation type is the same for both navigations because WebKit always used the navigation
action from the original request for the redirect request when the original request redirected.
Prior to r219013, WKNavigationAction.sourceFrame would be nil for a form submission that redirects.
Following r219013, WKNavigationAction.sourceFrame is non-nil unless the navigation was initiated by
API. In particular, WKNavigationAction.sourceFrame is non-nil for the redirect navigation corresponding
to a form submission that redirects.

  • loader/EmptyClients.cpp:

(WebCore::EmptyFrameLoaderClient::dispatchDecidePolicyForNavigationAction):

  • loader/FrameLoaderClient.h:

Have dispatchDecidePolicyForNavigationAction() take a boolean as to whether the navigation was in
response to receiving a redirect response.

  • loader/PolicyChecker.cpp:

(WebCore::PolicyChecker::checkNavigationPolicy): Notify the frame loader client whether the navigation
is in response to receiving a redirect response.

Source/WebKit:

Add SPI WKNavigationAction._isRedirect to query whether the navigation was in response to receiving
a redirect response. The majority of the WebKit change is plumbing this knowledge through to connect
it with the SPI.

  • Shared/NavigationActionData.cpp:

(WebKit::NavigationActionData::encode const):
(WebKit::NavigationActionData::decode):
Encode and decode the boolean NavigationActionData::isRedirect.

  • Shared/NavigationActionData.h:
  • UIProcess/API/APINavigationAction.h:
  • UIProcess/API/Cocoa/WKNavigationAction.mm:

(-[WKNavigationAction _isRedirect]): Added.

  • UIProcess/API/Cocoa/WKNavigationActionPrivate.h:
  • WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:

(WebKit::WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction): Set NavigationActionData::isRedirect
depending on whether the navigation is in response to receiving a redirect response.

  • WebProcess/WebCoreSupport/WebFrameLoaderClient.h:

Source/WebKitLegacy/mac:

Plumb knowledge of whether a navigation was in response to receiving a redirect response.
We do not actually make use of this knowledge in WebKitLegacy because we do not know of any
clients that need to make use of this information at this time. If such a needs comes up
then we can expose API/SPI similar to what we do for WebKit.

  • WebCoreSupport/WebFrameLoaderClient.h:
  • WebCoreSupport/WebFrameLoaderClient.mm:

(WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction):

Source/WebKitLegacy/win:

Plumb knowledge of whether a navigation was in response to receiving a redirect response.
We do not actually make use of this knowledge in WebKitLegacy because we do not know of any
clients that need to make use of this information at this time. If such a needs comes up
then we can expose API/SPI similar to what we do for WebKit.

  • WebCoreSupport/WebFrameLoaderClient.cpp:

(WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction):

  • WebCoreSupport/WebFrameLoaderClient.h:

Tools:

Add tests for redirects.

  • TestWebKitAPI/Tests/WebKit2Cocoa/DecidePolicyForNavigationAction.mm:

(TEST):

  • TestWebKitAPI/cocoa/TestProtocol.mm:

(createRedirectURL):
(-[TestProtocol startLoading]):

Location:
trunk
Files:
21 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r220457 r220459  
     12017-08-09  Daniel Bates  <dabates@apple.com>
     2
     3        REGRESSION (r219013): OAuth flows are broken when redirecting back to application after authentication
     4        https://bugs.webkit.org/show_bug.cgi?id=175247
     5        <rdar://problem/33679804>
     6
     7        Reviewed by Brady Eidson.
     8
     9        Add SPI so that Safari can differentiate between a form submission and a redirected form submission
     10        and have PolicyCheck notify the frame loader client if the navigation was in response to receiving a
     11        redirect response. This is the WebKit portion to fix an issue when a native app makes use of an OAuth
     12        OAuth flow that bounces to Safari for user login and then bounce back to the app. Microsoft Graph's
     13        OAuth flow is one example.
     14
     15        Safari was differentiating between a form submission and a redirected form submission based on the
     16        nullity of WKNavigationAction.sourceFrame because in both cases the navigation type was WKNavigationTypeFormSubmitted.
     17        The navigation type is the same for both navigations because WebKit always used the navigation
     18        action from the original request for the redirect request when the original request redirected.
     19        Prior to r219013, WKNavigationAction.sourceFrame would be nil for a form submission that redirects.
     20        Following r219013, WKNavigationAction.sourceFrame is non-nil unless the navigation was initiated by
     21        API. In particular, WKNavigationAction.sourceFrame is non-nil for the redirect navigation corresponding
     22        to a form submission that redirects.
     23
     24        * loader/EmptyClients.cpp:
     25        (WebCore::EmptyFrameLoaderClient::dispatchDecidePolicyForNavigationAction):
     26        * loader/FrameLoaderClient.h:
     27        Have dispatchDecidePolicyForNavigationAction() take a boolean as to whether the navigation was in
     28        response to receiving a redirect response.
     29        * loader/PolicyChecker.cpp:
     30        (WebCore::PolicyChecker::checkNavigationPolicy): Notify the frame loader client whether the navigation
     31        is in response to receiving a redirect response.
     32
    1332017-08-09  Sam Weinig  <sam@webkit.org>
    234
  • trunk/Source/WebCore/loader/EmptyClients.cpp

    r220071 r220459  
    340340    void dispatchDecidePolicyForResponse(const ResourceResponse&, const ResourceRequest&, FramePolicyFunction&&) final { }
    341341    void dispatchDecidePolicyForNewWindowAction(const NavigationAction&, const ResourceRequest&, FormState*, const String&, FramePolicyFunction&&) final;
    342     void dispatchDecidePolicyForNavigationAction(const NavigationAction&, const ResourceRequest&, FormState*, FramePolicyFunction&&) final;
     342    void dispatchDecidePolicyForNavigationAction(const NavigationAction&, const ResourceRequest&, bool didReceiveRedirectResponse, FormState*, FramePolicyFunction&&) final;
    343343    void cancelPolicyCheck() final { }
    344344
     
    609609}
    610610
    611 void EmptyFrameLoaderClient::dispatchDecidePolicyForNavigationAction(const NavigationAction&, const ResourceRequest&, FormState*, FramePolicyFunction&&)
     611void EmptyFrameLoaderClient::dispatchDecidePolicyForNavigationAction(const NavigationAction&, const ResourceRequest&, bool, FormState*, FramePolicyFunction&&)
    612612{
    613613}
  • trunk/Source/WebCore/loader/FrameLoaderClient.h

    r219733 r220459  
    180180    virtual void dispatchDecidePolicyForResponse(const ResourceResponse&, const ResourceRequest&, FramePolicyFunction&&) = 0;
    181181    virtual void dispatchDecidePolicyForNewWindowAction(const NavigationAction&, const ResourceRequest&, FormState*, const String& frameName, FramePolicyFunction&&) = 0;
    182     virtual void dispatchDecidePolicyForNavigationAction(const NavigationAction&, const ResourceRequest&, FormState*, FramePolicyFunction&&) = 0;
     182    virtual void dispatchDecidePolicyForNavigationAction(const NavigationAction&, const ResourceRequest&, bool didReceiveRedirectResponse, FormState*, FramePolicyFunction&&) = 0;
    183183    virtual void cancelPolicyCheck() = 0;
    184184
  • trunk/Source/WebCore/loader/PolicyChecker.cpp

    r219407 r220459  
    148148    m_delegateIsDecidingNavigationPolicy = true;
    149149    m_suggestedFilename = action.downloadAttribute().isEmpty() ? nullAtom() : action.downloadAttribute();
    150     m_frame.loader().client().dispatchDecidePolicyForNavigationAction(action, request, formState, [this](PolicyAction action) {
     150    m_frame.loader().client().dispatchDecidePolicyForNavigationAction(action, request, didReceiveRedirectResponse, formState, [this](PolicyAction action) {
    151151        continueAfterNavigationPolicy(action);
    152152    });
  • trunk/Source/WebKit/ChangeLog

    r220457 r220459  
     12017-08-09  Daniel Bates  <dabates@apple.com>
     2
     3        REGRESSION (r219013): OAuth flows are broken when redirecting back to application after authentication
     4        https://bugs.webkit.org/show_bug.cgi?id=175247
     5        <rdar://problem/33679804>
     6
     7        Reviewed by Brady Eidson.
     8
     9        Add SPI WKNavigationAction._isRedirect to query whether the navigation was in response to receiving
     10        a redirect response. The majority of the WebKit change is plumbing this knowledge through to connect
     11        it with the SPI.
     12
     13        * Shared/NavigationActionData.cpp:
     14        (WebKit::NavigationActionData::encode const):
     15        (WebKit::NavigationActionData::decode):
     16        Encode and decode the boolean NavigationActionData::isRedirect.
     17        * Shared/NavigationActionData.h:
     18        * UIProcess/API/APINavigationAction.h:
     19        * UIProcess/API/Cocoa/WKNavigationAction.mm:
     20        (-[WKNavigationAction _isRedirect]): Added.
     21        * UIProcess/API/Cocoa/WKNavigationActionPrivate.h:
     22        * WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
     23        (WebKit::WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction): Set NavigationActionData::isRedirect
     24        depending on whether the navigation is in response to receiving a redirect response.
     25        * WebProcess/WebCoreSupport/WebFrameLoaderClient.h:
     26
    1272017-08-09  Sam Weinig  <sam@webkit.org>
    228
  • trunk/Source/WebKit/Shared/NavigationActionData.cpp

    r219304 r220459  
    4747    encoder << downloadAttribute;
    4848    encoder << clickLocationInRootViewCoordinates;
     49    encoder << isRedirect;
    4950}
    5051
     
    6970    if (!decoder.decode(result.clickLocationInRootViewCoordinates))
    7071        return false;
     72    if (!decoder.decode(result.isRedirect))
     73        return false;
    7174
    7275    return true;
  • trunk/Source/WebKit/Shared/NavigationActionData.h

    r219871 r220459  
    5050    WTF::String downloadAttribute;
    5151    WebCore::FloatPoint clickLocationInRootViewCoordinates;
     52    bool isRedirect { false };
    5253};
    5354
  • trunk/Source/WebKit/UIProcess/API/APINavigationAction.h

    r219871 r220459  
    5757    bool shouldOpenAppLinks() const { return m_shouldOpenAppLinks && m_navigationActionData.shouldOpenExternalURLsPolicy == WebCore::ShouldOpenExternalURLsPolicy::ShouldAllow; }
    5858    bool shouldPerformDownload() const { return !m_navigationActionData.downloadAttribute.isNull(); }
     59    bool isRedirect() const { return m_navigationActionData.isRedirect; }
    5960
    6061    bool isProcessingUserGesture() const { return m_userInitiatedAction; }
  • trunk/Source/WebKit/UIProcess/API/Cocoa/WKNavigationAction.mm

    r219304 r220459  
    232232}
    233233
     234- (BOOL)_isRedirect
     235{
     236    return _navigationAction->isRedirect();
     237}
     238
    234239@end
    235240
  • trunk/Source/WebKit/UIProcess/API/Cocoa/WKNavigationActionPrivate.h

    r219304 r220459  
    5555#endif
    5656
     57@property (nonatomic, readonly) BOOL _isRedirect WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
     58
    5759@end
    5860
  • trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp

    r220074 r220459  
    758758}
    759759
    760 void WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(const NavigationAction& navigationAction, const ResourceRequest& request, FormState* formState, FramePolicyFunction&& function)
     760void WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(const NavigationAction& navigationAction, const ResourceRequest& request, bool didReceiveRedirectResponse, FormState* formState, FramePolicyFunction&& function)
    761761{
    762762    WebPage* webPage = m_frame->page();
     
    809809    navigationActionData.shouldOpenExternalURLsPolicy = navigationAction.shouldOpenExternalURLsPolicy();
    810810    navigationActionData.downloadAttribute = navigationAction.downloadAttribute();
     811    navigationActionData.isRedirect = didReceiveRedirectResponse;
    811812
    812813    WebCore::Frame* coreFrame = m_frame->coreFrame();
  • trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.h

    r219733 r220459  
    114114    void dispatchDecidePolicyForResponse(const WebCore::ResourceResponse&, const WebCore::ResourceRequest&, WebCore::FramePolicyFunction&&) final;
    115115    void dispatchDecidePolicyForNewWindowAction(const WebCore::NavigationAction&, const WebCore::ResourceRequest&, WebCore::FormState*, const String& frameName, WebCore::FramePolicyFunction&&) final;
    116     void dispatchDecidePolicyForNavigationAction(const WebCore::NavigationAction&, const WebCore::ResourceRequest&, WebCore::FormState*, WebCore::FramePolicyFunction&&) final;
     116    void dispatchDecidePolicyForNavigationAction(const WebCore::NavigationAction&, const WebCore::ResourceRequest&, bool didReceiveRedirectResponse, WebCore::FormState*, WebCore::FramePolicyFunction&&) final;
    117117    void cancelPolicyCheck() final;
    118118   
  • trunk/Source/WebKitLegacy/mac/ChangeLog

    r220429 r220459  
     12017-08-09  Daniel Bates  <dabates@apple.com>
     2
     3        REGRESSION (r219013): OAuth flows are broken when redirecting back to application after authentication
     4        https://bugs.webkit.org/show_bug.cgi?id=175247
     5        <rdar://problem/33679804>
     6
     7        Reviewed by Brady Eidson.
     8
     9        Plumb knowledge of whether a navigation was in response to receiving a redirect response.
     10        We do not actually make use of this knowledge in WebKitLegacy because we do not know of any
     11        clients that need to make use of this information at this time. If such a needs comes up
     12        then we can expose API/SPI similar to what we do for WebKit.
     13
     14        * WebCoreSupport/WebFrameLoaderClient.h:
     15        * WebCoreSupport/WebFrameLoaderClient.mm:
     16        (WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction):
     17
    1182017-08-08  Brady Eidson  <beidson@apple.com>
    219
  • trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebFrameLoaderClient.h

    r219733 r220459  
    121121    void dispatchDecidePolicyForResponse(const WebCore::ResourceResponse&, const WebCore::ResourceRequest&, WebCore::FramePolicyFunction&&) final;
    122122    void dispatchDecidePolicyForNewWindowAction(const WebCore::NavigationAction&, const WebCore::ResourceRequest&, WebCore::FormState*, const WTF::String& frameName, WebCore::FramePolicyFunction&&) final;
    123     void dispatchDecidePolicyForNavigationAction(const WebCore::NavigationAction&, const WebCore::ResourceRequest&, WebCore::FormState*, WebCore::FramePolicyFunction&&) final;
     123    void dispatchDecidePolicyForNavigationAction(const WebCore::NavigationAction&, const WebCore::ResourceRequest&, bool didReceiveRedirectResponse, WebCore::FormState*, WebCore::FramePolicyFunction&&) final;
    124124    void cancelPolicyCheck() final;
    125125
  • trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebFrameLoaderClient.mm

    r220429 r220459  
    893893}
    894894
    895 void WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(const NavigationAction& action, const ResourceRequest& request, FormState* formState, FramePolicyFunction&& function)
     895void WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(const NavigationAction& action, const ResourceRequest& request, bool, FormState* formState, FramePolicyFunction&& function)
    896896{
    897897    WebView *webView = getWebView(m_webFrame.get());
  • trunk/Source/WebKitLegacy/win/ChangeLog

    r219876 r220459  
     12017-08-09  Daniel Bates  <dabates@apple.com>
     2
     3        REGRESSION (r219013): OAuth flows are broken when redirecting back to application after authentication
     4        https://bugs.webkit.org/show_bug.cgi?id=175247
     5        <rdar://problem/33679804>
     6
     7        Reviewed by Brady Eidson.
     8
     9        Plumb knowledge of whether a navigation was in response to receiving a redirect response.
     10        We do not actually make use of this knowledge in WebKitLegacy because we do not know of any
     11        clients that need to make use of this information at this time. If such a needs comes up
     12        then we can expose API/SPI similar to what we do for WebKit.
     13
     14        * WebCoreSupport/WebFrameLoaderClient.cpp:
     15        (WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction):
     16        * WebCoreSupport/WebFrameLoaderClient.h:
     17
    1182017-07-25  Said Abou-Hallawa  <sabouhallawa@apple.com>
    219
  • trunk/Source/WebKitLegacy/win/WebCoreSupport/WebFrameLoaderClient.cpp

    r219099 r220459  
    550550}
    551551
    552 void WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(const NavigationAction& action, const ResourceRequest& request, FormState* formState, FramePolicyFunction&& function)
     552void WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(const NavigationAction& action, const ResourceRequest& request, bool, FormState* formState, FramePolicyFunction&& function)
    553553{
    554554    WebView* webView = m_webFrame->webView();
  • trunk/Source/WebKitLegacy/win/WebCoreSupport/WebFrameLoaderClient.h

    r219099 r220459  
    9999    void dispatchDecidePolicyForResponse(const WebCore::ResourceResponse&, const WebCore::ResourceRequest&, WebCore::FramePolicyFunction&&) override;
    100100    void dispatchDecidePolicyForNewWindowAction(const WebCore::NavigationAction&, const WebCore::ResourceRequest&, WebCore::FormState*, const WTF::String& frameName, WebCore::FramePolicyFunction&&) override;
    101     void dispatchDecidePolicyForNavigationAction(const WebCore::NavigationAction&, const WebCore::ResourceRequest&, WebCore::FormState*, WebCore::FramePolicyFunction&&) override;
     101    void dispatchDecidePolicyForNavigationAction(const WebCore::NavigationAction&, const WebCore::ResourceRequest&, bool didReceiveRedirectResponse, WebCore::FormState*, WebCore::FramePolicyFunction&&) override;
    102102    void cancelPolicyCheck() override;
    103103
  • trunk/Tools/ChangeLog

    r220443 r220459  
     12017-08-09  Daniel Bates  <dabates@apple.com>
     2
     3        REGRESSION (r219013): OAuth flows are broken when redirecting back to application after authentication
     4        https://bugs.webkit.org/show_bug.cgi?id=175247
     5        <rdar://problem/33679804>
     6
     7        Reviewed by Brady Eidson.
     8
     9        Add tests for redirects.
     10
     11        * TestWebKitAPI/Tests/WebKit2Cocoa/DecidePolicyForNavigationAction.mm:
     12        (TEST):
     13        * TestWebKitAPI/cocoa/TestProtocol.mm:
     14        (createRedirectURL):
     15        (-[TestProtocol startLoading]):
     16
    1172017-08-08  Wenson Hsieh  <wenson_hsieh@apple.com>
    218
  • trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/DecidePolicyForNavigationAction.mm

    r219149 r220459  
    2929
    3030#import "PlatformUtilities.h"
     31#import "TestProtocol.h"
     32#import <WebKit/WKNavigationActionPrivate.h>
    3133#import <wtf/RetainPtr.h>
    3234#import <wtf/mac/AppKitCompatibilityDeclarations.h>
     
    381383}
    382384
     385TEST(WebKit2, DecidePolicyForNavigationActionForHyperlinkThatRedirects)
     386{
     387    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
     388
     389    auto window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]);
     390    [[window contentView] addSubview:webView.get()];
     391
     392    auto controller = adoptNS([[DecidePolicyForNavigationActionController alloc] init]);
     393    [webView setNavigationDelegate:controller.get()];
     394    [webView setUIDelegate:controller.get()];
     395
     396    [TestProtocol registerWithScheme:@"http"];
     397    finishedNavigation = false;
     398    [webView loadHTMLString:@"<a style=\"display: block; height: 100%\" href=\"http://redirect/?result\">" baseURL:[NSURL URLWithString:@"http://webkit.org"]];
     399    TestWebKitAPI::Util::run(&finishedNavigation);
     400
     401    decidedPolicy = false;
     402    [newWebView setNavigationDelegate:controller.get()];
     403    NSPoint clickPoint = NSMakePoint(100, 100);
     404    [[webView hitTest:clickPoint] mouseDown:[NSEvent mouseEventWithType:NSEventTypeLeftMouseDown location:clickPoint modifierFlags:0 timestamp:0 windowNumber:[window windowNumber] context:nil eventNumber:0 clickCount:1 pressure:1]];
     405    [[webView hitTest:clickPoint] mouseUp:[NSEvent mouseEventWithType:NSEventTypeLeftMouseUp location:clickPoint modifierFlags:0 timestamp:0 windowNumber:[window windowNumber] context:nil eventNumber:0 clickCount:1 pressure:1]];
     406    TestWebKitAPI::Util::run(&decidedPolicy);
     407
     408    EXPECT_EQ(WKNavigationTypeLinkActivated, [action navigationType]);
     409    EXPECT_TRUE([action sourceFrame] == [action targetFrame]);
     410    EXPECT_WK_STREQ("GET", [[action request] HTTPMethod]);
     411    EXPECT_WK_STREQ("http://redirect/?result", [[[action request] URL] absoluteString]);
     412    EXPECT_EQ(webView.get(), [[action sourceFrame] webView]);
     413    EXPECT_WK_STREQ("http", [[[action sourceFrame] securityOrigin] protocol]);
     414    EXPECT_WK_STREQ("webkit.org", [[[action sourceFrame] securityOrigin] host]);
     415    EXPECT_FALSE([action _isRedirect]);
     416
     417    // Wait to decide policy for redirect.
     418    decidedPolicy = false;
     419    TestWebKitAPI::Util::run(&decidedPolicy);
     420
     421    EXPECT_EQ(WKNavigationTypeLinkActivated, [action navigationType]);
     422    EXPECT_TRUE([action sourceFrame] == [action targetFrame]);
     423    EXPECT_WK_STREQ("GET", [[action request] HTTPMethod]);
     424    EXPECT_WK_STREQ("http://result/", [[[action request] URL] absoluteString]);
     425    EXPECT_EQ(webView.get(), [[action sourceFrame] webView]);
     426    EXPECT_WK_STREQ("http", [[[action sourceFrame] securityOrigin] protocol]);
     427    EXPECT_WK_STREQ("webkit.org", [[[action sourceFrame] securityOrigin] host]);
     428    EXPECT_TRUE([action _isRedirect]);
     429
     430    [TestProtocol unregister];
     431    newWebView = nullptr;
     432    action = nullptr;
     433}
     434
     435TEST(WebKit2, DecidePolicyForNavigationActionForPOSTFormSubmissionThatRedirectsToGET)
     436{
     437    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
     438
     439    auto window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]);
     440    [[window contentView] addSubview:webView.get()];
     441
     442    auto controller = adoptNS([[DecidePolicyForNavigationActionController alloc] init]);
     443    [webView setNavigationDelegate:controller.get()];
     444    [webView setUIDelegate:controller.get()];
     445
     446    finishedNavigation = false;
     447    [webView loadHTMLString:@"<form action=\"http://redirect/?result\" method=\"POST\"><input type=\"submit\" name=\"submitButton\" value=\"Submit\"></form>" baseURL:[NSURL URLWithString:@"http://webkit.org"]];
     448    TestWebKitAPI::Util::run(&finishedNavigation);
     449
     450    [TestProtocol registerWithScheme:@"http"];
     451    decidedPolicy = false;
     452    [webView evaluateJavaScript:@"document.forms[0].submit()" completionHandler:nil];
     453    TestWebKitAPI::Util::run(&decidedPolicy);
     454
     455    EXPECT_EQ(WKNavigationTypeFormSubmitted, [action navigationType]);
     456    EXPECT_TRUE([action sourceFrame] == [action targetFrame]);
     457    EXPECT_WK_STREQ("POST", [[action request] HTTPMethod]);
     458    EXPECT_WK_STREQ("http://redirect/?result", [[[action request] URL] absoluteString]);
     459    EXPECT_EQ(webView.get(), [[action sourceFrame] webView]);
     460    EXPECT_WK_STREQ("http", [[[action sourceFrame] securityOrigin] protocol]);
     461    EXPECT_WK_STREQ("webkit.org", [[[action sourceFrame] securityOrigin] host]);
     462    EXPECT_FALSE([action _isRedirect]);
     463
     464    // Wait to decide policy for redirect.
     465    decidedPolicy = false;
     466    TestWebKitAPI::Util::run(&decidedPolicy);
     467
     468    EXPECT_EQ(WKNavigationTypeFormSubmitted, [action navigationType]);
     469    EXPECT_TRUE([action sourceFrame] == [action targetFrame]);
     470    EXPECT_WK_STREQ("GET", [[action request] HTTPMethod]);
     471    EXPECT_WK_STREQ("http://result/", [[[action request] URL] absoluteString]);
     472    EXPECT_EQ(webView.get(), [[action sourceFrame] webView]);
     473    EXPECT_WK_STREQ("http", [[[action sourceFrame] securityOrigin] protocol]);
     474    EXPECT_WK_STREQ("webkit.org", [[[action sourceFrame] securityOrigin] host]);
     475    EXPECT_TRUE([action _isRedirect]);
     476
     477    [TestProtocol unregister];
     478    newWebView = nullptr;
     479    action = nullptr;
     480}
     481
     482TEST(WebKit2, DecidePolicyForNavigationActionForPOSTFormSubmissionThatRedirectsToPOST)
     483{
     484    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
     485
     486    auto window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]);
     487    [[window contentView] addSubview:webView.get()];
     488
     489    auto controller = adoptNS([[DecidePolicyForNavigationActionController alloc] init]);
     490    [webView setNavigationDelegate:controller.get()];
     491    [webView setUIDelegate:controller.get()];
     492
     493    finishedNavigation = false;
     494    [webView loadHTMLString:@"<form action=\"http://307-redirect/?result\" method=\"POST\"><input type=\"submit\" name=\"submitButton\" value=\"Submit\"></form>" baseURL:[NSURL URLWithString:@"http://webkit.org"]];
     495    TestWebKitAPI::Util::run(&finishedNavigation);
     496
     497    [TestProtocol registerWithScheme:@"http"];
     498    decidedPolicy = false;
     499    [webView evaluateJavaScript:@"document.forms[0].submit()" completionHandler:nil];
     500    TestWebKitAPI::Util::run(&decidedPolicy);
     501
     502    EXPECT_EQ(WKNavigationTypeFormSubmitted, [action navigationType]);
     503    EXPECT_TRUE([action sourceFrame] == [action targetFrame]);
     504    EXPECT_WK_STREQ("POST", [[action request] HTTPMethod]);
     505    EXPECT_WK_STREQ("http://307-redirect/?result", [[[action request] URL] absoluteString]);
     506    EXPECT_EQ(webView.get(), [[action sourceFrame] webView]);
     507    EXPECT_WK_STREQ("http", [[[action sourceFrame] securityOrigin] protocol]);
     508    EXPECT_WK_STREQ("webkit.org", [[[action sourceFrame] securityOrigin] host]);
     509    EXPECT_FALSE([action _isRedirect]);
     510
     511    // Wait to decide policy for redirect.
     512    decidedPolicy = false;
     513    TestWebKitAPI::Util::run(&decidedPolicy);
     514
     515    EXPECT_EQ(WKNavigationTypeFormSubmitted, [action navigationType]);
     516    EXPECT_TRUE([action sourceFrame] == [action targetFrame]);
     517    EXPECT_WK_STREQ("POST", [[action request] HTTPMethod]);
     518    EXPECT_WK_STREQ("http://result/", [[[action request] URL] absoluteString]);
     519    EXPECT_EQ(webView.get(), [[action sourceFrame] webView]);
     520    EXPECT_WK_STREQ("http", [[[action sourceFrame] securityOrigin] protocol]);
     521    EXPECT_WK_STREQ("webkit.org", [[[action sourceFrame] securityOrigin] host]);
     522    EXPECT_TRUE([action _isRedirect]);
     523
     524    [TestProtocol unregister];
     525    newWebView = nullptr;
     526    action = nullptr;
     527}
     528
    383529#endif
    384530
  • trunk/Tools/TestWebKitAPI/cocoa/TestProtocol.mm

    r194950 r220459  
    7373}
    7474
     75static NSURL *createRedirectURL(NSString *query)
     76{
     77    return [NSURL URLWithString:[NSString stringWithFormat:@"%@://%@", testScheme, query]];
     78}
     79
    7580- (void)startLoading
    7681{
     
    7883    EXPECT_TRUE([requestURL.scheme isEqualToString:testScheme]);
    7984
     85    if ([requestURL.host isEqualToString:@"307-redirect"]) {
     86        RetainPtr<NSHTTPURLResponse> response = adoptNS([[NSHTTPURLResponse alloc] initWithURL:requestURL statusCode:307 HTTPVersion:@"HTTP/1.1" headerFields:@{@"Content-Type" : @"text/html"}]);
     87        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:createRedirectURL(requestURL.query)];
     88        request.HTTPMethod = self.request.HTTPMethod;
     89        [self.client URLProtocol:self wasRedirectedToRequest:request redirectResponse:response.get()];
     90        return;
     91    }
     92
    8093    NSData *data = [@"PASS" dataUsingEncoding:NSASCIIStringEncoding];
    8194    RetainPtr<NSURLResponse> response = adoptNS([[NSURLResponse alloc] initWithURL:requestURL MIMEType:@"text/html" expectedContentLength:data.length textEncodingName:nil]);
    8295
    8396    if ([requestURL.host isEqualToString:@"redirect"]) {
    84         NSURL *redirectURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@://%@", testScheme, requestURL.query]];
    85         [self.client URLProtocol:self wasRedirectedToRequest:[NSURLRequest requestWithURL:redirectURL] redirectResponse:response.get()];
     97        [self.client URLProtocol:self wasRedirectedToRequest:[NSURLRequest requestWithURL:createRedirectURL(requestURL.query)] redirectResponse:response.get()];
    8698        return;
    8799    }
Note: See TracChangeset for help on using the changeset viewer.