Changeset 163022 in webkit


Ignore:
Timestamp:
Jan 29, 2014 9:03:59 AM (10 years ago)
Author:
commit-queue@webkit.org
Message:

Source/WebCore: Have XHR.getResponseHeader() return null and XHR.getAllResponseHeader() return the empty string in initial ready states
https://bugs.webkit.org/show_bug.cgi?id=125840

Patch by Youenn Fablet <youennf@gmail.com> on 2014-01-29
Reviewed by Alexey Proskuryakov.

Merging https://chromium.googlesource.com/chromium/blink/+/d201caf874a0bd6f101f517462b3cf1d8c5fce3d
This patch makes it clear that null/empty string is returned whenever the error flag is set.
This new code path is covered by the added test.

Test: http/tests/xmlhttprequest/response-access-on-error.html

  • xml/XMLHttpRequest.cpp:

(WebCore::XMLHttpRequest::getAllResponseHeaders):
(WebCore::XMLHttpRequest::getResponseHeader):

  • xml/XMLHttpRequest.h:
  • xml/XMLHttpRequest.idl:

LayoutTests: Have XHR.getResponseHeader() return null and XHR.getAllResponseHeaders() return empty string in initial ready states
https://bugs.webkit.org/show_bug.cgi?id=125840

Patch by Youenn Fablet <youennf@gmail.com> on 2014-01-29
Reviewed by Alexey Proskuryakov.

Merging https://chromium.googlesource.com/chromium/blink/+/d201caf874a0bd6f101f517462b3cf1d8c5fce3d
The new test exercices the new code path in case xhr received HTTP headers but m_error is set

  • http/tests/xmlhttprequest/getAllResponseHeaders-expected.txt:
  • http/tests/xmlhttprequest/getAllResponseHeaders.html:
  • http/tests/xmlhttprequest/getResponseHeader-expected.txt:
  • http/tests/xmlhttprequest/getResponseHeader.html:
  • http/tests/xmlhttprequest/response-access-on-error-expected.txt: Added.
  • http/tests/xmlhttprequest/response-access-on-error.html: Added.
Location:
trunk
Files:
2 added
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r163021 r163022  
     12014-01-29  Youenn Fablet  <youennf@gmail.com>
     2
     3        Have XHR.getResponseHeader() return null and XHR.getAllResponseHeaders() return empty string in initial ready states
     4        https://bugs.webkit.org/show_bug.cgi?id=125840
     5
     6        Reviewed by Alexey Proskuryakov.
     7
     8        Merging https://chromium.googlesource.com/chromium/blink/+/d201caf874a0bd6f101f517462b3cf1d8c5fce3d
     9        The new test exercices the new code path in case xhr received HTTP headers but m_error is set
     10
     11        * http/tests/xmlhttprequest/getAllResponseHeaders-expected.txt:
     12        * http/tests/xmlhttprequest/getAllResponseHeaders.html:
     13        * http/tests/xmlhttprequest/getResponseHeader-expected.txt:
     14        * http/tests/xmlhttprequest/getResponseHeader.html:
     15        * http/tests/xmlhttprequest/response-access-on-error-expected.txt: Added.
     16        * http/tests/xmlhttprequest/response-access-on-error.html: Added.
     17
    1182014-01-29  Antti Koivisto  <antti@apple.com>
    219
  • trunk/LayoutTests/http/tests/xmlhttprequest/getAllResponseHeaders-expected.txt

    r48433 r163022  
    1 Test page for bug 15356 and bug 29121
     1Test the required behavior of XMLHttpRequest.getAllResponseHeaders()
    22
    3 Assertion: Invoking getAllResponseHeaders method when readyState >= 2 (HEADERS_RECEIVED) should return a conforming list of headers.
     3On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
    44
    5 PASSED 0
    6 PASSED 1
    7 PASSED 2: getAllResponseHeaders returned what looks like a conforming headerlist.
    8 PASSED 3
    9 PASSED 4
    105
     6PASS {state: 0}; headerValues = xhr.getAllResponseHeaders(); did not throw exception.
     7PASS headerValues is the empty string
     8PASS {state: 1}; headerValues = xhr.getAllResponseHeaders(); did not throw exception.
     9PASS headerValues is the empty string
     10PASS getAllResponseHeaders() result is empty in ready state 1.
     11PASS xhr.open("GET", "resources/1251.html", true); did not throw exception.
     12PASS {state: 1}; headerValues = xhr.getAllResponseHeaders(); did not throw exception.
     13PASS headerValues is the empty string
     14PASS xhr.send(null); did not throw exception.
     15PASS {state: 2}; headerValues = xhr.getAllResponseHeaders(); did not throw exception.
     16PASS headerValues is not the empty string
     17PASS Header values appears to be conforming.
     18PASS {state: 3}; headerValues = xhr.getAllResponseHeaders(); did not throw exception.
     19PASS headerValues is not the empty string
     20PASS responseHeaders is savedHeaders
     21PASS {state: 4}; headerValues = xhr.getAllResponseHeaders(); did not throw exception.
     22PASS headerValues is not the empty string
     23PASS responseHeaders is savedHeaders
     24PASS successfullyParsed is true
     25
     26TEST COMPLETE
     27
  • trunk/LayoutTests/http/tests/xmlhttprequest/getAllResponseHeaders.html

    r120167 r163022  
     1<!doctype html>
    12<html>
    23<head>
    3     <title>Check exception thrown by getAllResponseHeaders and some
    4     characteristics of the return value</title>
     4<title>Testing XMLHttpRequest.getReponseHeader behavior</title>
     5<script src="/js-test-resources/js-test-pre.js"></script>
    56<script type="text/javascript">
     7description("Test the required behavior of XMLHttpRequest.getAllResponseHeaders()");
    68
    7 function log (msg) {
    8     var paragraph = document.createElement("li");
    9     paragraph.innerHTML=msg.replace(/\n/gm,"<br>");
    10     document.getElementById("console").appendChild(paragraph);
     9window.jsTestIsAsync = true;
     10
     11var xhr = new XMLHttpRequest();
     12
     13var savedHeaders = null;
     14
     15var headerValues;
     16function testGetAllResponseHeaders(xhr, expectEmpty) {
     17    shouldNotThrow("{state: " + xhr.readyState + "}; headerValues = xhr.getAllResponseHeaders();");
     18    if (expectEmpty && headerValues !== "")
     19        testFailed("Expected the empty string, got: '" + headerValues + "'");
     20    else
     21        testPassed("headerValues is " + (!expectEmpty ? "not " : "") + "the empty string");
     22    return headerValues;
    1123}
    1224
    13 var xhr;
     25var responseHeaders;
     26xhr.onreadystatechange = function() {
     27    var rState = this.readyState;
     28    responseHeaders = testGetAllResponseHeaders(this, rState <= XMLHttpRequest.OPENED);
     29    if (responseHeaders) {
     30        if (savedHeaders) {
     31            shouldBe("responseHeaders", "savedHeaders");
     32        } else {
     33            if (/^Set-Cookie:|^Set-Cookie2:/im.test(responseHeaders)) {
     34                testFailed("Did not expect to find a Set-Cookie{2} header, got: '" + responseHeaders + "'");
     35            } else {
     36                // Do not print list for automated tests to avoid false failures.
     37                if (self.testRunner)
     38                    testPassed("Header values appears to be conforming.");
     39                else
     40                    testPassed("Header values appears ok: " + JSON.stringify(headerValues));
     41            }
     42        }
     43        savedHeaders = responseHeaders;
     44    } else {
     45        if (rState > XMLHttpRequest.OPENED)
     46            testFailed("In ready state " + rState + ", unexpected empty value.");
     47        else if (responseHeaders !== "")
     48            testFailed("In ready state " + rState + ", expected the empty string, got: " + JSON.stringify(responseHeaders) + ".");
     49        else
     50            testPassed("getAllResponseHeaders() result is empty in ready state " + rState + ".");
     51    }
    1452
    15 if (window.XMLHttpRequest) {
    16     xhr = new XMLHttpRequest();
    17 } else {
    18     try {
    19         xhr = new ActiveXObject("Msxml2.XMLHTTP");
    20     } catch (ex) {
    21         xhr = new ActiveXObject("Microsoft.XMLHTTP");
    22     }
     53    if (rState == XMLHttpRequest.DONE)
     54        finishJSTest();
    2355}
    2456
    25 var savedHeader = null;
    26 xhr.onreadystatechange = function() {
    27     var rState = this.readyState;
    28     // We expect an INVALID_STATE_ERR exception for readyState < 2
    29     // and no exception for readyState >= 2
    30     try {
    31         var header = this.getAllResponseHeaders();
    32         if (rState != this.readyState)
    33             log("UNCERTAIN " + rState + ": readyState changed while getting headers.");
    34         if (rState < 2) {
    35             log("FAILED " + rState + ": headerlist=" + header);
    36         } else if (header)
    37             if (savedHeader)
    38                 if (savedHeader != header) {
    39                     log("FAILED " + rState +
    40 ": headerlist changed after it was first returned. Previous header list:\n"
    41 + savedHeader + "\n New headerlist:\n" + header);
    42                 savedHeader = header;
    43                 }
    44                 else //savedHeader == header here; no need to reprint header
    45                     log("PASSED " + rState);
    46             else {//first header list retrieved
    47                 if (/^Set-Cookie:|^Set-Cookie2:/im.test(header))
    48                     log("FAILED " + rState +
    49 ": /^Set-Cookie:|^Set-Cookie2:/ matches. getAllResponseHeaders returned:\n" + header);
    50                 else if (window.testRunner)
    51 //do not print list for automated tests to avoid false failures.
    52                     log("PASSED " + rState +
    53 ": getAllResponseHeaders returned what looks like a conforming headerlist.");
    54                 else
    55                     log("PASSED " + rState +
    56 ": getAllResponseHeaders returned:\n" + header);
    57                 savedHeader = header;
    58             }
    59         else //header is null
    60             log("FAILED " + rState + ": null header list returned");
    61     } catch (e) {
    62         if (rState < 2) {
    63             log("PASSED " + rState);
    64         } else {
    65             log("FAILED " + rState + ": EXCEPTION THROWN: " + e.message + ".");
    66         }
    67     }
    68     if ((rState == 4) && (window.testRunner))
    69             testRunner.notifyDone();
     57function runTest() {
     58    // Test for readyState = 0
     59    testGetAllResponseHeaders(xhr, true);
     60    shouldNotThrow('xhr.open("GET", "resources/1251.html", true);');
     61    // Test for readyState = 1
     62    testGetAllResponseHeaders(xhr, true);
     63    shouldNotThrow("xhr.send(null);");
    7064}
    71 
    72 function test() {
    73     if (window.testRunner) {
    74         testRunner.waitUntilDone();
    75         testRunner.dumpAsText();
    76     }
    77     // Test for readyState = 0
    78     try {
    79         var header = xhr.getAllResponseHeaders();
    80         log("FAILED " + xhr.readyState + ": header=" + header);
    81     } catch (e) {
    82         log("PASSED " + xhr.readyState);
    83     }
    84     try {
    85         xhr.open("GET","resources/1251.html", true);
    86         xhr.send(null);
    87     } catch(e) {
    88         log("FAILED open/send: EXCEPTION THROWN: " + e.message +".");
    89         if (window.testRunner)
    90             testRunner.notifyDone();
    91     }
    92 }
     65runTest();
    9366</script>
     67<script src="/js-test-resources/js-test-post.js"></script>
    9468</head>
    95 <body onload="test()">
    96 
    97 <p>Test page for <a href="http://bugs.webkit.org/show_bug.cgi?id=15356">bug 15356</a>
    98 and <a href="http://bugs.webkit.org/show_bug.cgi?id=29121">bug 29121</a></p>
    99 <p>Assertion: Invoking getAllResponseHeaders method when readyState >= 2
    100 (HEADERS_RECEIVED) should return a conforming list of headers.</p>
    101 <script>
    102     if (!window.testRunner)
    103         document.write("<p>If the test passes one should see \
    104 below the ruler the text \"passed\" in all capital letters, 5 times, \
    105 followed each time by a space and the readyState number.</p>\n\
    106 <p>ReadyStatenumbers should be in ascending order 0 to 4.</p>\n\
    107 <p>A conforming list of response headers should also be printed.</p>\n\
    108 <p>A conforming list of headers:</p> \
    109    <li> contains one header per line.</li> \
    110    <li> has header names and header values separated by a COLON and \
    111 a SPACE.</li>\
    112    <li> does not contain any headers that match (case-insensitively) \
    113 Set-Cookie or Set-Cookie2</li>");
    114  </script>
    115  <hr>
    116  <p><ol id=console></ol></p>
    117 </body>
    11869</html>
  • trunk/LayoutTests/http/tests/xmlhttprequest/getResponseHeader-expected.txt

    r104803 r163022  
    55CONSOLE MESSAGE: Refused to get unsafe header "SeT-COoKie"
    66CONSOLE MESSAGE: Refused to get unsafe header "sEt-coOkIE2"
    7 Test page for bug 15356 and bug 29121
     7Test the required behavior of XMLHttpRequest.getResponseHeader()
    88
    9 Assertion: Invoking the getResponseHeader method when readyState >= 2 (HEADERS_RECEIVED) returns a header value if the header exists.
     9On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
    1010
    11 Assertion: Invoking the getResponseHeader method with the parameter satisfying the following conditions causes getResponseHeader to return null:
    1211
    13 1a. The parameter case-insensitively matches Set-Cookie;
    14 1b. The parameter case-insensitively matches Set-Cookie2;
    15 2. The parameter does not match any header in the response;
    16 3a. The parameter is null (it is not a valid header name);
    17 3b. The parameter is "Content-Type:" (it is not a valid header name).
    18 PASSED 0 Content-Type: exception thrown.
    19 PASSED 1 Content-Type: exception thrown
    20 PASSED 2 Content-Type: ResponseHeader(Content-Type) returned a value.
    21 PASSED 2 SeT-COoKie: getResponseHeader(SeT-COoKie) returned null.
    22 PASSED 2 sEt-coOkIE2: getResponseHeader(sEt-coOkIE2) returned null.
    23 PASSED 2 xxx-mytest-headerabc: getResponseHeader(xxx-mytest-headerabc) returned null.
    24 PASSED 2 null: getResponseHeader(null) returned null.
    25 PASSED 2 Content-Type:: getResponseHeader(Content-Type:) returned null.
    26 PASSED 3 Content-Type: Content-Type
    27 PASSED 3 SeT-COoKie: getResponseHeader(SeT-COoKie) returned null.
    28 PASSED 3 sEt-coOkIE2: getResponseHeader(sEt-coOkIE2) returned null.
    29 PASSED 3 xxx-mytest-headerabc: getResponseHeader(xxx-mytest-headerabc) returned null.
    30 PASSED 3 null: getResponseHeader(null) returned null.
    31 PASSED 3 Content-Type:: getResponseHeader(Content-Type:) returned null.
    32 PASSED 4 Content-Type: Content-Type
    33 PASSED 4 SeT-COoKie: getResponseHeader(SeT-COoKie) returned null.
    34 PASSED 4 sEt-coOkIE2: getResponseHeader(sEt-coOkIE2) returned null.
    35 PASSED 4 xxx-mytest-headerabc: getResponseHeader(xxx-mytest-headerabc) returned null.
    36 PASSED 4 null: getResponseHeader(null) returned null.
    37 PASSED 4 Content-Type:: getResponseHeader(Content-Type:) returned null.
     12PASS {state: 0}; headerValue = xhr.getResponseHeader('Content-Type'); did not throw exception.
     13PASS headerValue is null
     14PASS {state: 1}; headerValue = xhr.getResponseHeader('Content-Type'); did not throw exception.
     15PASS headerValue is null
     16PASS Header 'Content-Type' is null in ready state 1.
     17PASS xhr.open("GET", "resources/1251.html", true); did not throw exception.
     18PASS {state: 1}; headerValue = xhr.getResponseHeader('Content-Type'); did not throw exception.
     19PASS headerValue is null
     20PASS xhr.send(null); did not throw exception.
     21PASS {state: 2}; headerValue = xhr.getResponseHeader('Content-Type'); did not throw exception.
     22PASS headerValue is non-null.
     23PASS {state: 2}; headerValue = xhr.getResponseHeader('SeT-COoKie'); did not throw exception.
     24PASS headerValue is null
     25PASS {state: 2}; headerValue = xhr.getResponseHeader('sEt-coOkIE2'); did not throw exception.
     26PASS headerValue is null
     27PASS {state: 2}; headerValue = xhr.getResponseHeader('xxx-mytest-headerabc'); did not throw exception.
     28PASS headerValue is null
     29PASS {state: 2}; headerValue = xhr.getResponseHeader('null'); did not throw exception.
     30PASS headerValue is null
     31PASS {state: 2}; headerValue = xhr.getResponseHeader('Content-Type:'); did not throw exception.
     32PASS headerValue is null
     33PASS {state: 3}; headerValue = xhr.getResponseHeader('Content-Type'); did not throw exception.
     34PASS headerValue is non-null.
     35PASS result is savedHeader
     36PASS {state: 3}; headerValue = xhr.getResponseHeader('SeT-COoKie'); did not throw exception.
     37PASS headerValue is null
     38PASS {state: 3}; headerValue = xhr.getResponseHeader('sEt-coOkIE2'); did not throw exception.
     39PASS headerValue is null
     40PASS {state: 3}; headerValue = xhr.getResponseHeader('xxx-mytest-headerabc'); did not throw exception.
     41PASS headerValue is null
     42PASS {state: 3}; headerValue = xhr.getResponseHeader('null'); did not throw exception.
     43PASS headerValue is null
     44PASS {state: 3}; headerValue = xhr.getResponseHeader('Content-Type:'); did not throw exception.
     45PASS headerValue is null
     46PASS {state: 4}; headerValue = xhr.getResponseHeader('Content-Type'); did not throw exception.
     47PASS headerValue is non-null.
     48PASS result is savedHeader
     49PASS {state: 4}; headerValue = xhr.getResponseHeader('SeT-COoKie'); did not throw exception.
     50PASS headerValue is null
     51PASS {state: 4}; headerValue = xhr.getResponseHeader('sEt-coOkIE2'); did not throw exception.
     52PASS headerValue is null
     53PASS {state: 4}; headerValue = xhr.getResponseHeader('xxx-mytest-headerabc'); did not throw exception.
     54PASS headerValue is null
     55PASS {state: 4}; headerValue = xhr.getResponseHeader('null'); did not throw exception.
     56PASS headerValue is null
     57PASS {state: 4}; headerValue = xhr.getResponseHeader('Content-Type:'); did not throw exception.
     58PASS headerValue is null
     59PASS successfullyParsed is true
    3860
     61TEST COMPLETE
     62
  • trunk/LayoutTests/http/tests/xmlhttprequest/getResponseHeader.html

    r120167 r163022  
     1<!doctype html>
    12<html>
    23<head>
    3     <title>Check exception thrown by getReponseHeader </title>
     4<title>Testing XMLHttpRequest.getReponseHeader behavior</title>
     5<script src="/js-test-resources/js-test-pre.js"></script>
    46<script type="text/javascript">
     7description("Test the required behavior of XMLHttpRequest.getResponseHeader()");
     8
     9window.jsTestIsAsync = true;
    510
    611var savedHeader = null;
    7 var headerName="Content-Type";
    8 var nullTests =  new Array("SeT-COoKie", "sEt-coOkIE2",
    9     "xxx-mytest-headerabc", null, "Content-Type:");
     12var headerName = "Content-Type";
     13var nullTests = [ "SeT-COoKie",
     14                  "sEt-coOkIE2",
     15                  "xxx-mytest-headerabc",
     16                  null,
     17                  "Content-Type:" ];
    1018
    11 function log (msg) {
    12     var paragraph = document.createElement("li");
    13     paragraph.innerHTML=msg.replace(/\n/gm,"<br>");
    14     document.getElementById("console").appendChild(paragraph);
     19var xhr = new XMLHttpRequest();
     20
     21var headerValue;
     22function testGetResponseHeader(xhr, headerName, expectNull) {
     23    shouldNotThrow("{state: " + xhr.readyState + "}; headerValue = xhr.getResponseHeader('" + headerName + "');");
     24    if (expectNull)
     25        shouldBeNull("headerValue");
     26    else
     27        shouldBeNonNull("headerValue");
     28
     29    return headerValue;
    1530}
    1631
    17 function log4(status, rState, subState, msg) {
    18     log(status + " " + rState + " " + subState + ": " + msg);
     32var result;
     33xhr.onreadystatechange = function() {
     34    var rState = this.readyState;
     35    result = testGetResponseHeader(this, headerName, rState <= XMLHttpRequest.OPENED);
     36    if (result) {
     37        if (savedHeader)
     38            shouldBe("result", "savedHeader");
     39
     40        savedHeader = result;
     41
     42        for (var i = 0; i < nullTests.length; ++i)
     43            testGetResponseHeader(this, nullTests[i], true);
     44    } else {
     45        if (rState > XMLHttpRequest.OPENED)
     46            testFailed("In ready state " + rState + ", unexpected null value for '" + headerName + "'.");
     47        else if (result !== null)
     48            testFailed("In ready state " + rState + ", expected null for '" + headerName + ", got: " + JSON.stringify(result) + ".");
     49        else
     50            testPassed("Header '" + headerName + "' is null in ready state " + rState + ".");
     51    }
     52
     53    if (rState == XMLHttpRequest.DONE)
     54        finishJSTest();
    1955}
    2056
    21 function log3(status, rState, msg) {
    22     log4(status, rState, headerName, msg);
     57function runTest() {
     58    // Test for readyState = 0
     59    testGetResponseHeader(xhr, headerName, true);
     60    shouldNotThrow('xhr.open("GET", "resources/1251.html", true);');
     61    // Test for readyState = 1
     62    testGetResponseHeader(xhr, headerName, true);
     63    shouldNotThrow("xhr.send(null);");
    2364}
    24 
    25 if (window.XMLHttpRequest) {
    26     xhr = new XMLHttpRequest();
    27 } else {
    28     try {
    29         xhr = new ActiveXObject("Msxml2.XMLHTTP");
    30     } catch (ex) {
    31         xhr = new ActiveXObject("Microsoft.XMLHTTP");
    32     }
    33 }
    34 
    35 xhr.onreadystatechange = function() {
    36     var rState = this.readyState;
    37     // We expect an INVALID_STATE_ERR exception for readyState < 2
    38     // and no exception for readyState >= 2
    39     try {
    40         var header = this.getResponseHeader(headerName);
    41         if (rState != this.readyState)
    42             log3("UNCERTAIN", rState, "readyState changed while getting the header.");
    43         if (rState < 2) {
    44             log3("FAILED", rState, headerName + "=" + header);
    45         } else if (header) {
    46             if (savedHeader)
    47                 if (savedHeader != header) {
    48                     log3("FAILED", rState,headerName + " changed after it was first returned. Previous " + headerName
    49                         + "=" + savedHeader + "; New " + headerName + "=" + header + ".");
    50                 savedHeader = header;
    51                 }
    52                 else //savedHeader == header here; no need to reprint header
    53                     log3("PASSED", rState, headerName);
    54             else {//first header value retrieved
    55                 if (window.testRunner)
    56 //do not print the header's value for automated tests to avoid false failures.
    57                     log3("PASSED", rState, "ResponseHeader(" + headerName + ") returned a value.");
    58                 else
    59                     log3("PASSED", rState, "getResponseHeader(" + headerName + ") returned: " + header + ".");
    60                 savedHeader = header;
    61             }
    62             for (var i=0;i<nullTests.length;++i) {
    63                 try {
    64                     var str = this.getResponseHeader(nullTests[i]);
    65                     if (str == null)
    66                         log4("PASSED", rState, nullTests[i], "getResponseHeader(" + nullTests[i] +
    67                             ") returned null.");
    68                     else
    69                         log4("FAILED", rState, nullTests[i], "getResponseHeader(" + nullTests[i] +
    70                             ") returned \"" + str + "\"");
    71                 } catch(e) {
    72                     log4("FAILED", rState, nullTests[i], "getResponseHeader(" + nullTests[i] + ") threw exception:" + e);
    73                 }
    74             }
    75         }
    76         else //header is null
    77             log3("FAILED", rState, "null " + headerName + " returned.");
    78     } catch (e) {
    79         if (rState < 2)
    80             log3("PASSED", rState, "exception thrown");
    81         else
    82             log3("FAILED", rState, "exception thrown: " + e.message + ".");
    83     }
    84     if ((rState == 4) && (window.testRunner))
    85             testRunner.notifyDone();
    86 }
    87 
    88 if (window.testRunner) {
    89     testRunner.waitUntilDone();
    90     testRunner.dumpAsText();
    91 }
    92 
    93 function test() {
    94     // Test for readyState = 0
    95     try {
    96         var header = xhr.getResponseHeader(headerName);
    97         log3("FAILED", xhr.readyState, headerName + "=" + header + ".");
    98     } catch (e) {
    99         log3("PASSED", xhr.readyState, "exception thrown.");
    100     }
    101     try {
    102         xhr.open("GET","resources/1251.html", true);
    103         xhr.send(null);
    104     } catch(e) {
    105         log3("FAILED", "open/send", "exception thrown: " + e.message +".");
    106         if (window.testRunner)
    107             testRunner.notifyDone();
    108     }
    109 }
     65runTest();
    11066</script>
     67<script src="/js-test-resources/js-test-post.js"></script>
    11168</head>
    112 <body onload="test()">
    113 
    114 <p>Test page for <a href="http://bugs.webkit.org/show_bug.cgi?id=15356">bug
    115 15356</a>
    116 and <a href="http://bugs.webkit.org/show_bug.cgi?id=29121">bug 29121</a></p>
    117 <p>Assertion: Invoking the getResponseHeader method when readyState >= 2
    118 (HEADERS_RECEIVED) returns a header value if the header exists.</p>
    119 <p>Assertion: Invoking the getResponseHeader method with the parameter
    120     satisfying the following conditions causes getResponseHeader
    121     to return null:
    122 <li>1a. The parameter case-insensitively matches Set-Cookie;</li>
    123 <li>1b. The parameter case-insensitively matches Set-Cookie2;</li>
    124 <li>2.  The parameter does not match any header in the response;</li>
    125 <li>3a. The parameter is null (it is not a valid header name);</li>
    126 <li>3b. The parameter is "Content-Type:" (it is not a valid header name).</li>
    127 
    128 <script>
    129     if (!window.testRunner)
    130         document.write("<p>If the test passes one should see \
    131 below the ruler the text \"passed\" in all capital letters, once for every ready state &lt; 2, \
    132 followed each time by a space and the readyState number and 6 times for every ready state >= 2.</p>\n\
    133 <p>ReadyState numbers should be in ascending order 0 to 4.</p>\n\
    134 <p>ReadyState numbers should be followed by a blank, the name of the header tested, colon a space and a message.</p>\
    135 <p>The value of the " + headerName + " header should  be printed for ready state 2.</p>");
    136 </script>
    137  <hr>
    138  <p><ol id=console></ol></p>
    139 </body>
    14069</html>
  • trunk/Source/WebCore/ChangeLog

    r163021 r163022  
     12014-01-29  Youenn Fablet  <youennf@gmail.com>
     2
     3        Have XHR.getResponseHeader() return null and XHR.getAllResponseHeader() return the empty string in initial ready states
     4        https://bugs.webkit.org/show_bug.cgi?id=125840
     5
     6        Reviewed by Alexey Proskuryakov.
     7
     8        Merging https://chromium.googlesource.com/chromium/blink/+/d201caf874a0bd6f101f517462b3cf1d8c5fce3d
     9        This patch makes it clear that null/empty string is returned whenever the error flag is set.
     10        This new code path is covered by the added test.
     11       
     12        Test: http/tests/xmlhttprequest/response-access-on-error.html
     13
     14        * xml/XMLHttpRequest.cpp:
     15        (WebCore::XMLHttpRequest::getAllResponseHeaders):
     16        (WebCore::XMLHttpRequest::getResponseHeader):
     17        * xml/XMLHttpRequest.h:
     18        * xml/XMLHttpRequest.idl:
     19
    1202014-01-29  Antti Koivisto  <antti@apple.com>
    221
  • trunk/Source/WebCore/xml/XMLHttpRequest.cpp

    r161891 r163022  
    987987}
    988988
    989 String XMLHttpRequest::getAllResponseHeaders(ExceptionCode& ec) const
    990 {
    991     if (m_state < HEADERS_RECEIVED) {
    992         ec = INVALID_STATE_ERR;
     989String XMLHttpRequest::getAllResponseHeaders() const
     990{
     991    if (m_state < HEADERS_RECEIVED || m_error)
    993992        return "";
    994     }
    995993
    996994    StringBuilder stringBuilder;
     
    10231021}
    10241022
    1025 String XMLHttpRequest::getResponseHeader(const AtomicString& name, ExceptionCode& ec) const
    1026 {
    1027     if (m_state < HEADERS_RECEIVED) {
    1028         ec = INVALID_STATE_ERR;
     1023String XMLHttpRequest::getResponseHeader(const AtomicString& name) const
     1024{
     1025    if (m_state < HEADERS_RECEIVED || m_error)
    10291026        return String();
    1030     }
    10311027
    10321028    // See comment in getAllResponseHeaders above.
  • trunk/Source/WebCore/xml/XMLHttpRequest.h

    r162158 r163022  
    106106    void overrideMimeType(const String& override);
    107107    bool doneWithoutErrors() const { return !m_error && m_state == DONE; }
    108     String getAllResponseHeaders(ExceptionCode&) const;
    109     String getResponseHeader(const AtomicString& name, ExceptionCode&) const;
     108    String getAllResponseHeaders() const;
     109    String getResponseHeader(const AtomicString& name) const;
    110110    String responseText(ExceptionCode&);
    111111    String responseTextIgnoringResponseType() const { return m_responseBuilder.toStringPreserveCapacity(); }
  • trunk/Source/WebCore/xml/XMLHttpRequest.idl

    r161058 r163022  
    8181
    8282    // response
    83     [TreatReturnedNullStringAs=Undefined, RaisesException] DOMString getAllResponseHeaders();
    84     [TreatReturnedNullStringAs=Null, RaisesException] DOMString getResponseHeader(DOMString header);
     83    [TreatReturnedNullStringAs=Undefined] DOMString getAllResponseHeaders();
     84    [TreatReturnedNullStringAs=Null] DOMString getResponseHeader(DOMString header);
    8585    [GetterRaisesException, CustomGetter] readonly attribute DOMString responseText; // The custom getter implements TreatReturnedNullStringAs=Null
    8686    [GetterRaisesException] readonly attribute Document responseXML;
Note: See TracChangeset for help on using the changeset viewer.