DoxigAlpha

chunkedSendFile

Function parameters

Parameters

#
w:*Writer
file_reader:*File.Reader
limit:std.Io.Limit

Type definitions in this namespace

Types

#
Method
https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods
Status
https://developer.mozilla.org/en-US/docs/Web/HTTP/Status
TransferEncoding
compression is intentionally omitted here since it is handled in `ContentEncoding`.
BodyWriter
Request or response body.

Source

Implementation

#
pub fn chunkedSendFile(w: *Writer, file_reader: *File.Reader, limit: std.Io.Limit) Writer.FileError!usize {
    const bw: *BodyWriter = @alignCast(@fieldParentPtr("writer", w));
    assert(!bw.isEliding());
    const data_len = Writer.countSendFileLowerBound(w.end, file_reader, limit) orelse {
        // If the file size is unknown, we cannot lower to a `sendFile` since we would
        // have to flush the chunk header before knowing the chunk length.
        return error.Unimplemented;
    };
    const out = bw.http_protocol_output;
    l: switch (bw.state.chunk_len) {
        0 => {
            const header_buf = try out.writableArray(chunk_header_template.len);
            @memcpy(header_buf, chunk_header_template);
            writeHex(header_buf[0..chunk_len_digits], data_len);
            bw.state.chunk_len = data_len + 2;
            continue :l bw.state.chunk_len;
        },
        1 => unreachable, // Wrote more data than specified in chunk header.
        2 => {
            try out.writeAll("\r\n");
            bw.state.chunk_len = 0;
            assert(file_reader.atEnd());
            return error.EndOfStream;
        },
        else => {
            const chunk_limit: std.Io.Limit = .limited(bw.state.chunk_len - 2);
            const n = if (chunk_limit.subtract(w.buffered().len)) |sendfile_limit|
                try out.sendFileHeader(w.buffered(), file_reader, sendfile_limit.min(limit))
            else
                try out.write(chunk_limit.slice(w.buffered()));
            bw.state.chunk_len -= n;
            const ret = w.consume(n);
            return ret;
        },
    }
}