1 use std::fmt; 2 3 use bytes::{Buf, IntoBuf}; 4 use bytes::buf::{Chain, Take}; 5 use iovec::IoVec; 6 7 use common::StaticBuf; 8 use super::io::WriteBuf; 9 10 /// Encoders to handle different Transfer-Encodings. 11 #[derive(Debug, Clone, PartialEq)] 12 pub struct Encoder { 13 kind: Kind, 14 is_last: bool, 15 } 16 17 #[derive(Debug)] 18 pub struct EncodedBuf<B> { 19 kind: BufKind<B>, 20 } 21 22 #[derive(Debug)] 23 pub struct NotEof; 24 25 #[derive(Debug, PartialEq, Clone)] 26 enum Kind { 27 /// An Encoder for when Transfer-Encoding includes `chunked`. 28 Chunked, 29 /// An Encoder for when Content-Length is set. 30 /// 31 /// Enforces that the body is not longer than the Content-Length header. 32 Length(u64), 33 /// An Encoder for when neither Content-Length nore Chunked encoding is set. 34 /// 35 /// This is mostly only used with HTTP/1.0 with a length. This kind requires 36 /// the connection to be closed when the body is finished. 37 CloseDelimited, 38 } 39 40 #[derive(Debug)] 41 enum BufKind<B> { 42 Exact(B), 43 Limited(Take<B>), 44 Chunked(Chain<Chain<ChunkSize, B>, StaticBuf>), 45 ChunkedEnd(StaticBuf), 46 } 47 48 impl Encoder { new(kind: Kind) -> Encoder49 fn new(kind: Kind) -> Encoder { 50 Encoder { 51 kind: kind, 52 is_last: false, 53 } 54 } chunked() -> Encoder55 pub fn chunked() -> Encoder { 56 Encoder::new(Kind::Chunked) 57 } 58 length(len: u64) -> Encoder59 pub fn length(len: u64) -> Encoder { 60 Encoder::new(Kind::Length(len)) 61 } 62 close_delimited() -> Encoder63 pub fn close_delimited() -> Encoder { 64 Encoder::new(Kind::CloseDelimited) 65 } 66 is_eof(&self) -> bool67 pub fn is_eof(&self) -> bool { 68 match self.kind { 69 Kind::Length(0) => true, 70 _ => false 71 } 72 } 73 set_last(mut self, is_last: bool) -> Self74 pub fn set_last(mut self, is_last: bool) -> Self { 75 self.is_last = is_last; 76 self 77 } 78 is_last(&self) -> bool79 pub fn is_last(&self) -> bool { 80 self.is_last 81 } 82 end<B>(&self) -> Result<Option<EncodedBuf<B>>, NotEof>83 pub fn end<B>(&self) -> Result<Option<EncodedBuf<B>>, NotEof> { 84 match self.kind { 85 Kind::Length(0) => Ok(None), 86 Kind::Chunked => Ok(Some(EncodedBuf { 87 kind: BufKind::ChunkedEnd(StaticBuf(b"0\r\n\r\n")), 88 })), 89 _ => Err(NotEof), 90 } 91 } 92 encode<B>(&mut self, msg: B) -> EncodedBuf<B::Buf> where B: IntoBuf,93 pub fn encode<B>(&mut self, msg: B) -> EncodedBuf<B::Buf> 94 where 95 B: IntoBuf, 96 { 97 let msg = msg.into_buf(); 98 let len = msg.remaining(); 99 debug_assert!(len > 0, "encode() called with empty buf"); 100 101 let kind = match self.kind { 102 Kind::Chunked => { 103 trace!("encoding chunked {}B", len); 104 let buf = ChunkSize::new(len) 105 .chain(msg) 106 .chain(StaticBuf(b"\r\n")); 107 BufKind::Chunked(buf) 108 }, 109 Kind::Length(ref mut remaining) => { 110 trace!("sized write, len = {}", len); 111 if len as u64 > *remaining { 112 let limit = *remaining as usize; 113 *remaining = 0; 114 BufKind::Limited(msg.take(limit)) 115 } else { 116 *remaining -= len as u64; 117 BufKind::Exact(msg) 118 } 119 }, 120 Kind::CloseDelimited => { 121 trace!("close delimited write {}B", len); 122 BufKind::Exact(msg) 123 } 124 }; 125 EncodedBuf { 126 kind, 127 } 128 } 129 encode_and_end<B>(&self, msg: B, dst: &mut WriteBuf<EncodedBuf<B::Buf>>) -> bool where B: IntoBuf,130 pub(super) fn encode_and_end<B>(&self, msg: B, dst: &mut WriteBuf<EncodedBuf<B::Buf>>) -> bool 131 where 132 B: IntoBuf, 133 { 134 let msg = msg.into_buf(); 135 let len = msg.remaining(); 136 debug_assert!(len > 0, "encode() called with empty buf"); 137 138 match self.kind { 139 Kind::Chunked => { 140 trace!("encoding chunked {}B", len); 141 let buf = ChunkSize::new(len) 142 .chain(msg) 143 .chain(StaticBuf(b"\r\n0\r\n\r\n")); 144 dst.buffer(buf); 145 !self.is_last 146 }, 147 Kind::Length(remaining) => { 148 use std::cmp::Ordering; 149 150 trace!("sized write, len = {}", len); 151 match (len as u64).cmp(&remaining) { 152 Ordering::Equal => { 153 dst.buffer(msg); 154 !self.is_last 155 }, 156 Ordering::Greater => { 157 dst.buffer(msg.take(remaining as usize)); 158 !self.is_last 159 }, 160 Ordering::Less => { 161 dst.buffer(msg); 162 false 163 } 164 } 165 }, 166 Kind::CloseDelimited => { 167 trace!("close delimited write {}B", len); 168 dst.buffer(msg); 169 false 170 } 171 } 172 } 173 174 /// Encodes the full body, without verifying the remaining length matches. 175 /// 176 /// This is used in conjunction with Payload::__hyper_full_data(), which 177 /// means we can trust that the buf has the correct size (the buf itself 178 /// was checked to make the headers). danger_full_buf<B>(self, msg: B, dst: &mut WriteBuf<EncodedBuf<B::Buf>>) where B: IntoBuf,179 pub(super) fn danger_full_buf<B>(self, msg: B, dst: &mut WriteBuf<EncodedBuf<B::Buf>>) 180 where 181 B: IntoBuf, 182 { 183 let msg = msg.into_buf(); 184 debug_assert!(msg.remaining() > 0, "encode() called with empty buf"); 185 debug_assert!(match self.kind { 186 Kind::Length(len) => len == msg.remaining() as u64, 187 _ => true, 188 }, "danger_full_buf length mismatches"); 189 190 match self.kind { 191 Kind::Chunked => { 192 let len = msg.remaining(); 193 trace!("encoding chunked {}B", len); 194 let buf = ChunkSize::new(len) 195 .chain(msg) 196 .chain(StaticBuf(b"\r\n0\r\n\r\n")); 197 dst.buffer(buf); 198 }, 199 _ => { 200 dst.buffer(msg); 201 }, 202 } 203 } 204 } 205 206 impl<B> Buf for EncodedBuf<B> 207 where 208 B: Buf, 209 { 210 #[inline] remaining(&self) -> usize211 fn remaining(&self) -> usize { 212 match self.kind { 213 BufKind::Exact(ref b) => b.remaining(), 214 BufKind::Limited(ref b) => b.remaining(), 215 BufKind::Chunked(ref b) => b.remaining(), 216 BufKind::ChunkedEnd(ref b) => b.remaining(), 217 } 218 } 219 220 #[inline] bytes(&self) -> &[u8]221 fn bytes(&self) -> &[u8] { 222 match self.kind { 223 BufKind::Exact(ref b) => b.bytes(), 224 BufKind::Limited(ref b) => b.bytes(), 225 BufKind::Chunked(ref b) => b.bytes(), 226 BufKind::ChunkedEnd(ref b) => b.bytes(), 227 } 228 } 229 230 #[inline] advance(&mut self, cnt: usize)231 fn advance(&mut self, cnt: usize) { 232 match self.kind { 233 BufKind::Exact(ref mut b) => b.advance(cnt), 234 BufKind::Limited(ref mut b) => b.advance(cnt), 235 BufKind::Chunked(ref mut b) => b.advance(cnt), 236 BufKind::ChunkedEnd(ref mut b) => b.advance(cnt), 237 } 238 } 239 240 #[inline] bytes_vec<'t>(&'t self, dst: &mut [&'t IoVec]) -> usize241 fn bytes_vec<'t>(&'t self, dst: &mut [&'t IoVec]) -> usize { 242 match self.kind { 243 BufKind::Exact(ref b) => b.bytes_vec(dst), 244 BufKind::Limited(ref b) => b.bytes_vec(dst), 245 BufKind::Chunked(ref b) => b.bytes_vec(dst), 246 BufKind::ChunkedEnd(ref b) => b.bytes_vec(dst), 247 } 248 } 249 } 250 251 252 #[cfg(target_pointer_width = "32")] 253 const USIZE_BYTES: usize = 4; 254 255 #[cfg(target_pointer_width = "64")] 256 const USIZE_BYTES: usize = 8; 257 258 // each byte will become 2 hex 259 const CHUNK_SIZE_MAX_BYTES: usize = USIZE_BYTES * 2; 260 261 #[derive(Clone, Copy)] 262 struct ChunkSize { 263 bytes: [u8; CHUNK_SIZE_MAX_BYTES + 2], 264 pos: u8, 265 len: u8, 266 } 267 268 impl ChunkSize { new(len: usize) -> ChunkSize269 fn new(len: usize) -> ChunkSize { 270 use std::fmt::Write; 271 let mut size = ChunkSize { 272 bytes: [0; CHUNK_SIZE_MAX_BYTES + 2], 273 pos: 0, 274 len: 0, 275 }; 276 write!(&mut size, "{:X}\r\n", len) 277 .expect("CHUNK_SIZE_MAX_BYTES should fit any usize"); 278 size 279 } 280 } 281 282 impl Buf for ChunkSize { 283 #[inline] remaining(&self) -> usize284 fn remaining(&self) -> usize { 285 (self.len - self.pos).into() 286 } 287 288 #[inline] bytes(&self) -> &[u8]289 fn bytes(&self) -> &[u8] { 290 &self.bytes[self.pos.into() .. self.len.into()] 291 } 292 293 #[inline] advance(&mut self, cnt: usize)294 fn advance(&mut self, cnt: usize) { 295 assert!(cnt <= self.remaining()); 296 self.pos += cnt as u8; // just asserted cnt fits in u8 297 } 298 } 299 300 impl fmt::Debug for ChunkSize { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result301 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 302 f.debug_struct("ChunkSize") 303 .field("bytes", &&self.bytes[..self.len.into()]) 304 .field("pos", &self.pos) 305 .finish() 306 } 307 } 308 309 impl fmt::Write for ChunkSize { write_str(&mut self, num: &str) -> fmt::Result310 fn write_str(&mut self, num: &str) -> fmt::Result { 311 use std::io::Write; 312 (&mut self.bytes[self.len.into()..]).write(num.as_bytes()) 313 .expect("&mut [u8].write() cannot error"); 314 self.len += num.len() as u8; // safe because bytes is never bigger than 256 315 Ok(()) 316 } 317 } 318 319 impl<B: Buf> From<B> for EncodedBuf<B> { from(buf: B) -> Self320 fn from(buf: B) -> Self { 321 EncodedBuf { 322 kind: BufKind::Exact(buf), 323 } 324 } 325 } 326 327 impl<B: Buf> From<Take<B>> for EncodedBuf<B> { from(buf: Take<B>) -> Self328 fn from(buf: Take<B>) -> Self { 329 EncodedBuf { 330 kind: BufKind::Limited(buf), 331 } 332 } 333 } 334 335 impl<B: Buf> From<Chain<Chain<ChunkSize, B>, StaticBuf>> for EncodedBuf<B> { from(buf: Chain<Chain<ChunkSize, B>, StaticBuf>) -> Self336 fn from(buf: Chain<Chain<ChunkSize, B>, StaticBuf>) -> Self { 337 EncodedBuf { 338 kind: BufKind::Chunked(buf), 339 } 340 } 341 } 342 343 #[cfg(test)] 344 mod tests { 345 use bytes::{BufMut}; 346 347 use super::super::io::Cursor; 348 use super::Encoder; 349 350 #[test] chunked()351 fn chunked() { 352 let mut encoder = Encoder::chunked(); 353 let mut dst = Vec::new(); 354 355 let msg1 = b"foo bar".as_ref(); 356 let buf1 = encoder.encode(msg1); 357 dst.put(buf1); 358 assert_eq!(dst, b"7\r\nfoo bar\r\n"); 359 360 let msg2 = b"baz quux herp".as_ref(); 361 let buf2 = encoder.encode(msg2); 362 dst.put(buf2); 363 364 assert_eq!(dst, b"7\r\nfoo bar\r\nD\r\nbaz quux herp\r\n"); 365 366 let end = encoder.end::<Cursor<Vec<u8>>>().unwrap().unwrap(); 367 dst.put(end); 368 369 assert_eq!(dst, b"7\r\nfoo bar\r\nD\r\nbaz quux herp\r\n0\r\n\r\n".as_ref()); 370 } 371 372 #[test] length()373 fn length() { 374 let max_len = 8; 375 let mut encoder = Encoder::length(max_len as u64); 376 let mut dst = Vec::new(); 377 378 379 let msg1 = b"foo bar".as_ref(); 380 let buf1 = encoder.encode(msg1); 381 dst.put(buf1); 382 383 384 assert_eq!(dst, b"foo bar"); 385 assert!(!encoder.is_eof()); 386 encoder.end::<()>().unwrap_err(); 387 388 let msg2 = b"baz".as_ref(); 389 let buf2 = encoder.encode(msg2); 390 dst.put(buf2); 391 392 assert_eq!(dst.len(), max_len); 393 assert_eq!(dst, b"foo barb"); 394 assert!(encoder.is_eof()); 395 assert!(encoder.end::<()>().unwrap().is_none()); 396 } 397 398 #[test] eof()399 fn eof() { 400 let mut encoder = Encoder::close_delimited(); 401 let mut dst = Vec::new(); 402 403 404 let msg1 = b"foo bar".as_ref(); 405 let buf1 = encoder.encode(msg1); 406 dst.put(buf1); 407 408 409 assert_eq!(dst, b"foo bar"); 410 assert!(!encoder.is_eof()); 411 encoder.end::<()>().unwrap_err(); 412 413 let msg2 = b"baz".as_ref(); 414 let buf2 = encoder.encode(msg2); 415 dst.put(buf2); 416 417 assert_eq!(dst, b"foo barbaz"); 418 assert!(!encoder.is_eof()); 419 encoder.end::<()>().unwrap_err(); 420 } 421 } 422