WebCore:
authorbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 29 Jul 2009 18:22:35 +0000 (18:22 +0000)
committerbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 29 Jul 2009 18:22:35 +0000 (18:22 +0000)
2009-07-29  Brady Eidson  <beidson@apple.com>

        Reviewed by Sam Weinig.

        https://bugs.webkit.org/show_bug.cgi?id=27791
        307 redirects of POSTs should use POST, not GET

        Test: http/tests/loading/redirect-methods.html

        * platform/network/cf/ResourceHandleCFNet.cpp:
        (WebCore::willSendRequest):

        * platform/network/mac/ResourceHandleMac.mm:
        (-[WebCoreResourceHandleAsDelegate connection:willSendRequest:redirectResponse:]):

LayoutTests:

2009-07-29  Brady Eidson  <beidson@apple.com>

        Reviewed by Sam Weinig.

        https://bugs.webkit.org/show_bug.cgi?id=27791
        307 redirects of POSTs should use POST, not GET

        * http/tests/loading/redirect-methods-expected.txt: Added.
        * http/tests/loading/redirect-methods.html: Added.
        * http/tests/loading/resources/redirect-methods-form.html: Added.
        * http/tests/loading/resources/redirect-methods-result.php: Added.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@46548 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/http/tests/loading/redirect-methods-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/loading/redirect-methods.html [new file with mode: 0644]
LayoutTests/http/tests/loading/resources/redirect-methods-form.html [new file with mode: 0644]
LayoutTests/http/tests/loading/resources/redirect-methods-result.php [new file with mode: 0644]
WebCore/ChangeLog
WebCore/platform/network/cf/ResourceHandleCFNet.cpp
WebCore/platform/network/mac/ResourceHandleMac.mm

index c95abaf790df393c1bf1b308c53c136df84a1fee..09384309d8b1bdc7e72bbc796ca7e12e9cc8395e 100644 (file)
@@ -1,3 +1,15 @@
+2009-07-29  Brady Eidson  <beidson@apple.com>
+
+        Reviewed by Sam Weinig.
+
+        https://bugs.webkit.org/show_bug.cgi?id=27791
+        307 redirects of POSTs should use POST, not GET
+
+        * http/tests/loading/redirect-methods-expected.txt: Added.
+        * http/tests/loading/redirect-methods.html: Added.
+        * http/tests/loading/resources/redirect-methods-form.html: Added.
+        * http/tests/loading/resources/redirect-methods-result.php: Added.
+
 2009-07-29  Chris Marrin  <cmarrin@apple.com>
 
         Reviewed by Simon Fraser.
diff --git a/LayoutTests/http/tests/loading/redirect-methods-expected.txt b/LayoutTests/http/tests/loading/redirect-methods-expected.txt
new file mode 100644 (file)
index 0000000..30c0160
--- /dev/null
@@ -0,0 +1,126 @@
+main frame - didStartProvisionalLoadForFrame
+main frame - didCommitLoadForFrame
+<unknown> - willCacheResponse: called
+main frame - didFinishDocumentLoadForFrame
+main frame - didHandleOnloadEventsForFrame
+main frame - didFinishLoadForFrame
+<unknown> - didFinishLoading
+frame "0" - didStartProvisionalLoadForFrame
+about:blank - willSendRequest <NSURLRequest URL about:blank, main document URL http://127.0.0.1:8000/loading/redirect-methods.html, http method GET> redirectResponse (null)
+about:blank - didReceiveResponse <NSURLResponse about:blank, http status code 0>
+frame "0" - didCommitLoadForFrame
+frame "0" - didFinishDocumentLoadForFrame
+frame "0" - didHandleOnloadEventsForFrame
+frame "0" - didFinishLoadForFrame
+about:blank - didFinishLoading
+frame "0" - willPerformClientRedirectToURL: http://127.0.0.1:8000/loading/resources/redirect-methods-form.html 
+frame "0" - didStartProvisionalLoadForFrame
+http://127.0.0.1:8000/loading/resources/redirect-methods-form.html - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/redirect-methods-form.html, main document URL http://127.0.0.1:8000/loading/redirect-methods.html, http method GET> redirectResponse (null)
+http://127.0.0.1:8000/loading/resources/redirect-methods-form.html - willCacheResponse: called
+http://127.0.0.1:8000/loading/resources/redirect-methods-form.html - didReceiveResponse <NSURLResponse http://127.0.0.1:8000/loading/resources/redirect-methods-form.html, http status code 200>
+frame "0" - didCancelClientRedirectForFrame
+frame "0" - didCommitLoadForFrame
+frame "0" - didFinishDocumentLoadForFrame
+frame "0" - didHandleOnloadEventsForFrame
+frame "0" - didFinishLoadForFrame
+http://127.0.0.1:8000/loading/resources/redirect-methods-form.html - didFinishLoading
+frame "0" - didStartProvisionalLoadForFrame
+http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, main document URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, http method POST> redirectResponse (null)
+http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true, main document URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, http method GET> redirectResponse <NSURLResponse http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, http status code 301>
+frame "0" - didReceiveServerRedirectForProvisionalLoadForFrame
+http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - willCacheResponse: called
+http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - didReceiveResponse <NSURLResponse http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true, http status code 200>
+frame "0" - didCommitLoadForFrame
+frame "0" - didFinishDocumentLoadForFrame
+frame "1" - didStartProvisionalLoadForFrame
+about:blank - willSendRequest <NSURLRequest URL about:blank, main document URL http://127.0.0.1:8000/loading/redirect-methods.html, http method GET> redirectResponse (null)
+about:blank - didReceiveResponse <NSURLResponse about:blank, http status code 0>
+frame "1" - didCommitLoadForFrame
+frame "1" - didFinishDocumentLoadForFrame
+frame "1" - didHandleOnloadEventsForFrame
+frame "1" - didFinishLoadForFrame
+about:blank - didFinishLoading
+frame "1" - willPerformClientRedirectToURL: http://127.0.0.1:8000/loading/resources/redirect-methods-form.html 
+frame "0" - didHandleOnloadEventsForFrame
+frame "0" - didFinishLoadForFrame
+http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - didFinishLoading
+frame "1" - didStartProvisionalLoadForFrame
+http://127.0.0.1:8000/loading/resources/redirect-methods-form.html - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/redirect-methods-form.html, main document URL http://127.0.0.1:8000/loading/redirect-methods.html, http method GET> redirectResponse (null)
+http://127.0.0.1:8000/loading/resources/redirect-methods-form.html - didReceiveResponse <NSURLResponse http://127.0.0.1:8000/loading/resources/redirect-methods-form.html, http status code 200>
+frame "1" - didCancelClientRedirectForFrame
+frame "1" - didCommitLoadForFrame
+frame "1" - didFinishDocumentLoadForFrame
+frame "1" - didHandleOnloadEventsForFrame
+frame "1" - didFinishLoadForFrame
+http://127.0.0.1:8000/loading/resources/redirect-methods-form.html - didFinishLoading
+frame "1" - didStartProvisionalLoadForFrame
+http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, main document URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, http method POST> redirectResponse (null)
+http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true, main document URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, http method GET> redirectResponse <NSURLResponse http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, http status code 302>
+frame "1" - didReceiveServerRedirectForProvisionalLoadForFrame
+http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - willCacheResponse: called
+http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - didReceiveResponse <NSURLResponse http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true, http status code 200>
+frame "1" - didCommitLoadForFrame
+frame "1" - didFinishDocumentLoadForFrame
+frame "2" - didStartProvisionalLoadForFrame
+about:blank - willSendRequest <NSURLRequest URL about:blank, main document URL http://127.0.0.1:8000/loading/redirect-methods.html, http method GET> redirectResponse (null)
+about:blank - didReceiveResponse <NSURLResponse about:blank, http status code 0>
+frame "2" - didCommitLoadForFrame
+frame "2" - didFinishDocumentLoadForFrame
+frame "2" - didHandleOnloadEventsForFrame
+frame "2" - didFinishLoadForFrame
+about:blank - didFinishLoading
+frame "2" - willPerformClientRedirectToURL: http://127.0.0.1:8000/loading/resources/redirect-methods-form.html 
+frame "1" - didHandleOnloadEventsForFrame
+frame "1" - didFinishLoadForFrame
+http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - didFinishLoading
+frame "2" - didStartProvisionalLoadForFrame
+http://127.0.0.1:8000/loading/resources/redirect-methods-form.html - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/redirect-methods-form.html, main document URL http://127.0.0.1:8000/loading/redirect-methods.html, http method GET> redirectResponse (null)
+http://127.0.0.1:8000/loading/resources/redirect-methods-form.html - didReceiveResponse <NSURLResponse http://127.0.0.1:8000/loading/resources/redirect-methods-form.html, http status code 200>
+frame "2" - didCancelClientRedirectForFrame
+frame "2" - didCommitLoadForFrame
+frame "2" - didFinishDocumentLoadForFrame
+frame "2" - didHandleOnloadEventsForFrame
+frame "2" - didFinishLoadForFrame
+http://127.0.0.1:8000/loading/resources/redirect-methods-form.html - didFinishLoading
+frame "2" - didStartProvisionalLoadForFrame
+http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, main document URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, http method POST> redirectResponse (null)
+http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true, main document URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, http method GET> redirectResponse <NSURLResponse http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, http status code 303>
+frame "2" - didReceiveServerRedirectForProvisionalLoadForFrame
+http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - willCacheResponse: called
+http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - didReceiveResponse <NSURLResponse http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true, http status code 200>
+frame "2" - didCommitLoadForFrame
+frame "2" - didFinishDocumentLoadForFrame
+frame "3" - didStartProvisionalLoadForFrame
+about:blank - willSendRequest <NSURLRequest URL about:blank, main document URL http://127.0.0.1:8000/loading/redirect-methods.html, http method GET> redirectResponse (null)
+about:blank - didReceiveResponse <NSURLResponse about:blank, http status code 0>
+frame "3" - didCommitLoadForFrame
+frame "3" - didFinishDocumentLoadForFrame
+frame "3" - didHandleOnloadEventsForFrame
+frame "3" - didFinishLoadForFrame
+about:blank - didFinishLoading
+frame "3" - willPerformClientRedirectToURL: http://127.0.0.1:8000/loading/resources/redirect-methods-form.html 
+frame "2" - didHandleOnloadEventsForFrame
+frame "2" - didFinishLoadForFrame
+http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - didFinishLoading
+frame "3" - didStartProvisionalLoadForFrame
+http://127.0.0.1:8000/loading/resources/redirect-methods-form.html - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/redirect-methods-form.html, main document URL http://127.0.0.1:8000/loading/redirect-methods.html, http method GET> redirectResponse (null)
+http://127.0.0.1:8000/loading/resources/redirect-methods-form.html - didReceiveResponse <NSURLResponse http://127.0.0.1:8000/loading/resources/redirect-methods-form.html, http status code 200>
+frame "3" - didCancelClientRedirectForFrame
+frame "3" - didCommitLoadForFrame
+frame "3" - didFinishDocumentLoadForFrame
+frame "3" - didHandleOnloadEventsForFrame
+frame "3" - didFinishLoadForFrame
+http://127.0.0.1:8000/loading/resources/redirect-methods-form.html - didFinishLoading
+frame "3" - didStartProvisionalLoadForFrame
+http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, main document URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, http method POST> redirectResponse (null)
+http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - willSendRequest <NSURLRequest URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true, main document URL http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, http method POST> redirectResponse <NSURLResponse http://127.0.0.1:8000/loading/resources/redirect-methods-result.php, http status code 307>
+frame "3" - didReceiveServerRedirectForProvisionalLoadForFrame
+http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - willCacheResponse: called
+http://127.0.0.1:8000/loading/resources/redirect-methods-result.php - didReceiveResponse <NSURLResponse http://127.0.0.1:8000/loading/resources/redirect-methods-result.php?redirected=true, http status code 200>
+frame "3" - didCommitLoadForFrame
+frame "3" - didFinishDocumentLoadForFrame
+frame "3" - didHandleOnloadEventsForFrame
+frame "3" - didFinishLoadForFrame
+This test checks to see what HTTP method is used to fetch the final resource in the case where the first request results in a redirect.
+301, 302, 303, and 307 http redirects are all tested.
+
diff --git a/LayoutTests/http/tests/loading/redirect-methods.html b/LayoutTests/http/tests/loading/redirect-methods.html
new file mode 100644 (file)
index 0000000..d4497b0
--- /dev/null
@@ -0,0 +1,57 @@
+<html>
+<script>
+if (window.layoutTestController) {
+    layoutTestController.dumpAsText();
+    layoutTestController.dumpResourceLoadCallbacks();
+    layoutTestController.waitUntilDone();
+}
+
+function startTest()
+{
+    window.setTimeout("createFrame(0);", 0);
+}
+
+var testCodes = [301, 302, 303, 307];
+
+function createFrame(index)
+{
+    var iframe = document.createElement("iframe");
+    iframe.setAttribute("testCode", testCodes[index]);
+    iframe.setAttribute("id", index);
+    document.body.appendChild(iframe);
+    iframe.src="resources/redirect-methods-form.html";
+    iframe.setAttribute("onload", "iframeLoaded(" + index + ");");
+}
+
+function iframeLoaded(frameID)
+{
+    var iframe = document.getElementById(frameID);
+    if (iframe.hasAttribute("submitted")) {
+        if (++frameID == testCodes.length) {
+            if (window.layoutTestController)
+                layoutTestController.notifyDone();
+            return;
+        }
+        createFrame(frameID);
+    } else {
+        submitFormForFrame(iframe);
+    }
+}
+
+function submitFormForFrame(iframe)
+{
+    var testInput = iframe.contentDocument.getElementById("testFormInput");
+    testInput.value = iframe.getAttribute("testCode");
+    var testForm = iframe.contentDocument.getElementById("testForm");
+    iframe.setAttribute("submitted", "true");
+    testForm.submit();
+}
+
+</script>
+</head>
+<body onload="startTest();">
+This test checks to see what HTTP method is used to fetch the final resource in the case where the first request results in a redirect.<br>
+301, 302, 303, and 307 http redirects are all tested.<br>
+
+</body>
+</html>
diff --git a/LayoutTests/http/tests/loading/resources/redirect-methods-form.html b/LayoutTests/http/tests/loading/resources/redirect-methods-form.html
new file mode 100644 (file)
index 0000000..db5c3d3
--- /dev/null
@@ -0,0 +1,7 @@
+<html>
+<body>
+<form id="testForm" action="redirect-methods-result.php" method="POST">
+<input id="testFormInput" type="radio" name="status" checked>
+</form>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/loading/resources/redirect-methods-result.php b/LayoutTests/http/tests/loading/resources/redirect-methods-result.php
new file mode 100644 (file)
index 0000000..775ed30
--- /dev/null
@@ -0,0 +1,8 @@
+<?php
+$status = (int)$_REQUEST['status'];
+if ($status > 200 && !$_GET['redirected']) {
+  header("Location: redirect-methods-result.php?redirected=true", TRUE, $status);
+  exit();
+}
+?>
+This page loaded using the <?php echo $_SERVER['REQUEST_METHOD'] ?> method.
index 559ea3dee2f924d5e5303f85816b676e1fb1f1df..53c9d30c6deec9ed6ed37314e45f1213cdd993bb 100644 (file)
@@ -1,3 +1,18 @@
+2009-07-29  Brady Eidson  <beidson@apple.com>
+
+        Reviewed by Sam Weinig.
+
+        https://bugs.webkit.org/show_bug.cgi?id=27791
+        307 redirects of POSTs should use POST, not GET
+
+        Test: http/tests/loading/redirect-methods.html
+
+        * platform/network/cf/ResourceHandleCFNet.cpp:
+        (WebCore::willSendRequest):
+
+        * platform/network/mac/ResourceHandleMac.mm:
+        (-[WebCoreResourceHandleAsDelegate connection:willSendRequest:redirectResponse:]):
+
 2009-07-29  Chris Marrin  <cmarrin@apple.com>
 
         Reviewed by Simon Fraser.
index dbcc9c83647d969fadbb4e6219b9254bda86628d..e348f83f56663988d359e9ada49ffb7df2f7f413 100644 (file)
@@ -116,7 +116,22 @@ CFURLRequestRef willSendRequest(CFURLConnectionRef conn, CFURLRequestRef cfReque
 
     LOG(Network, "CFNet - willSendRequest(conn=%p, handle=%p) (%s)", conn, handle, handle->request().url().string().utf8().data());
 
-    ResourceRequest request(cfRequest);
+    ResourceRequest request;
+    if (cfRedirectResponse) {
+        CFHTTPMessageRef httpMessage = CFURLResponseGetHTTPResponse(cfRedirectResponse);
+        if (httpMessage && CFHTTPMessageGetResponseStatusCode(httpMessage) == 307) {
+            RetainPtr<CFStringRef> originalMethod(AdoptCF, handle->request().httpMethod().createCFString());
+            RetainPtr<CFStringRef> newMethod(AdoptCF, CFURLRequestCopyHTTPRequestMethod(cfRequest));
+            if (CFStringCompareWithOptions(originalMethod.get(), newMethod.get(), CFRangeMake(0, CFStringGetLength(originalMethod.get())), kCFCompareCaseInsensitive)) {
+                RetainPtr<CFMutableURLRequestRef> mutableRequest(AdoptCF, CFURLRequestCreateMutableCopy(0, cfRequest));
+                CFURLRequestSetHTTPRequestMethod(mutableRequest.get(), originalMethod.get());
+                request = mutableRequest.get();
+            }
+        }
+    }
+    if (request.isNull())
+        request = cfRequest;
+    
     handle->willSendRequest(request, cfRedirectResponse);
 
     if (request.isNull())
index dc16e23186f3d1be592a3c1b3d43eca1ccde37e8..db76d1acab8fe5c81ddd7a028b9be5598c443de8 100644 (file)
@@ -567,6 +567,15 @@ void ResourceHandle::receivedCancellation(const AuthenticationChallenge& challen
     
     LOG(Network, "Handle %p delegate connection:%p willSendRequest:%@ redirectResponse:%p", m_handle, connection, [newRequest description], redirectResponse);
 
+    if (redirectResponse && [redirectResponse isKindOfClass:[NSHTTPURLResponse class]] && [(NSHTTPURLResponse *)redirectResponse statusCode] == 307) {
+        String originalMethod = m_handle->request().httpMethod();
+        if (!equalIgnoringCase(originalMethod, String([newRequest HTTPMethod]))) {
+            NSMutableURLRequest *mutableRequest = [newRequest mutableCopy];
+            [mutableRequest setHTTPMethod:originalMethod];
+            newRequest = [mutableRequest autorelease];
+        }
+    }
+
     CallbackGuard guard;
     ResourceRequest request = newRequest;
     m_handle->willSendRequest(request, redirectResponse);