Skip to content

Commit f015582

Browse files
Merge pull request #277 from lightpanda-io/merge_bin
Merge get and server binaires
2 parents 8665d04 + cf0636c commit f015582

File tree

8 files changed

+120
-168
lines changed

8 files changed

+120
-168
lines changed

.github/workflows/build.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,13 @@ jobs:
3232
run: zig build --release=safe -Doptimize=ReleaseSafe -Dengine=v8 -Dcpu=x86_64
3333

3434
- name: Rename binary
35-
run: mv zig-out/bin/browsercore-get lightpanda-get-${{ env.ARCH }}-${{ env.OS }}
35+
run: mv zig-out/bin/lightpanda lightpanda-${{ env.ARCH }}-${{ env.OS }}
3636

3737
- name: Upload the build
3838
uses: ncipollo/release-action@v1
3939
with:
4040
allowUpdates: true
41-
artifacts: lightpanda-get-${{ env.ARCH }}-${{ env.OS }}
41+
artifacts: lightpanda-${{ env.ARCH }}-${{ env.OS }}
4242
tag: nightly
4343

4444
build-macos-aarch64:
@@ -65,11 +65,11 @@ jobs:
6565
run: zig build --release=safe -Doptimize=ReleaseSafe -Dengine=v8
6666

6767
- name: Rename binary
68-
run: mv zig-out/bin/browsercore-get lightpanda-get-${{ env.ARCH }}-${{ env.OS }}
68+
run: mv zig-out/bin/lightpanda lightpanda-${{ env.ARCH }}-${{ env.OS }}
6969

7070
- name: Upload the build
7171
uses: ncipollo/release-action@v1
7272
with:
7373
allowUpdates: true
74-
artifacts: lightpanda-get-${{ env.ARCH }}-${{ env.OS }}
74+
artifacts: lightpanda-${{ env.ARCH }}-${{ env.OS }}
7575
tag: nightly

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ build-dev:
6969
## Run the server in debug mode
7070
run: build
7171
@printf "\e[36mRunning...\e[0m\n"
72-
@./zig-out/bin/browsercore || (printf "\e[33mRun ERROR\e[0m\n"; exit 1;)
72+
@./zig-out/bin/lightpanda || (printf "\e[33mRun ERROR\e[0m\n"; exit 1;)
7373

7474
## Run a JS shell in debug mode
7575
shell:

build.zig

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ pub fn build(b: *std.Build) !void {
5252

5353
// compile and install
5454
const exe = b.addExecutable(.{
55-
.name = "browsercore",
55+
.name = "lightpanda",
5656
.root_source_file = b.path("src/main.zig"),
5757
.target = target,
5858
.optimize = mode,
@@ -75,7 +75,7 @@ pub fn build(b: *std.Build) !void {
7575

7676
// compile and install
7777
const shell = b.addExecutable(.{
78-
.name = "browsercore-shell",
78+
.name = "lightpanda-shell",
7979
.root_source_file = b.path("src/main_shell.zig"),
8080
.target = target,
8181
.optimize = mode,
@@ -124,7 +124,7 @@ pub fn build(b: *std.Build) !void {
124124

125125
// compile and install
126126
const wpt = b.addExecutable(.{
127-
.name = "browsercore-wpt",
127+
.name = "lightpanda-wpt",
128128
.root_source_file = b.path("src/main_wpt.zig"),
129129
.target = target,
130130
.optimize = mode,
@@ -139,28 +139,6 @@ pub fn build(b: *std.Build) !void {
139139
// step
140140
const wpt_step = b.step("wpt", "WPT tests");
141141
wpt_step.dependOn(&wpt_cmd.step);
142-
143-
// get
144-
// -----
145-
146-
// compile and install
147-
const get = b.addExecutable(.{
148-
.name = "browsercore-get",
149-
.root_source_file = b.path("src/main_get.zig"),
150-
.target = target,
151-
.optimize = mode,
152-
});
153-
try common(b, get, options);
154-
b.installArtifact(get);
155-
156-
// run
157-
const get_cmd = b.addRunArtifact(get);
158-
if (b.args) |args| {
159-
get_cmd.addArgs(args);
160-
}
161-
// step
162-
const get_step = b.step("get", "request URL");
163-
get_step.dependOn(&get_cmd.step);
164142
}
165143

166144
fn common(

src/main.zig

Lines changed: 109 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,6 @@ const server = @import("server.zig");
2727
const parser = @import("netsurf");
2828
const apiweb = @import("apiweb.zig");
2929

30-
const log = std.log.scoped(.server);
31-
3230
pub const Types = jsruntime.reflect(apiweb.Interfaces);
3331
pub const UserContext = apiweb.UserContext;
3432

@@ -38,13 +36,18 @@ const Port = 3245;
3836
const Timeout = 3; // in seconds
3937

4038
const usage =
41-
\\usage: {s} [options]
42-
\\ start Lightpanda browser in CDP server mode
39+
\\usage: {s} [options] [URL]
40+
\\
41+
\\ start Lightpanda browser
42+
\\
43+
\\ * if an url is provided the browser will fetch the page and exit
44+
\\ * otherwhise the browser starts a CDP server
4345
\\
4446
\\ -h, --help Print this help message and exit.
45-
\\ --host Host of the server (default "127.0.0.1")
46-
\\ --port Port of the server (default "3245")
47-
\\ --timeout Timeout for incoming connections in seconds (default "3")
47+
\\ --host Host of the CDP server (default "127.0.0.1")
48+
\\ --port Port of the CDP server (default "3245")
49+
\\ --timeout Timeout for incoming connections of the CDP server (in seconds, default "3")
50+
\\ --dump Dump document in stdout (fetch mode only)
4851
\\
4952
;
5053

@@ -146,7 +149,7 @@ pub const StreamServer = struct {
146149

147150
fn printUsageExit(execname: []const u8, res: u8) void {
148151
std.io.getStdErr().writer().print(usage, .{execname}) catch |err| {
149-
log.err("Print usage error: {any}", .{err});
152+
std.log.err("Print usage error: {any}", .{err});
150153
std.posix.exit(1);
151154
};
152155
std.posix.exit(res);
@@ -157,12 +160,20 @@ pub fn main() !void {
157160
// allocator
158161
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
159162
defer arena.deinit();
163+
const alloc = arena.allocator();
160164

161165
// args
162166
var args = try std.process.argsWithAllocator(arena.allocator());
163167
defer args.deinit();
164168

165169
const execname = args.next().?;
170+
var server_mode = true;
171+
172+
// fetch mode variables
173+
var url: []const u8 = "";
174+
var dump: bool = false;
175+
176+
// server mode variables
166177
var host: []const u8 = Host;
167178
var port: u16 = Port;
168179
var addr: std.net.Address = undefined;
@@ -172,64 +183,126 @@ pub fn main() !void {
172183
if (std.mem.eql(u8, "-h", opt) or std.mem.eql(u8, "--help", opt)) {
173184
printUsageExit(execname, 0);
174185
}
186+
if (std.mem.eql(u8, "--dump", opt)) {
187+
dump = true;
188+
continue;
189+
}
175190
if (std.mem.eql(u8, "--host", opt)) {
176191
if (args.next()) |arg| {
177192
host = arg;
178193
continue;
179194
} else {
180-
log.err("--host not provided\n", .{});
195+
std.log.err("--host not provided\n", .{});
181196
return printUsageExit(execname, 1);
182197
}
183198
}
184199
if (std.mem.eql(u8, "--port", opt)) {
185200
if (args.next()) |arg| {
186201
port = std.fmt.parseInt(u16, arg, 10) catch |err| {
187-
log.err("--port {any}\n", .{err});
202+
std.log.err("--port {any}\n", .{err});
188203
return printUsageExit(execname, 1);
189204
};
190205
continue;
191206
} else {
192-
log.err("--port not provided\n", .{});
207+
std.log.err("--port not provided\n", .{});
193208
return printUsageExit(execname, 1);
194209
}
195210
}
196211
if (std.mem.eql(u8, "--timeout", opt)) {
197212
if (args.next()) |arg| {
198213
timeout = std.fmt.parseInt(u8, arg, 10) catch |err| {
199-
log.err("--timeout {any}\n", .{err});
214+
std.log.err("--timeout {any}\n", .{err});
200215
return printUsageExit(execname, 1);
201216
};
202217
continue;
203218
} else {
204-
log.err("--timeout not provided\n", .{});
219+
std.log.err("--timeout not provided\n", .{});
205220
return printUsageExit(execname, 1);
206221
}
207222
}
223+
224+
// unknown option
225+
if (std.mem.startsWith(u8, opt, "--")) {
226+
std.log.err("unknown option\n", .{});
227+
return printUsageExit(execname, 1);
228+
}
229+
230+
// other argument is considered to be an URL, ie. fetch mode
231+
server_mode = false;
232+
233+
// allow only one url
234+
if (url.len != 0) {
235+
std.log.err("more than 1 url provided\n", .{});
236+
return printUsageExit(execname, 1);
237+
}
238+
239+
url = opt;
208240
}
209-
addr = std.net.Address.parseIp4(host, port) catch |err| {
210-
log.err("address (host:port) {any}\n", .{err});
211-
return printUsageExit(execname, 1);
212-
};
213241

214-
// server
215-
var srv = StreamServer.init(.{
216-
.reuse_address = true,
217-
.reuse_port = true,
218-
.nonblocking = true,
219-
});
220-
defer srv.deinit();
221-
222-
srv.listen(addr) catch |err| {
223-
log.err("address (host:port) {any}\n", .{err});
224-
return printUsageExit(execname, 1);
225-
};
226-
defer srv.close();
227-
log.info("Listening on: {s}:{d}...", .{ host, port });
242+
if (server_mode) {
243+
244+
// server mode
245+
addr = std.net.Address.parseIp4(host, port) catch |err| {
246+
std.log.err("address (host:port) {any}\n", .{err});
247+
return printUsageExit(execname, 1);
248+
};
228249

229-
// loop
230-
var loop = try jsruntime.Loop.init(arena.allocator());
231-
defer loop.deinit();
250+
// server
251+
var srv = StreamServer.init(.{
252+
.reuse_address = true,
253+
.reuse_port = true,
254+
.nonblocking = true,
255+
});
256+
defer srv.deinit();
257+
258+
srv.listen(addr) catch |err| {
259+
std.log.err("address (host:port) {any}\n", .{err});
260+
return printUsageExit(execname, 1);
261+
};
262+
defer srv.close();
263+
std.log.info("Listening on: {s}:{d}...", .{ host, port });
264+
265+
// loop
266+
var loop = try jsruntime.Loop.init(arena.allocator());
267+
defer loop.deinit();
268+
269+
// listen
270+
try server.listen(alloc, &loop, srv.sockfd.?, std.time.ns_per_s * @as(u64, timeout));
271+
} else {
272+
273+
// fetch mode
274+
if (url.len == 0) {
275+
try std.io.getStdErr().writer().print(usage, .{execname});
276+
std.posix.exit(1);
277+
}
278+
279+
const vm = jsruntime.VM.init();
280+
defer vm.deinit();
281+
282+
var loop = try jsruntime.Loop.init(arena.allocator());
283+
defer loop.deinit();
284+
285+
var browser = Browser{};
286+
try Browser.init(&browser, alloc, &loop, vm);
287+
defer browser.deinit();
232288

233-
// listen
234-
try server.listen(arena.allocator(), &loop, srv.sockfd.?, std.time.ns_per_s * @as(u64, timeout));
289+
const page = try browser.session.createPage();
290+
291+
_ = page.navigate(url, null) catch |err| switch (err) {
292+
error.UnsupportedUriScheme, error.UriMissingHost => {
293+
std.log.err("'{s}' is not a valid URL ({any})\n", .{ url, err });
294+
return printUsageExit(execname, 1);
295+
},
296+
else => {
297+
std.log.err("'{s}' fetching error ({any})s\n", .{ url, err });
298+
return printUsageExit(execname, 1);
299+
},
300+
};
301+
302+
try page.wait();
303+
304+
if (dump) {
305+
try page.dump(std.io.getStdOut());
306+
}
307+
}
235308
}

0 commit comments

Comments
 (0)