mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-10-29 15:13:28 +00:00
add TLS integration test for sync client
This commit is contained in:
@@ -133,8 +133,8 @@ pub fn build(b: *std.Build) !void {
|
|||||||
|
|
||||||
// compile
|
// compile
|
||||||
const unit_tests = b.addTest(.{
|
const unit_tests = b.addTest(.{
|
||||||
.root_source_file = b.path("src/unit_tests.zig"),
|
.root_source_file = b.path("src/main_unit_tests.zig"),
|
||||||
.test_runner = .{ .path = b.path("src/unit_tests.zig"), .mode = .simple },
|
.test_runner = .{ .path = b.path("src/test_runner.zig"), .mode = .simple },
|
||||||
.target = target,
|
.target = target,
|
||||||
.optimize = mode,
|
.optimize = mode,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -4,6 +4,9 @@
|
|||||||
.version = "0.0.0",
|
.version = "0.0.0",
|
||||||
.fingerprint = 0xda130f3af836cea0,
|
.fingerprint = 0xda130f3af836cea0,
|
||||||
.dependencies = .{
|
.dependencies = .{
|
||||||
.tls = .{ .url = "https://github.com/ianic/tls.zig/archive/96b923fcdaa6371617154857cef7b8337778cbe2.tar.gz", .hash = "122031f94565d7420a155b6eaec65aaa02acc80e75e6f0947899be2106bc3055b1ec" },
|
.tls = .{
|
||||||
|
.url = "https://github.com/ianic/tls.zig/archive/21aeaa9dd90f89fb86b0cd597f201a2680236f06.tar.gz",
|
||||||
|
.hash = "1220e584a5962cfba7c2f8d13151754bf76338c9916fedfd9b7a754501b9d9276c61",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ pub const Browser = struct {
|
|||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
.http_client = &app.http_client,
|
.http_client = &app.http_client,
|
||||||
.session_pool = SessionPool.init(allocator),
|
.session_pool = SessionPool.init(allocator),
|
||||||
.http_client = try http.Client.init(allocator, 5),
|
.http_client = try http.Client.init(allocator, 5, null),
|
||||||
.page_arena = std.heap.ArenaAllocator.init(allocator),
|
.page_arena = std.heap.ArenaAllocator.init(allocator),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,20 @@
|
|||||||
|
// Copyright (C) 2023-2024 Lightpanda (Selecy SAS)
|
||||||
|
//
|
||||||
|
// Francis Bouvier <francis@lightpanda.io>
|
||||||
|
// Pierre Tachoire <pierre@lightpanda.io>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
|
|
||||||
@@ -30,8 +47,9 @@ pub const Client = struct {
|
|||||||
state_pool: StatePool,
|
state_pool: StatePool,
|
||||||
root_ca: tls.config.CertBundle,
|
root_ca: tls.config.CertBundle,
|
||||||
|
|
||||||
pub fn init(allocator: Allocator, max_concurrent: usize) !Client {
|
// we only allow passing in a root_ca for testing
|
||||||
var root_ca = try tls.config.CertBundle.fromSystem(allocator);
|
pub fn init(allocator: Allocator, max_concurrent: usize, root_ca_: ?tls.config.CertBundle) !Client {
|
||||||
|
var root_ca = root_ca_ orelse try tls.config.CertBundle.fromSystem(allocator);
|
||||||
errdefer root_ca.deinit(allocator);
|
errdefer root_ca.deinit(allocator);
|
||||||
|
|
||||||
const state_pool = try StatePool.init(allocator, max_concurrent);
|
const state_pool = try StatePool.init(allocator, max_concurrent);
|
||||||
@@ -1420,8 +1438,7 @@ pub const Response = struct {
|
|||||||
fn processData(self: *Response) !?[]u8 {
|
fn processData(self: *Response) !?[]u8 {
|
||||||
const data = self._data orelse return null;
|
const data = self._data orelse return null;
|
||||||
const result = try self._reader.process(data);
|
const result = try self._reader.process(data);
|
||||||
self._done = result
|
self._done = result.done;
|
||||||
.done;
|
|
||||||
self._data = result.unprocessed; // for the next call
|
self._data = result.unprocessed; // for the next call
|
||||||
return result.data;
|
return result.data;
|
||||||
}
|
}
|
||||||
@@ -1631,13 +1648,13 @@ test "HttpClient Reader: fuzz" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test "HttpClient: invalid url" {
|
test "HttpClient: invalid url" {
|
||||||
var client = try Client.init(testing.allocator, 1);
|
var client = try testClient();
|
||||||
defer client.deinit();
|
defer client.deinit();
|
||||||
try testing.expectError(error.UriMissingHost, client.request(.GET, "http:///"));
|
try testing.expectError(error.UriMissingHost, client.request(.GET, "http:///"));
|
||||||
}
|
}
|
||||||
|
|
||||||
test "HttpClient: sync connect error" {
|
test "HttpClient: sync connect error" {
|
||||||
var client = try Client.init(testing.allocator, 2);
|
var client = try testClient();
|
||||||
defer client.deinit();
|
defer client.deinit();
|
||||||
|
|
||||||
var req = try client.request(.GET, "HTTP://127.0.0.1:9920");
|
var req = try client.request(.GET, "HTTP://127.0.0.1:9920");
|
||||||
@@ -1645,7 +1662,7 @@ test "HttpClient: sync connect error" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test "HttpClient: sync no body" {
|
test "HttpClient: sync no body" {
|
||||||
var client = try Client.init(testing.allocator, 2);
|
var client = try testClient();
|
||||||
defer client.deinit();
|
defer client.deinit();
|
||||||
|
|
||||||
var req = try client.request(.GET, "http://127.0.0.1:9582/http_client/simple");
|
var req = try client.request(.GET, "http://127.0.0.1:9582/http_client/simple");
|
||||||
@@ -1658,8 +1675,24 @@ test "HttpClient: sync no body" {
|
|||||||
try testing.expectEqual("0", res.header.get("content-length"));
|
try testing.expectEqual("0", res.header.get("content-length"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "HttpClient: sync tls no body" {
|
||||||
|
// https://github.com/ianic/tls.zig/issues/10
|
||||||
|
for (0..1) |_| {
|
||||||
|
var client = try testClient();
|
||||||
|
defer client.deinit();
|
||||||
|
|
||||||
|
var req = try client.request(.GET, "https://127.0.0.1:9581/http_client/simple");
|
||||||
|
var res = try req.sendSync(.{});
|
||||||
|
|
||||||
|
try testing.expectEqual(null, try res.next());
|
||||||
|
try testing.expectEqual(200, res.header.status);
|
||||||
|
try testing.expectEqual(1, res.header.count());
|
||||||
|
try testing.expectEqual("0", res.header.get("content-length"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
test "HttpClient: sync with body" {
|
test "HttpClient: sync with body" {
|
||||||
var client = try Client.init(testing.allocator, 2);
|
var client = try testClient();
|
||||||
defer client.deinit();
|
defer client.deinit();
|
||||||
|
|
||||||
var req = try client.request(.GET, "http://127.0.0.1:9582/http_client/echo");
|
var req = try client.request(.GET, "http://127.0.0.1:9582/http_client/echo");
|
||||||
@@ -1674,8 +1707,84 @@ test "HttpClient: sync with body" {
|
|||||||
try testing.expectEqual("Close", res.header.get("_connection"));
|
try testing.expectEqual("Close", res.header.get("_connection"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "HttpClient: sync tls with body" {
|
||||||
|
var arr: std.ArrayListUnmanaged(u8) = .{};
|
||||||
|
defer arr.deinit(testing.allocator);
|
||||||
|
try arr.ensureTotalCapacity(testing.allocator, 20);
|
||||||
|
|
||||||
|
// https://github.com/ianic/tls.zig/issues/10
|
||||||
|
for (0..1) |_| {
|
||||||
|
defer arr.clearRetainingCapacity();
|
||||||
|
var client = try testClient();
|
||||||
|
defer client.deinit();
|
||||||
|
|
||||||
|
var req = try client.request(.GET, "https://127.0.0.1:9581/http_client/body");
|
||||||
|
var res = try req.sendSync(.{});
|
||||||
|
|
||||||
|
while (try res.next()) |data| {
|
||||||
|
arr.appendSliceAssumeCapacity(data);
|
||||||
|
}
|
||||||
|
try testing.expectEqual("1234567890abcdefhijk", arr.items);
|
||||||
|
try testing.expectEqual(201, res.header.status);
|
||||||
|
try testing.expectEqual(2, res.header.count());
|
||||||
|
try testing.expectEqual("20", res.header.get("content-length"));
|
||||||
|
try testing.expectEqual("HEaDer", res.header.get("another"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test "HttpClient: sync redirect from TLS to Plaintext" {
|
||||||
|
var arr: std.ArrayListUnmanaged(u8) = .{};
|
||||||
|
defer arr.deinit(testing.allocator);
|
||||||
|
try arr.ensureTotalCapacity(testing.allocator, 20);
|
||||||
|
|
||||||
|
// https://github.com/ianic/tls.zig/issues/10
|
||||||
|
for (0..1) |_| {
|
||||||
|
defer arr.clearRetainingCapacity();
|
||||||
|
var client = try testClient();
|
||||||
|
defer client.deinit();
|
||||||
|
|
||||||
|
var req = try client.request(.GET, "https://127.0.0.1:9581/http_client/redirect/insecure");
|
||||||
|
var res = try req.sendSync(.{});
|
||||||
|
|
||||||
|
while (try res.next()) |data| {
|
||||||
|
arr.appendSliceAssumeCapacity(data);
|
||||||
|
}
|
||||||
|
try testing.expectEqual(201, res.header.status);
|
||||||
|
try testing.expectEqual(4, res.header.count());
|
||||||
|
try testing.expectEqual("close", res.header.get("connection"));
|
||||||
|
try testing.expectEqual("10", res.header.get("content-length"));
|
||||||
|
try testing.expectEqual("127.0.0.1", res.header.get("_host"));
|
||||||
|
try testing.expectEqual("Close", res.header.get("_connection"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test "HttpClient: sync redirect plaintext to TLS" {
|
||||||
|
var arr: std.ArrayListUnmanaged(u8) = .{};
|
||||||
|
defer arr.deinit(testing.allocator);
|
||||||
|
try arr.ensureTotalCapacity(testing.allocator, 20);
|
||||||
|
|
||||||
|
// https://github.com/ianic/tls.zig/issues/10
|
||||||
|
for (0..1) |_| {
|
||||||
|
defer arr.clearRetainingCapacity();
|
||||||
|
var client = try testClient();
|
||||||
|
defer client.deinit();
|
||||||
|
|
||||||
|
var req = try client.request(.GET, "http://127.0.0.1:9582/http_client/redirect/secure");
|
||||||
|
var res = try req.sendSync(.{});
|
||||||
|
|
||||||
|
while (try res.next()) |data| {
|
||||||
|
arr.appendSliceAssumeCapacity(data);
|
||||||
|
}
|
||||||
|
try testing.expectEqual(201, res.header.status);
|
||||||
|
try testing.expectEqual("1234567890abcdefhijk", arr.items);
|
||||||
|
try testing.expectEqual(2, res.header.count());
|
||||||
|
try testing.expectEqual("20", res.header.get("content-length"));
|
||||||
|
try testing.expectEqual("HEaDer", res.header.get("another"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
test "HttpClient: sync GET redirect" {
|
test "HttpClient: sync GET redirect" {
|
||||||
var client = try Client.init(testing.allocator, 2);
|
var client = try testClient();
|
||||||
defer client.deinit();
|
defer client.deinit();
|
||||||
|
|
||||||
var req = try client.request(.GET, "http://127.0.0.1:9582/http_client/redirect");
|
var req = try client.request(.GET, "http://127.0.0.1:9582/http_client/redirect");
|
||||||
@@ -1710,7 +1819,7 @@ test "HttpClient: async connect error" {
|
|||||||
};
|
};
|
||||||
|
|
||||||
var reset: Thread.ResetEvent = .{};
|
var reset: Thread.ResetEvent = .{};
|
||||||
var client = try Client.init(testing.allocator, 2);
|
var client = try testClient();
|
||||||
defer client.deinit();
|
defer client.deinit();
|
||||||
|
|
||||||
var req = try client.request(.GET, "HTTP://127.0.0.1:9920");
|
var req = try client.request(.GET, "HTTP://127.0.0.1:9920");
|
||||||
@@ -1720,7 +1829,7 @@ test "HttpClient: async connect error" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test "HttpClient: async no body" {
|
test "HttpClient: async no body" {
|
||||||
var client = try Client.init(testing.allocator, 2);
|
var client = try testClient();
|
||||||
defer client.deinit();
|
defer client.deinit();
|
||||||
|
|
||||||
var handler = try CaptureHandler.init();
|
var handler = try CaptureHandler.init();
|
||||||
@@ -1731,8 +1840,7 @@ test "HttpClient: async no body" {
|
|||||||
|
|
||||||
var req = try client.request(.GET, "HTTP://127.0.0.1:9582/http_client/simple");
|
var req = try client.request(.GET, "HTTP://127.0.0.1:9582/http_client/simple");
|
||||||
try req.sendAsync(&handler.loop, &handler, .{});
|
try req.sendAsync(&handler.loop, &handler, .{});
|
||||||
try handler.loop.io.run_for_ns(std.time.ns_per_ms);
|
try handler.waitUntilDone();
|
||||||
try handler.reset.timedWait(std.time.ns_per_s);
|
|
||||||
|
|
||||||
const res = handler.response;
|
const res = handler.response;
|
||||||
try testing.expectEqual("", res.body.items);
|
try testing.expectEqual("", res.body.items);
|
||||||
@@ -1740,8 +1848,28 @@ test "HttpClient: async no body" {
|
|||||||
try res.assertHeaders(&.{ "connection", "close", "content-length", "0" });
|
try res.assertHeaders(&.{ "connection", "close", "content-length", "0" });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// test "HttpClient: async tls no body" {
|
||||||
|
// var client = try testClient();
|
||||||
|
// defer client.deinit();
|
||||||
|
|
||||||
|
// var handler = try CaptureHandler.init();
|
||||||
|
// defer handler.deinit();
|
||||||
|
|
||||||
|
// var loop = try jsruntime.Loop.init(testing.allocator);
|
||||||
|
// defer loop.deinit();
|
||||||
|
|
||||||
|
// var req = try client.request(.GET, "HTTPs://127.0.0.1:9581/http_client/simple");
|
||||||
|
// try req.sendAsync(&handler.loop, &handler, .{});
|
||||||
|
// try handler.waitUntilDone();
|
||||||
|
|
||||||
|
// const res = handler.response;
|
||||||
|
// try testing.expectEqual("", res.body.items);
|
||||||
|
// try testing.expectEqual(200, res.status);
|
||||||
|
// try res.assertHeaders(&.{ "connection", "close", "content-length", "0" });
|
||||||
|
// }
|
||||||
|
|
||||||
test "HttpClient: async with body" {
|
test "HttpClient: async with body" {
|
||||||
var client = try Client.init(testing.allocator, 2);
|
var client = try testClient();
|
||||||
defer client.deinit();
|
defer client.deinit();
|
||||||
|
|
||||||
var handler = try CaptureHandler.init();
|
var handler = try CaptureHandler.init();
|
||||||
@@ -1749,8 +1877,7 @@ test "HttpClient: async with body" {
|
|||||||
|
|
||||||
var req = try client.request(.GET, "HTTP://127.0.0.1:9582/http_client/echo");
|
var req = try client.request(.GET, "HTTP://127.0.0.1:9582/http_client/echo");
|
||||||
try req.sendAsync(&handler.loop, &handler, .{});
|
try req.sendAsync(&handler.loop, &handler, .{});
|
||||||
try handler.loop.io.run_for_ns(std.time.ns_per_ms);
|
try handler.waitUntilDone();
|
||||||
try handler.reset.timedWait(std.time.ns_per_s);
|
|
||||||
|
|
||||||
const res = handler.response;
|
const res = handler.response;
|
||||||
try testing.expectEqual("over 9000!", res.body.items);
|
try testing.expectEqual("over 9000!", res.body.items);
|
||||||
@@ -1764,7 +1891,7 @@ test "HttpClient: async with body" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test "HttpClient: async redirect" {
|
test "HttpClient: async redirect" {
|
||||||
var client = try Client.init(testing.allocator, 2);
|
var client = try testClient();
|
||||||
defer client.deinit();
|
defer client.deinit();
|
||||||
|
|
||||||
var handler = try CaptureHandler.init();
|
var handler = try CaptureHandler.init();
|
||||||
@@ -1781,8 +1908,7 @@ test "HttpClient: async redirect" {
|
|||||||
// start to requeue events (from the redirected request), so we need the
|
// start to requeue events (from the redirected request), so we need the
|
||||||
//loop to process those also.
|
//loop to process those also.
|
||||||
try handler.loop.io.run_for_ns(std.time.ns_per_ms);
|
try handler.loop.io.run_for_ns(std.time.ns_per_ms);
|
||||||
try handler.loop.io.run_for_ns(std.time.ns_per_ms);
|
try handler.waitUntilDone();
|
||||||
try handler.reset.timedWait(std.time.ns_per_s);
|
|
||||||
|
|
||||||
const res = handler.response;
|
const res = handler.response;
|
||||||
try testing.expectEqual("over 9000!", res.body.items);
|
try testing.expectEqual("over 9000!", res.body.items);
|
||||||
@@ -1885,6 +2011,11 @@ const CaptureHandler = struct {
|
|||||||
self.reset.set();
|
self.reset.set();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn waitUntilDone(self: *CaptureHandler) !void {
|
||||||
|
try self.loop.io.run_for_ns(std.time.ns_per_ms);
|
||||||
|
try self.reset.timedWait(std.time.ns_per_s);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
fn testReader(state: *State, res: *TestResponse, data: []const u8) !void {
|
fn testReader(state: *State, res: *TestResponse, data: []const u8) !void {
|
||||||
@@ -1928,3 +2059,9 @@ fn testReader(state: *State, res: *TestResponse, data: []const u8) !void {
|
|||||||
}
|
}
|
||||||
return error.NeverDone;
|
return error.NeverDone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn testClient() !Client {
|
||||||
|
const test_dir = try std.fs.cwd().openDir("tests", .{});
|
||||||
|
const root_ca = try tls.config.CertBundle.fromFile(testing.allocator, test_dir, "test_cert.pem");
|
||||||
|
return try Client.init(testing.allocator, 1, root_ca);
|
||||||
|
}
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ fn testExecFn(
|
|||||||
std.debug.print("documentHTMLClose error: {s}\n", .{@errorName(err)});
|
std.debug.print("documentHTMLClose error: {s}\n", .{@errorName(err)});
|
||||||
};
|
};
|
||||||
|
|
||||||
var http_client = try @import("http/client.zig").Client.init(alloc, 5);
|
var http_client = try @import("http/client.zig").Client.init(alloc, 5, null);
|
||||||
defer http_client.deinit();
|
defer http_client.deinit();
|
||||||
|
|
||||||
try js_env.setUserContext(.{
|
try js_env.setUserContext(.{
|
||||||
|
|||||||
211
src/main_unit_tests.zig
Normal file
211
src/main_unit_tests.zig
Normal file
@@ -0,0 +1,211 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const builtin = @import("builtin");
|
||||||
|
const parser = @import("netsurf");
|
||||||
|
const tls = @import("tls");
|
||||||
|
|
||||||
|
const Allocator = std.mem.Allocator;
|
||||||
|
|
||||||
|
test {
|
||||||
|
std.testing.refAllDecls(@import("url/query.zig"));
|
||||||
|
std.testing.refAllDecls(@import("browser/dump.zig"));
|
||||||
|
std.testing.refAllDecls(@import("browser/mime.zig"));
|
||||||
|
std.testing.refAllDecls(@import("css/css.zig"));
|
||||||
|
std.testing.refAllDecls(@import("css/libdom_test.zig"));
|
||||||
|
std.testing.refAllDecls(@import("css/match_test.zig"));
|
||||||
|
std.testing.refAllDecls(@import("css/parser.zig"));
|
||||||
|
std.testing.refAllDecls(@import("generate.zig"));
|
||||||
|
std.testing.refAllDecls(@import("http/client.zig"));
|
||||||
|
std.testing.refAllDecls(@import("storage/storage.zig"));
|
||||||
|
std.testing.refAllDecls(@import("storage/cookie.zig"));
|
||||||
|
std.testing.refAllDecls(@import("iterator/iterator.zig"));
|
||||||
|
std.testing.refAllDecls(@import("server.zig"));
|
||||||
|
std.testing.refAllDecls(@import("cdp/cdp.zig"));
|
||||||
|
std.testing.refAllDecls(@import("log.zig"));
|
||||||
|
std.testing.refAllDecls(@import("datetime.zig"));
|
||||||
|
std.testing.refAllDecls(@import("telemetry/telemetry.zig"));
|
||||||
|
std.testing.refAllDecls(@import("http/client.zig"));
|
||||||
|
}
|
||||||
|
|
||||||
|
var wg: std.Thread.WaitGroup = .{};
|
||||||
|
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||||
|
test "tests:beforeAll" {
|
||||||
|
try parser.init();
|
||||||
|
wg.startMany(3);
|
||||||
|
|
||||||
|
{
|
||||||
|
const address = try std.net.Address.parseIp("127.0.0.1", 9582);
|
||||||
|
const thread = try std.Thread.spawn(.{}, serveHTTP, .{ address });
|
||||||
|
thread.detach();
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const address = try std.net.Address.parseIp("127.0.0.1", 9581);
|
||||||
|
const thread = try std.Thread.spawn(.{}, serveHTTPS, .{ address });
|
||||||
|
thread.detach();
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const address = try std.net.Address.parseIp("127.0.0.1", 9583);
|
||||||
|
const thread = try std.Thread.spawn(.{}, serveCDP, .{address});
|
||||||
|
thread.detach();
|
||||||
|
}
|
||||||
|
// need to wait for the servers to be listening, else tests will fail because
|
||||||
|
// they aren't able to connect.
|
||||||
|
wg.wait();
|
||||||
|
}
|
||||||
|
|
||||||
|
test "tests:afterAll" {
|
||||||
|
parser.deinit();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn serveHTTP(address: std.net.Address) !void {
|
||||||
|
const allocator = gpa.allocator();
|
||||||
|
var arena = std.heap.ArenaAllocator.init(allocator);
|
||||||
|
defer arena.deinit();
|
||||||
|
|
||||||
|
var listener = try address.listen(.{ .reuse_address = true });
|
||||||
|
defer listener.deinit();
|
||||||
|
|
||||||
|
wg.finish();
|
||||||
|
|
||||||
|
var read_buffer: [1024]u8 = undefined;
|
||||||
|
ACCEPT: while (true) {
|
||||||
|
defer _ = arena.reset(.{ .retain_with_limit = 1024 });
|
||||||
|
const aa = arena.allocator();
|
||||||
|
|
||||||
|
var conn = try listener.accept();
|
||||||
|
defer conn.stream.close();
|
||||||
|
var server = std.http.Server.init(conn, &read_buffer);
|
||||||
|
|
||||||
|
while (server.state == .ready) {
|
||||||
|
var request = server.receiveHead() catch |err| switch (err) {
|
||||||
|
error.HttpConnectionClosing => continue :ACCEPT,
|
||||||
|
else => {
|
||||||
|
std.debug.print("Test HTTP Server error: {}\n", .{err});
|
||||||
|
return err;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const path = request.head.target;
|
||||||
|
if (std.mem.eql(u8, path, "/loader")) {
|
||||||
|
try request.respond("Hello!", .{});
|
||||||
|
} else if (std.mem.eql(u8, path, "/http_client/simple")) {
|
||||||
|
try request.respond("", .{});
|
||||||
|
} else if (std.mem.eql(u8, path, "/http_client/redirect")) {
|
||||||
|
try request.respond("", .{
|
||||||
|
.status = .moved_permanently,
|
||||||
|
.extra_headers = &.{.{ .name = "LOCATION", .value = "../http_client/echo" }},
|
||||||
|
});
|
||||||
|
} else if (std.mem.eql(u8, path, "/http_client/redirect/secure")) {
|
||||||
|
try request.respond("", .{
|
||||||
|
.status = .moved_permanently,
|
||||||
|
.extra_headers = &.{.{ .name = "LOCATION", .value = "https://127.0.0.1:9581/http_client/body" }},
|
||||||
|
});
|
||||||
|
} else if (std.mem.eql(u8, path, "/http_client/echo")) {
|
||||||
|
var headers: std.ArrayListUnmanaged(std.http.Header) = .{};
|
||||||
|
|
||||||
|
var it = request.iterateHeaders();
|
||||||
|
while (it.next()) |hdr| {
|
||||||
|
try headers.append(aa, .{
|
||||||
|
.name = try std.fmt.allocPrint(aa, "_{s}", .{hdr.name}),
|
||||||
|
.value = hdr.value,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
try request.respond("over 9000!", .{
|
||||||
|
.status = .created,
|
||||||
|
.extra_headers = headers.items,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is a lot of work for testing TLS, but the TLS (async) code is complicated
|
||||||
|
// This "server" is written specifically to test the client. It assumes the client
|
||||||
|
// isn't a jerk.
|
||||||
|
fn serveHTTPS(address: std.net.Address) !void {
|
||||||
|
const allocator = gpa.allocator();
|
||||||
|
const test_dir = try std.fs.cwd().openDir("tests", .{});
|
||||||
|
|
||||||
|
// openssl req -x509 -newkey rsa:4096 -keyout tests/test_key.pem -out tests/test_cert.pem -sha256 -days 3650 -nodes -subj "/CN=127.0.0.1"
|
||||||
|
var auth = try tls.config.CertKeyPair.load(allocator, test_dir, "test_cert.pem", "test_key.pem");
|
||||||
|
defer auth.deinit(allocator);
|
||||||
|
|
||||||
|
var listener = try address.listen(.{ .reuse_address = true });
|
||||||
|
defer listener.deinit();
|
||||||
|
|
||||||
|
var arena = std.heap.ArenaAllocator.init(allocator);
|
||||||
|
defer arena.deinit();
|
||||||
|
|
||||||
|
wg.finish();
|
||||||
|
|
||||||
|
var seed: u64 = undefined;
|
||||||
|
std.posix.getrandom(std.mem.asBytes(&seed)) catch unreachable;
|
||||||
|
var r = std.Random.DefaultPrng.init(seed);
|
||||||
|
const rand = r.random();
|
||||||
|
|
||||||
|
var read_buffer: [1024]u8 = undefined;
|
||||||
|
while (true) {
|
||||||
|
// defer _ = arena.reset(.{ .retain_with_limit = 1024 });
|
||||||
|
// const aa = arena.allocator();
|
||||||
|
|
||||||
|
const stream = blk: {
|
||||||
|
const conn = try listener.accept();
|
||||||
|
break :blk conn.stream;
|
||||||
|
};
|
||||||
|
defer stream.close();
|
||||||
|
|
||||||
|
var conn = try tls.server(stream, .{ .auth = &auth });
|
||||||
|
defer conn.close() catch {};
|
||||||
|
|
||||||
|
var pos: usize = 0;
|
||||||
|
while (true) {
|
||||||
|
const n = try conn.read(read_buffer[pos..]);
|
||||||
|
if (n == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pos += n;
|
||||||
|
const header_end = std.mem.indexOf(u8, read_buffer[0..pos], "\r\n\r\n") orelse {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
var it = std.mem.splitScalar(u8, read_buffer[0..header_end], ' ');
|
||||||
|
_ = it.next() orelse unreachable; // method
|
||||||
|
const path = it.next() orelse unreachable;
|
||||||
|
|
||||||
|
var response: []const u8 = undefined;
|
||||||
|
if (std.mem.eql(u8, path, "/http_client/simple")) {
|
||||||
|
response = "HTTP/1.1 200 \r\nContent-Length: 0\r\n\r\n";
|
||||||
|
} else if (std.mem.eql(u8, path, "/http_client/body")) {
|
||||||
|
response = "HTTP/1.1 201 CREATED\r\nContent-Length: 20\r\n Another : HEaDer \r\n\r\n1234567890abcdefhijk";
|
||||||
|
} else if (std.mem.eql(u8, path, "/http_client/redirect/insecure")) {
|
||||||
|
response = "HTTP/1.1 307 GOTO\r\nLocation: http://127.0.0.1:9582/http_client/redirect\r\n\r\n";
|
||||||
|
} else {
|
||||||
|
// should not have an unknown path
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
|
|
||||||
|
var unsent = response;
|
||||||
|
while (unsent.len > 0) {
|
||||||
|
const to_send = rand.intRangeAtMost(usize, 1, unsent.len);
|
||||||
|
const sent = try conn.write(unsent[0..to_send]);
|
||||||
|
unsent = unsent[sent..];
|
||||||
|
// std.time.sleep(std.time.ns_per_us * 5);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn serveCDP(address: std.net.Address) !void {
|
||||||
|
const App = @import("app.zig").App;
|
||||||
|
var app = try App.init(gpa.allocator(), .serve);
|
||||||
|
defer app.deinit();
|
||||||
|
|
||||||
|
const server = @import("server.zig");
|
||||||
|
wg.finish();
|
||||||
|
server.run(&app, address, std.time.ns_per_s * 2) catch |err| {
|
||||||
|
std.debug.print("CDP server error: {}", .{err});
|
||||||
|
return err;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -18,34 +18,31 @@
|
|||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
const parser = @import("netsurf");
|
|
||||||
|
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
|
|
||||||
const App = @import("app.zig").App;
|
|
||||||
const jsruntime = @import("jsruntime");
|
|
||||||
pub const Types = jsruntime.reflect(@import("generate.zig").Tuple(.{}){});
|
|
||||||
pub const UserContext = @import("user_context.zig").UserContext;
|
|
||||||
|
|
||||||
pub const std_options = std.Options{
|
|
||||||
.log_level = .err,
|
|
||||||
.http_disable_tls = true,
|
|
||||||
};
|
|
||||||
|
|
||||||
const BORDER = "=" ** 80;
|
const BORDER = "=" ** 80;
|
||||||
|
|
||||||
// use in custom panic handler
|
// use in custom panic handler
|
||||||
var current_test: ?[]const u8 = null;
|
var current_test: ?[]const u8 = null;
|
||||||
|
|
||||||
|
const jsruntime = @import("jsruntime");
|
||||||
|
pub const Types = jsruntime.reflect(@import("generate.zig").Tuple(.{}){});
|
||||||
|
pub const UserContext = @import("user_context.zig").UserContext;
|
||||||
|
|
||||||
|
pub const std_options = std.Options{
|
||||||
|
.log_level = .warn,
|
||||||
|
|
||||||
|
// Crypto in Zig is generally slow, but it's particularly slow in debug mode
|
||||||
|
// this helps a lot (but it's still slow). Not safe to do this in non-test!
|
||||||
|
.side_channels_mitigations = .none,
|
||||||
|
};
|
||||||
|
|
||||||
pub fn main() !void {
|
pub fn main() !void {
|
||||||
try parser.init();
|
var mem: [8192]u8 = undefined;
|
||||||
defer parser.deinit();
|
var fba = std.heap.FixedBufferAllocator.init(&mem);
|
||||||
|
|
||||||
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
const allocator = fba.allocator();
|
||||||
const allocator = gpa.allocator();
|
|
||||||
|
|
||||||
var app = try App.init(allocator, .serve);
|
|
||||||
defer app.deinit();
|
|
||||||
|
|
||||||
const env = Env.init(allocator);
|
const env = Env.init(allocator);
|
||||||
defer env.deinit(allocator);
|
defer env.deinit(allocator);
|
||||||
@@ -58,30 +55,20 @@ pub fn main() !void {
|
|||||||
var skip: usize = 0;
|
var skip: usize = 0;
|
||||||
var leak: usize = 0;
|
var leak: usize = 0;
|
||||||
|
|
||||||
const http_thread = blk: {
|
|
||||||
const address = try std.net.Address.parseIp("127.0.0.1", 9582);
|
|
||||||
const thread = try std.Thread.spawn(.{}, serveHTTP, .{ allocator, address });
|
|
||||||
break :blk thread;
|
|
||||||
};
|
|
||||||
defer http_thread.join();
|
|
||||||
|
|
||||||
const cdp_thread = blk: {
|
|
||||||
const address = try std.net.Address.parseIp("127.0.0.1", 9583);
|
|
||||||
const thread = try std.Thread.spawn(.{}, serveCDP, .{
|
|
||||||
app,
|
|
||||||
address,
|
|
||||||
});
|
|
||||||
break :blk thread;
|
|
||||||
};
|
|
||||||
defer cdp_thread.join();
|
|
||||||
|
|
||||||
const printer = Printer.init();
|
const printer = Printer.init();
|
||||||
printer.fmt("\r\x1b[0K", .{}); // beginning of line and clear to end of line
|
printer.fmt("\r\x1b[0K", .{}); // beginning of line and clear to end of line
|
||||||
|
|
||||||
for (builtin.test_functions) |t| {
|
for (builtin.test_functions) |t| {
|
||||||
if (std.mem.eql(u8, t.name, "unit_tests.test_0")) {
|
if (isSetup(t)) {
|
||||||
// don't display anything for this test
|
t.func() catch |err| {
|
||||||
try t.func();
|
printer.status(.fail, "\nsetup \"{s}\" failed: {}\n", .{ t.name, err });
|
||||||
|
return err;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (builtin.test_functions) |t| {
|
||||||
|
if (isSetup(t) or isTeardown(t)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,6 +138,15 @@ pub fn main() !void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (builtin.test_functions) |t| {
|
||||||
|
if (isTeardown(t)) {
|
||||||
|
t.func() catch |err| {
|
||||||
|
printer.status(.fail, "\nteardown \"{s}\" failed: {}\n", .{ t.name, err });
|
||||||
|
return err;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const total_tests = pass + fail;
|
const total_tests = pass + fail;
|
||||||
const status = if (fail == 0) Status.pass else Status.fail;
|
const status = if (fail == 0) Status.pass else Status.fail;
|
||||||
printer.status(status, "\n{d} of {d} test{s} passed\n", .{ pass, total_tests, if (total_tests != 1) "s" else "" });
|
printer.status(status, "\n{d} of {d} test{s} passed\n", .{ pass, total_tests, if (total_tests != 1) "s" else "" });
|
||||||
@@ -315,6 +311,15 @@ const Env = struct {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const panic = std.debug.FullPanic(struct {
|
||||||
|
pub fn panicFn(msg: []const u8, first_trace_addr: ?usize) noreturn {
|
||||||
|
if (current_test) |ct| {
|
||||||
|
std.debug.print("\x1b[31m{s}\npanic running \"{s}\"\n{s}\x1b[0m\n", .{ BORDER, ct, BORDER });
|
||||||
|
}
|
||||||
|
std.debug.defaultPanic(msg, first_trace_addr);
|
||||||
|
}
|
||||||
|
}.panicFn);
|
||||||
|
|
||||||
fn isUnnamed(t: std.builtin.TestFn) bool {
|
fn isUnnamed(t: std.builtin.TestFn) bool {
|
||||||
const marker = ".test_";
|
const marker = ".test_";
|
||||||
const test_name = t.name;
|
const test_name = t.name;
|
||||||
@@ -323,86 +328,10 @@ fn isUnnamed(t: std.builtin.TestFn) bool {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serveHTTP(allocator: Allocator, address: std.net.Address) !void {
|
fn isSetup(t: std.builtin.TestFn) bool {
|
||||||
var arena = std.heap.ArenaAllocator.init(allocator);
|
return std.mem.endsWith(u8, t.name, "tests:beforeAll");
|
||||||
defer arena.deinit();
|
|
||||||
|
|
||||||
var listener = try address.listen(.{ .reuse_address = true });
|
|
||||||
defer listener.deinit();
|
|
||||||
|
|
||||||
var read_buffer: [1024]u8 = undefined;
|
|
||||||
ACCEPT: while (true) {
|
|
||||||
defer _ = arena.reset(.{ .retain_with_limit = 1024 });
|
|
||||||
const aa = arena.allocator();
|
|
||||||
|
|
||||||
var conn = try listener.accept();
|
|
||||||
defer conn.stream.close();
|
|
||||||
var server = std.http.Server.init(conn, &read_buffer);
|
|
||||||
|
|
||||||
while (server.state == .ready) {
|
|
||||||
var request = server.receiveHead() catch |err| switch (err) {
|
|
||||||
error.HttpConnectionClosing => continue :ACCEPT,
|
|
||||||
else => {
|
|
||||||
std.debug.print("Test HTTP Server error: {}\n", .{err});
|
|
||||||
return err;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const path = request.head.target;
|
|
||||||
if (std.mem.eql(u8, path, "/loader")) {
|
|
||||||
try request.respond("Hello!", .{});
|
|
||||||
} else if (std.mem.eql(u8, path, "/http_client/simple")) {
|
|
||||||
try request.respond("", .{});
|
|
||||||
} else if (std.mem.eql(u8, path, "/http_client/redirect")) {
|
|
||||||
try request.respond("", .{
|
|
||||||
.status = .moved_permanently,
|
|
||||||
.extra_headers = &.{.{ .name = "LOCATION", .value = "../http_client/echo" }},
|
|
||||||
});
|
|
||||||
} else if (std.mem.eql(u8, path, "/http_client/echo")) {
|
|
||||||
var headers: std.ArrayListUnmanaged(std.http.Header) = .{};
|
|
||||||
|
|
||||||
var it = request.iterateHeaders();
|
|
||||||
while (it.next()) |hdr| {
|
|
||||||
try headers.append(aa, .{
|
|
||||||
.name = try std.fmt.allocPrint(aa, "_{s}", .{hdr.name}),
|
|
||||||
.value = hdr.value,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
try request.respond("over 9000!", .{
|
|
||||||
.status = .created,
|
|
||||||
.extra_headers = headers.items,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serveCDP(app: *App, address: std.net.Address) !void {
|
fn isTeardown(t: std.builtin.TestFn) bool {
|
||||||
const server = @import("server.zig");
|
return std.mem.endsWith(u8, t.name, "tests:afterAll");
|
||||||
server.run(app, address, std.time.ns_per_s * 2) catch |err| {
|
|
||||||
std.debug.print("CDP server error: {}", .{err});
|
|
||||||
return err;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
test {
|
|
||||||
std.testing.refAllDecls(@import("url/query.zig"));
|
|
||||||
std.testing.refAllDecls(@import("browser/dump.zig"));
|
|
||||||
std.testing.refAllDecls(@import("browser/mime.zig"));
|
|
||||||
std.testing.refAllDecls(@import("css/css.zig"));
|
|
||||||
std.testing.refAllDecls(@import("css/libdom_test.zig"));
|
|
||||||
std.testing.refAllDecls(@import("css/match_test.zig"));
|
|
||||||
std.testing.refAllDecls(@import("css/parser.zig"));
|
|
||||||
std.testing.refAllDecls(@import("generate.zig"));
|
|
||||||
std.testing.refAllDecls(@import("http/client.zig"));
|
|
||||||
std.testing.refAllDecls(@import("storage/storage.zig"));
|
|
||||||
std.testing.refAllDecls(@import("storage/cookie.zig"));
|
|
||||||
std.testing.refAllDecls(@import("iterator/iterator.zig"));
|
|
||||||
std.testing.refAllDecls(@import("server.zig"));
|
|
||||||
std.testing.refAllDecls(@import("cdp/cdp.zig"));
|
|
||||||
std.testing.refAllDecls(@import("log.zig"));
|
|
||||||
std.testing.refAllDecls(@import("datetime.zig"));
|
|
||||||
std.testing.refAllDecls(@import("telemetry/telemetry.zig"));
|
|
||||||
std.testing.refAllDecls(@import("http/client.zig"));
|
|
||||||
}
|
}
|
||||||
@@ -167,7 +167,7 @@ pub const Random = struct {
|
|||||||
var seed: u64 = undefined;
|
var seed: u64 = undefined;
|
||||||
std.posix.getrandom(std.mem.asBytes(&seed)) catch unreachable;
|
std.posix.getrandom(std.mem.asBytes(&seed)) catch unreachable;
|
||||||
instance = std.Random.DefaultPrng.init(seed);
|
instance = std.Random.DefaultPrng.init(seed);
|
||||||
instance = std.Random.DefaultPrng.init(0);
|
// instance = std.Random.DefaultPrng.init(0);
|
||||||
}
|
}
|
||||||
return instance.?.random();
|
return instance.?.random();
|
||||||
}
|
}
|
||||||
|
|||||||
29
tests/test_cert.pem
Normal file
29
tests/test_cert.pem
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
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
|
||||||
|
-----END CERTIFICATE-----
|
||||||
52
tests/test_key.pem
Normal file
52
tests/test_key.pem
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
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
|
||||||
|
Z31M1oPIcKZ4ayKKiG5GYX/+juUlMA==
|
||||||
|
-----END PRIVATE KEY-----
|
||||||
Reference in New Issue
Block a user