author | Valentin Gosu <valentin.gosu@gmail.com> |
Wed, 12 Aug 2015 00:43:48 +0200 | |
changeset 289987 | 846e76b0e711b7b7640f41ddcf45904fe737d24a |
parent 289986 | 751d8abf0b7666484bbfd3397ae1e54e758d3fc9 |
child 289988 | 762524f4d9ff68d8a5e19f2a1281b584c0ba7f62 |
push id | 5245 |
push user | raliiev@mozilla.com |
push date | Thu, 29 Oct 2015 11:30:51 +0000 |
treeherder | mozilla-beta@dac831dc1bd0 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | mcmanus |
bugs | 1172701 |
milestone | 43.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
|
--- a/netwerk/protocol/http/PackagedAppService.cpp +++ b/netwerk/protocol/http/PackagedAppService.cpp @@ -407,18 +407,25 @@ PackagedAppService::PackagedAppDownloade nsAutoCString path; rv = uri->GetPath(path); if (NS_FAILED(rv)) { return rv; } path += PACKAGED_APP_TOKEN; - // TODO: make sure the path is normalized - if (StringBeginsWith(contentLocation, NS_LITERAL_CSTRING("/"))) { + { + // We use this temp URI to generate a path that is relative + // to the package URI and not to the root of the domain. + nsCOMPtr<nsIURI> tempURI; + NS_NewURI(getter_AddRefs(tempURI), "http://temp-domain.local/"); + tempURI->SetPath(contentLocation); + // The path is now normalized. + tempURI->GetPath(contentLocation); + // Remove the leading slash. contentLocation = Substring(contentLocation, 1); } path += contentLocation; nsCOMPtr<nsIURI> partURI; rv = uri->CloneIgnoringRef(getter_AddRefs(partURI)); if (NS_FAILED(rv)) {
new file mode 100644 --- /dev/null +++ b/netwerk/test/unit/test_packaged_app_service_paths.js @@ -0,0 +1,127 @@ +Cu.import('resource://gre/modules/LoadContextInfo.jsm'); +Cu.import("resource://testing-common/httpd.js"); +Cu.import("resource://gre/modules/Services.jsm"); + +var gRequestNo = 0; +function packagedAppContentHandler(metadata, response) +{ + response.setHeader("Content-Type", 'application/package'); + var body = testData.getData(); + response.bodyOutputStream.write(body, body.length); + gRequestNo++; +} + +function getPrincipal(url) { + let uri = createURI(url); + return Components.classes["@mozilla.org/scriptsecuritymanager;1"] + .getService(Ci.nsIScriptSecurityManager) + .getNoAppCodebasePrincipal(uri); +} + +var subresourcePaths = [ + [ "/index.html", "index.html" ], + [ "index.html", "index.html" ], + [ "/../../index.html", "index.html" ], + [ "../../index.html", "index.html" ], + [ "/hello/./.././index.html", "index.html" ], + [ "hello/./.././index.html", "index.html" ], + [ "../hello/index.html", "hello/index.html" ], + [ "/../hello/index.html", "hello/index.html" ], + [ "/./././index.html", "index.html" ], +] + +var content = "<html><body> Test </body></html>"; + +// The package content +// getData formats it as described at http://www.w3.org/TR/web-packaging/#streamable-package-format +var testData = { + token : "gc0pJq0M:08jU534c0p", + getData: function() { + var str = ""; + + str += "--" + this.token + "\r\n"; + str += "Content-Location: " + subresourcePaths[gRequestNo][0] + "\r\n"; + str += "Content-Type: text/html" + "\r\n"; + str += "\r\n"; + + str += content + "\r\n"; + str += "--" + this.token + "--"; + + return str; + } +} + +XPCOMUtils.defineLazyGetter(this, "uri", function() { + return "http://localhost:" + httpserver.identity.primaryPort; +}); + +// The active http server initialized in run_test +var httpserver = null; +// The packaged app service initialized in run_test +var paservice = null; +// This variable is set before getResource is called. The listener uses this variable +// to check the correct resource path for the returned entry +var packagePath = null; + +function run_test() +{ + // setup test + httpserver = new HttpServer(); + httpserver.registerPrefixHandler("/package/", packagedAppContentHandler); + httpserver.start(-1); + + paservice = Cc["@mozilla.org/network/packaged-app-service;1"] + .getService(Ci.nsIPackagedAppService); + + var testuri = createURI("http://localhost/"); + + add_test(continueTest); + // run tests + run_next_test(); +} + +// A listener we use to check the proper cache entry is returned by the service +function packagedResourceListener(path, content) { + this.path = path; + this.content = content; +} + +packagedResourceListener.prototype = { + QueryInterface: function (iid) { + if (iid.equals(Ci.nsICacheEntryOpenCallback) || + iid.equals(Ci.nsISupports)) + return this; + throw Cr.NS_ERROR_NO_INTERFACE; + }, + onCacheEntryCheck: function() { return Ci.nsICacheEntryOpenCallback.ENTRY_WANTED; }, + onCacheEntryAvailable: function (entry, isnew, appcache, status) { + equal(status, Cr.NS_OK, "status is NS_OK"); + ok(!!entry, "Needs to have an entry"); + equal(entry.key, uri + packagePath + "!//" + this.path, "Check entry has correct name"); + var inputStream = entry.openInputStream(0); + pumpReadStream(inputStream, (read) => { + inputStream.close(); + equal(read, this.content); // not using do_check_eq since logger will fail for the 1/4MB string + continueTest(); + }); + } +}; + +var gGenerator = test_paths(); +function continueTest() { + try { + gGenerator.next(); + } catch (e if e instanceof StopIteration) { + run_next_test(); + } +} +function test_paths() { + for (var i in subresourcePaths) { + packagePath = "/package/" + i; + dump("Iteration " + i + "\n"); + paservice.getResource(getPrincipal(uri + packagePath + "!//" + subresourcePaths[i][1]), 0, + LoadContextInfo.default, + new packagedResourceListener(subresourcePaths[i][1], content)); + yield undefined; + } +}
--- a/netwerk/test/unit/xpcshell.ini +++ b/netwerk/test/unit/xpcshell.ini @@ -321,8 +321,9 @@ skip-if = os == "android" [test_1073747.js] [test_multipart_streamconv_application_package.js] [test_safeoutputstream_append.js] [test_packaged_app_service.js] [test_suspend_channel_before_connect.js] [test_inhibit_caching.js] [test_dns_disable_ipv4.js] [test_dns_disable_ipv6.js] +[test_packaged_app_service_paths.js]