actix_http/encoding/
mod.rs1use std::io;
28
29use bytes::{Bytes, BytesMut};
30
31mod decoder;
32mod encoder;
33
34pub use self::{decoder::Decoder, encoder::Encoder};
35
36struct Writer {
40 buf: BytesMut,
41
42 remaining: Option<usize>,
44}
45
46impl Writer {
47 fn new() -> Writer {
48 Writer {
49 buf: BytesMut::with_capacity(8192),
50 remaining: None,
51 }
52 }
53
54 fn set_limit(&mut self, limit: usize) {
55 self.remaining = Some(limit);
56 }
57
58 fn take(&mut self) -> Bytes {
59 self.buf.split().freeze()
60 }
61}
62
63impl io::Write for Writer {
64 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
65 if let Some(remaining) = &mut self.remaining {
66 if buf.len() > *remaining {
67 *remaining = 0;
68 return Err(io::ErrorKind::FileTooLarge.into());
69 }
70
71 *remaining -= buf.len();
72 }
73
74 self.buf.extend_from_slice(buf);
75 Ok(buf.len())
76 }
77
78 fn flush(&mut self) -> io::Result<()> {
79 Ok(())
80 }
81}
82
83#[cfg(test)]
84mod tests {
85 use std::io::Write as _;
86
87 use super::Writer;
88
89 #[test]
90 fn writer_rejects_overflow_without_copying() {
91 let mut writer = Writer::new();
92 writer.set_limit(3);
93 writer.write_all(b"ab").unwrap();
94 assert!(writer.write_all(b"cdef").is_err());
95
96 assert_eq!(writer.take().as_ref(), b"ab");
97
98 assert!(writer.write_all(b"more output").is_err());
99 assert!(writer.take().is_empty());
100 }
101
102 #[test]
103 fn writer_zero_limit_rejects_output() {
104 let mut writer = Writer::new();
105 writer.set_limit(0);
106 assert!(writer.write_all(b"ab").is_err());
107
108 assert!(writer.take().is_empty());
109 }
110
111 #[test]
112 fn taking_output_does_not_reset_limit() {
113 let mut writer = Writer::new();
114 writer.set_limit(3);
115 writer.write_all(b"ab").unwrap();
116 assert_eq!(writer.take().as_ref(), b"ab");
117
118 writer.write_all(b"c").unwrap();
119 assert!(writer.write_all(b"d").is_err());
120 assert_eq!(writer.take().as_ref(), b"c");
121 }
122
123 #[test]
124 fn writer_max_limit_does_not_wrap() {
125 let mut writer = Writer::new();
126 writer.set_limit(usize::MAX);
127 writer.write_all(b"abc").unwrap();
128
129 assert_eq!(writer.take().as_ref(), b"abc");
130 }
131
132 #[test]
133 fn writer_is_unlimited_by_default() {
134 let mut writer = Writer::new();
135 let data = vec![0; 1024 * 1024];
136 writer.write_all(&data).unwrap();
137
138 assert_eq!(writer.take().as_ref(), data);
139 }
140}