diff --git a/eng/testing/scenarios/BuildWasmAppsJobsList.txt b/eng/testing/scenarios/BuildWasmAppsJobsList.txt
index 38a666c61e7341..6995c5db62758c 100644
--- a/eng/testing/scenarios/BuildWasmAppsJobsList.txt
+++ b/eng/testing/scenarios/BuildWasmAppsJobsList.txt
@@ -47,3 +47,5 @@ Wasm.Build.Tests.WorkloadTests
Wasm.Build.Tests.MT.Blazor.SimpleMultiThreadedTests
Wasm.Build.Tests.DebugLevelTests
Wasm.Build.Tests.PreloadingTests
+Wasm.Build.Tests.EnvVariablesTests
+Wasm.Build.Tests.HttpTests
diff --git a/src/mono/browser/browser.proj b/src/mono/browser/browser.proj
index de5f97ca003809..83e4c3ca3f8e4e 100644
--- a/src/mono/browser/browser.proj
+++ b/src/mono/browser/browser.proj
@@ -335,7 +335,6 @@
"PropertiesThatTriggerRelinking": [
{ "identity": "InvariantTimezone", "defaultValueInRuntimePack": "$(InvariantTimezone)" },
{ "identity": "InvariantGlobalization", "defaultValueInRuntimePack": "$(InvariantGlobalization)" },
- { "identity": "WasmEnableStreamingResponse", "defaultValueInRuntimePack": "$(WasmEnableStreamingResponse)" },
{ "identity": "WasmNativeStrip", "defaultValueInRuntimePack": "$(WasmNativeStrip)" },
{ "identity": "WasmSingleFileBundle", "defaultValueInRuntimePack": "$(WasmSingleFileBundle)" },
{ "identity": "WasmEnableSIMD", "defaultValueInRuntimePack": "$(WasmEnableSIMD)" },
diff --git a/src/mono/browser/build/BrowserWasmApp.targets b/src/mono/browser/build/BrowserWasmApp.targets
index d73b97ec616e92..d5c3925ff068a5 100644
--- a/src/mono/browser/build/BrowserWasmApp.targets
+++ b/src/mono/browser/build/BrowserWasmApp.targets
@@ -181,7 +181,7 @@
WasmIcuDataFileName="$(WasmIcuDataFileName)"
RuntimeAssetsLocation="$(WasmRuntimeAssetsLocation)"
CacheBootResources="$(BlazorCacheBootResources)"
- RuntimeConfigJsonPath="$(_WasmRuntimeConfigFilePath)"
+ RuntimeConfigJsonPath="$(ProjectRuntimeConfigFilePath)"
IsAot="$(RunAOTCompilation)"
IsMultiThreaded="$(WasmEnableThreads)"
>
diff --git a/src/mono/browser/build/WasmApp.InTree.targets b/src/mono/browser/build/WasmApp.InTree.targets
index 580fed8bf8f2fb..76de4a1b97410a 100644
--- a/src/mono/browser/build/WasmApp.InTree.targets
+++ b/src/mono/browser/build/WasmApp.InTree.targets
@@ -2,7 +2,6 @@
-
diff --git a/src/mono/browser/runtime/cwraps.ts b/src/mono/browser/runtime/cwraps.ts
index 72da390f74f8d1..74cf261bc5e1ec 100644
--- a/src/mono/browser/runtime/cwraps.ts
+++ b/src/mono/browser/runtime/cwraps.ts
@@ -46,7 +46,7 @@ const fn_signatures: SigLine[] = [
[true, "mono_wasm_load_icu_data", "number", ["number"]],
[false, "mono_wasm_add_assembly", "number", ["string", "number", "number"]],
[true, "mono_wasm_add_satellite_assembly", "void", ["string", "string", "number", "number"]],
- [false, "mono_wasm_load_runtime", null, ["number"]],
+ [false, "mono_wasm_load_runtime", null, ["number", "number", "number", "number"]],
[true, "mono_wasm_change_debugger_log_level", "void", ["number"]],
[true, "mono_wasm_assembly_load", "number", ["string"]],
@@ -173,7 +173,7 @@ export interface t_Cwraps {
mono_wasm_load_icu_data(offset: VoidPtr): number;
mono_wasm_add_assembly(name: string, data: VoidPtr, size: number): number;
mono_wasm_add_satellite_assembly(name: string, culture: string, data: VoidPtr, size: number): void;
- mono_wasm_load_runtime(debugLevel: number): void;
+ mono_wasm_load_runtime(debugLevel: number, propertyCount:number, propertyKeys:CharPtrPtr, propertyValues:CharPtrPtr): void;
mono_wasm_change_debugger_log_level(value: number): void;
mono_wasm_assembly_load(name: string): MonoAssembly;
diff --git a/src/mono/browser/runtime/dotnet.d.ts b/src/mono/browser/runtime/dotnet.d.ts
index 85cc8a6b7106e7..07428895e9d44f 100644
--- a/src/mono/browser/runtime/dotnet.d.ts
+++ b/src/mono/browser/runtime/dotnet.d.ts
@@ -192,6 +192,16 @@ type MonoConfig = {
environmentVariables?: {
[i: string]: string;
};
+ /**
+ * Subset of runtimeconfig.json
+ */
+ runtimeConfig?: {
+ runtimeOptions?: {
+ configProperties?: {
+ [i: string]: string | number | boolean;
+ };
+ };
+ };
/**
* initial number of workers to add to the emscripten pthread pool
*/
diff --git a/src/mono/browser/runtime/driver.c b/src/mono/browser/runtime/driver.c
index 5a49b7753aa583..120abb1dff92a1 100644
--- a/src/mono/browser/runtime/driver.c
+++ b/src/mono/browser/runtime/driver.c
@@ -63,8 +63,6 @@ int mono_regression_test_step (int verbose_level, char *image, char *method_name
static MonoDomain *root_domain;
-#define RUNTIMECONFIG_BIN_FILE "runtimeconfig.bin"
-
extern void mono_wasm_trace_logger (const char *log_domain, const char *log_level, const char *message, mono_bool fatal, void *user_data);
static void
@@ -184,7 +182,7 @@ cleanup_runtime_config (MonovmRuntimeConfigArguments *args, void *user_data)
static int runtime_initialized = 0;
EMSCRIPTEN_KEEPALIVE void
-mono_wasm_load_runtime (int debug_level)
+mono_wasm_load_runtime (int debug_level, int propertyCount, const char **propertyKeys, const char **propertyValues)
{
runtime_initialized = 1;
const char *interp_opts = "";
@@ -193,34 +191,7 @@ mono_wasm_load_runtime (int debug_level)
mono_wasm_link_icu_shim ();
#endif
- // When the list of app context properties changes, please update RuntimeConfigReservedProperties for
- // target _WasmGenerateRuntimeConfig in BrowserWasmApp.targets file
- const char *appctx_keys[2];
- appctx_keys [0] = "APP_CONTEXT_BASE_DIRECTORY";
- appctx_keys [1] = "RUNTIME_IDENTIFIER";
-
- const char *appctx_values[2];
- appctx_values [0] = "/";
- appctx_values [1] = "browser-wasm";
-
- char *file_name = RUNTIMECONFIG_BIN_FILE;
- int str_len = strlen (file_name) + 1; // +1 is for the "/"
- char *file_path = (char *)malloc (sizeof (char) * (str_len +1)); // +1 is for the terminating null character
- int num_char = snprintf (file_path, (str_len + 1), "/%s", file_name);
- struct stat buffer;
-
- assert (num_char > 0 && num_char == str_len);
-
- if (stat (file_path, &buffer) == 0) {
- MonovmRuntimeConfigArguments *arg = (MonovmRuntimeConfigArguments *)malloc (sizeof (MonovmRuntimeConfigArguments));
- arg->kind = 0;
- arg->runtimeconfig.name.path = file_path;
- monovm_runtimeconfig_initialize (arg, cleanup_runtime_config, file_path);
- } else {
- free (file_path);
- }
-
- monovm_initialize (2, appctx_keys, appctx_values);
+ monovm_initialize (propertyCount, propertyKeys, propertyValues);
#ifndef INVARIANT_TIMEZONE
char* invariant_timezone = monoeg_g_getenv ("DOTNET_SYSTEM_TIMEZONE_INVARIANT");
@@ -237,7 +208,17 @@ int initialize_runtime()
{
if (runtime_initialized == 1)
return 0;
- mono_wasm_load_runtime (0);
+
+ const char *appctx_keys[2];
+ appctx_keys [0] = "APP_CONTEXT_BASE_DIRECTORY";
+ appctx_keys [1] = "RUNTIME_IDENTIFIER";
+
+ const char *appctx_values[2];
+ appctx_values [0] = "/";
+ appctx_values [1] = "browser-wasm";
+
+ // this does not support loading runtimeConfig.json part of boot.config.json
+ mono_wasm_load_runtime (0, 2, appctx_keys, appctx_values);
return 0;
}
diff --git a/src/mono/browser/runtime/startup.ts b/src/mono/browser/runtime/startup.ts
index 60ab49bc0f6611..325caeb4cd1a98 100644
--- a/src/mono/browser/runtime/startup.ts
+++ b/src/mono/browser/runtime/startup.ts
@@ -13,10 +13,10 @@ import { mono_wasm_init_aot_profiler, mono_wasm_init_devtools_profiler, mono_was
import { initialize_marshalers_to_cs } from "./marshal-to-cs";
import { initialize_marshalers_to_js } from "./marshal-to-js";
import { init_polyfills_async } from "./polyfills";
-import { strings_init, utf8ToString } from "./strings";
+import { strings_init, stringToUTF8Ptr, utf8ToString } from "./strings";
import { init_managed_exports } from "./managed-exports";
import { cwraps_internal } from "./exports-internal";
-import { CharPtr, EmscriptenModule, InstantiateWasmCallBack, InstantiateWasmSuccessCallback } from "./types/emscripten";
+import { CharPtr, CharPtrPtr, EmscriptenModule, InstantiateWasmCallBack, InstantiateWasmSuccessCallback, VoidPtr } from "./types/emscripten";
import { wait_for_all_assets } from "./assets";
import { replace_linker_placeholders } from "./exports-binding";
import { endMeasure, MeasuredBlock, startMeasure } from "./profiler";
@@ -28,7 +28,7 @@ import { populateEmscriptenPool, mono_wasm_init_threads } from "./pthreads";
import { currentWorkerThreadEvents, dotnetPthreadCreated, initWorkerThreadEvents, monoThreadInfo } from "./pthreads";
import { mono_wasm_pthread_ptr, update_thread_info } from "./pthreads";
import { jiterpreter_allocate_tables } from "./jiterpreter-support";
-import { localHeapViewU8, malloc } from "./memory";
+import { localHeapViewU8, malloc, setU32 } from "./memory";
import { assertNoProxies } from "./gc-handles";
import { runtimeList } from "./exports";
import { nativeAbort, nativeExit } from "./run";
@@ -617,7 +617,41 @@ export function mono_wasm_load_runtime (): void {
if (!loaderHelpers.isDebuggingSupported() || !runtimeHelpers.config.resources!.pdb) {
debugLevel = 0;
}
- cwraps.mono_wasm_load_runtime(debugLevel);
+
+ const runtimeConfigProperties = new Map();
+ if (runtimeHelpers.config.runtimeConfig?.runtimeOptions?.configProperties) {
+ for (const [key, value] of Object.entries(runtimeHelpers.config.runtimeConfig?.runtimeOptions?.configProperties)) {
+ runtimeConfigProperties.set(key, "" + value);
+ }
+ }
+ runtimeConfigProperties.set("APP_CONTEXT_BASE_DIRECTORY", "/");
+ runtimeConfigProperties.set("RUNTIME_IDENTIFIER", "browser-wasm");
+ const propertyCount = runtimeConfigProperties.size;
+
+ const buffers:VoidPtr[] = [];
+ const appctx_keys = malloc(4 * runtimeConfigProperties.size) as any as CharPtrPtr;
+ const appctx_values = malloc(4 * runtimeConfigProperties.size) as any as CharPtrPtr;
+ buffers.push(appctx_keys as any);
+ buffers.push(appctx_values as any);
+
+ let position = 0;
+ for (const [key, value] of runtimeConfigProperties.entries()) {
+ const keyPtr = stringToUTF8Ptr(key);
+ const valuePtr = stringToUTF8Ptr(value);
+ setU32((appctx_keys as any) + (position * 4), keyPtr);
+ setU32((appctx_values as any) + (position * 4), valuePtr);
+ position++;
+ buffers.push(keyPtr as any);
+ buffers.push(valuePtr as any);
+ }
+
+ cwraps.mono_wasm_load_runtime(debugLevel, propertyCount, appctx_keys, appctx_values);
+
+ // free the buffers
+ for (const buffer of buffers) {
+ Module._free(buffer);
+ }
+
endMeasure(mark, MeasuredBlock.loadRuntime);
} catch (err: any) {
diff --git a/src/mono/browser/runtime/types/index.ts b/src/mono/browser/runtime/types/index.ts
index b651b6828e210f..2be4b9be28ea2e 100644
--- a/src/mono/browser/runtime/types/index.ts
+++ b/src/mono/browser/runtime/types/index.ts
@@ -144,6 +144,16 @@ export type MonoConfig = {
environmentVariables?: {
[i: string]: string;
},
+ /**
+ * Subset of runtimeconfig.json
+ */
+ runtimeConfig?: {
+ runtimeOptions?: {
+ configProperties?: {
+ [i: string]: string | number | boolean;
+ }
+ }
+ },
/**
* initial number of workers to add to the emscripten pthread pool
*/
diff --git a/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets b/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets
index 6d84ca64f64f23..ba6e8b09fdecc1 100644
--- a/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets
+++ b/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets
@@ -130,6 +130,7 @@ Copyright (c) .NET Foundation. All rights reserved.
$(GenerateBuildWasmBootJsonDependsOn);
+ GenerateBuildRuntimeConfigurationFiles;
ResolveWasmOutputs;
@@ -403,6 +404,7 @@ Copyright (c) .NET Foundation. All rights reserved.
Extensions="@(WasmBootConfigExtension)"
EnvVariables="@(WasmEnvironmentVariable)"
Profilers="$(_WasmProfilers)"
+ RuntimeConfigJsonPath="$(ProjectRuntimeConfigFilePath)"
TargetFrameworkVersion="$(TargetFrameworkVersion)"
ModuleAfterConfigLoaded="@(WasmModuleAfterConfigLoaded)"
ModuleAfterRuntimeReady="@(WasmModuleAfterRuntimeReady)"
@@ -810,6 +812,7 @@ Copyright (c) .NET Foundation. All rights reserved.
RuntimeOptions="$(_BlazorWebAssemblyRuntimeOptions)"
EnvVariables="@(WasmEnvironmentVariable)"
Profilers="$(_WasmProfilers)"
+ RuntimeConfigJsonPath="$(ProjectRuntimeConfigFilePath)"
Extensions="@(WasmBootConfigExtension)"
TargetFrameworkVersion="$(TargetFrameworkVersion)"
ModuleAfterConfigLoaded="@(WasmModuleAfterConfigLoaded)"
diff --git a/src/mono/wasi/build/WasiApp.props b/src/mono/wasi/build/WasiApp.props
index b2f79014de3ec3..fed1e144913b91 100644
--- a/src/mono/wasi/build/WasiApp.props
+++ b/src/mono/wasi/build/WasiApp.props
@@ -10,4 +10,16 @@
+
+
+
+ _PrepareForNestedPublish;
+ $(WasmNestedPublishAppDependsOn);
+
+
+ $(PrepareInputsForWasmBuildDependsOn);
+ _WasmGetRuntimeConfigPath;
+
+
+
diff --git a/src/mono/wasi/build/WasiApp.targets b/src/mono/wasi/build/WasiApp.targets
index 8eaf68c07bd1eb..a0133219afb7cb 100644
--- a/src/mono/wasi/build/WasiApp.targets
+++ b/src/mono/wasi/build/WasiApp.targets
@@ -11,12 +11,14 @@
+ _WasmGenerateRuntimeConfig;
$(WasmLinkDotNetDependsOn);
_WasiLinkDotNet;
$(WasmGenerateAppBundleDependsOn);
+ _WasmGenerateRuntimeConfig;
_GetWasiGenerateAppBundleDependencies;
_WasiGenerateAppBundle;
_GenerateRunWasmtimeScript;
@@ -46,6 +48,44 @@
+
+
+ <_RuntimeConfigReservedProperties Include="RUNTIME_IDENTIFIER"/>
+ <_RuntimeConfigReservedProperties Include="APP_CONTEXT_BASE_DIRECTORY"/>
+
+
+
+
+
+
+
+
+
+
+
+
+ <_MainAssemblyPath Condition="'%(WasmAssembliesToBundle.FileName)' == '$(AssemblyName)' and '%(WasmAssembliesToBundle.Extension)' == '.dll' and $(WasmGenerateAppBundle) == 'true'">%(WasmAssembliesToBundle.Identity)
+ <_WasmRuntimeConfigFilePath Condition="'$(_WasmRuntimeConfigFilePath)' == '' and $(_MainAssemblyPath) != ''">$([System.IO.Path]::ChangeExtension($(_MainAssemblyPath), '.runtimeconfig.json'))
+ <_ParsedRuntimeConfigFilePath Condition="'$(_WasmRuntimeConfigFilePath)' != ''">$([System.IO.Path]::GetDirectoryName($(_WasmRuntimeConfigFilePath)))\runtimeconfig.bin
+
+
+
+
+
+ <_WasmRuntimeConfigFilePath Condition="$([System.String]::new(%(PublishItemsOutputGroupOutputs.Identity)).EndsWith('$(AssemblyName).runtimeconfig.json'))">@(PublishItemsOutputGroupOutputs)
+
+
+
+ <_WasmRuntimeConfigFilePath Condition="$([System.String]::new(%(PublishItemsOutputGroupOutputs.Identity)).EndsWith('$(AssemblyName).runtimeconfig.json'))">@(PublishItemsOutputGroupOutputs)
+
+
+
diff --git a/src/mono/wasm/Wasm.Build.Tests/HttpTests.cs b/src/mono/wasm/Wasm.Build.Tests/HttpTests.cs
new file mode 100644
index 00000000000000..c33e68ffd32c22
--- /dev/null
+++ b/src/mono/wasm/Wasm.Build.Tests/HttpTests.cs
@@ -0,0 +1,36 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Text.RegularExpressions;
+using Xunit.Abstractions;
+using Xunit;
+
+#nullable enable
+
+namespace Wasm.Build.Tests;
+
+public class HttpTests : WasmTemplateTestsBase
+{
+ public HttpTests(ITestOutputHelper output, SharedBuildPerTestClassFixture buildContext)
+ : base(output, buildContext)
+ {
+ }
+
+ [Fact]
+ // testing that WasmEnableStreamingResponse=false MSbuild prop is passed to the app and HTTP behaves as expected
+ public async Task HttpNoStreamingTest()
+ {
+ Configuration config = Configuration.Release;
+ ProjectInfo info = CopyTestAsset(config, false, TestAsset.WasmBasicTestApp, "HttpTest");
+
+ BuildProject(info, config, new BuildOptions(ExtraMSBuildArgs: "-p:WasmEnableStreamingResponse=false",AssertAppBundle: false), isNativeBuild: false);
+
+ var result = await RunForBuildWithDotnetRun(new BrowserRunOptions(Configuration: config, TestScenario: "HttpNoStreamingTest"));
+ Assert.Contains("AppContext WasmEnableStreamingResponse=false", result.TestOutput);
+ Assert.Contains("baz=boo", result.TestOutput);
+ }
+}
diff --git a/src/mono/wasm/build/WasmApp.Common.props b/src/mono/wasm/build/WasmApp.Common.props
index f74fa9acda0be1..9884d97b1d20bf 100644
--- a/src/mono/wasm/build/WasmApp.Common.props
+++ b/src/mono/wasm/build/WasmApp.Common.props
@@ -18,7 +18,6 @@
- _PrepareForNestedPublish;
_WasmBuildAppCore;
diff --git a/src/mono/wasm/build/WasmApp.Common.targets b/src/mono/wasm/build/WasmApp.Common.targets
index 7941eba7030a0c..a65a79440aafcd 100644
--- a/src/mono/wasm/build/WasmApp.Common.targets
+++ b/src/mono/wasm/build/WasmApp.Common.targets
@@ -125,12 +125,10 @@
_ReadWasmProps;
_SetWasmBuildNativeDefaults;
_GetDefaultWasmAssembliesToBundle;
- _WasmGetRuntimeConfigPath;
$(WasmGenerateAppBundleDependsOn);
- _WasmGenerateRuntimeConfig;
@@ -152,7 +150,6 @@
_WasmSelectRuntimeComponentsForLinking;
_WasmCompileAssemblyBitCodeFilesForAOT;
_WasmCalculateInitialHeapSizeFromBitcodeFiles;
- _WasmGenerateRuntimeConfig;
_WasmWriteRspForCompilingNativeSourceFiles;
_WasmCompileNativeSourceFiles;
_GenerateObjectFilesForSingleFileBundle;
@@ -350,14 +347,6 @@
-
-
- <_MainAssemblyPath Condition="'%(WasmAssembliesToBundle.FileName)' == '$(AssemblyName)' and '%(WasmAssembliesToBundle.Extension)' == '.dll' and $(WasmGenerateAppBundle) == 'true'">%(WasmAssembliesToBundle.Identity)
- <_WasmRuntimeConfigFilePath Condition="'$(_WasmRuntimeConfigFilePath)' == '' and $(_MainAssemblyPath) != ''">$([System.IO.Path]::ChangeExtension($(_MainAssemblyPath), '.runtimeconfig.json'))
- <_ParsedRuntimeConfigFilePath Condition="'$(_WasmRuntimeConfigFilePath)' != ''">$([System.IO.Path]::GetDirectoryName($(_WasmRuntimeConfigFilePath)))\runtimeconfig.bin
-
-
-
-
-
- <_RuntimeConfigReservedProperties Include="RUNTIME_IDENTIFIER"/>
- <_RuntimeConfigReservedProperties Include="APP_CONTEXT_BASE_DIRECTORY"/>
-
-
-
-
-
-
-
-
-
-
@@ -482,16 +451,6 @@
-
-
- <_WasmRuntimeConfigFilePath Condition="$([System.String]::new(%(PublishItemsOutputGroupOutputs.Identity)).EndsWith('$(AssemblyName).runtimeconfig.json'))">@(PublishItemsOutputGroupOutputs)
-
-
-
- <_WasmRuntimeConfigFilePath Condition="$([System.String]::new(%(PublishItemsOutputGroupOutputs.Identity)).EndsWith('$(AssemblyName).runtimeconfig.json'))">@(PublishItemsOutputGroupOutputs)
-
-
-
diff --git a/src/mono/wasm/build/WasmApp.LocalBuild.targets b/src/mono/wasm/build/WasmApp.LocalBuild.targets
index bedbba30750c07..31dcd68be03259 100644
--- a/src/mono/wasm/build/WasmApp.LocalBuild.targets
+++ b/src/mono/wasm/build/WasmApp.LocalBuild.targets
@@ -24,7 +24,6 @@
-
true
diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/App/HttpTest.cs b/src/mono/wasm/testassets/WasmBasicTestApp/App/HttpTest.cs
new file mode 100644
index 00000000000000..4a24a3ca39d3db
--- /dev/null
+++ b/src/mono/wasm/testassets/WasmBasicTestApp/App/HttpTest.cs
@@ -0,0 +1,48 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.IO;
+using System.Net.Http;
+using System.Threading.Tasks;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices.JavaScript;
+
+public partial class HttpTest
+{
+ private static bool FeatureEnableStreamingResponse { get; } = AppContext.TryGetSwitch("System.Net.Http.WasmEnableStreamingResponse", out bool value) ? value : true;
+
+ [JSExport]
+ public static async Task HttpNoStreamingTest()
+ {
+ Console.WriteLine($"AppContext FeatureEnableStreamingResponse={FeatureEnableStreamingResponse}");
+ if(FeatureEnableStreamingResponse)
+ {
+ Console.WriteLine("FeatureEnableStreamingResponse is true, this test is not valid.");
+ return -1;
+ }
+
+ var uri = GetOriginUrl() + "/main.js";
+ using var client = new HttpClient();
+ using var response = await client.GetAsync(uri);
+
+ var contentType = response.Content.GetType();
+
+ Console.WriteLine("response.Content is " + contentType.FullName);
+ if (contentType == typeof(StreamContent))
+ {
+ Console.WriteLine($"response.Content is {contentType.FullName}");
+ return -2;
+ }
+
+ return 42;
+ }
+
+ public static string GetOriginUrl()
+ {
+ using var globalThis = JSHost.GlobalThis;
+ using var document = globalThis.GetPropertyAsJSObject("document");
+ using var location = globalThis.GetPropertyAsJSObject("location");
+ return location.GetPropertyAsString("origin");
+ }
+}
diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/App/wwwroot/main.js b/src/mono/wasm/testassets/WasmBasicTestApp/App/wwwroot/main.js
index b4a5b04d5af5c6..5d8213a12ab908 100644
--- a/src/mono/wasm/testassets/WasmBasicTestApp/App/wwwroot/main.js
+++ b/src/mono/wasm/testassets/WasmBasicTestApp/App/wwwroot/main.js
@@ -166,6 +166,8 @@ switch (testCase) {
case "EnvVariablesTest":
dotnet.withEnvironmentVariable("foo", "bar");
break;
+ case "HttpNoStreamingTest":
+ break;
case "BrowserProfilerTest":
break;
case "OverrideBootConfigName":
@@ -256,6 +258,29 @@ try {
exports.MemoryTest.Run();
exit(0);
break;
+ case "HttpNoStreamingTest":
+ console.log("not ready yet")
+ const myExportsHttp = await getAssemblyExports(config.mainAssemblyName);
+ const httpNoStreamingTest = myExportsHttp.HttpTest.HttpNoStreamingTest;
+ console.log("ready");
+ if (config.runtimeConfig.runtimeOptions.configProperties) {
+ const configProperties = config.runtimeConfig.runtimeOptions.configProperties;
+ console.log("configProperties: " + Object.keys(configProperties).length);
+ const wasmEnableStreamingResponse = configProperties["System.Net.Http.WasmEnableStreamingResponse"];
+ if (wasmEnableStreamingResponse === undefined) {
+ exit(2);
+ }
+ if (wasmEnableStreamingResponse === true) {
+ exit(3);
+ }
+ }
+
+ const retHttp = await httpNoStreamingTest();
+ document.getElementById("out").innerHTML = retHttp;
+ console.debug(`ret: ${retHttp}`);
+
+ exit(retHttp == 42 ? 0 : 1);
+ break;
case "EnvVariablesTest":
console.log("not ready yet")
const myExportsEnv = await getAssemblyExports(config.mainAssemblyName);
diff --git a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/BootJsonData.cs b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/BootJsonData.cs
index f8c0761c76494b..846a7b3bfe65c6 100644
--- a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/BootJsonData.cs
+++ b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/BootJsonData.cs
@@ -104,6 +104,10 @@ public class BootJsonData
/// Gets or sets environment variables.
///
public System.Collections.Generic.Dictionary environmentVariables { get; set; }
+ ///
+ /// Subset of runtimeconfig.json
+ ///
+ public RuntimeConfigData runtimeConfig { get; set; }
///
/// Gets or sets diagnostic tracing.
@@ -121,6 +125,25 @@ public class BootJsonData
public int? pthreadPoolUnusedSize { get; set; }
}
+///
+/// Subset of runtimeconfig.json
+///
+public class RuntimeConfigData
+{
+ ///
+ /// Runtime options
+ ///
+ public RuntimeOptionsData runtimeOptions { get; set; }
+}
+
+public class RuntimeOptionsData
+{
+ ///
+ /// Config properties for the runtime
+ ///
+ public Dictionary configProperties { get; set; }
+}
+
public class ResourcesData
{
///
diff --git a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/GenerateWasmBootJson.cs b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/GenerateWasmBootJson.cs
index b84b5a3109b9dd..b48a733b739ae1 100644
--- a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/GenerateWasmBootJson.cs
+++ b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/GenerateWasmBootJson.cs
@@ -62,6 +62,8 @@ public class GenerateWasmBootJson : Task
public string[]? Profilers { get; set; }
+ public string? RuntimeConfigJsonPath { get; set; }
+
public string StartupMemoryCache { get; set; }
public string Jiterpreter { get; set; }
@@ -435,6 +437,14 @@ private void WriteBootConfig(string entryAssemblyName)
result.extensions[key] = config;
}
}
+
+ if (RuntimeConfigJsonPath != null && File.Exists(RuntimeConfigJsonPath))
+ {
+ using var fs = File.OpenRead(RuntimeConfigJsonPath);
+ var runtimeConfig = JsonSerializer.Deserialize(fs, BootJsonBuilderHelper.JsonOptions);
+ result.runtimeConfig = runtimeConfig;
+ }
+
Profilers ??= Array.Empty();
var browserProfiler = Profilers.FirstOrDefault(p => p.StartsWith("browser:"));
if (browserProfiler != null)
diff --git a/src/tasks/WasmAppBuilder/WasmAppBuilder.cs b/src/tasks/WasmAppBuilder/WasmAppBuilder.cs
index bea5d8fbf7eb67..87980f370ff824 100644
--- a/src/tasks/WasmAppBuilder/WasmAppBuilder.cs
+++ b/src/tasks/WasmAppBuilder/WasmAppBuilder.cs
@@ -397,7 +397,7 @@ protected override bool ExecuteInternal()
var envs = (JsonElement)valueObject!;
foreach (var env in envs.EnumerateObject())
{
- bootConfig.environmentVariables[env.Name] = env.Value.GetString();
+ bootConfig.environmentVariables[env.Name] = env.Value.GetString()!;
}
}
else if (string.Equals(name, nameof(BootJsonData.diagnosticTracing), StringComparison.OrdinalIgnoreCase))
@@ -421,6 +421,13 @@ protected override bool ExecuteInternal()
bootConfig.environmentVariables["DOTNET_WasmPerfInstrumentation"] = browserProfiler.Substring("browser:".Length);
}
+ if (RuntimeConfigJsonPath != null && File.Exists(RuntimeConfigJsonPath))
+ {
+ using var fs = File.OpenRead(RuntimeConfigJsonPath);
+ var runtimeConfig = JsonSerializer.Deserialize(fs, BootJsonBuilderHelper.JsonOptions);
+ bootConfig.runtimeConfig = runtimeConfig;
+ }
+
foreach (ITaskItem env in EnvVariables ?? Enumerable.Empty())
{
bootConfig.environmentVariables ??= new();