| ... | @@ -334,11 +334,6 @@ pub const Reader = struct { | ... | @@ -334,11 +334,6 @@ pub const Reader = struct { |
| 334 | /// Number of bytes of HTTP trailers. These are at the end of a | 334 | /// Number of bytes of HTTP trailers. These are at the end of a |
| 335 | /// transfer-encoding: chunked message. | 335 | /// transfer-encoding: chunked message. |
| 336 | trailers_len: usize = 0, | 336 | trailers_len: usize = 0, |
| 337 | body_state: union { | | |
| 338 | none: void, | | |
| 339 | remaining_content_length: u64, | | |
| 340 | remaining_chunk_len: RemainingChunkLen, | | |
| 341 | }, | | |
| 342 | body_err: ?BodyError = null, | 337 | body_err: ?BodyError = null, |
| 343 | /// Stolen from `in`. | 338 | /// Stolen from `in`. |
| 344 | head_buffer: []u8 = &.{}, | 339 | head_buffer: []u8 = &.{}, |
| ... | @@ -361,12 +356,13 @@ pub const Reader = struct { | ... | @@ -361,12 +356,13 @@ pub const Reader = struct { |
| 361 | } | 356 | } |
| 362 | }; | 357 | }; |
| 363 | | 358 | |
| 364 | pub const State = enum { | 359 | pub const State = union(enum) { |
| 365 | /// The stream is available to be used for the first time, or reused. | 360 | /// The stream is available to be used for the first time, or reused. |
| 366 | ready, | 361 | ready, |
| 367 | receiving_head, | | |
| 368 | received_head, | 362 | received_head, |
| 369 | receiving_body, | 363 | body_none: void, |
| | 364 | body_remaining_content_length: u64, |
| | 365 | body_remaining_chunk_len: RemainingChunkLen, |
| 370 | /// The stream would be eligible for another HTTP request, however the | 366 | /// The stream would be eligible for another HTTP request, however the |
| 371 | /// client and server did not negotiate a persistent connection. | 367 | /// client and server did not negotiate a persistent connection. |
| 372 | closing, | 368 | closing, |
| ... | @@ -413,6 +409,7 @@ pub const Reader = struct { | ... | @@ -413,6 +409,7 @@ pub const Reader = struct { |
| 413 | head_end += hp.feed(buf[head_end..]); | 409 | head_end += hp.feed(buf[head_end..]); |
| 414 | if (hp.state == .finished) { | 410 | if (hp.state == .finished) { |
| 415 | reader.head_buffer = in.steal(head_end); | 411 | reader.head_buffer = in.steal(head_end); |
| | 412 | reader.state = .received_head; |
| 416 | return; | 413 | return; |
| 417 | } | 414 | } |
| 418 | } | 415 | } |
| ... | @@ -426,10 +423,9 @@ pub const Reader = struct { | ... | @@ -426,10 +423,9 @@ pub const Reader = struct { |
| 426 | /// * `interfaceDecompressing` | 423 | /// * `interfaceDecompressing` |
| 427 | pub fn bodyReader(reader: *Reader, transfer_encoding: TransferEncoding, content_length: ?u64) std.io.Reader { | 424 | pub fn bodyReader(reader: *Reader, transfer_encoding: TransferEncoding, content_length: ?u64) std.io.Reader { |
| 428 | assert(reader.state == .received_head); | 425 | assert(reader.state == .received_head); |
| 429 | reader.state = .receiving_body; | | |
| 430 | return switch (transfer_encoding) { | 426 | return switch (transfer_encoding) { |
| 431 | .chunked => { | 427 | .chunked => { |
| 432 | reader.body_state = .{ .remaining_chunk_len = .head }; | 428 | reader.state = .{ .body_remaining_chunk_len = .head }; |
| 433 | return .{ | 429 | return .{ |
| 434 | .context = reader, | 430 | .context = reader, |
| 435 | .vtable = &.{ | 431 | .vtable = &.{ |
| ... | @@ -441,7 +437,7 @@ pub const Reader = struct { | ... | @@ -441,7 +437,7 @@ pub const Reader = struct { |
| 441 | }, | 437 | }, |
| 442 | .none => { | 438 | .none => { |
| 443 | if (content_length) |len| { | 439 | if (content_length) |len| { |
| 444 | reader.body_state = .{ .remaining_content_length = len }; | 440 | reader.state = .{ .body_remaining_content_length = len }; |
| 445 | return .{ | 441 | return .{ |
| 446 | .context = reader, | 442 | .context = reader, |
| 447 | .vtable = &.{ | 443 | .vtable = &.{ |
| ... | @@ -451,6 +447,7 @@ pub const Reader = struct { | ... | @@ -451,6 +447,7 @@ pub const Reader = struct { |
| 451 | }, | 447 | }, |
| 452 | }; | 448 | }; |
| 453 | } else { | 449 | } else { |
| | 450 | reader.state = .body_none; |
| 454 | return reader.in.reader(); | 451 | return reader.in.reader(); |
| 455 | } | 452 | } |
| 456 | }, | 453 | }, |
| ... | @@ -473,7 +470,7 @@ pub const Reader = struct { | ... | @@ -473,7 +470,7 @@ pub const Reader = struct { |
| 473 | ) std.io.Reader { | 470 | ) std.io.Reader { |
| 474 | if (transfer_encoding == .none and content_length == null) { | 471 | if (transfer_encoding == .none and content_length == null) { |
| 475 | assert(reader.state == .received_head); | 472 | assert(reader.state == .received_head); |
| 476 | reader.state = .receiving_body; | 473 | reader.state = .body_none; |
| 477 | switch (content_encoding) { | 474 | switch (content_encoding) { |
| 478 | .identity => { | 475 | .identity => { |
| 479 | return reader.in.reader(); | 476 | return reader.in.reader(); |
| ... | @@ -503,7 +500,7 @@ pub const Reader = struct { | ... | @@ -503,7 +500,7 @@ pub const Reader = struct { |
| 503 | limit: std.io.Reader.Limit, | 500 | limit: std.io.Reader.Limit, |
| 504 | ) std.io.Reader.RwError!usize { | 501 | ) std.io.Reader.RwError!usize { |
| 505 | const reader: *Reader = @alignCast(@ptrCast(ctx)); | 502 | const reader: *Reader = @alignCast(@ptrCast(ctx)); |
| 506 | const remaining_content_length = &reader.body_state.remaining_content_length; | 503 | const remaining_content_length = &reader.state.body_remaining_content_length; |
| 507 | const remaining = remaining_content_length.*; | 504 | const remaining = remaining_content_length.*; |
| 508 | if (remaining == 0) { | 505 | if (remaining == 0) { |
| 509 | reader.state = .ready; | 506 | reader.state = .ready; |
| ... | @@ -516,7 +513,7 @@ pub const Reader = struct { | ... | @@ -516,7 +513,7 @@ pub const Reader = struct { |
| 516 | | 513 | |
| 517 | fn contentLengthReadVec(context: ?*anyopaque, data: []const []u8) std.io.Reader.Error!usize { | 514 | fn contentLengthReadVec(context: ?*anyopaque, data: []const []u8) std.io.Reader.Error!usize { |
| 518 | const reader: *Reader = @alignCast(@ptrCast(context)); | 515 | const reader: *Reader = @alignCast(@ptrCast(context)); |
| 519 | const remaining_content_length = &reader.body_state.remaining_content_length; | 516 | const remaining_content_length = &reader.state.body_remaining_content_length; |
| 520 | const remaining = remaining_content_length.*; | 517 | const remaining = remaining_content_length.*; |
| 521 | if (remaining == 0) { | 518 | if (remaining == 0) { |
| 522 | reader.state = .ready; | 519 | reader.state = .ready; |
| ... | @@ -529,7 +526,7 @@ pub const Reader = struct { | ... | @@ -529,7 +526,7 @@ pub const Reader = struct { |
| 529 | | 526 | |
| 530 | fn contentLengthDiscard(ctx: ?*anyopaque, limit: std.io.Reader.Limit) std.io.Reader.Error!usize { | 527 | fn contentLengthDiscard(ctx: ?*anyopaque, limit: std.io.Reader.Limit) std.io.Reader.Error!usize { |
| 531 | const reader: *Reader = @alignCast(@ptrCast(ctx)); | 528 | const reader: *Reader = @alignCast(@ptrCast(ctx)); |
| 532 | const remaining_content_length = &reader.body_state.remaining_content_length; | 529 | const remaining_content_length = &reader.state.body_remaining_content_length; |
| 533 | const remaining = remaining_content_length.*; | 530 | const remaining = remaining_content_length.*; |
| 534 | if (remaining == 0) { | 531 | if (remaining == 0) { |
| 535 | reader.state = .ready; | 532 | reader.state = .ready; |
| ... | @@ -546,7 +543,7 @@ pub const Reader = struct { | ... | @@ -546,7 +543,7 @@ pub const Reader = struct { |
| 546 | limit: std.io.Reader.Limit, | 543 | limit: std.io.Reader.Limit, |
| 547 | ) std.io.Reader.RwError!usize { | 544 | ) std.io.Reader.RwError!usize { |
| 548 | const reader: *Reader = @alignCast(@ptrCast(ctx)); | 545 | const reader: *Reader = @alignCast(@ptrCast(ctx)); |
| 549 | const chunk_len_ptr = &reader.body_state.remaining_chunk_len; | 546 | const chunk_len_ptr = &reader.state.body_remaining_chunk_len; |
| 550 | const in = reader.in; | 547 | const in = reader.in; |
| 551 | len: switch (chunk_len_ptr.*) { | 548 | len: switch (chunk_len_ptr.*) { |
| 552 | .head => { | 549 | .head => { |
| ... | @@ -594,7 +591,7 @@ pub const Reader = struct { | ... | @@ -594,7 +591,7 @@ pub const Reader = struct { |
| 594 | | 591 | |
| 595 | fn chunkedReadVec(ctx: ?*anyopaque, data: []const []u8) std.io.Reader.Error!usize { | 592 | fn chunkedReadVec(ctx: ?*anyopaque, data: []const []u8) std.io.Reader.Error!usize { |
| 596 | const reader: *Reader = @alignCast(@ptrCast(ctx)); | 593 | const reader: *Reader = @alignCast(@ptrCast(ctx)); |
| 597 | const chunk_len_ptr = &reader.body_state.remaining_chunk_len; | 594 | const chunk_len_ptr = &reader.state.body_remaining_chunk_len; |
| 598 | const in = reader.in; | 595 | const in = reader.in; |
| 599 | var already_requested_more = false; | 596 | var already_requested_more = false; |
| 600 | var amt_read: usize = 0; | 597 | var amt_read: usize = 0; |
| ... | @@ -662,7 +659,7 @@ pub const Reader = struct { | ... | @@ -662,7 +659,7 @@ pub const Reader = struct { |
| 662 | | 659 | |
| 663 | fn chunkedDiscard(ctx: ?*anyopaque, limit: std.io.Reader.Limit) std.io.Reader.Error!usize { | 660 | fn chunkedDiscard(ctx: ?*anyopaque, limit: std.io.Reader.Limit) std.io.Reader.Error!usize { |
| 664 | const reader: *Reader = @alignCast(@ptrCast(ctx)); | 661 | const reader: *Reader = @alignCast(@ptrCast(ctx)); |
| 665 | const chunk_len_ptr = &reader.body_state.remaining_chunk_len; | 662 | const chunk_len_ptr = &reader.state.body_remaining_chunk_len; |
| 666 | const in = reader.in; | 663 | const in = reader.in; |
| 667 | len: switch (chunk_len_ptr.*) { | 664 | len: switch (chunk_len_ptr.*) { |
| 668 | .head => { | 665 | .head => { |
| ... | @@ -719,7 +716,7 @@ pub const Reader = struct { | ... | @@ -719,7 +716,7 @@ pub const Reader = struct { |
| 719 | try in.fill(trailers_len + 1); | 716 | try in.fill(trailers_len + 1); |
| 720 | trailers_len += hp.feed(in.bufferContents()[trailers_len..]); | 717 | trailers_len += hp.feed(in.bufferContents()[trailers_len..]); |
| 721 | if (hp.state == .finished) { | 718 | if (hp.state == .finished) { |
| 722 | reader.body_state.remaining_chunk_len = .done; | 719 | reader.state.body_remaining_chunk_len = .done; |
| 723 | reader.state = .ready; | 720 | reader.state = .ready; |
| 724 | reader.trailers_len = trailers_len; | 721 | reader.trailers_len = trailers_len; |
| 725 | return amt_read; | 722 | return amt_read; |