web / ferron /src /util /fcgi_encoder.rs
victorgeek's picture
Upload folder using huggingface_hub
9552aa0 verified
use tokio_util::bytes::{BufMut, BytesMut};
use tokio_util::codec::Encoder;
use crate::ferron_util::fcgi_record::construct_fastcgi_record;
pub struct FcgiEncoder;
impl FcgiEncoder {
pub fn new() -> Self {
Self
}
}
impl Encoder<&[u8]> for FcgiEncoder {
type Error = std::io::Error;
fn encode(&mut self, item: &[u8], dst: &mut BytesMut) -> Result<(), Self::Error> {
let mut offset = 0;
let mut first_written = false;
while offset < item.len() || (item.is_empty() && !first_written) {
let chunk_size = std::cmp::min(65535, item.len() - offset);
let chunk = &item[offset..offset + chunk_size];
// Record type 5 means STDIN
let record = construct_fastcgi_record(5, 1, chunk);
dst.put(record.as_slice());
first_written = true;
offset += chunk_size;
}
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
use tokio_util::codec::Encoder;
#[test]
fn test_fcgi_encoder() {
let mut encoder = FcgiEncoder::new();
let mut dst = BytesMut::new();
let item = b"Test data";
encoder.encode(item, &mut dst).unwrap();
// Expected encoded record structure
let expected_record = vec![
1, // FCGI_VERSION_1
5, // Record type
0, 1, // Request ID (big-endian)
0, 9, // Content length (big-endian)
7, // Padding length
0, // Reserved
84, 101, 115, 116, 32, // Content: "Test "
100, 97, 116, 97, // Content: "data"
0, 0, 0, 0, 0, 0, 0, // Padding
];
assert_eq!(dst.to_vec(), expected_record);
}
}