@@ -661,3 +661,74 @@ pub fn accept(server: *Server, options: HeaderStrategy) AcceptError!*Response {
661
661
662
662
return res ;
663
663
}
664
+
665
+ test "HTTP server handles a chunked transfer coding request" {
666
+ const builtin = @import ("builtin" );
667
+
668
+ // This test requires spawning threads.
669
+ if (builtin .single_threaded ) {
670
+ return error .SkipZigTest ;
671
+ }
672
+
673
+ const native_endian = comptime builtin .cpu .arch .endian ();
674
+ if (builtin .zig_backend == .stage2_llvm and native_endian == .Big ) {
675
+ // https://github.com/ziglang/zig/issues/13782
676
+ return error .SkipZigTest ;
677
+ }
678
+
679
+ if (builtin .os .tag == .wasi ) return error .SkipZigTest ;
680
+
681
+ const allocator = std .testing .allocator ;
682
+ const expect = std .testing .expect ;
683
+
684
+ const max_header_size = 8192 ;
685
+ var server = std .http .Server .init (allocator , .{ .reuse_address = true });
686
+ defer server .deinit ();
687
+
688
+ const address = try std .net .Address .parseIp ("127.0.0.1" , 0 );
689
+ try server .listen (address );
690
+ const server_port = server .socket .listen_address .in .getPort ();
691
+
692
+ const server_thread = try std .Thread .spawn (.{}, (struct {
693
+ fn apply (s : * std.http.Server ) ! void {
694
+ const res = try s .accept (.{ .dynamic = max_header_size });
695
+ defer res .deinit ();
696
+ defer res .reset ();
697
+ try res .wait ();
698
+
699
+ try expect (res .request .transfer_encoding .? == .chunked );
700
+
701
+ const server_body : []const u8 = "message from server!\n " ;
702
+ res .transfer_encoding = .{ .content_length = server_body .len };
703
+ try res .headers .append ("content-type" , "text/plain" );
704
+ try res .headers .append ("connection" , "close" );
705
+ try res .do ();
706
+
707
+ var buf : [128 ]u8 = undefined ;
708
+ const n = try res .readAll (& buf );
709
+ try expect (std .mem .eql (u8 , buf [0.. n ], "ABCD" ));
710
+ _ = try res .writer ().writeAll (server_body );
711
+ try res .finish ();
712
+ }
713
+ }).apply , .{& server });
714
+
715
+ const request_bytes =
716
+ "POST / HTTP/1.1\r \n " ++
717
+ "Content-Type: text/plain\r \n " ++
718
+ "Transfer-Encoding: chunked\r \n " ++
719
+ "\r \n " ++
720
+ "1\r \n " ++
721
+ "A\r \n " ++
722
+ "1\r \n " ++
723
+ "B\r \n " ++
724
+ "2\r \n " ++
725
+ "CD\r \n " ++
726
+ "0\r \n " ++
727
+ "\r \n " ;
728
+
729
+ const stream = try std .net .tcpConnectToHost (allocator , "127.0.0.1" , server_port );
730
+ defer stream .close ();
731
+ _ = try stream .writeAll (request_bytes [0.. ]);
732
+
733
+ server_thread .join ();
734
+ }
0 commit comments