╭─────────────╮ │scroll to top│ ╰─────────────╯ ╭ serve.zig ────────────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │http│ ssh │ │ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
140 var wui_server = wui_address.listen(io, .{}) catch |listen_err| switch (listen_err) { 141 // the default port is taken; bind port 0 so the OS assigns a free one 142 error.AddressInUse => blk: { 143 const any_port = try std.Io.net.IpAddress.parseIp4(wui_listen_address.host, 0); 144 break :blk try any_port.listen(io, .{}); 145 }, 146 else => |e| return e, 147 }; 148 defer wui_server.deinit(io); 149 150 var tasks: std.Io.Group = .init; 151 defer tasks.cancel(io); 152 153 runWebListener(io, allocator, &wui_server, &tasks, .{ .local = local }, err); 154 155 try runnable.run(wui_server.socket.address.getPort()); 156 } 157 158 fn runWebListener( 159 io: std.Io, 160 allocator: std.mem.Allocator, 161 net_server: *std.Io.net.Server, 162 tasks: *std.Io.Group, 163 host: web.Host, 164 err: *std.Io.Writer, 165 ) void { 166 const Context = struct { 167 io: std.Io, 168 allocator: std.mem.Allocator, 169 host: web.Host, 170 err: *std.Io.Writer, 171 }; 172 173 const handle = struct { 174 fn h(ctx: Context, stream: std.Io.net.Stream) void { 175 defer stream.close(ctx.io); 176 web.handleConnection(ctx.io, ctx.allocator, stream, ctx.host, ctx.err) catch |request_err| { 177 serve_common.logError(ctx.err, "web ui request failed: {s}\n", .{@errorName(request_err)}); 178 }; 179 } 180 }.h; 181 182 serve_common.runListener(io, net_server, tasks, err, "web ui", Context{ 183 .io = io, 184 .allocator = allocator, 185 .host = host, 186 .err = err, 187 }, handle); 188 } 189 190 fn parseListenAddress(value: []const u8) !ListenAddress { 191 const colon = std.mem.lastIndexOfScalar(u8, value, ':') orelse return error.InvalidListenAddress; 192 if (colon == 0 or colon + 1 >= value.len) return error.InvalidListenAddress; 193 const port = try std.fmt.parseInt(u16, value[colon + 1 ..], 10); 194 return .{ .host = value[0..colon], .port = port }; 195 } 196