@@ -251,48 +251,44 @@ pub fn now(s: *const WebServer) i64 {
251
251
fn accept (ws : * WebServer , connection : std.net.Server.Connection ) void {
252
252
defer connection .stream .close ();
253
253
254
- var read_buf : [0x4000 ]u8 = undefined ;
255
- var server : std.http.Server = .init (connection , & read_buf );
254
+ var send_buffer : [4096 ]u8 = undefined ;
255
+ var recv_buffer : [4096 ]u8 = undefined ;
256
+ var connection_reader = connection .stream .reader (& recv_buffer );
257
+ var connection_writer = connection .stream .writer (& send_buffer );
258
+ var server : http.Server = .init (connection_reader .interface (), & connection_writer .interface );
256
259
257
260
while (true ) {
258
261
var request = server .receiveHead () catch | err | switch (err ) {
259
262
error .HttpConnectionClosing = > return ,
260
- else = > {
261
- log .err ("failed to receive http request: {s}" , .{@errorName (err )});
262
- return ;
263
- },
263
+ else = > return log .err ("failed to receive http request: {t}" , .{err }),
264
264
};
265
- var ws_send_buf : [0x4000 ]u8 = undefined ;
266
- var ws_recv_buf : [0x4000 ]u8 align (4 ) = undefined ;
267
- if (std .http .WebSocket .init (& request , & ws_send_buf , & ws_recv_buf ) catch | err | {
268
- log .err ("failed to initialize websocket connection: {s}" , .{@errorName (err )});
269
- return ;
270
- }) | ws_init | {
271
- var web_socket = ws_init ;
272
- ws .serveWebSocket (& web_socket ) catch | err | {
273
- log .err ("failed to serve websocket: {s}" , .{@errorName (err )});
274
- return ;
275
- };
276
- comptime unreachable ;
277
- } else {
278
- ws .serveRequest (& request ) catch | err | switch (err ) {
279
- error .AlreadyReported = > return ,
280
- else = > {
281
- log .err ("failed to serve '{s}': {s}" , .{ request .head .target , @errorName (err ) });
265
+ switch (request .upgradeRequested ()) {
266
+ .websocket = > | opt_key | {
267
+ const key = opt_key orelse return log .err ("missing websocket key" , .{});
268
+ var web_socket = request .respondWebSocket (.{ .key = key }) catch {
269
+ return log .err ("failed to respond web socket: {t}" , .{connection_writer .err .? });
270
+ };
271
+ ws .serveWebSocket (& web_socket ) catch | err | {
272
+ log .err ("failed to serve websocket: {t}" , .{err });
282
273
return ;
283
- },
284
- };
274
+ };
275
+ comptime unreachable ;
276
+ },
277
+ .other = > | name | return log .err ("unknown upgrade request: {s}" , .{name }),
278
+ .none = > {
279
+ ws .serveRequest (& request ) catch | err | switch (err ) {
280
+ error .AlreadyReported = > return ,
281
+ else = > {
282
+ log .err ("failed to serve '{s}': {t}" , .{ request .head .target , err });
283
+ return ;
284
+ },
285
+ };
286
+ },
285
287
}
286
288
}
287
289
}
288
290
289
- fn makeIov (s : []const u8 ) std.posix.iovec_const {
290
- return .{
291
- .base = s .ptr ,
292
- .len = s .len ,
293
- };
294
- }
295
- fn serveWebSocket (ws : * WebServer , sock : * std.http.WebSocket ) ! noreturn {
291
+ fn serveWebSocket (ws : * WebServer , sock : * http.Server.WebSocket ) ! noreturn {
296
292
var prev_build_status = ws .build_status .load (.monotonic );
297
293
298
294
const prev_step_status_bits = try ws .gpa .alloc (u8 , ws .step_status_bits .len );
@@ -312,11 +308,8 @@ fn serveWebSocket(ws: *WebServer, sock: *std.http.WebSocket) !noreturn {
312
308
.timestamp = ws .now (),
313
309
.steps_len = @intCast (ws .all_steps .len ),
314
310
};
315
- try sock .writeMessagev (&.{
316
- makeIov (@ptrCast (& hello_header )),
317
- makeIov (ws .step_names_trailing ),
318
- makeIov (prev_step_status_bits ),
319
- }, .binary );
311
+ var bufs : [3 ][]const u8 = .{ @ptrCast (& hello_header ), ws .step_names_trailing , prev_step_status_bits };
312
+ try sock .writeMessageVec (& bufs , .binary );
320
313
}
321
314
322
315
var prev_fuzz : Fuzz.Previous = .init ;
@@ -380,7 +373,7 @@ fn serveWebSocket(ws: *WebServer, sock: *std.http.WebSocket) !noreturn {
380
373
std .Thread .Futex .timedWait (& ws .update_id , start_update_id , std .time .ns_per_ms * default_update_interval_ms ) catch {};
381
374
}
382
375
}
383
- fn recvWebSocketMessages (ws : * WebServer , sock : * std. http.WebSocket ) void {
376
+ fn recvWebSocketMessages (ws : * WebServer , sock : * http.Server .WebSocket ) void {
384
377
while (true ) {
385
378
const msg = sock .readSmallMessage () catch return ;
386
379
if (msg .opcode != .binary ) continue ;
@@ -402,7 +395,7 @@ fn recvWebSocketMessages(ws: *WebServer, sock: *std.http.WebSocket) void {
402
395
}
403
396
}
404
397
405
- fn serveRequest (ws : * WebServer , req : * std. http.Server.Request ) ! void {
398
+ fn serveRequest (ws : * WebServer , req : * http.Server.Request ) ! void {
406
399
// Strip an optional leading '/debug' component from the request.
407
400
const target : []const u8 , const debug : bool = target : {
408
401
if (mem .eql (u8 , req .head .target , "/debug" )) break :target .{ "/" , true };
@@ -431,7 +424,7 @@ fn serveRequest(ws: *WebServer, req: *std.http.Server.Request) !void {
431
424
432
425
fn serveLibFile (
433
426
ws : * WebServer ,
434
- request : * std. http.Server.Request ,
427
+ request : * http.Server.Request ,
435
428
sub_path : []const u8 ,
436
429
content_type : []const u8 ,
437
430
) ! void {
@@ -442,7 +435,7 @@ fn serveLibFile(
442
435
}
443
436
fn serveClientWasm (
444
437
ws : * WebServer ,
445
- req : * std. http.Server.Request ,
438
+ req : * http.Server.Request ,
446
439
optimize_mode : std.builtin.OptimizeMode ,
447
440
) ! void {
448
441
var arena_state : std.heap.ArenaAllocator = .init (ws .gpa );
@@ -456,12 +449,12 @@ fn serveClientWasm(
456
449
457
450
pub fn serveFile (
458
451
ws : * WebServer ,
459
- request : * std. http.Server.Request ,
452
+ request : * http.Server.Request ,
460
453
path : Cache.Path ,
461
454
content_type : []const u8 ,
462
455
) ! void {
463
456
const gpa = ws .gpa ;
464
- // The desired API is actually sendfile, which will require enhancing std. http.Server.
457
+ // The desired API is actually sendfile, which will require enhancing http.Server.
465
458
// We load the file with every request so that the user can make changes to the file
466
459
// and refresh the HTML page without restarting this server.
467
460
const file_contents = path .root_dir .handle .readFileAlloc (gpa , path .sub_path , 10 * 1024 * 1024 ) catch | err | {
@@ -478,14 +471,13 @@ pub fn serveFile(
478
471
}
479
472
pub fn serveTarFile (
480
473
ws : * WebServer ,
481
- request : * std. http.Server.Request ,
474
+ request : * http.Server.Request ,
482
475
paths : []const Cache.Path ,
483
476
) ! void {
484
477
const gpa = ws .gpa ;
485
478
486
- var send_buf : [0x4000 ]u8 = undefined ;
487
- var response = request .respondStreaming (.{
488
- .send_buffer = & send_buf ,
479
+ var send_buffer : [0x4000 ]u8 = undefined ;
480
+ var response = try request .respondStreaming (& send_buffer , .{
489
481
.respond_options = .{
490
482
.extra_headers = &.{
491
483
.{ .name = "Content-Type" , .value = "application/x-tar" },
@@ -497,10 +489,7 @@ pub fn serveTarFile(
497
489
var cached_cwd_path : ? []const u8 = null ;
498
490
defer if (cached_cwd_path ) | p | gpa .free (p );
499
491
500
- var response_buf : [1024 ]u8 = undefined ;
501
- var adapter = response .writer ().adaptToNewApi ();
502
- adapter .new_interface .buffer = & response_buf ;
503
- var archiver : std.tar.Writer = .{ .underlying_writer = & adapter .new_interface };
492
+ var archiver : std.tar.Writer = .{ .underlying_writer = & response .writer };
504
493
505
494
for (paths ) | path | {
506
495
var file = path .root_dir .handle .openFile (path .sub_path , .{}) catch | err | {
@@ -526,7 +515,6 @@ pub fn serveTarFile(
526
515
}
527
516
528
517
// intentionally not calling `archiver.finishPedantically`
529
- try adapter .new_interface .flush ();
530
518
try response .end ();
531
519
}
532
520
@@ -804,7 +792,7 @@ pub fn wait(ws: *WebServer) RunnerRequest {
804
792
}
805
793
}
806
794
807
- const cache_control_header : std. http.Header = .{
795
+ const cache_control_header : http.Header = .{
808
796
.name = "Cache-Control" ,
809
797
.value = "max-age=0, must-revalidate" ,
810
798
};
@@ -819,5 +807,6 @@ const Build = std.Build;
819
807
const Cache = Build .Cache ;
820
808
const Fuzz = Build .Fuzz ;
821
809
const abi = Build .abi ;
810
+ const http = std .http ;
822
811
823
812
const WebServer = @This ();
0 commit comments