Bug 1510281 - Backed out changeset 093960021b8b because we want to use a different approach. r=mkaply

Differential Revision: https://phabricator.services.mozilla.com/D13328

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Marco Bonardo 2018-12-08 17:32:27 +00:00
Родитель 6b7c1b63a9
Коммит 4df6b25ace
8 изменённых файлов: 70 добавлений и 152 удалений

Просмотреть файл

@ -273,10 +273,11 @@ var ContentSearch = {
let ok = SearchSuggestionController.engineOffersSuggestions(engine);
controller.maxLocalResults = ok ? MAX_LOCAL_SUGGESTIONS : MAX_SUGGESTIONS;
controller.maxRemoteResults = ok ? MAX_SUGGESTIONS : 0;
let priv = PrivateBrowsingUtils.isBrowserPrivate(browser);
// fetch() rejects its promise if there's a pending request, but since we
// process our event queue serially, there's never a pending request.
this._currentSuggestion = { controller, target: browser };
let suggestions = await controller.fetch(searchString, engine);
let suggestions = await controller.fetch(searchString, priv, engine);
this._currentSuggestion = null;
// suggestions will be null if the request was cancelled

Просмотреть файл

@ -137,7 +137,7 @@ class SuggestionsFetch {
this._engine = engine;
this._suggestions = [];
this._success = false;
this._promise = this._controller.fetch(searchString, engine, userContextId).then(results => {
this._promise = this._controller.fetch(searchString, inPrivateContext, engine, userContextId).then(results => {
this._success = true;
if (results) {
this._suggestions.push(

Просмотреть файл

@ -46,8 +46,6 @@ function SearchSuggestionController(callback = null) {
}
this.SearchSuggestionController.prototype = {
FIRST_PARTY_DOMAIN: "search.suggestions.8c845959-a33d-4787-953c-5d55a0afd56e.mozilla",
/**
* The maximum number of local form history results to return. This limit is
* only enforced if remote results are also returned.
@ -101,15 +99,13 @@ this.SearchSuggestionController.prototype = {
* results from them will not be provided.
*
* @param {string} searchTerm - the term to provide suggestions for
* @param {bool} privateMode - whether the request is being made in the context of private browsing
* @param {nsISearchEngine} engine - search engine for the suggestions.
* @param {int} userContextId - the userContextId of the selected tab.
* @param {bool} privateMode - whether the request should be made private.
* Note that usually we want a private context, even in a non-private
* window, because we don't want to store cookies and offline data.
*
* @return {Promise} resolving to an object containing results or null.
*/
fetch(searchTerm, engine, userContextId = 0, privateMode = true) {
fetch(searchTerm, privateMode, engine, userContextId) {
// There is no smart filtering from previous results here (as there is when looking through
// history/form data) because the result set returned by the server is different for every typed
// value - e.g. "ocean breathes" does not return a subset of the results returned for "ocean".
@ -119,6 +115,9 @@ this.SearchSuggestionController.prototype = {
if (!Services.search.isInitialized) {
throw new Error("Search not initialized yet (how did you get here?)");
}
if (typeof privateMode === "undefined") {
throw new Error("The privateMode argument is required to avoid unintentional privacy leaks");
}
if (!(engine instanceof Ci.nsISearchEngine)) {
throw new Error("Invalid search engine");
}
@ -232,12 +231,8 @@ this.SearchSuggestionController.prototype = {
let method = (submission.postData ? "POST" : "GET");
this._request.open(method, submission.uri.spec, true);
this._request.setOriginAttributes({
userContextId,
privateBrowsingId: privateMode ? 1 : 0,
// Use a unique first-party domain to isolate the suggestions cookies.
firstPartyDomain: this.FIRST_PARTY_DOMAIN,
});
this._request.setOriginAttributes({userContextId,
privateBrowsingId: privateMode ? 1 : 0});
this._request.mozBackgroundRequest = true; // suppress dialogs and fail silently

Просмотреть файл

@ -119,10 +119,19 @@ SuggestAutoComplete.prototype = {
var formHistorySearchParam = searchParam.split("|")[0];
// Receive the information about the privacy mode of the window to which
// this search box belongs. The front-end's search.xml bindings passes this
// information in the searchParam parameter. The alternative would have
// been to modify nsIAutoCompleteSearch to add an argument to startSearch
// and patch all of autocomplete to be aware of this, but the searchParam
// argument is already an opaque argument, so this solution is hopefully
// less hackish (although still gross.)
var privacyMode = (searchParam.split("|")[1] == "private");
// Start search immediately if possible, otherwise once the search
// service is initialized
if (Services.search.isInitialized) {
this._triggerSearch(searchString, formHistorySearchParam, listener);
this._triggerSearch(searchString, formHistorySearchParam, listener, privacyMode);
return;
}
@ -131,16 +140,17 @@ SuggestAutoComplete.prototype = {
Cu.reportError("Could not initialize search service, bailing out: " + aResult);
return;
}
this._triggerSearch(searchString, formHistorySearchParam, listener);
this._triggerSearch(searchString, formHistorySearchParam, listener, privacyMode);
});
},
/**
* Actual implementation of search.
*/
_triggerSearch(searchString, searchParam, listener) {
_triggerSearch(searchString, searchParam, listener, privacyMode) {
this._listener = listener;
this._suggestionController.fetch(searchString,
privacyMode,
Services.search.defaultEngine);
},

Просмотреть файл

@ -21,10 +21,7 @@ function handleRequest(request, response) {
response.setStatusLine(request.httpVersion, 200, "OK");
let q = request.method == "GET" ? query.q : undefined;
if (q == "cookie") {
response.setHeader("Set-Cookie", "cookie=1");
writeSuggestions(q);
} else if (q == "no remote" || q == "no results") {
if (q == "no remote" || q == "no results") {
writeSuggestions(q);
} else if (q == "Query Mismatch") {
writeSuggestions("This is an incorrect query string", ["some result"]);

Просмотреть файл

@ -96,7 +96,7 @@ add_task(async function simple_no_result_callback() {
resolve();
});
controller.fetch("no remote", getEngine);
controller.fetch("no remote", false, getEngine);
});
});
@ -110,7 +110,7 @@ add_task(async function simple_no_result_callback_and_promise() {
deferred.resolve();
});
let result = await controller.fetch("no results", getEngine);
let result = await controller.fetch("no results", false, getEngine);
Assert.equal(result.term, "no results");
Assert.equal(result.local.length, 0);
Assert.equal(result.remote.length, 0);
@ -120,7 +120,7 @@ add_task(async function simple_no_result_callback_and_promise() {
add_task(async function simple_no_result_promise() {
let controller = new SearchSuggestionController();
let result = await controller.fetch("no remote", getEngine);
let result = await controller.fetch("no remote", false, getEngine);
Assert.equal(result.term, "no remote");
Assert.equal(result.local.length, 0);
Assert.equal(result.remote.length, 0);
@ -128,7 +128,7 @@ add_task(async function simple_no_result_promise() {
add_task(async function simple_remote_no_local_result() {
let controller = new SearchSuggestionController();
let result = await controller.fetch("mo", getEngine);
let result = await controller.fetch("mo", false, getEngine);
Assert.equal(result.term, "mo");
Assert.equal(result.local.length, 0);
Assert.equal(result.remote.length, 3);
@ -139,7 +139,7 @@ add_task(async function simple_remote_no_local_result() {
add_task(async function simple_remote_no_local_result_alternative_type() {
let controller = new SearchSuggestionController();
let result = await controller.fetch("mo", alternateJSONEngine);
let result = await controller.fetch("mo", false, alternateJSONEngine);
Assert.equal(result.term, "mo");
Assert.equal(result.local.length, 0);
Assert.equal(result.remote.length, 3);
@ -150,7 +150,7 @@ add_task(async function simple_remote_no_local_result_alternative_type() {
add_task(async function remote_term_case_mismatch() {
let controller = new SearchSuggestionController();
let result = await controller.fetch("Query Case Mismatch", getEngine);
let result = await controller.fetch("Query Case Mismatch", false, getEngine);
Assert.equal(result.term, "Query Case Mismatch");
Assert.equal(result.remote.length, 1);
Assert.equal(result.remote[0], "Query Case Mismatch");
@ -160,7 +160,7 @@ add_task(async function simple_local_no_remote_result() {
await updateSearchHistory("bump", "no remote entries");
let controller = new SearchSuggestionController();
let result = await controller.fetch("no remote", getEngine);
let result = await controller.fetch("no remote", false, getEngine);
Assert.equal(result.term, "no remote");
Assert.equal(result.local.length, 1);
Assert.equal(result.local[0], "no remote entries");
@ -173,7 +173,7 @@ add_task(async function simple_non_ascii() {
await updateSearchHistory("bump", "I ❤️ XUL");
let controller = new SearchSuggestionController();
let result = await controller.fetch("I ❤️", getEngine);
let result = await controller.fetch("I ❤️", false, getEngine);
Assert.equal(result.term, "I ❤️");
Assert.equal(result.local.length, 1);
Assert.equal(result.local[0], "I ❤️ XUL");
@ -185,7 +185,7 @@ add_task(async function both_local_remote_result_dedupe() {
await updateSearchHistory("bump", "Mozilla");
let controller = new SearchSuggestionController();
let result = await controller.fetch("mo", getEngine);
let result = await controller.fetch("mo", false, getEngine);
Assert.equal(result.term, "mo");
Assert.equal(result.local.length, 1);
Assert.equal(result.local[0], "Mozilla");
@ -196,7 +196,7 @@ add_task(async function both_local_remote_result_dedupe() {
add_task(async function POST_both_local_remote_result_dedupe() {
let controller = new SearchSuggestionController();
let result = await controller.fetch("mo", postEngine);
let result = await controller.fetch("mo", false, postEngine);
Assert.equal(result.term, "mo");
Assert.equal(result.local.length, 1);
Assert.equal(result.local[0], "Mozilla");
@ -209,7 +209,7 @@ add_task(async function both_local_remote_result_dedupe2() {
await updateSearchHistory("bump", "mom");
let controller = new SearchSuggestionController();
let result = await controller.fetch("mo", getEngine);
let result = await controller.fetch("mo", false, getEngine);
Assert.equal(result.term, "mo");
Assert.equal(result.local.length, 2);
Assert.equal(result.local[0], "mom");
@ -223,7 +223,7 @@ add_task(async function both_local_remote_result_dedupe3() {
await updateSearchHistory("bump", "modern");
let controller = new SearchSuggestionController();
let result = await controller.fetch("mo", getEngine);
let result = await controller.fetch("mo", false, getEngine);
Assert.equal(result.term, "mo");
Assert.equal(result.local.length, 3);
Assert.equal(result.local[0], "modern");
@ -238,10 +238,10 @@ add_task(async function fetch_twice_in_a_row() {
await updateSearchHistory("bump", "delayed local");
let controller = new SearchSuggestionController();
let resultPromise1 = controller.fetch("delay", getEngine);
let resultPromise1 = controller.fetch("delay", false, getEngine);
// A second fetch while the server is still waiting to return results leads to an abort.
let resultPromise2 = controller.fetch("delayed ", getEngine);
let resultPromise2 = controller.fetch("delayed ", false, getEngine);
await resultPromise1.then((results) => Assert.equal(null, results));
let result = await resultPromise2;
@ -259,7 +259,7 @@ add_task(async function fetch_twice_subset_reuse_formHistoryResult() {
await updateSearchHistory("bump", "delayed local");
let controller = new SearchSuggestionController();
let result = await controller.fetch("delay", getEngine);
let result = await controller.fetch("delay", false, getEngine);
Assert.equal(result.term, "delay");
Assert.equal(result.local.length, 2);
Assert.equal(result.local[0], "delay local");
@ -270,7 +270,7 @@ add_task(async function fetch_twice_subset_reuse_formHistoryResult() {
// Remove the entry from the DB but it should remain in the cached formHistoryResult.
await updateSearchHistory("remove", "delayed local");
let result2 = await controller.fetch("delayed ", getEngine);
let result2 = await controller.fetch("delayed ", false, getEngine);
Assert.equal(result2.term, "delayed ");
Assert.equal(result2.local.length, 1);
Assert.equal(result2.local[0], "delayed local");
@ -287,7 +287,7 @@ add_task(async function both_identical_with_more_than_max_results() {
let controller = new SearchSuggestionController();
controller.maxLocalResults = 7;
controller.maxRemoteResults = 10;
let result = await controller.fetch("letter ", getEngine);
let result = await controller.fetch("letter ", false, getEngine);
Assert.equal(result.term, "letter ");
Assert.equal(result.local.length, 7);
for (let i = 0; i < controller.maxLocalResults; i++) {
@ -304,7 +304,7 @@ add_task(async function noremote_maxLocal() {
let controller = new SearchSuggestionController();
controller.maxLocalResults = 2; // (should be ignored because no remote results)
controller.maxRemoteResults = 0;
let result = await controller.fetch("letter ", getEngine);
let result = await controller.fetch("letter ", false, getEngine);
Assert.equal(result.term, "letter ");
Assert.equal(result.local.length, 26);
for (let i = 0; i < result.local.length; i++) {
@ -317,7 +317,7 @@ add_task(async function someremote_maxLocal() {
let controller = new SearchSuggestionController();
controller.maxLocalResults = 2;
controller.maxRemoteResults = 4;
let result = await controller.fetch("letter ", getEngine);
let result = await controller.fetch("letter ", false, getEngine);
Assert.equal(result.term, "letter ");
Assert.equal(result.local.length, 2);
for (let i = 0; i < result.local.length; i++) {
@ -334,7 +334,7 @@ add_task(async function one_of_each() {
let controller = new SearchSuggestionController();
controller.maxLocalResults = 1;
controller.maxRemoteResults = 2;
let result = await controller.fetch("letter ", getEngine);
let result = await controller.fetch("letter ", false, getEngine);
Assert.equal(result.term, "letter ");
Assert.equal(result.local.length, 1);
Assert.equal(result.local[0], "letter A");
@ -347,7 +347,7 @@ add_task(async function local_result_returned_remote_result_disabled() {
let controller = new SearchSuggestionController();
controller.maxLocalResults = 1;
controller.maxRemoteResults = 1;
let result = await controller.fetch("letter ", getEngine);
let result = await controller.fetch("letter ", false, getEngine);
Assert.equal(result.term, "letter ");
Assert.equal(result.local.length, 26);
for (let i = 0; i < 26; i++) {
@ -362,7 +362,7 @@ add_task(async function local_result_returned_remote_result_disabled_after_creat
controller.maxLocalResults = 1;
controller.maxRemoteResults = 1;
Services.prefs.setBoolPref("browser.search.suggest.enabled", false);
let result = await controller.fetch("letter ", getEngine);
let result = await controller.fetch("letter ", false, getEngine);
Assert.equal(result.term, "letter ");
Assert.equal(result.local.length, 26);
for (let i = 0; i < 26; i++) {
@ -378,7 +378,7 @@ add_task(async function one_of_each_disabled_before_creation_enabled_after_creat
controller.maxLocalResults = 1;
controller.maxRemoteResults = 2;
Services.prefs.setBoolPref("browser.search.suggest.enabled", true);
let result = await controller.fetch("letter ", getEngine);
let result = await controller.fetch("letter ", false, getEngine);
Assert.equal(result.term, "letter ");
Assert.equal(result.local.length, 1);
Assert.equal(result.local[0], "letter A");
@ -394,7 +394,7 @@ add_task(async function one_local_zero_remote() {
let controller = new SearchSuggestionController();
controller.maxLocalResults = 1;
controller.maxRemoteResults = 0;
let result = await controller.fetch("letter ", getEngine);
let result = await controller.fetch("letter ", false, getEngine);
Assert.equal(result.term, "letter ");
Assert.equal(result.local.length, 26);
for (let i = 0; i < 26; i++) {
@ -407,7 +407,7 @@ add_task(async function zero_local_one_remote() {
let controller = new SearchSuggestionController();
controller.maxLocalResults = 0;
controller.maxRemoteResults = 1;
let result = await controller.fetch("letter ", getEngine);
let result = await controller.fetch("letter ", false, getEngine);
Assert.equal(result.term, "letter ");
Assert.equal(result.local.length, 0);
Assert.equal(result.remote.length, 1);
@ -418,7 +418,7 @@ add_task(async function stop_search() {
let controller = new SearchSuggestionController((result) => {
do_throw("The callback shouldn't be called after stop()");
});
let resultPromise = controller.fetch("mo", getEngine);
let resultPromise = controller.fetch("mo", false, getEngine);
controller.stop();
await resultPromise.then((result) => {
Assert.equal(null, result);
@ -428,7 +428,7 @@ add_task(async function stop_search() {
add_task(async function empty_searchTerm() {
// Empty searches don't go to the server but still get form history.
let controller = new SearchSuggestionController();
let result = await controller.fetch("", getEngine);
let result = await controller.fetch("", false, getEngine);
Assert.equal(result.term, "");
Assert.ok(result.local.length > 0);
Assert.equal(result.remote.length, 0);
@ -450,7 +450,7 @@ add_task(async function slow_timeout() {
check_result(result);
d.resolve();
}, 2000);
let result = await controller.fetch("slow ", getEngine);
let result = await controller.fetch("slow ", false, getEngine);
check_result(result);
await d.promise;
});
@ -458,7 +458,7 @@ add_task(async function slow_timeout() {
add_task(async function slow_stop() {
let d = PromiseUtils.defer();
let controller = new SearchSuggestionController();
let resultPromise = controller.fetch("slow ", getEngine);
let resultPromise = controller.fetch("slow ", false, getEngine);
setTimeout(function check_timeout() {
// The HTTP response takes 10 seconds but we timeout in less than a second so just use 0.
controller.stop();
@ -478,7 +478,7 @@ add_task(async function remote_term_mismatch() {
await updateSearchHistory("bump", "Query Mismatch Entry");
let controller = new SearchSuggestionController();
let result = await controller.fetch("Query Mismatch", getEngine);
let result = await controller.fetch("Query Mismatch", false, getEngine);
Assert.equal(result.term, "Query Mismatch");
Assert.equal(result.local.length, 1);
Assert.equal(result.local[0], "Query Mismatch Entry");
@ -489,7 +489,7 @@ add_task(async function http_404() {
await updateSearchHistory("bump", "HTTP 404 Entry");
let controller = new SearchSuggestionController();
let result = await controller.fetch("HTTP 404", getEngine);
let result = await controller.fetch("HTTP 404", false, getEngine);
Assert.equal(result.term, "HTTP 404");
Assert.equal(result.local.length, 1);
Assert.equal(result.local[0], "HTTP 404 Entry");
@ -500,7 +500,7 @@ add_task(async function http_500() {
await updateSearchHistory("bump", "HTTP 500 Entry");
let controller = new SearchSuggestionController();
let result = await controller.fetch("HTTP 500", getEngine);
let result = await controller.fetch("HTTP 500", false, getEngine);
Assert.equal(result.term, "HTTP 500");
Assert.equal(result.local.length, 1);
Assert.equal(result.local[0], "HTTP 500 Entry");
@ -511,7 +511,7 @@ add_task(async function unresolvable_server() {
await updateSearchHistory("bump", "Unresolvable Server Entry");
let controller = new SearchSuggestionController();
let result = await controller.fetch("Unresolvable Server", unresolvableEngine);
let result = await controller.fetch("Unresolvable Server", false, unresolvableEngine);
Assert.equal(result.term, "Unresolvable Server");
Assert.equal(result.local.length, 1);
Assert.equal(result.local[0], "Unresolvable Server Entry");
@ -521,17 +521,24 @@ add_task(async function unresolvable_server() {
// Exception handling
add_task(async function missing_pb() {
Assert.throws(() => {
let controller = new SearchSuggestionController();
controller.fetch("No privacy");
}, /priva/i);
});
add_task(async function missing_engine() {
Assert.throws(() => {
let controller = new SearchSuggestionController();
controller.fetch("No engine");
controller.fetch("No engine", false);
}, /engine/i);
});
add_task(async function invalid_engine() {
Assert.throws(() => {
let controller = new SearchSuggestionController();
controller.fetch("invalid engine", {});
controller.fetch("invalid engine", false, {});
}, /engine/i);
});
@ -540,7 +547,7 @@ add_task(async function no_results_requested() {
let controller = new SearchSuggestionController();
controller.maxLocalResults = 0;
controller.maxRemoteResults = 0;
controller.fetch("No results requested", getEngine);
controller.fetch("No results requested", false, getEngine);
}, /result/i);
});
@ -548,18 +555,18 @@ add_task(async function minus_one_results_requested() {
Assert.throws(() => {
let controller = new SearchSuggestionController();
controller.maxLocalResults = -1;
controller.fetch("-1 results requested", getEngine);
controller.fetch("-1 results requested", false, getEngine);
}, /result/i);
});
add_task(async function test_userContextId() {
let controller = new SearchSuggestionController();
controller._fetchRemote = function(searchTerm, engine, userContextId, privateMode) {
controller._fetchRemote = function(searchTerm, engine, privateMode, userContextId) {
Assert.equal(userContextId, 1);
return PromiseUtils.defer();
};
controller.fetch("test", getEngine, 1);
controller.fetch("test", false, getEngine, 1);
});
// Helpers

Просмотреть файл

@ -1,91 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/* eslint-disable mozilla/no-arbitrary-setTimeout */
/**
* Testing search suggestions from SearchSuggestionController.jsm.
*/
"use strict";
ChromeUtils.import("resource://gre/modules/FormHistory.jsm");
ChromeUtils.import("resource://gre/modules/SearchSuggestionController.jsm");
ChromeUtils.import("resource://gre/modules/Timer.jsm");
ChromeUtils.import("resource://gre/modules/PromiseUtils.jsm");
// We must make sure the FormHistoryStartup component is
// initialized in order for it to respond to FormHistory
// requests from nsFormAutoComplete.js.
var formHistoryStartup = Cc["@mozilla.org/satchel/form-history-startup;1"].
getService(Ci.nsIObserver);
formHistoryStartup.observe(null, "profile-after-change", null);
var httpServer = new HttpServer();
var getEngine;
add_task(async function setup() {
Services.prefs.setBoolPref("browser.search.suggest.enabled", true);
let server = useHttpServer();
server.registerContentType("sjs", "sjs");
registerCleanupFunction(async function cleanup() {
Services.prefs.clearUserPref("browser.search.suggest.enabled");
});
[getEngine] = await addTestEngines([
{
name: "GET suggestion engine",
xmlFileName: "engineMaker.sjs?" + JSON.stringify({
baseURL: gDataUrl,
name: "GET suggestion engine",
method: "GET",
}),
},
]);
});
add_task(async function test_private() {
await new Promise(resolve => {
let controller = new SearchSuggestionController((result) => {
Assert.equal(result.term, "cookie");
Assert.equal(result.local.length, 0);
Assert.equal(result.remote.length, 0);
resolve();
});
controller.fetch("cookie", getEngine);
});
info("Enumerating cookies");
let enumerator = Services.cookies.enumerator;
let cookies = [];
for (let cookie of enumerator) {
info("Cookie:" + cookie.rawHost + " " + JSON.stringify(cookie.originAttributes));
cookies.push(cookie);
break;
}
Assert.equal(cookies.length, 0, "Should not find any cookie");
});
add_task(async function test_nonprivate() {
let controller;
await new Promise(resolve => {
controller = new SearchSuggestionController((result) => {
Assert.equal(result.term, "cookie");
Assert.equal(result.local.length, 0);
Assert.equal(result.remote.length, 0);
resolve();
});
controller.fetch("cookie", getEngine, 0, false);
});
info("Enumerating cookies");
let enumerator = Services.cookies.enumerator;
let cookies = [];
for (let cookie of enumerator) {
info("Cookie:" + cookie.rawHost + " " + JSON.stringify(cookie.originAttributes));
cookies.push(cookie);
break;
}
Assert.equal(cookies.length, 1, "Should find one cookie");
Assert.equal(cookies[0].originAttributes.firstPartyDomain,
controller.FIRST_PARTY_DOMAIN, "Check firstPartyDomain");
});

Просмотреть файл

@ -66,7 +66,6 @@ support-files = data/search_ignorelist.json
[test_multipleIcons.js]
[test_resultDomain.js]
[test_searchSuggest.js]
[test_searchSuggest_cookies.js]
[test_async.js]
[test_async_addon.js]
tags = addons