Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion eng/AcquireWasiSdk.targets
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
-->
<Project>
<PropertyGroup>
<_WasiSdkVersion>25.0</_WasiSdkVersion>
<_WasiSdkVersion>33.0</_WasiSdkVersion>
<_RuntimeLocalWasiSdkPath>$([MSBuild]::NormalizeDirectory('$(ArtifactsDir)', 'wasi-sdk'))</_RuntimeLocalWasiSdkPath>
</PropertyGroup>

Expand Down
2 changes: 1 addition & 1 deletion eng/native/gen-buildsys.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ if /i "%__Arch%" == "wasm" (
set "WASI_SDK_PATH=%__repoRoot%\artifacts\wasi-sdk"
)
set __CmakeGenerator=Ninja
set __ExtraCmakeParams=%__ExtraCmakeParams% -DCLR_CMAKE_TARGET_OS=wasi "-DCMAKE_TOOLCHAIN_FILE=!WASI_SDK_PATH!/share/cmake/wasi-sdk-p2.cmake" "-DCMAKE_CROSSCOMPILING_EMULATOR=node --experimental-wasm-bigint --experimental-wasi-unstable-preview1"
set __ExtraCmakeParams=%__ExtraCmakeParams% -DCLR_CMAKE_TARGET_OS=wasi "-DCMAKE_TOOLCHAIN_FILE=!WASI_SDK_PATH!/share/cmake/wasi-sdk-p2.cmake"
)
) else (
set __ExtraCmakeParams=%__ExtraCmakeParams% "-DCMAKE_SYSTEM_VERSION=10.0"
Expand Down
2 changes: 1 addition & 1 deletion eng/native/gen-buildsys.sh
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ if [[ "$host_arch" == "wasm" ]]; then
exit 1
fi
fi
cmake_extra_defines_wasm=("-DCLR_CMAKE_TARGET_OS=wasi" "-DCMAKE_TOOLCHAIN_FILE=${WASI_SDK_PATH}/share/cmake/wasi-sdk-p2.cmake" "-DCMAKE_CROSSCOMPILING_EMULATOR=node --experimental-wasm-bigint --experimental-wasi-unstable-preview1")
cmake_extra_defines_wasm=("-DCLR_CMAKE_TARGET_OS=wasi" "-DCMAKE_TOOLCHAIN_FILE=${WASI_SDK_PATH}/share/cmake/wasi-sdk-p2.cmake")
else
echo "target_os was not specified"
exit 1
Expand Down
8 changes: 8 additions & 0 deletions eng/testing/tests.wasi.targets
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
<_XHarnessArgs >$(_XHarnessArgs) --engine-arg=--wasi --engine-arg=tcp</_XHarnessArgs>
<_XHarnessArgs >$(_XHarnessArgs) --engine-arg=--wasi --engine-arg=udp</_XHarnessArgs>
<_XHarnessArgs >$(_XHarnessArgs) --engine-arg=--wasi --engine-arg=allow-ip-name-lookup</_XHarnessArgs>
<_XHarnessArgs >$(_XHarnessArgs) --engine-arg=--wasi --engine-arg=hostcall-fuel=4294967295</_XHarnessArgs>
<_XHarnessArgs >$(_XHarnessArgs) --engine-arg=--env --engine-arg=DOTNET_WASI_PRINT_EXIT_CODE=1</_XHarnessArgs>
<_XHarnessArgs Condition="'$(WasmXHarnessArgsCli)' != ''" >$(_XHarnessArgs) $(WasmXHarnessArgsCli)</_XHarnessArgs>

Expand Down Expand Up @@ -87,6 +88,13 @@
<PropertyGroup Condition="'$(BuildAOTTestsOnHelix)' != 'true'">
<WasmBuildOnlyAfterPublish>true</WasmBuildOnlyAfterPublish>

<!-- Test projects are libraries (OutputType=Library), for which WasmGenerateAppBundle defaults to false.
Unlike browser (where the WebAssembly SDK bundles via static web assets), wasi has no such SDK, so the
in-tree WasiAppBuilder must run to populate the AppBundle. Force it on for local wasi test builds.
Set unconditionally: WasmApp.Common.targets is imported earlier and already defaulted this to 'false',
so a '== ''' guard would not take effect. A '/p:' override remains a global property and still wins. -->
<WasmGenerateAppBundle>true</WasmGenerateAppBundle>

<!-- wasm's publish targets will trigger publish, so we shouldn't do that -->
<PublishTestAsSelfContainedDependsOn />
<WasmNestedPublishAppDependsOn>PrepareForWasiBuildApp;$(WasmNestedPublishAppDependsOn)</WasmNestedPublishAppDependsOn>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ internal enum SocketEvents : int
}

[LibraryImport(Libraries.SystemNative, EntryPoint = "SystemNative_GetWasiSocketDescriptor")]
internal static unsafe partial Error GetWasiSocketDescriptor(IntPtr socket, IntPtr* entry);
internal static unsafe partial Error GetWasiSocketDescriptor(IntPtr socket, IntPtr* entry, int* socketType);

[LibraryImport(Libraries.SystemNative, EntryPoint = "SystemNative_WasiSubscribeSocketPollable")]
internal static partial int WasiSubscribeSocketPollable(int kind, int handle);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public HttpClientHandler_Authentication_Test(ITestOutputHelper output) : base(ou

[Theory]
[MemberData(nameof(Authentication_SocketsHttpHandler_TestData))]
[SkipOnPlatform(TestPlatforms.Wasi, "WASI HttpHandler does not support authentication")]
public async Task SocketsHttpHandler_Authentication_Succeeds(string authenticateHeader, bool result)
{
await HttpClientHandler_Authentication_Succeeds(authenticateHeader, result);
Expand Down Expand Up @@ -106,6 +107,7 @@ public static IEnumerable<object[]> Authentication_SocketsHttpHandler_TestData()

[Theory]
[MemberData(nameof(Authentication_TestData))]
[SkipOnPlatform(TestPlatforms.Wasi, "WASI HttpHandler does not support authentication")]
public async Task HttpClientHandler_Authentication_Succeeds(string authenticateHeader, bool result)
{
if (PlatformDetection.IsWindowsNanoServer)
Expand All @@ -132,6 +134,7 @@ await TestHelper.WhenAllCompletedOrAnyFailedWithTimeout(TestHelper.PassingTestTi
[InlineData("WWW-Authenticate: Basic realm=\"hello\"\r\nWWW-Authenticate: Basic realm=\"hello\"\r\n")]
[InlineData("WWW-Authenticate: Digest realm=\"hello\", nonce=\"hello\", algorithm=MD5\r\nWWW-Authenticate: Digest realm=\"hello\", nonce=\"hello\", algorithm=MD5\r\n")]
[InlineData("WWW-Authenticate: Digest realm=\"hello1\", nonce=\"hello\", algorithm=MD5\r\nWWW-Authenticate: Digest realm=\"hello\", nonce=\"hello\", algorithm=MD5\r\n")]
[SkipOnPlatform(TestPlatforms.Wasi, "WASI HttpHandler does not support authentication")]
public async Task HttpClientHandler_MultipleAuthenticateHeaders_WithSameAuth_Succeeds(string authenticateHeader)
{
if (IsWinHttpHandler)
Expand All @@ -145,6 +148,7 @@ public async Task HttpClientHandler_MultipleAuthenticateHeaders_WithSameAuth_Suc
[Theory]
[InlineData("WWW-Authenticate: Basic realm=\"hello\"\r\nWWW-Authenticate: Digest realm=\"hello\", nonce=\"hello\", algorithm=MD5\r\n")]
[InlineData("WWW-Authenticate: Digest realm=\"hello\", nonce=\"hello\", algorithm=MD5\r\nWWW-Authenticate: Basic realm=\"hello\"\r\n")]
[SkipOnPlatform(TestPlatforms.Wasi, "WASI HttpHandler does not support authentication")]
public async Task HttpClientHandler_MultipleAuthenticateHeaders_Succeeds(string authenticateHeader)
{
if (PlatformDetection.IsWindowsNanoServer)
Expand All @@ -164,6 +168,7 @@ await LoopbackServer.CreateServerAsync(async (server, url) =>
[Theory]
[InlineData("WWW-Authenticate: Basic realm=\"hello\"\r\nWWW-Authenticate: NTLM\r\n", "Basic", "Negotiate")]
[InlineData("WWW-Authenticate: Basic realm=\"hello\"\r\nWWW-Authenticate: Digest realm=\"hello\", nonce=\"hello\", algorithm=MD5\r\nWWW-Authenticate: NTLM\r\n", "Digest", "Negotiate")]
[SkipOnPlatform(TestPlatforms.Wasi, "WASI HttpHandler does not support authentication")]
public async Task HttpClientHandler_MultipleAuthenticateHeaders_PicksSupported(string authenticateHeader, string supportedAuth, string unsupportedAuth)
{
if (PlatformDetection.IsWindowsNanoServer)
Expand All @@ -189,6 +194,7 @@ await LoopbackServer.CreateServerAsync(async (server, url) =>
[Theory]
[InlineData("WWW-Authenticate: Basic realm=\"hello\"\r\n")]
[InlineData("WWW-Authenticate: Digest realm=\"hello\", nonce=\"testnonce\"\r\n")]
[SkipOnPlatform(TestPlatforms.Wasi, "WASI HttpHandler does not support authentication")]
public async Task HttpClientHandler_IncorrectCredentials_Fails(string authenticateHeader)
{
var options = new LoopbackServer.Options { Domain = Domain, Username = Username, Password = Password };
Expand Down Expand Up @@ -226,6 +232,7 @@ public static IEnumerable<object[]> Authentication_TestData()
[InlineData("NTLM")]
[InlineData("Kerberos")]
[InlineData("Negotiate")]
[SkipOnPlatform(TestPlatforms.Wasi, "WASI HttpHandler does not support PreAuthenticate")]
public async Task PreAuthenticate_NoPreviousAuthenticatedRequests_NoCredentialsSent(string? credCacheScheme)
{
const int NumRequests = 3;
Expand Down Expand Up @@ -268,6 +275,7 @@ await LoopbackServer.CreateClientAndServerAsync(async uri =>
[Theory]
[InlineData(null, "WWW-Authenticate: Basic realm=\"hello\"\r\n")]
[InlineData("Basic", "WWW-Authenticate: Basic realm=\"hello\"\r\n")]
[SkipOnPlatform(TestPlatforms.Wasi, "WASI HttpHandler does not support PreAuthenticate")]
public async Task PreAuthenticate_FirstRequestNoHeaderAndAuthenticates_SecondRequestPreauthenticates(string? credCacheScheme, string authResponse)
{
await LoopbackServer.CreateClientAndServerAsync(async uri =>
Expand Down Expand Up @@ -360,6 +368,7 @@ await LoopbackServer.CreateClientAndServerAsync(async uri =>
[InlineData((HttpStatusCode)508)] // LoopDetected
[InlineData((HttpStatusCode)510)] // NotExtended
[InlineData((HttpStatusCode)511)] // NetworkAuthenticationRequired
[SkipOnPlatform(TestPlatforms.Wasi, "WASI HttpHandler does not support PreAuthenticate")]
public async Task PreAuthenticate_FirstRequestNoHeader_SecondRequestVariousStatusCodes_ThirdRequestPreauthenticates(HttpStatusCode statusCode)
{
const string AuthResponse = "WWW-Authenticate: Basic realm=\"hello\"\r\n";
Expand Down Expand Up @@ -403,6 +412,7 @@ await LoopbackServer.CreateClientAndServerAsync(async uri =>
[InlineData("/something/hello.html", "/world.html", false)]
[InlineData("/something/hello.html", "/another/", false)]
[InlineData("/something/hello.html", "/another/hello.html", false)]
[SkipOnPlatform(TestPlatforms.Wasi, "WASI HttpHandler does not support PreAuthenticate")]
public async Task PreAuthenticate_AuthenticatedUrl_ThenTryDifferentUrl_SendsAuthHeaderOnlyIfPrefixMatches(
string originalRelativeUri, string secondRelativeUri, bool expectedAuthHeader)
{
Expand Down Expand Up @@ -442,6 +452,7 @@ await LoopbackServer.CreateClientAndServerAsync(async uri =>
}

[Fact]
[SkipOnPlatform(TestPlatforms.Wasi, "WASI HttpHandler does not support PreAuthenticate")]
public async Task PreAuthenticate_SuccessfulBasicButThenFails_DoesntLoopInfinitely()
{
await LoopbackServer.CreateClientAndServerAsync(async uri =>
Expand Down Expand Up @@ -480,6 +491,7 @@ await LoopbackServer.CreateClientAndServerAsync(async uri =>
}

[Fact]
[SkipOnPlatform(TestPlatforms.Wasi, "WASI HttpHandler does not support PreAuthenticate")]
public async Task PreAuthenticate_SuccessfulBasic_ThenDigestChallenged()
{
if (IsWinHttpHandler)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public abstract class HttpClientHandler_Proxy_Test : HttpClientHandlerTestBase
public HttpClientHandler_Proxy_Test(ITestOutputHelper output) : base(output) { }

[Fact]
[SkipOnPlatform(TestPlatforms.Wasi, "WASI HttpHandler does not support proxy")]
public async Task Dispose_HandlerWithProxy_ProxyNotDisposed()
{
if (IsWinHttpHandler && UseVersion >= HttpVersion20.Value)
Expand Down Expand Up @@ -655,6 +656,7 @@ await LoopbackServer.CreateClientAndServerAsync(async proxyUri =>
[Theory]
[InlineData(true)]
[InlineData(false)]
[SkipOnPlatform(TestPlatforms.Wasi, "WASI HttpHandler does not support proxy")]
public async Task ProxyTunnelRequest_UserAgentHeaderAdded(bool addUserAgentHeader)
{
if (IsWinHttpHandler)
Expand Down
22 changes: 12 additions & 10 deletions src/libraries/System.Net.Http/src/System.Net.Http.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -457,16 +457,18 @@
<Compile Include="System\Net\Http\WasiHttpHandler\WasiOutputStream.cs" />
<Compile Include="System\Net\Http\WasiHttpHandler\WasiInputStream.cs" />
<Compile Include="System\Net\Http\WasiHttpHandler\WasiHttp.cs" />
<Compile Include="System\Net\Http\WasiHttpHandler\WasiHttpWorld.wit.imports.wasi.clocks.v0_2_0.MonotonicClockInterop.cs" />
<Compile Include="System\Net\Http\WasiHttpHandler\WasiHttpWorld.wit.imports.wasi.http.v0_2_0.ITypes.cs" />
<Compile Include="System\Net\Http\WasiHttpHandler\WasiHttpWorld.wit.imports.wasi.http.v0_2_0.OutgoingHandlerInterop.cs" />
<Compile Include="System\Net\Http\WasiHttpHandler\WasiHttpWorld.wit.imports.wasi.http.v0_2_0.TypesInterop.cs" />
<Compile Include="System\Net\Http\WasiHttpHandler\WasiHttpWorld.wit.imports.wasi.io.v0_2_0.ErrorInterop.cs" />
<Compile Include="System\Net\Http\WasiHttpHandler\WasiHttpWorld.wit.imports.wasi.io.v0_2_0.IError.cs" />
<Compile Include="System\Net\Http\WasiHttpHandler\WasiHttpWorld.wit.imports.wasi.io.v0_2_0.IPoll.cs" />
<Compile Include="System\Net\Http\WasiHttpHandler\WasiHttpWorld.wit.imports.wasi.io.v0_2_0.IStreams.cs" />
<Compile Include="System\Net\Http\WasiHttpHandler\WasiHttpWorld.wit.imports.wasi.io.v0_2_0.PollInterop.cs" />
<Compile Include="System\Net\Http\WasiHttpHandler\WasiHttpWorld.wit.imports.wasi.io.v0_2_0.StreamsInterop.cs" />
<Compile Include="System\Net\Http\WasiHttpHandler\WasiHttpWorld.wit.Imports.wasi.clocks.v0_2_8.IMonotonicClockImports.cs" />
<Compile Include="System\Net\Http\WasiHttpHandler\WasiHttpWorld.wit.Imports.wasi.clocks.v0_2_8.MonotonicClockImportsInterop.cs" />
<Compile Include="System\Net\Http\WasiHttpHandler\WasiHttpWorld.wit.Imports.wasi.http.v0_2_8.IOutgoingHandlerImports.cs" />
<Compile Include="System\Net\Http\WasiHttpHandler\WasiHttpWorld.wit.Imports.wasi.http.v0_2_8.ITypesImports.cs" />
<Compile Include="System\Net\Http\WasiHttpHandler\WasiHttpWorld.wit.Imports.wasi.http.v0_2_8.OutgoingHandlerImportsInterop.cs" />
<Compile Include="System\Net\Http\WasiHttpHandler\WasiHttpWorld.wit.Imports.wasi.http.v0_2_8.TypesImportsInterop.cs" />
<Compile Include="System\Net\Http\WasiHttpHandler\WasiHttpWorld.wit.Imports.wasi.io.v0_2_8.ErrorImportsInterop.cs" />
<Compile Include="System\Net\Http\WasiHttpHandler\WasiHttpWorld.wit.Imports.wasi.io.v0_2_8.IErrorImports.cs" />
<Compile Include="System\Net\Http\WasiHttpHandler\WasiHttpWorld.wit.Imports.wasi.io.v0_2_8.IPollImports.cs" />
<Compile Include="System\Net\Http\WasiHttpHandler\WasiHttpWorld.wit.Imports.wasi.io.v0_2_8.IStreamsImports.cs" />
<Compile Include="System\Net\Http\WasiHttpHandler\WasiHttpWorld.wit.Imports.wasi.io.v0_2_8.PollImportsInterop.cs" />
<Compile Include="System\Net\Http\WasiHttpHandler\WasiHttpWorld.wit.Imports.wasi.io.v0_2_8.StreamsImportsInterop.cs" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,22 @@
// Generated by `wit-bindgen` 0.32.0. DO NOT EDIT!
// Generated by `wit-bindgen` 0.57.1. DO NOT EDIT!
// <auto-generated />
#nullable enable

using System;
using System.Runtime.CompilerServices;
using System.Collections;
using System.Runtime.InteropServices;
using System.Text;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;

namespace WasiHttpWorld {

internal interface IWasiHttpWorld {
internal interface IWasiHttpWorldImports{
}

internal readonly struct None {}

[StructLayout(LayoutKind.Sequential)]
internal readonly struct Result<Ok, Err>
[global::System.Runtime.InteropServices.StructLayoutAttribute(global::System.Runtime.InteropServices.LayoutKind.Sequential)]
internal readonly struct Result<TOk, TErr>
{
internal readonly byte Tag;
private readonly object value;
Expand All @@ -29,47 +27,54 @@ private Result(byte tag, object value)
this.value = value;
}

internal static Result<Ok, Err> ok(Ok ok)
internal static Result<TOk, TErr> Ok(TOk ok)
{
return new Result<Ok, Err>(OK, ok!);
return new Result<TOk, TErr>(Tags.Ok, ok!);
}

internal static Result<Ok, Err> err(Err err)
internal static Result<TOk, TErr> Err(TErr err)
{
return new Result<Ok, Err>(ERR, err!);
return new Result<TOk, TErr>(Tags.Err, err!);
}

internal bool IsOk => Tag == OK;
internal bool IsErr => Tag == ERR;
internal bool IsOk => Tag == Tags.Ok;
internal bool IsErr => Tag == Tags.Err;

internal Ok AsOk
internal TOk AsOk
{
get
{
if (Tag == OK)
return (Ok)value;
else
throw new ArgumentException("expected OK, got " + Tag);
if (Tag == Tags.Ok)
{
return (TOk)value;
}

throw new global::System.ArgumentException("expected k, got " + Tag);
Comment thread
pavelsavara marked this conversation as resolved.
}
}

internal Err AsErr
internal TErr AsErr
{
get
{
if (Tag == ERR)
return (Err)value;
else
throw new ArgumentException("expected ERR, got " + Tag);
if (Tag == Tags.Err)
{
return (TErr)value;
}

throw new global::System.ArgumentException("expected Err, got " + Tag);
}
}

internal const byte OK = 0;
internal const byte ERR = 1;
internal class Tags
{
internal const byte Ok = 0;
internal const byte Err = 1;
}
}

internal class Option<T> {
private static Option<T> none = new();
private static Option<T> none = new ();

private Option()
{
Expand All @@ -84,24 +89,13 @@ internal Option(T v)

internal static Option<T> None => none;

[MemberNotNullWhen(true, nameof(Value))]
[global::System.Diagnostics.CodeAnalysis.MemberNotNullWhenAttribute(true, nameof(Value))]
internal bool HasValue { get; }

internal T? Value { get; }
}

internal static class InteropString
{
internal static IntPtr FromString(string input, out int length)
{
var utf8Bytes = Encoding.UTF8.GetBytes(input);
length = utf8Bytes.Length;
var gcHandle = GCHandle.Alloc(utf8Bytes, GCHandleType.Pinned);
return gcHandle.AddrOfPinnedObject();
}
}

internal class WitException: Exception {
internal class WitException: global::System.Exception {
internal object Value { get; }
internal uint NestingLevel { get; }

Expand All @@ -112,10 +106,25 @@ internal WitException(object v, uint level)
}
}

namespace exports {
internal static class WasiHttpWorld
internal class WitException<T>: WitException {
internal T TypedValue { get { return (T)this.Value;} }

internal WitException(T v, uint level) : base(v!, level)
{
}
}

internal static class MemoryHelper
{
internal static unsafe void* AlignStackPtr(void* stackAddress, uint alignment)
{
return (void*)(((nint)stackAddress) + ((int)alignment - 1) & -(int)alignment);
}
}

namespace Imports {
internal partial class WasiHttpWorldImportsInterop : IWasiHttpWorldImports
{}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
using System.Threading;
using System.Threading.Tasks;
using WasiHttpWorld;
using WasiHttpWorld.wit.imports.wasi.http.v0_2_0;
using WasiHttpWorld.wit.imports.wasi.io.v0_2_0;
using static WasiHttpWorld.wit.imports.wasi.http.v0_2_0.ITypes;
using WasiHttpWorld.wit.Imports.wasi.http.v0_2_8;
using WasiHttpWorld.wit.Imports.wasi.io.v0_2_8;
using static WasiHttpWorld.wit.Imports.wasi.http.v0_2_8.ITypesImports;

namespace System.Net.Http
{
Expand Down Expand Up @@ -48,7 +48,7 @@ public async Task<HttpResponseMessage> SendRequestAsync(HttpRequestMessage reque
#pragma warning restore CA2025
#pragma warning restore CS4014

future = OutgoingHandlerInterop.Handle(outgoingRequest, null);
future = IOutgoingHandlerImports.Handle(outgoingRequest, null);

using var incomingResponse = await SendRequest(cancellationToken).ConfigureAwait(false);

Expand Down
Loading
Loading