summaryrefslogtreecommitdiff
path: root/test/web/native.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-14 14:28:15 -0300
committerGabriel Schneider <[email protected]>2026-09-16 11:18:48 -0300
commitae310a207534b33b7321dd2b9f423a73b1969159 (patch)
treeb4c2e85091a4ff6657e0a04ba1b2ef030d588ac8 /test/web/native.zig
parent5f24c4a2284a0af84fb9d116f7a39f6a58e42ae9 (diff)
downloadcloud9-ae310a207534b33b7321dd2b9f423a73b1969159.tar.gz
cloud9-ae310a207534b33b7321dd2b9f423a73b1969159.zip
Add reusable HTTP transport, serial gateway, and WASM file browser
Diffstat (limited to 'test/web/native.zig')
-rw-r--r--test/web/native.zig66
1 files changed, 66 insertions, 0 deletions
diff --git a/test/web/native.zig b/test/web/native.zig
new file mode 100644
index 0000000..ad11386
--- /dev/null
+++ b/test/web/native.zig
@@ -0,0 +1,66 @@
+//! Native use of the public HTTPS transport, exercised by the browser E2E runner.
+const std = @import("std");
+const c9 = @import("cloud9");
+const Session = struct {
+ tunnel: *c9.http.Client,
+ client: c9.Client,
+ fn ask(s: *Session, request: c9.Client.Request) !c9.Client.Result {
+ const tag = try s.client.submit(request);
+ try s.tunnel.send(s.client.output());
+ s.client.wrote(s.client.output().len);
+ var buffer: [65536]u8 = undefined;
+ const frame = try s.tunnel.receive(&buffer);
+ if (s.client.push(frame) != frame.len) return error.InputFull;
+ const done = s.client.take() orelse return error.MissingReply;
+ if (done.tag != tag or done.result == .fail) return error.UnexpectedReply;
+ return done.result;
+ }
+};
+pub fn main(init: std.process.Init) !void {
+ const args = try init.minimal.args.toSlice(init.arena.allocator());
+ if (args.len < 3 or args.len > 4) return error.Arguments;
+ var http: std.http.Client = .{ .allocator = init.gpa, .io = init.io };
+ defer http.deinit();
+ if (args.len == 4) {
+ http.now = std.Io.Clock.real.now(init.io);
+ try http.ca_bundle.addCertsFromFilePathAbsolute(init.gpa, init.io, http.now.?, args[3]);
+ }
+ var tunnel = try c9.http.Client.connect(&http, args[1], args[2]);
+ defer tunnel.deinit();
+ var input: [65536]u8 = undefined;
+ var output: [65536]u8 = undefined;
+ var session: Session = .{ .tunnel = &tunnel, .client = .init(.{ .in = &input, .out = &output }) };
+ _ = try session.ask(.{ .version = .{} });
+ _ = try session.ask(.{ .attach = .{ .fid = 0, .uname = "user" } });
+ _ = try session.ask(.{ .walk = .{ .fid = 0, .newfid = 1, .names = &.{"hello.txt"} } });
+ _ = try session.ask(.{ .open = .{ .fid = 1, .mode = c9.oread } });
+ const result = try session.ask(.{ .read = .{ .fid = 1, .offset = 0, .count = 1024 } });
+ if (!std.mem.eql(u8, result.read, "Hello from 9P.\n")) return error.WrongContents;
+ // Two outstanding tags exercise the full-duplex bridge independently of
+ // the browser UI's serialized file-operation queue.
+ const read_tag = try session.client.submit(.{ .read = .{ .fid = 1, .offset = 0, .count = 1024 } });
+ try tunnel.send(session.client.output());
+ session.client.wrote(session.client.output().len);
+ const stat_tag = try session.client.submit(.{ .stat = .{ .fid = 0 } });
+ try tunnel.send(session.client.output());
+ session.client.wrote(session.client.output().len);
+ var seen_read = false;
+ var seen_stat = false;
+ var reply_buffer: [65536]u8 = undefined;
+ for (0..2) |_| {
+ const frame = try tunnel.receive(&reply_buffer);
+ if (session.client.push(frame) != frame.len) return error.InputFull;
+ const done = session.client.take() orelse return error.MissingReply;
+ if (done.tag == read_tag and !seen_read and done.result == .read) {
+ if (!std.mem.eql(u8, done.result.read, "Hello from 9P.\n")) return error.WrongContents;
+ seen_read = true;
+ } else if (done.tag == stat_tag and !seen_stat and done.result == .stat) {
+ if (done.result.stat.qid.type & c9.qtdir == 0) return error.WrongStat;
+ seen_stat = true;
+ } else return error.UnexpectedReply;
+ }
+ if (!seen_read or !seen_stat) return error.MissingReply;
+ _ = try session.ask(.{ .clunk = .{ .fid = 1 } });
+ _ = try session.ask(.{ .clunk = .{ .fid = 0 } });
+ std.debug.print("native HTTP transport passed\n", .{});
+}