| ... | ... | @@ -65,23 +65,22 @@ test "trailers" { |
| 65 | 65 | try req.sendBodiless(); |
| 66 | 66 | var response = try req.receiveHead(&.{}); |
| 67 | 67 | |
| 68 | | const body = try response.reader(&.{}).allocRemaining(gpa, .unlimited); |
| 69 | | defer gpa.free(body); |
| 70 | | |
| 71 | | try expectEqualStrings("Hello, World!\n", body); |
| 72 | | |
| 73 | 68 | { |
| 74 | 69 | var it = response.head.iterateHeaders(); |
| 75 | 70 | const header = it.next().?; |
| 76 | | try expect(!it.is_trailer); |
| 77 | 71 | try expectEqualStrings("transfer-encoding", header.name); |
| 78 | 72 | try expectEqualStrings("chunked", header.value); |
| 79 | 73 | try expectEqual(null, it.next()); |
| 80 | 74 | } |
| 75 | |
| 76 | const body = try response.reader(&.{}).allocRemaining(gpa, .unlimited); |
| 77 | defer gpa.free(body); |
| 78 | |
| 79 | try expectEqualStrings("Hello, World!\n", body); |
| 80 | |
| 81 | 81 | { |
| 82 | 82 | var it = response.iterateTrailers(); |
| 83 | 83 | const header = it.next().?; |
| 84 | | try expect(it.is_trailer); |
| 85 | 84 | try expectEqualStrings("X-Checksum", header.name); |
| 86 | 85 | try expectEqualStrings("aaaa", header.value); |
| 87 | 86 | try expectEqual(null, it.next()); |
| ... | ... | @@ -208,12 +207,14 @@ test "echo content server" { |
| 208 | 207 | // request.head.target, |
| 209 | 208 | //}); |
| 210 | 209 | |
| 210 | try expect(mem.startsWith(u8, request.head.target, "/echo-content")); |
| 211 | try expectEqualStrings("text/plain", request.head.content_type.?); |
| 212 | |
| 213 | // head strings expire here |
| 211 | 214 | const body = try (try request.readerExpectContinue(&.{})).allocRemaining(std.testing.allocator, .unlimited); |
| 212 | 215 | defer std.testing.allocator.free(body); |
| 213 | 216 | |
| 214 | | try expect(mem.startsWith(u8, request.head.target, "/echo-content")); |
| 215 | 217 | try expectEqualStrings("Hello, World!\n", body); |
| 216 | | try expectEqualStrings("text/plain", request.head.content_type.?); |
| 217 | 218 | |
| 218 | 219 | var response = try request.respondStreaming(&.{}, .{ |
| 219 | 220 | .content_length = switch (request.head.transfer_encoding) { |
| ... | ... | @@ -410,17 +411,19 @@ test "general client/server API coverage" { |
| 410 | 411 | |
| 411 | 412 | fn handleRequest(request: *http.Server.Request, listen_port: u16) !void { |
| 412 | 413 | const log = std.log.scoped(.server); |
| 414 | const gpa = std.testing.allocator; |
| 413 | 415 | |
| 414 | 416 | log.info("{f} {t} {s}", .{ request.head.method, request.head.version, request.head.target }); |
| 417 | const target = try gpa.dupe(u8, request.head.target); |
| 418 | defer gpa.free(target); |
| 415 | 419 | |
| 416 | | const gpa = std.testing.allocator; |
| 417 | 420 | const reader = (try request.readerExpectContinue(&.{})); |
| 418 | 421 | const body = try reader.allocRemaining(gpa, .unlimited); |
| 419 | 422 | defer gpa.free(body); |
| 420 | 423 | |
| 421 | | if (mem.startsWith(u8, request.head.target, "/get")) { |
| 424 | if (mem.startsWith(u8, target, "/get")) { |
| 422 | 425 | var response = try request.respondStreaming(&.{}, .{ |
| 423 | | .content_length = if (mem.indexOf(u8, request.head.target, "?chunked") == null) |
| 426 | .content_length = if (mem.indexOf(u8, target, "?chunked") == null) |
| 424 | 427 | 14 |
| 425 | 428 | else |
| 426 | 429 | null, |
| ... | ... | @@ -435,7 +438,7 @@ test "general client/server API coverage" { |
| 435 | 438 | try w.writeAll("World!\n"); |
| 436 | 439 | try response.end(); |
| 437 | 440 | // Writing again would cause an assertion failure. |
| 438 | | } else if (mem.startsWith(u8, request.head.target, "/large")) { |
| 441 | } else if (mem.startsWith(u8, target, "/large")) { |
| 439 | 442 | var response = try request.respondStreaming(&.{}, .{ |
| 440 | 443 | .content_length = 14 * 1024 + 14 * 10, |
| 441 | 444 | }); |
| ... | ... | @@ -458,7 +461,7 @@ test "general client/server API coverage" { |
| 458 | 461 | } |
| 459 | 462 | |
| 460 | 463 | try response.end(); |
| 461 | | } else if (mem.eql(u8, request.head.target, "/redirect/1")) { |
| 464 | } else if (mem.eql(u8, target, "/redirect/1")) { |
| 462 | 465 | var response = try request.respondStreaming(&.{}, .{ |
| 463 | 466 | .respond_options = .{ |
| 464 | 467 | .status = .found, |
| ... | ... | @@ -472,14 +475,14 @@ test "general client/server API coverage" { |
| 472 | 475 | try w.writeAll("Hello, "); |
| 473 | 476 | try w.writeAll("Redirected!\n"); |
| 474 | 477 | try response.end(); |
| 475 | | } else if (mem.eql(u8, request.head.target, "/redirect/2")) { |
| 478 | } else if (mem.eql(u8, target, "/redirect/2")) { |
| 476 | 479 | try request.respond("Hello, Redirected!\n", .{ |
| 477 | 480 | .status = .found, |
| 478 | 481 | .extra_headers = &.{ |
| 479 | 482 | .{ .name = "location", .value = "/redirect/1" }, |
| 480 | 483 | }, |
| 481 | 484 | }); |
| 482 | | } else if (mem.eql(u8, request.head.target, "/redirect/3")) { |
| 485 | } else if (mem.eql(u8, target, "/redirect/3")) { |
| 483 | 486 | const location = try std.fmt.allocPrint(gpa, "http://127.0.0.1:{d}/redirect/2", .{ |
| 484 | 487 | listen_port, |
| 485 | 488 | }); |
| ... | ... | @@ -491,23 +494,23 @@ test "general client/server API coverage" { |
| 491 | 494 | .{ .name = "location", .value = location }, |
| 492 | 495 | }, |
| 493 | 496 | }); |
| 494 | | } else if (mem.eql(u8, request.head.target, "/redirect/4")) { |
| 497 | } else if (mem.eql(u8, target, "/redirect/4")) { |
| 495 | 498 | try request.respond("Hello, Redirected!\n", .{ |
| 496 | 499 | .status = .found, |
| 497 | 500 | .extra_headers = &.{ |
| 498 | 501 | .{ .name = "location", .value = "/redirect/3" }, |
| 499 | 502 | }, |
| 500 | 503 | }); |
| 501 | | } else if (mem.eql(u8, request.head.target, "/redirect/5")) { |
| 504 | } else if (mem.eql(u8, target, "/redirect/5")) { |
| 502 | 505 | try request.respond("Hello, Redirected!\n", .{ |
| 503 | 506 | .status = .found, |
| 504 | 507 | .extra_headers = &.{ |
| 505 | 508 | .{ .name = "location", .value = "/%2525" }, |
| 506 | 509 | }, |
| 507 | 510 | }); |
| 508 | | } else if (mem.eql(u8, request.head.target, "/%2525")) { |
| 511 | } else if (mem.eql(u8, target, "/%2525")) { |
| 509 | 512 | try request.respond("Encoded redirect successful!\n", .{}); |
| 510 | | } else if (mem.eql(u8, request.head.target, "/redirect/invalid")) { |
| 513 | } else if (mem.eql(u8, target, "/redirect/invalid")) { |
| 511 | 514 | const invalid_port = try getUnusedTcpPort(); |
| 512 | 515 | const location = try std.fmt.allocPrint(gpa, "http://127.0.0.1:{d}", .{invalid_port}); |
| 513 | 516 | defer gpa.free(location); |
| ... | ... | @@ -518,7 +521,7 @@ test "general client/server API coverage" { |
| 518 | 521 | .{ .name = "location", .value = location }, |
| 519 | 522 | }, |
| 520 | 523 | }); |
| 521 | | } else if (mem.eql(u8, request.head.target, "/empty")) { |
| 524 | } else if (mem.eql(u8, target, "/empty")) { |
| 522 | 525 | try request.respond("", .{ |
| 523 | 526 | .extra_headers = &.{ |
| 524 | 527 | .{ .name = "empty", .value = "" }, |
| ... | ... | @@ -559,11 +562,12 @@ test "general client/server API coverage" { |
| 559 | 562 | try req.sendBodiless(); |
| 560 | 563 | var response = try req.receiveHead(&redirect_buffer); |
| 561 | 564 | |
| 565 | try expectEqualStrings("text/plain", response.head.content_type.?); |
| 566 | |
| 562 | 567 | const body = try response.reader(&.{}).allocRemaining(gpa, .unlimited); |
| 563 | 568 | defer gpa.free(body); |
| 564 | 569 | |
| 565 | 570 | try expectEqualStrings("Hello, World!\n", body); |
| 566 | | try expectEqualStrings("text/plain", response.head.content_type.?); |
| 567 | 571 | } |
| 568 | 572 | |
| 569 | 573 | // connection has been kept alive |
| ... | ... | @@ -604,12 +608,13 @@ test "general client/server API coverage" { |
| 604 | 608 | try req.sendBodiless(); |
| 605 | 609 | var response = try req.receiveHead(&redirect_buffer); |
| 606 | 610 | |
| 611 | try expectEqualStrings("text/plain", response.head.content_type.?); |
| 612 | try expectEqual(14, response.head.content_length.?); |
| 613 | |
| 607 | 614 | const body = try response.reader(&.{}).allocRemaining(gpa, .unlimited); |
| 608 | 615 | defer gpa.free(body); |
| 609 | 616 | |
| 610 | 617 | try expectEqualStrings("", body); |
| 611 | | try expectEqualStrings("text/plain", response.head.content_type.?); |
| 612 | | try expectEqual(14, response.head.content_length.?); |
| 613 | 618 | } |
| 614 | 619 | |
| 615 | 620 | // connection has been kept alive |
| ... | ... | @@ -628,11 +633,12 @@ test "general client/server API coverage" { |
| 628 | 633 | try req.sendBodiless(); |
| 629 | 634 | var response = try req.receiveHead(&redirect_buffer); |
| 630 | 635 | |
| 636 | try expectEqualStrings("text/plain", response.head.content_type.?); |
| 637 | |
| 631 | 638 | const body = try response.reader(&.{}).allocRemaining(gpa, .unlimited); |
| 632 | 639 | defer gpa.free(body); |
| 633 | 640 | |
| 634 | 641 | try expectEqualStrings("Hello, World!\n", body); |
| 635 | | try expectEqualStrings("text/plain", response.head.content_type.?); |
| 636 | 642 | } |
| 637 | 643 | |
| 638 | 644 | // connection has been kept alive |
| ... | ... | @@ -651,12 +657,13 @@ test "general client/server API coverage" { |
| 651 | 657 | try req.sendBodiless(); |
| 652 | 658 | var response = try req.receiveHead(&redirect_buffer); |
| 653 | 659 | |
| 660 | try expectEqualStrings("text/plain", response.head.content_type.?); |
| 661 | try expect(response.head.transfer_encoding == .chunked); |
| 662 | |
| 654 | 663 | const body = try response.reader(&.{}).allocRemaining(gpa, .unlimited); |
| 655 | 664 | defer gpa.free(body); |
| 656 | 665 | |
| 657 | 666 | try expectEqualStrings("", body); |
| 658 | | try expectEqualStrings("text/plain", response.head.content_type.?); |
| 659 | | try expect(response.head.transfer_encoding == .chunked); |
| 660 | 667 | } |
| 661 | 668 | |
| 662 | 669 | // connection has been kept alive |
| ... | ... | @@ -677,11 +684,12 @@ test "general client/server API coverage" { |
| 677 | 684 | try req.sendBodiless(); |
| 678 | 685 | var response = try req.receiveHead(&redirect_buffer); |
| 679 | 686 | |
| 687 | try expectEqualStrings("text/plain", response.head.content_type.?); |
| 688 | |
| 680 | 689 | const body = try response.reader(&.{}).allocRemaining(gpa, .unlimited); |
| 681 | 690 | defer gpa.free(body); |
| 682 | 691 | |
| 683 | 692 | try expectEqualStrings("Hello, World!\n", body); |
| 684 | | try expectEqualStrings("text/plain", response.head.content_type.?); |
| 685 | 693 | } |
| 686 | 694 | |
| 687 | 695 | // connection has been closed |
| ... | ... | @@ -706,11 +714,6 @@ test "general client/server API coverage" { |
| 706 | 714 | |
| 707 | 715 | try std.testing.expectEqual(.ok, response.head.status); |
| 708 | 716 | |
| 709 | | const body = try response.reader(&.{}).allocRemaining(gpa, .unlimited); |
| 710 | | defer gpa.free(body); |
| 711 | | |
| 712 | | try expectEqualStrings("", body); |
| 713 | | |
| 714 | 717 | var it = response.head.iterateHeaders(); |
| 715 | 718 | { |
| 716 | 719 | const header = it.next().?; |
| ... | ... | @@ -718,6 +721,12 @@ test "general client/server API coverage" { |
| 718 | 721 | try expectEqualStrings("content-length", header.name); |
| 719 | 722 | try expectEqualStrings("0", header.value); |
| 720 | 723 | } |
| 724 | |
| 725 | const body = try response.reader(&.{}).allocRemaining(gpa, .unlimited); |
| 726 | defer gpa.free(body); |
| 727 | |
| 728 | try expectEqualStrings("", body); |
| 729 | |
| 721 | 730 | { |
| 722 | 731 | const header = it.next().?; |
| 723 | 732 | try expect(!it.is_trailer); |