From b735a19de7df1d66ec8dfe0107ff63ec7b40b2e4 Mon Sep 17 00:00:00 2001 From: Fatih Kilic Date: Mon, 31 Mar 2025 22:01:49 +0000 Subject: [PATCH] Bug 1947801: Add OHTTP client test. r=valentin,geckoview-reviewers,android-reviewers,ohall Differential Revision: https://phabricator.services.mozilla.com/D239907 --- .../geckoview/test/WebExecutorOhttpTest.kt | 31 ++ .../org/mozilla/geckoview/WebRequest.java | 1 + .../resistfingerprinting/tests/moz.build | 2 + .../tests/xpcshell/test_ohttp_client.js | 292 ++++++++++++++++++ .../tests/xpcshell/xpcshell.toml | 8 + widget/android/WebExecutorSupport.cpp | 62 ++++ widget/android/WebExecutorSupport.h | 13 + widget/android/jni/GeckoResultUtils.h | 8 + widget/android/moz.build | 6 + widget/android/tests/OhttpClientTest.cpp | 28 ++ widget/android/tests/OhttpClientTest.h | 29 ++ widget/android/tests/components.conf | 15 + widget/android/tests/moz.build | 21 ++ widget/android/tests/nsIOhttpClientTest.idl | 21 ++ 14 files changed, 537 insertions(+) create mode 100644 mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/WebExecutorOhttpTest.kt create mode 100644 toolkit/components/resistfingerprinting/tests/xpcshell/test_ohttp_client.js create mode 100644 toolkit/components/resistfingerprinting/tests/xpcshell/xpcshell.toml create mode 100644 widget/android/tests/OhttpClientTest.cpp create mode 100644 widget/android/tests/OhttpClientTest.h create mode 100644 widget/android/tests/components.conf create mode 100644 widget/android/tests/moz.build create mode 100644 widget/android/tests/nsIOhttpClientTest.idl diff --git a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/WebExecutorOhttpTest.kt b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/WebExecutorOhttpTest.kt new file mode 100644 index 000000000000..c438495a9181 --- /dev/null +++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/WebExecutorOhttpTest.kt @@ -0,0 +1,31 @@ +/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*- + * Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +package org.mozilla.geckoview.test + +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.MediumTest +import org.junit.Test +import org.junit.runner.RunWith +import org.mozilla.geckoview.* // ktlint-disable no-wildcard-imports +import org.mozilla.geckoview.test.util.RuntimeCreator + +@RunWith(AndroidJUnit4::class) +@MediumTest +class WebExecutorOhttpTest : BaseSessionTest() { + // We just want to make sure we don't crash when trying to use ohttp. + // We test the actual functionality in toolkit/components/resistfingerprinting/tests/xpcshell/test_ohttp_client.js. + @Test(expected = WebRequestError::class) + fun testOhttp() { + sessionRule.setPrefsUntilTestEnd( + mapOf( + // Don't make external requests. + "network.ohttp.configURL" to "https://example.com", + "network.ohttp.relayURL" to "https://example.com", + ), + ) + + GeckoWebExecutor(RuntimeCreator.getRuntime()).fetch(WebRequest.Builder("https://example.com").build(), GeckoWebExecutor.FETCH_FLAGS_OHTTP).poll(5 * 100) + } +} diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/WebRequest.java b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/WebRequest.java index 30ee5451aa2e..abfd1876e244 100644 --- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/WebRequest.java +++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/WebRequest.java @@ -119,6 +119,7 @@ public class WebRequest extends WebMessage { } /** Builder offers a convenient way for constructing {@link WebRequest} instances. */ + @WrapForJNI @AnyThread public static class Builder extends WebMessage.Builder { /* package */ String mMethod = "GET"; diff --git a/toolkit/components/resistfingerprinting/tests/moz.build b/toolkit/components/resistfingerprinting/tests/moz.build index 3a6ca329ff83..69174d96b972 100644 --- a/toolkit/components/resistfingerprinting/tests/moz.build +++ b/toolkit/components/resistfingerprinting/tests/moz.build @@ -6,4 +6,6 @@ BROWSER_CHROME_MANIFESTS += [ "browser/browser.toml", ] +XPCSHELL_TESTS_MANIFESTS += ["xpcshell/xpcshell.toml"] + TEST_DIRS += ["gtest"] diff --git a/toolkit/components/resistfingerprinting/tests/xpcshell/test_ohttp_client.js b/toolkit/components/resistfingerprinting/tests/xpcshell/test_ohttp_client.js new file mode 100644 index 000000000000..6c3fa9c06273 --- /dev/null +++ b/toolkit/components/resistfingerprinting/tests/xpcshell/test_ohttp_client.js @@ -0,0 +1,292 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +const { AddonTestUtils } = ChromeUtils.importESModule( + "resource://testing-common/AddonTestUtils.sys.mjs" +); + +const API_OHTTP_CONFIG = "http://example.com/ohttp-config"; +const API_OHTTP_RELAY = "http://example.com/relay/"; + +AddonTestUtils.maybeInit(this); +const server = AddonTestUtils.createHttpServer({ hosts: ["example.com"] }); + +const ohttp = Cc["@mozilla.org/network/oblivious-http;1"].getService( + Ci.nsIObliviousHttp +); +const ohttpServer = ohttp.server(); + +const serverContext = { + statusCode: 0, + configBody: ohttpServer.encodedConfig, + failure: false, +}; + +server.registerPathHandler( + new URL(API_OHTTP_CONFIG).pathname, + (request, response) => { + const bstream = Cc["@mozilla.org/binaryoutputstream;1"].createInstance( + Ci.nsIBinaryOutputStream + ); + bstream.setOutputStream(response.bodyOutputStream); + bstream.writeByteArray(serverContext.configBody); + } +); + +let requestPromise, resolveRequest; +let responsePromise, resolveResponse; + +server.registerPathHandler( + new URL(API_OHTTP_RELAY).pathname, + async (request, response) => { + const inputStream = Cc["@mozilla.org/binaryinputstream;1"].createInstance( + Ci.nsIBinaryInputStream + ); + inputStream.setInputStream(request.bodyInputStream); + const requestBody = inputStream.readByteArray(inputStream.available()); + const ohttpRequest = ohttpServer.decapsulate(requestBody); + const bhttp = Cc["@mozilla.org/network/binary-http;1"].getService( + Ci.nsIBinaryHttp + ); + const decodedRequest = bhttp.decodeRequest(ohttpRequest.request); + + response.processAsync(); + if (serverContext.failure) { + response.setStatusLine(request.httpVersion, 500, "Internal Server Error"); + response.finish(); + resolveRequest(decodedRequest); + return; + } + + const BinaryHttpResponse = { + status: serverContext.statusCode, + headerNames: [], + headerValues: [], + content: new TextEncoder().encode(decodedRequest.content), + QueryInterface: ChromeUtils.generateQI(["nsIBinaryHttpResponse"]), + }; + const encResponse = ohttpRequest.encapsulate( + bhttp.encodeResponse(BinaryHttpResponse) + ); + response.setStatusLine(request.httpVersion, 200, "OK"); + response.setHeader("Content-Type", "message/ohttp-res", false); + + const bstream = Cc["@mozilla.org/binaryoutputstream;1"].createInstance( + Ci.nsIBinaryOutputStream + ); + bstream.setOutputStream(response.bodyOutputStream); + bstream.writeByteArray(encResponse); + response.finish(); + + resolveRequest(decodedRequest); + } +); + +function resetPromises() { + const tmp1 = Promise.withResolvers(); + requestPromise = tmp1.promise; + resolveRequest = tmp1.resolve; + + const tmp2 = Promise.withResolvers(); + responsePromise = tmp2.promise; + resolveResponse = tmp2.resolve; +} + +async function test_success() { + resetPromises(); + + const request = { + method: "POST", + scheme: "https", + authority: "example.com", + path: "/my-path", + headerNames: ["User-Agent"], + headerValues: ["Mozilla/5.0"], + content: "Hello, world!", + }; + + const expectedResponse = { + url: `${request.scheme}://${request.authority}${request.path}`, + statusCode: 42, + error: "", + }; + + serverContext.statusCode = expectedResponse.statusCode; + + const ohttpClientTester = Cc[ + "@mozilla.org/ohttp-client-test;1" + ].createInstance(Ci.nsIOhttpClientTest); + + ohttpClientTester.fetch( + `${request.scheme}://${request.authority}${request.path}`, + request.method, + request.content, + request.headerNames, + request.headerValues, + (url, statusCode, headerKeys, headerValues, error) => { + resolveResponse({ + url, + statusCode, + headerKeys, + headerValues, + error, + }); + } + ); + + const [ohttpRequest, ohttpResponse] = await Promise.all([ + requestPromise, + responsePromise, + ]); + + // Verify request + Assert.equal(ohttpRequest.method, request.method); + Assert.equal(ohttpRequest.scheme, request.scheme); + Assert.equal(ohttpRequest.authority, request.authority); + Assert.equal(ohttpRequest.path, request.path); + Assert.deepEqual(ohttpRequest.headerNames, request.headerNames); + Assert.deepEqual(ohttpRequest.headerValues, request.headerValues); + Assert.deepEqual( + ohttpRequest.content, + request.content.split("").map(s => s.charCodeAt(0)) + ); + + // Verify response + Assert.equal(ohttpResponse.url, expectedResponse.url); + Assert.equal(ohttpResponse.statusCode, expectedResponse.statusCode); + Assert.equal(ohttpResponse.error, expectedResponse.error); +} + +async function test_invalid_config() { + resetPromises(); + + const request = { + method: "POST", + scheme: "https", + authority: "example.com", + path: "/my-path", + headerNames: ["User-Agent"], + headerValues: ["Mozilla/5.0"], + content: "Hello, world!", + }; + + const expectedResponse = { + url: "", + statusCode: 0, + error: "Request failed, error=0x11, category=0x1", + }; + + // Provide invalid config + // We still set status code to verify that we don't + // get back 42 as the status. + serverContext.configBody = [0, 0, 0, 0]; + serverContext.statusCode = 42; + + const ohttpClientTester = Cc[ + "@mozilla.org/ohttp-client-test;1" + ].createInstance(Ci.nsIOhttpClientTest); + + ohttpClientTester.fetch( + `${request.scheme}://${request.authority}${request.path}`, + request.method, + request.content, + request.headerNames, + request.headerValues, + (url, statusCode, headerKeys, headerValues, error) => { + resolveResponse({ + url, + statusCode, + headerKeys, + headerValues, + error, + }); + } + ); + + // Request promise never resolves as getting config fails + const ohttpResponse = await responsePromise; + + // Verify response + Assert.equal(ohttpResponse.url, expectedResponse.url); + Assert.equal(ohttpResponse.statusCode, expectedResponse.statusCode); + Assert.equal(ohttpResponse.error, expectedResponse.error); +} + +async function test_ohttp_failure() { + resetPromises(); + + const request = { + method: "POST", + scheme: "https", + authority: "example.com", + path: "/my-path", + headerNames: ["User-Agent"], + headerValues: ["Mozilla/5.0"], + content: "Hello, world!", + }; + + const expectedResponse = { + url: "", + statusCode: 0, + error: "Request failed, error=0x11, category=0x1", + }; + + // Provide a valid config, but make the server fail. + // We still set status code to verify that we don't + // get back 42 as the status. + serverContext.configBody = ohttpServer.encodedConfig; + serverContext.statusCode = 42; + serverContext.failure = true; + + const ohttpClientTester = Cc[ + "@mozilla.org/ohttp-client-test;1" + ].createInstance(Ci.nsIOhttpClientTest); + + ohttpClientTester.fetch( + `${request.scheme}://${request.authority}${request.path}`, + request.method, + request.content, + request.headerNames, + request.headerValues, + (url, statusCode, headerKeys, headerValues, error) => { + resolveResponse({ + url, + statusCode, + headerKeys, + headerValues, + error, + }); + } + ); + + const [ohttpRequest, ohttpResponse] = await Promise.all([ + requestPromise, + responsePromise, + ]); + + // Verify request + Assert.equal(ohttpRequest.method, request.method); + Assert.equal(ohttpRequest.scheme, request.scheme); + Assert.equal(ohttpRequest.authority, request.authority); + Assert.equal(ohttpRequest.path, request.path); + Assert.deepEqual(ohttpRequest.headerNames, request.headerNames); + Assert.deepEqual(ohttpRequest.headerValues, request.headerValues); + Assert.deepEqual( + ohttpRequest.content, + request.content.split("").map(s => s.charCodeAt(0)) + ); + + // Verify response + Assert.equal(ohttpResponse.url, expectedResponse.url); + Assert.equal(ohttpResponse.statusCode, expectedResponse.statusCode); + Assert.equal(ohttpResponse.error, expectedResponse.error); +} + +add_task(async function run_tests() { + await test_success(); + await test_invalid_config(); + await test_ohttp_failure(); +}); diff --git a/toolkit/components/resistfingerprinting/tests/xpcshell/xpcshell.toml b/toolkit/components/resistfingerprinting/tests/xpcshell/xpcshell.toml new file mode 100644 index 000000000000..a3f5d6b58fbc --- /dev/null +++ b/toolkit/components/resistfingerprinting/tests/xpcshell/xpcshell.toml @@ -0,0 +1,8 @@ +[DEFAULT] +prefs = [ + "network.ohttp.configURL='http://example.com/ohttp-config'", + "network.ohttp.relayURL='http://example.com/relay/'" +] + +["test_ohttp_client.js"] +run-if = ["os == 'android'"] diff --git a/widget/android/WebExecutorSupport.cpp b/widget/android/WebExecutorSupport.cpp index 209c5363e2e4..e381da937a5a 100644 --- a/widget/android/WebExecutorSupport.cpp +++ b/widget/android/WebExecutorSupport.cpp @@ -10,6 +10,7 @@ #include "ReferrerInfo.h" #include "WebExecutorSupport.h" #include "OhttpHelper.h" +#include "JavaExceptions.h" #include "nsIAsyncVerifyRedirectCallback.h" #include "nsICancelable.h" @@ -277,6 +278,67 @@ nsresult WebExecutorSupport::PerformOrQueueOhttpRequest( return OhttpHelper::FetchConfigAndFulfillRequests(); } +#if defined(ENABLE_TESTS) + +void WebExecutorSupport::TestOhttp(const nsACString& url, + const nsACString& method, + const nsACString& body, + const nsTArray& headerKeys, + const nsTArray& headerValues, + ohttpClientTestCallback* callback) { + auto result = java::GeckoResult::New(); + + nsCOMPtr callbackRef(callback); + auto resolve = jni::GeckoResultCallback::CreateAndAttach( + [callbackRef](jni::Object::Param aResolveVal) { + auto response = java::WebResponse::LocalRef(aResolveVal); + auto responseBase = + java::WebMessage::LocalRef(response.Cast()); + + auto headerKeysJava = responseBase->GetHeaderKeys(); + auto headerValuesJava = responseBase->GetHeaderValues(); + nsTArray headersKeys(headerKeysJava->Length()); + nsTArray headersValues(headerValuesJava->Length()); + for (size_t i = 0; i < headerKeysJava->Length(); i++) { + headersKeys.AppendElement( + jni::String::LocalRef(headerKeysJava->GetElement(i)) + ->ToCString()); + headersValues.AppendElement( + jni::String::LocalRef(headerValuesJava->GetElement(i)) + ->ToCString()); + } + + callbackRef->OnResponse(responseBase->Uri()->ToCString(), + response->StatusCode(), headersKeys, + headersValues, ""_ns); + }); + auto reject = jni::GeckoResultCallback::CreateAndAttach( + [callbackRef](jni::Object::Param aRejectVal) { + auto error = java::sdk::Throwable::LocalRef(aRejectVal); + + callbackRef->OnResponse(""_ns, 0, nsTArray(), + nsTArray(), + error->GetMessage()->ToCString()); + }); + result->NativeThen(resolve, reject); + + const auto requestBuilder = + java::WebRequest::Builder::New(url)->Method(method)->Body(body); + for (size_t i = 0; i < headerKeys.Length(); i++) { + requestBuilder->AddHeader(headerKeys[i], headerValues[i]); + } + const auto request = requestBuilder->Build(); + + nsresult rv = PerformOrQueueOhttpRequest( + request, java::GeckoWebExecutor::FETCH_FLAGS_OHTTP, result, true); + + if (NS_FAILED(rv)) { + CompleteWithError(result, rv); + } +} + +#endif + static nsresult ConvertCacheMode(int32_t mode, int32_t& result) { switch (mode) { case java::WebRequest::CACHE_MODE_DEFAULT: diff --git a/widget/android/WebExecutorSupport.h b/widget/android/WebExecutorSupport.h index d01f537f99ea..35b17a92dbe5 100644 --- a/widget/android/WebExecutorSupport.h +++ b/widget/android/WebExecutorSupport.h @@ -10,6 +10,10 @@ #include "mozilla/java/GeckoResultWrappers.h" #include "mozilla/java/WebRequestWrappers.h" +#if defined(ENABLE_TESTS) +# include "nsIOhttpClientTest.h" +#endif // defined(ENABLE_TESTS) + class nsIChannel; namespace mozilla { @@ -40,6 +44,15 @@ class WebExecutorSupport final int32_t aFlags, java::GeckoResult::Param aResult, bool bypassConfigCache = false); +#if defined(ENABLE_TESTS) + // Used for testing OHTTP. Porting all of the OHTTP server code to Java would + // be quite a bit of work, so we're just going to test it in JS. + static void TestOhttp(const nsACString& url, const nsACString& method, + const nsACString& body, + const nsTArray& headerKeys, + const nsTArray& headerValues, + ohttpClientTestCallback* callback); +#endif // defined(ENABLE_TESTS) }; } // namespace widget diff --git a/widget/android/jni/GeckoResultUtils.h b/widget/android/jni/GeckoResultUtils.h index da103f35eea4..91ea4a5e2ad3 100644 --- a/widget/android/jni/GeckoResultUtils.h +++ b/widget/android/jni/GeckoResultUtils.h @@ -41,6 +41,14 @@ class GeckoResultCallback final return java; } + static java::GeckoResult::GeckoCallback::LocalRef CreateAndAttach( + OuterCallback&& aCallback) { + auto java = java::GeckoResult::GeckoCallback::New(); + auto native = MakeUnique(std::move(aCallback)); + Base::AttachNative(java, std::move(native)); + return java; + } + explicit GeckoResultCallback(OuterCallback&& aCallback) : mCallback(std::move(aCallback)) {} diff --git a/widget/android/moz.build b/widget/android/moz.build index c3ad653423f4..9589a6e26741 100644 --- a/widget/android/moz.build +++ b/widget/android/moz.build @@ -15,6 +15,11 @@ DIRS += [ "jni", ] +if CONFIG["ENABLE_TESTS"]: + DIRS += [ + "tests", + ] + EXPORTS += [ "AndroidBridge.h", ] @@ -110,6 +115,7 @@ EXPORTS.mozilla.widget += [ "GeckoViewSupport.h", "InProcessAndroidCompositorWidget.h", "nsWindow.h", + "WebExecutorSupport.h", "WindowEvent.h", ] diff --git a/widget/android/tests/OhttpClientTest.cpp b/widget/android/tests/OhttpClientTest.cpp new file mode 100644 index 000000000000..d18baacd40a0 --- /dev/null +++ b/widget/android/tests/OhttpClientTest.cpp @@ -0,0 +1,28 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#if defined(ENABLE_TESTS) + +# include "mozilla/widget/WebExecutorSupport.h" +# include "mozilla/widget/OhttpClientTest.h" + +namespace mozilla::widget { + +NS_IMETHODIMP +OhttpClientTest::Fetch(const nsACString& url, const nsACString& method, + const nsACString& body, + const nsTArray& headerKeys, + const nsTArray& headerValues, + ohttpClientTestCallback* callback) { + widget::WebExecutorSupport::TestOhttp(url, method, body, headerKeys, + headerValues, callback); + return NS_OK; +} + +NS_IMPL_ISUPPORTS(OhttpClientTest, nsIOhttpClientTest) +} // namespace mozilla::widget + +#endif // defined(ENABLE_TESTS) diff --git a/widget/android/tests/OhttpClientTest.h b/widget/android/tests/OhttpClientTest.h new file mode 100644 index 000000000000..912e587fe455 --- /dev/null +++ b/widget/android/tests/OhttpClientTest.h @@ -0,0 +1,29 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_widget_android_tests +#define mozilla_widget_android_tests + +#if defined(ENABLE_TESTS) + +# include "nsIOhttpClientTest.h" + +namespace mozilla::widget { + +class OhttpClientTest final : public nsIOhttpClientTest { + public: + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSIOHTTPCLIENTTEST + + OhttpClientTest() = default; + + private: + ~OhttpClientTest() = default; +}; +} // namespace mozilla::widget + +#endif // defined(ENABLE_TESTS) +#endif // mozilla_widget_android_tests diff --git a/widget/android/tests/components.conf b/widget/android/tests/components.conf new file mode 100644 index 000000000000..7f0bd5ed8b49 --- /dev/null +++ b/widget/android/tests/components.conf @@ -0,0 +1,15 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +Classes = [ + { + 'cid': '{b3150bd2-689c-4cf0-b4ee-4f90aaf1cbd3}', + 'contract_ids': ['@mozilla.org/ohttp-client-test;1'], + 'type': 'mozilla::widget::OhttpClientTest', + 'headers': ['mozilla/widget/OhttpClientTest.h'], + 'processes': ProcessSelector.MAIN_PROCESS_ONLY, + }, +] diff --git a/widget/android/tests/moz.build b/widget/android/tests/moz.build new file mode 100644 index 000000000000..54097f737b59 --- /dev/null +++ b/widget/android/tests/moz.build @@ -0,0 +1,21 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +EXPORTS.mozilla.widget += ["OhttpClientTest.h"] + +UNIFIED_SOURCES += ["OhttpClientTest.cpp"] + +XPCOM_MANIFESTS += ["components.conf"] + +XPIDL_MODULE = "widget_android_tests" + +XPIDL_SOURCES += [ + "nsIOhttpClientTest.idl", +] + +include("/ipc/chromium/chromium-config.mozbuild") + +FINAL_LIBRARY = "xul" diff --git a/widget/android/tests/nsIOhttpClientTest.idl b/widget/android/tests/nsIOhttpClientTest.idl new file mode 100644 index 000000000000..8ee780f45df3 --- /dev/null +++ b/widget/android/tests/nsIOhttpClientTest.idl @@ -0,0 +1,21 @@ +/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsISupports.idl" + +[function, scriptable, uuid(cdec8db3-3868-41e7-a91a-68a3b5a24de0)] +interface ohttpClientTestCallback : nsISupports +{ + void onResponse(in ACString url, in long statusCode, in Array headerKeys, in Array headerValues, in ACString errorMessage); +}; + +[scriptable, uuid(b3150bd2-689c-4cf0-b4ee-4f90aaf1cbd3)] +interface nsIOhttpClientTest : nsISupports +{ + void fetch( + in ACString url, in ACString method, in ACString body, in Array headerKeys, in Array headerValues, + in ohttpClientTestCallback callback + ); +};