| author | |
| committer | |
| log | 06763c4c8c35d2e984ee2315e674a01d5506ded1 |
| tree | 5ef5eefcbebb8503d4ed0e3bb57dcd5fbea182be |
| parent | 39c0c24b5659bbcaec0a6f5ba4acc8666e3b8086 |
3 files changed, 72 insertions(+), 69 deletions(-)
lib/std/http.zig+1| ... | ... | @@ -275,4 +275,5 @@ test { |
| 275 | 275 | _ = Client; |
| 276 | 276 | _ = Method; |
| 277 | 277 | _ = Status; |
| 278 | _ = @import("http/test.zig"); | |
| 278 | 279 | } |
lib/std/http/Client.zig-69| ... | ... | @@ -1046,72 +1046,3 @@ test { |
| 1046 | 1046 | |
| 1047 | 1047 | std.testing.refAllDecls(@This()); |
| 1048 | 1048 | } |
| 1049 | ||
| 1050 | test "client requests server" { | |
| 1051 | const builtin = @import("builtin"); | |
| 1052 | ||
| 1053 | // This test requires spawning threads. | |
| 1054 | if (builtin.single_threaded) { | |
| 1055 | return error.SkipZigTest; | |
| 1056 | } | |
| 1057 | ||
| 1058 | const native_endian = comptime builtin.cpu.arch.endian(); | |
| 1059 | if (builtin.zig_backend == .stage2_llvm and native_endian == .Big) { | |
| 1060 | // https://github.com/ziglang/zig/issues/13782 | |
| 1061 | return error.SkipZigTest; | |
| 1062 | } | |
| 1063 | ||
| 1064 | if (builtin.os.tag == .wasi) return error.SkipZigTest; | |
| 1065 | ||
| 1066 | const allocator = std.testing.allocator; | |
| 1067 | ||
| 1068 | const max_header_size = 8192; | |
| 1069 | var server = std.http.Server.init(allocator, .{ .reuse_address = true }); | |
| 1070 | defer server.deinit(); | |
| 1071 | ||
| 1072 | const address = try std.net.Address.parseIp("127.0.0.1", 0); | |
| 1073 | try server.listen(address); | |
| 1074 | const server_port = server.socket.listen_address.in.getPort(); | |
| 1075 | ||
| 1076 | const thread = try std.Thread.spawn(.{}, (struct { | |
| 1077 | fn apply(s: *std.http.Server) !void { | |
| 1078 | const res = try s.accept(.{ .dynamic = max_header_size }); | |
| 1079 | defer res.reset(); | |
| 1080 | try res.wait(); | |
| 1081 | ||
| 1082 | const server_body: []const u8 = "message from server!\n"; | |
| 1083 | res.transfer_encoding = .{ .content_length = server_body.len }; | |
| 1084 | try res.headers.append("content-type", "text/plain"); | |
| 1085 | try res.headers.append("connection", "close"); | |
| 1086 | try res.do(); | |
| 1087 | ||
| 1088 | var buf: [128]u8 = undefined; | |
| 1089 | const n = try res.readAll(&buf); | |
| 1090 | try testing.expect(std.mem.eql(u8, buf[0..n], "Hello, World!\n")); | |
| 1091 | _ = try res.writer().writeAll(server_body); | |
| 1092 | try res.finish(); | |
| 1093 | } | |
| 1094 | }).apply, .{&server}); | |
| 1095 | ||
| 1096 | var uri_buf: [22]u8 = undefined; | |
| 1097 | const uri = std.Uri.parse(try std.fmt.bufPrint(&uri_buf, "http://127.0.0.1:{d}", .{server_port})) catch unreachable; | |
| 1098 | var client = std.http.Client{ .allocator = allocator }; | |
| 1099 | defer client.deinit(); | |
| 1100 | var client_headers = std.http.Headers{ .allocator = allocator }; | |
| 1101 | defer client_headers.deinit(); | |
| 1102 | var client_req = try client.request(.POST, uri, client_headers, .{}); | |
| 1103 | defer client_req.deinit(); | |
| 1104 | ||
| 1105 | client_req.transfer_encoding = .{ .content_length = 14 }; // this will be checked to ensure you sent exactly 14 bytes | |
| 1106 | try client_req.start(); // this sends the request | |
| 1107 | try client_req.writeAll("Hello, "); | |
| 1108 | try client_req.writeAll("World!\n"); | |
| 1109 | try client_req.finish(); | |
| 1110 | try client_req.do(); // this waits for a response | |
| 1111 | ||
| 1112 | const body = try client_req.reader().readAllAlloc(allocator, 8192 * 1024); | |
| 1113 | defer allocator.free(body); | |
| 1114 | try testing.expect(std.mem.eql(u8, body, "message from server!\n")); | |
| 1115 | ||
| 1116 | thread.join(); | |
| 1117 | } |
lib/std/http/test.zig created+71| ... | ... | @@ -0,0 +1,71 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | ||
| 4 | test "client requests server" { | |
| 5 | const builtin = @import("builtin"); | |
| 6 | ||
| 7 | // This test requires spawning threads. | |
| 8 | if (builtin.single_threaded) { | |
| 9 | return error.SkipZigTest; | |
| 10 | } | |
| 11 | ||
| 12 | const native_endian = comptime builtin.cpu.arch.endian(); | |
| 13 | if (builtin.zig_backend == .stage2_llvm and native_endian == .Big) { | |
| 14 | // https://github.com/ziglang/zig/issues/13782 | |
| 15 | return error.SkipZigTest; | |
| 16 | } | |
| 17 | ||
| 18 | if (builtin.os.tag == .wasi) return error.SkipZigTest; | |
| 19 | ||
| 20 | const allocator = std.testing.allocator; | |
| 21 | ||
| 22 | const max_header_size = 8192; | |
| 23 | var server = std.http.Server.init(allocator, .{ .reuse_address = true }); | |
| 24 | defer server.deinit(); | |
| 25 | ||
| 26 | const address = try std.net.Address.parseIp("127.0.0.1", 0); | |
| 27 | try server.listen(address); | |
| 28 | const server_port = server.socket.listen_address.in.getPort(); | |
| 29 | ||
| 30 | const server_thread = try std.Thread.spawn(.{}, (struct { | |
| 31 | fn apply(s: *std.http.Server) !void { | |
| 32 | const res = try s.accept(.{ .dynamic = max_header_size }); | |
| 33 | defer res.reset(); | |
| 34 | try res.wait(); | |
| 35 | ||
| 36 | const server_body: []const u8 = "message from server!\n"; | |
| 37 | res.transfer_encoding = .{ .content_length = server_body.len }; | |
| 38 | try res.headers.append("content-type", "text/plain"); | |
| 39 | try res.headers.append("connection", "close"); | |
| 40 | try res.do(); | |
| 41 | ||
| 42 | var buf: [128]u8 = undefined; | |
| 43 | const n = try res.readAll(&buf); | |
| 44 | try expect(std.mem.eql(u8, buf[0..n], "Hello, World!\n")); | |
| 45 | _ = try res.writer().writeAll(server_body); | |
| 46 | try res.finish(); | |
| 47 | } | |
| 48 | }).apply, .{&server}); | |
| 49 | ||
| 50 | var uri_buf: [22]u8 = undefined; | |
| 51 | const uri = try std.Uri.parse(try std.fmt.bufPrint(&uri_buf, "http://127.0.0.1:{d}", .{server_port})); | |
| 52 | var client = std.http.Client{ .allocator = allocator }; | |
| 53 | defer client.deinit(); | |
| 54 | var client_headers = std.http.Headers{ .allocator = allocator }; | |
| 55 | defer client_headers.deinit(); | |
| 56 | var client_req = try client.request(.POST, uri, client_headers, .{}); | |
| 57 | defer client_req.deinit(); | |
| 58 | ||
| 59 | client_req.transfer_encoding = .{ .content_length = 14 }; // this will be checked to ensure you sent exactly 14 bytes | |
| 60 | try client_req.start(); // this sends the request | |
| 61 | try client_req.writeAll("Hello, "); | |
| 62 | try client_req.writeAll("World!\n"); | |
| 63 | try client_req.finish(); | |
| 64 | try client_req.do(); // this waits for a response | |
| 65 | ||
| 66 | const body = try client_req.reader().readAllAlloc(allocator, 8192 * 1024); | |
| 67 | defer allocator.free(body); | |
| 68 | try expect(std.mem.eql(u8, body, "message from server!\n")); | |
| 69 | ||
| 70 | server_thread.join(); | |
| 71 | } |