author | Masatoshi Kimura <VYV03354@nifty.ne.jp> |
Sun, 19 Feb 2012 11:58:24 +0000 | |
changeset 90450 | 560cfb993c9d5def5c32f94e1e9ae27d46df6dc1 |
parent 90449 | da1dae1b215d59c18db993b042c43e6decd1138e |
child 90451 | 9a6fcf299f29136e446bf9bb4609f0aa1d5d564f |
push id | 136 |
push user | lsblakk@mozilla.com |
push date | Fri, 01 Jun 2012 02:39:32 +0000 |
treeherder | mozilla-release@7ebf7352c959 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jonas |
bugs | 727530 |
milestone | 13.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
content/base/src/nsXMLHttpRequest.cpp | file | annotate | diff | comparison | revisions | |
content/base/test/test_XHR.html | file | annotate | diff | comparison | revisions |
--- a/content/base/src/nsXMLHttpRequest.cpp +++ b/content/base/src/nsXMLHttpRequest.cpp @@ -1319,30 +1319,53 @@ nsXMLHttpRequest::Abort() /* string getAllResponseHeaders (); */ NS_IMETHODIMP nsXMLHttpRequest::GetAllResponseHeaders(char **_retval) { NS_ENSURE_ARG_POINTER(_retval); *_retval = nsnull; + // If the state is UNSENT or OPENED, + // return the empty string and terminate these steps. + if (mState & (XML_HTTP_REQUEST_UNSENT | + XML_HTTP_REQUEST_OPENED | XML_HTTP_REQUEST_SENT)) { + *_retval = ToNewCString(EmptyString()); + return NS_OK; + } + if (mState & XML_HTTP_REQUEST_USE_XSITE_AC) { *_retval = ToNewCString(EmptyString()); return NS_OK; } nsCOMPtr<nsIHttpChannel> httpChannel = GetCurrentHttpChannel(); if (httpChannel) { nsRefPtr<nsHeaderVisitor> visitor = new nsHeaderVisitor(); nsresult rv = httpChannel->VisitResponseHeaders(visitor); if (NS_SUCCEEDED(rv)) *_retval = ToNewCString(visitor->Headers()); + } else if (mChannel) { + // Even non-http channels supply content type. + nsCString value; + if (NS_SUCCEEDED(mChannel->GetContentType(value))) { + nsCString headers; + headers.Append("Content-Type: "); + headers.Append(value); + if (NS_SUCCEEDED(mChannel->GetContentCharset(value)) && + !value.IsEmpty()) { + headers.Append(";charset="); + headers.Append(value); + } + headers.Append('\n'); + *_retval = ToNewCString(headers); + } } - + if (!*_retval) { *_retval = ToNewCString(EmptyString()); } return NS_OK; } /* ACString getResponseHeader (in AUTF8String header); */ @@ -1351,16 +1374,47 @@ nsXMLHttpRequest::GetResponseHeader(cons nsACString& _retval) { nsresult rv = NS_OK; _retval.SetIsVoid(true); nsCOMPtr<nsIHttpChannel> httpChannel = GetCurrentHttpChannel(); if (!httpChannel) { + // If the state is UNSENT or OPENED, + // return null and terminate these steps. + if (mState & (XML_HTTP_REQUEST_UNSENT | + XML_HTTP_REQUEST_OPENED | XML_HTTP_REQUEST_SENT)) { + return NS_OK; + } + + // Even non-http channels supply content type. + // Remember we don't leak header information from denied cross-site + // requests. + nsresult status; + if (!mChannel || + NS_FAILED(mChannel->GetStatus(&status)) || + NS_FAILED(status) || + !header.LowerCaseEqualsASCII("content-type")) { + return NS_OK; + } + + if (NS_FAILED(mChannel->GetContentType(_retval))) { + // Means no content type + _retval.SetIsVoid(true); + return NS_OK; + } + + nsCString value; + if (NS_SUCCEEDED(mChannel->GetContentCharset(value)) && + !value.IsEmpty()) { + _retval.Append(";charset="); + _retval.Append(value); + } + return NS_OK; } // See bug #380418. Hide "Set-Cookie" headers from non-chrome scripts. bool chrome = false; // default to false in case IsCapabilityEnabled fails IsCapabilityEnabled("UniversalXPConnect", &chrome); if (!chrome && (header.LowerCaseEqualsASCII("set-cookie") ||
--- a/content/base/test/test_XHR.html +++ b/content/base/test/test_XHR.html @@ -17,43 +17,52 @@ SimpleTest.waitForExplicitFinish(); var gen = runTests(); function continueTest() { gen.next(); } function runTests() { var path = "/tests/content/base/test/"; -var passFiles = [['file_XHR_pass1.xml', 'GET', 200], - ['file_XHR_pass2.txt', 'GET', 200], - ['file_XHR_pass3.txt', 'GET', 200], - ['data:text/xml,%3Cres%3Ehello%3C/res%3E%0A', 'GET', 0], - ['data:text/plain,hello%20pass%0A', 'GET', 0], +var passFiles = [['file_XHR_pass1.xml', 'GET', 200, 'text/xml'], + ['file_XHR_pass2.txt', 'GET', 200, 'text/plain'], + ['file_XHR_pass3.txt', 'GET', 200, 'text/plain'], + ['data:text/xml,%3Cres%3Ehello%3C/res%3E%0A', 'GET', 0, 'text/xml'], + ['data:text/plain,hello%20pass%0A', 'GET', 0, 'text/plain'], + ['data:,foo', 'GET', 0, 'text/plain;charset=US-ASCII', 'foo'], + ['data:text/plain;base64,Zm9v', 'GET', 0, 'text/plain', 'foo'], + ['data:text/plain,foo#bar', 'GET', 0, 'text/plain', 'foo'], + ['data:text/plain,foo%23bar', 'GET', 0, 'text/plain', 'foo#bar'], ]; var failFiles = [['//example.com' + path + 'file_XHR_pass1.xml', 'GET'], ['ftp://localhost' + path + 'file_XHR_pass1.xml', 'GET'], ['file_XHR_fail1.txt', 'GET'], ]; for (i = 0; i < passFiles.length; ++i) { xhr = new XMLHttpRequest(); + is(xhr.getResponseHeader("Content-Type"), null, "should be null"); + is(xhr.getAllResponseHeaders(), "", "should be empty string"); is(xhr.responseType, "", "wrong initial responseType"); xhr.open(passFiles[i][1], passFiles[i][0], false); xhr.send(null); is(xhr.status, passFiles[i][2], "wrong status"); + is(xhr.getResponseHeader("Content-Type"), passFiles[i][3], "wrong content type"); + var headers = xhr.getAllResponseHeaders(); + ok(/(?:^|\n)Content-Type:\s*([^\n]*)\n/i.test(headers) && + RegExp.$1 === passFiles[i][3], "wrong response headers"); if (xhr.responseXML) { is((new XMLSerializer()).serializeToString(xhr.responseXML.documentElement), - "<res>hello</res>", - "wrong responseXML"); - is(xhr.response, "<res>hello</res>\n", "wrong response"); + passFiles[i][4] || "<res>hello</res>", "wrong responseXML"); + is(xhr.response, passFiles[i][4] || "<res>hello</res>\n", "wrong response"); } else { - is(xhr.responseText, "hello pass\n", "wrong responseText"); - is(xhr.response, "hello pass\n", "wrong response"); + is(xhr.responseText, passFiles[i][4] || "hello pass\n", "wrong responseText"); + is(xhr.response, passFiles[i][4] || "hello pass\n", "wrong response"); } } for (i = 0; i < failFiles.length; ++i) { xhr = new XMLHttpRequest(); var didthrow = false; try { xhr.open(failFiles[i][1], failFiles[i][0], false);