ferron/util/
fcgi_record.rs

1pub fn construct_fastcgi_record(record_type: u8, request_id: u16, content: &[u8]) -> Vec<u8> {
2  let mut record = Vec::new();
3
4  // FastCGI version: FCGI_VERSION_1
5  record.push(1);
6
7  // Record type
8  record.extend_from_slice(&(record_type.to_be_bytes()));
9
10  // Request ID
11  record.extend_from_slice(&(request_id.to_be_bytes()));
12
13  // Content length
14  let content_length = content.len() as u16;
15  record.extend_from_slice(&(content_length.to_be_bytes()));
16
17  // Padding length
18  let content_length_modulo = (content_length % 8) as u8;
19  let padding_length = match content_length_modulo {
20    0 => 0,
21    _ => 8 - content_length_modulo,
22  };
23  record.extend_from_slice(&(padding_length.to_be_bytes()));
24
25  // Reserved
26  record.push(0);
27
28  // Content
29  record.extend_from_slice(content);
30
31  // Padding
32  record.append(&mut vec![0u8; padding_length as usize]);
33
34  record
35}
36
37#[cfg(test)]
38mod tests {
39  use super::*;
40
41  #[test]
42  fn test_construct_fastcgi_record() {
43    // Test case 1: Empty content
44    let record_type = 1;
45    let request_id = 1234;
46    let content: &[u8] = &[];
47    let expected_record = vec![
48      1, // FastCGI version
49      1, // Record type
50      4, 210, // Request ID
51      0, 0, // Content length
52      0, // Padding length
53      0, // Reserved
54    ];
55    assert_eq!(
56      construct_fastcgi_record(record_type, request_id, content),
57      expected_record
58    );
59
60    // Test case 2: Content with length 5
61    let record_type = 2;
62    let request_id = 5678;
63    let content = b"Hello";
64    let expected_record = vec![
65      1, // FastCGI version
66      2, // Record type
67      22, 46, // Request ID
68      0, 5, // Content length
69      3, // Padding length
70      0, // Reserved
71      72, 101, 108, 108, 111, // Content
72      0, 0, 0, // Padding
73    ];
74    assert_eq!(
75      construct_fastcgi_record(record_type, request_id, content),
76      expected_record
77    );
78
79    // Test case 3: Content with length 8 (no padding needed)
80    let record_type = 3;
81    let request_id = 9012;
82    let content = b"12345678";
83    let expected_record = vec![
84      1, // FastCGI version
85      3, // Record type
86      35, 52, // Request ID
87      0, 8, // Content length
88      0, // Padding length
89      0, // Reserved
90      49, 50, 51, 52, 53, 54, 55, 56, // Content
91    ];
92    assert_eq!(
93      construct_fastcgi_record(record_type, request_id, content),
94      expected_record
95    );
96  }
97}