Skip to content

Commit

Permalink
[wasi] wasi:http + WasiHttpHandler (dotnet#103752)
Browse files Browse the repository at this point in the history
Co-authored-by: Joel Dice <joel.dice@fermyon.com>
  • Loading branch information
pavelsavara and dicej committed Aug 1, 2024
1 parent c0a31c5 commit 0e8db73
Show file tree
Hide file tree
Showing 46 changed files with 10,266 additions and 41 deletions.
1 change: 1 addition & 0 deletions eng/liveBuilds.targets
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@
<LibrariesRuntimeFiles
Include="
$(LibrariesNativeArtifactsPath)dotnet.wasm;
$(LibrariesNativeArtifactsPath)*.wit;
$(LibrariesNativeArtifactsPath)*.dat;"
IsNative="true" />

Expand Down
2 changes: 1 addition & 1 deletion eng/testing/linker/SupportFiles/Directory.Build.targets
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<Target Name="CreateTestWasmAppBundle"
AfterTargets="Publish"
DependsOnTargets="BundleTestWasmApp"
Condition="'$(TargetArchitecture)' == 'wasm' And '$(TargetOS)' == 'browser'" />
Condition="'$(TargetOS)' == 'browser' or '$(TargetOS)' == 'wasi'" />

<PropertyGroup Condition="'$(PublishAot)' == 'true'">
<_IlcReferencedAsPackage>false</_IlcReferencedAsPackage>
Expand Down
4 changes: 3 additions & 1 deletion eng/testing/tests.wasi.targets
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@
<_XHarnessArgs Condition="'$(IsFunctionalTest)' == 'true'" >$(_XHarnessArgs) --expected-exit-code=$(ExpectedExitCode)</_XHarnessArgs>
<_XHarnessArgs Condition="'$(WasmXHarnessArgs)' != ''" >$(_XHarnessArgs) $(WasmXHarnessArgs)</_XHarnessArgs>
<_XHarnessArgs Condition="'$(WasmXHarnessTestsTimeout)' != ''" >$(_XHarnessArgs) &quot;--timeout=$(WasmXHarnessTestsTimeout)&quot;</_XHarnessArgs>
<_XHarnessArgs >$(_XHarnessArgs) --engine-arg=-W --engine-arg=max-wasm-stack=134217728</_XHarnessArgs>
<_XHarnessArgs >$(_XHarnessArgs) --engine-arg=--wasm --engine-arg=max-wasm-stack=134217728</_XHarnessArgs>
<_XHarnessArgs >$(_XHarnessArgs) --engine-arg=--wasi --engine-arg=http</_XHarnessArgs>
<_XHarnessArgs >$(_XHarnessArgs) --engine-arg=--env --engine-arg=DOTNET_WASI_PRINT_EXIT_CODE=1</_XHarnessArgs>
<_XHarnessArgs Condition="'$(WasmXHarnessArgsCli)' != ''" >$(_XHarnessArgs) $(WasmXHarnessArgsCli)</_XHarnessArgs>

<_InvariantGlobalization Condition="'$(InvariantGlobalization)' == 'true'">--env=DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=true</_InvariantGlobalization>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@
<PlatformManifestFileEntry Include="stubs.c" IsNative="true" />
<PlatformManifestFileEntry Include="synthetic-pthread.c" IsNative="true" />
<PlatformManifestFileEntry Include="dotnet.wasm" IsNative="true" />
<PlatformManifestFileEntry Include="WasiHttpWorld_component_type.wit" IsNative="true" />
<!-- ICU-specific files -->
<PlatformManifestFileEntry Include="libicudata.a" IsNative="true" />
<PlatformManifestFileEntry Include="libicui18n.a" IsNative="true" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<Project>
<PropertyGroup Condition="'$(TargetOS)' == 'browser'">
<PropertyGroup Condition="'$(TargetOS)' == 'browser' or '$(TargetOS)' == 'wasi'">
<_TargetFrameworkForXHarness>$(AspNetCoreAppCurrent)</_TargetFrameworkForXHarness>
<HelixTargetsFile>$(MSBuildThisFileDirectory)LocalEchoServer.helix.targets</HelixTargetsFile>

Expand All @@ -19,7 +19,7 @@
<WasmXHarnessArgs>$(WasmXHarnessArgs) --web-server-middleware=$(_TestEchoMiddleware)/NetCoreServer.dll,NetCoreServer.GenericHandler</WasmXHarnessArgs>
</PropertyGroup>

<ItemGroup Condition="'$(TargetOS)' == 'browser'">
<ItemGroup Condition="'$(TargetOS)' == 'browser' or '$(TargetOS)' == 'wasi'">
<!-- The middleware doesn't need to be built for browser-wasm, so remove the relevant properties.
Also, due to https://github.com/dotnet/runtime/issues/77707 RunAOTCompilation needs to be removed
as a workaround. -->
Expand Down
16 changes: 16 additions & 0 deletions src/libraries/System.Net.Http/src/System.Net.Http.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,22 @@
Link="Common\System\Net\Http\HttpHandlerDefaults.cs" />
</ItemGroup>

<ItemGroup Condition="'$(TargetPlatformIdentifier)' == 'wasi'">
<Reference Include="System.Threading.Thread" />
<Compile Include="System\Net\Http\WasiHttpHandler\WasiHttpHandler.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" />
</ItemGroup>

<ItemGroup>
<Reference Include="Microsoft.Win32.Primitives" />
<Reference Include="System.Collections.NonGeneric" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics.Metrics;
#if TARGET_BROWSER
#if TARGET_WASI
using System.Diagnostics;
using System.Net.Http.Metrics;
using HttpHandlerType = System.Net.Http.WasiHttpHandler;
#elif TARGET_BROWSER
using System.Diagnostics;
using System.Net.Http.Metrics;
using HttpHandlerType = System.Net.Http.BrowserHttpHandler;
Expand All @@ -24,7 +28,7 @@ public partial class HttpClientHandler : HttpMessageHandler
{
private readonly HttpHandlerType _underlyingHandler;

#if TARGET_BROWSER
#if TARGET_BROWSER || TARGET_WASI
private IMeterFactory? _meterFactory;
private HttpMessageHandler? _firstHandler; // DiagnosticsHandler or MetricsHandler, depending on global configuration.

Expand Down Expand Up @@ -94,7 +98,7 @@ protected override void Dispose(bool disposing)
[CLSCompliant(false)]
public IMeterFactory? MeterFactory
{
#if TARGET_BROWSER
#if TARGET_BROWSER || TARGET_WASI
get => _meterFactory;
set
{
Expand Down Expand Up @@ -262,14 +266,14 @@ public ClientCertificateOption ClientCertificateOptions
switch (value)
{
case ClientCertificateOption.Manual:
#if !TARGET_BROWSER
#if !(TARGET_BROWSER || TARGET_WASI)
ThrowForModifiedManagedSslOptionsIfStarted();
_underlyingHandler.SslOptions.LocalCertificateSelectionCallback = (sender, targetHost, localCertificates, remoteCertificate, acceptableIssuers) => CertificateHelper.GetEligibleClientCertificate(_underlyingHandler.SslOptions.ClientCertificates)!;
#endif
break;

case ClientCertificateOption.Automatic:
#if !TARGET_BROWSER
#if !(TARGET_BROWSER || TARGET_WASI)
ThrowForModifiedManagedSslOptionsIfStarted();
_underlyingHandler.SslOptions.LocalCertificateSelectionCallback = (sender, targetHost, localCertificates, remoteCertificate, acceptableIssuers) => CertificateHelper.GetEligibleClientCertificate()!;
#endif
Expand Down Expand Up @@ -300,7 +304,7 @@ public X509CertificateCollection ClientCertificates
[UnsupportedOSPlatform("browser")]
public Func<HttpRequestMessage, X509Certificate2?, X509Chain?, SslPolicyErrors, bool>? ServerCertificateCustomValidationCallback
{
#if TARGET_BROWSER
#if TARGET_BROWSER || TARGET_WASI
get => throw new PlatformNotSupportedException();
set => throw new PlatformNotSupportedException();
#else
Expand Down Expand Up @@ -349,7 +353,7 @@ public SslProtocols SslProtocols
//[UnsupportedOSPlatform("tvos")]
protected internal override HttpResponseMessage Send(HttpRequestMessage request, CancellationToken cancellationToken)
{
#if TARGET_BROWSER
#if TARGET_BROWSER || TARGET_WASI
throw new PlatformNotSupportedException();
#else
ArgumentNullException.ThrowIfNull(request);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
// Generated by `wit-bindgen` 0.27.0. 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;

namespace WasiHttpWorld {

internal interface IWasiHttpWorld {
}

internal readonly struct None {}

[StructLayout(LayoutKind.Sequential)]
internal readonly struct Result<Ok, Err>
{
internal readonly byte Tag;
private readonly object value;

private Result(byte tag, object value)
{
Tag = tag;
this.value = value;
}

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

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

internal bool IsOk => Tag == OK;
internal bool IsErr => Tag == ERR;

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

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

internal const byte OK = 0;
internal const byte ERR = 1;
}

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

private Option()
{
HasValue = false;
}

internal Option(T v)
{
HasValue = true;
Value = v;
}

internal static Option<T> None => none;

[MemberNotNullWhen(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 object Value { get; }
internal uint NestingLevel { get; }

internal WitException(object v, uint level)
{
Value = v;
NestingLevel = level;
}
}

namespace exports {
internal static class WasiHttpWorld
{
}
}

}
Loading

0 comments on commit 0e8db73

Please sign in to comment.