1 //! Frame a stream of bytes based on a length prefix 2 //! 3 //! Many protocols delimit their frames by prefacing frame data with a 4 //! frame head that specifies the length of the frame. The 5 //! `length_delimited` module provides utilities for handling the length 6 //! based framing. This allows the consumer to work with entire frames 7 //! without having to worry about buffering or other framing logic. 8 //! 9 //! # Getting started 10 //! 11 //! If implementing a protocol from scratch, using length delimited framing 12 //! is an easy way to get started. [`Codec::new()`] will return a length 13 //! delimited codec using default configuration values. This can then be 14 //! used to construct a framer to adapt a full-duplex byte stream into a 15 //! stream of frames. 16 //! 17 //! ``` 18 //! # extern crate tokio; 19 //! use tokio::io::{AsyncRead, AsyncWrite}; 20 //! use tokio::codec::*; 21 //! 22 //! fn bind_transport<T: AsyncRead + AsyncWrite>(io: T) 23 //! -> Framed<T, LengthDelimitedCodec> 24 //! { 25 //! Framed::new(io, LengthDelimitedCodec::new()) 26 //! } 27 //! # pub fn main() {} 28 //! ``` 29 //! 30 //! The returned transport implements `Sink + Stream` for `BytesMut`. It 31 //! encodes the frame with a big-endian `u32` header denoting the frame 32 //! payload length: 33 //! 34 //! ```text 35 //! +----------+--------------------------------+ 36 //! | len: u32 | frame payload | 37 //! +----------+--------------------------------+ 38 //! ``` 39 //! 40 //! Specifically, given the following: 41 //! 42 //! ``` 43 //! # extern crate tokio; 44 //! # extern crate bytes; 45 //! # extern crate futures; 46 //! # 47 //! use tokio::io::{AsyncRead, AsyncWrite}; 48 //! use tokio::codec::*; 49 //! use bytes::Bytes; 50 //! use futures::{Sink, Future}; 51 //! 52 //! fn write_frame<T: AsyncRead + AsyncWrite>(io: T) { 53 //! let mut transport = Framed::new(io, LengthDelimitedCodec::new()); 54 //! let frame = Bytes::from("hello world"); 55 //! 56 //! transport.send(frame).wait().unwrap(); 57 //! } 58 //! # 59 //! # pub fn main() {} 60 //! ``` 61 //! 62 //! The encoded frame will look like this: 63 //! 64 //! ```text 65 //! +---- len: u32 ----+---- data ----+ 66 //! | \x00\x00\x00\x0b | hello world | 67 //! +------------------+--------------+ 68 //! ``` 69 //! 70 //! # Decoding 71 //! 72 //! [`FramedRead`] adapts an [`AsyncRead`] into a `Stream` of [`BytesMut`], 73 //! such that each yielded [`BytesMut`] value contains the contents of an 74 //! entire frame. There are many configuration parameters enabling 75 //! [`FramedRead`] to handle a wide range of protocols. Here are some 76 //! examples that will cover the various options at a high level. 77 //! 78 //! ## Example 1 79 //! 80 //! The following will parse a `u16` length field at offset 0, including the 81 //! frame head in the yielded `BytesMut`. 82 //! 83 //! ``` 84 //! # extern crate tokio; 85 //! # use tokio::io::AsyncRead; 86 //! # use tokio::codec::length_delimited; 87 //! # fn bind_read<T: AsyncRead>(io: T) { 88 //! length_delimited::Builder::new() 89 //! .length_field_offset(0) // default value 90 //! .length_field_length(2) 91 //! .length_adjustment(0) // default value 92 //! .num_skip(0) // Do not strip frame header 93 //! .new_read(io); 94 //! # } 95 //! # pub fn main() {} 96 //! ``` 97 //! 98 //! The following frame will be decoded as such: 99 //! 100 //! ```text 101 //! INPUT DECODED 102 //! +-- len ---+--- Payload ---+ +-- len ---+--- Payload ---+ 103 //! | \x00\x0B | Hello world | --> | \x00\x0B | Hello world | 104 //! +----------+---------------+ +----------+---------------+ 105 //! ``` 106 //! 107 //! The value of the length field is 11 (`\x0B`) which represents the length 108 //! of the payload, `hello world`. By default, [`FramedRead`] assumes that 109 //! the length field represents the number of bytes that **follows** the 110 //! length field. Thus, the entire frame has a length of 13: 2 bytes for the 111 //! frame head + 11 bytes for the payload. 112 //! 113 //! ## Example 2 114 //! 115 //! The following will parse a `u16` length field at offset 0, omitting the 116 //! frame head in the yielded `BytesMut`. 117 //! 118 //! ``` 119 //! # extern crate tokio; 120 //! # use tokio::io::AsyncRead; 121 //! # use tokio::codec::length_delimited; 122 //! # fn bind_read<T: AsyncRead>(io: T) { 123 //! length_delimited::Builder::new() 124 //! .length_field_offset(0) // default value 125 //! .length_field_length(2) 126 //! .length_adjustment(0) // default value 127 //! // `num_skip` is not needed, the default is to skip 128 //! .new_read(io); 129 //! # } 130 //! # pub fn main() {} 131 //! ``` 132 //! 133 //! The following frame will be decoded as such: 134 //! 135 //! ```text 136 //! INPUT DECODED 137 //! +-- len ---+--- Payload ---+ +--- Payload ---+ 138 //! | \x00\x0B | Hello world | --> | Hello world | 139 //! +----------+---------------+ +---------------+ 140 //! ``` 141 //! 142 //! This is similar to the first example, the only difference is that the 143 //! frame head is **not** included in the yielded `BytesMut` value. 144 //! 145 //! ## Example 3 146 //! 147 //! The following will parse a `u16` length field at offset 0, including the 148 //! frame head in the yielded `BytesMut`. In this case, the length field 149 //! **includes** the frame head length. 150 //! 151 //! ``` 152 //! # extern crate tokio; 153 //! # use tokio::io::AsyncRead; 154 //! # use tokio::codec::length_delimited; 155 //! # fn bind_read<T: AsyncRead>(io: T) { 156 //! length_delimited::Builder::new() 157 //! .length_field_offset(0) // default value 158 //! .length_field_length(2) 159 //! .length_adjustment(-2) // size of head 160 //! .num_skip(0) 161 //! .new_read(io); 162 //! # } 163 //! # pub fn main() {} 164 //! ``` 165 //! 166 //! The following frame will be decoded as such: 167 //! 168 //! ```text 169 //! INPUT DECODED 170 //! +-- len ---+--- Payload ---+ +-- len ---+--- Payload ---+ 171 //! | \x00\x0D | Hello world | --> | \x00\x0D | Hello world | 172 //! +----------+---------------+ +----------+---------------+ 173 //! ``` 174 //! 175 //! In most cases, the length field represents the length of the payload 176 //! only, as shown in the previous examples. However, in some protocols the 177 //! length field represents the length of the whole frame, including the 178 //! head. In such cases, we specify a negative `length_adjustment` to adjust 179 //! the value provided in the frame head to represent the payload length. 180 //! 181 //! ## Example 4 182 //! 183 //! The following will parse a 3 byte length field at offset 0 in a 5 byte 184 //! frame head, including the frame head in the yielded `BytesMut`. 185 //! 186 //! ``` 187 //! # extern crate tokio; 188 //! # use tokio::io::AsyncRead; 189 //! # use tokio::codec::length_delimited; 190 //! # fn bind_read<T: AsyncRead>(io: T) { 191 //! length_delimited::Builder::new() 192 //! .length_field_offset(0) // default value 193 //! .length_field_length(3) 194 //! .length_adjustment(2) // remaining head 195 //! .num_skip(0) 196 //! .new_read(io); 197 //! # } 198 //! # pub fn main() {} 199 //! ``` 200 //! 201 //! The following frame will be decoded as such: 202 //! 203 //! ```text 204 //! INPUT 205 //! +---- len -----+- head -+--- Payload ---+ 206 //! | \x00\x00\x0B | \xCAFE | Hello world | 207 //! +--------------+--------+---------------+ 208 //! 209 //! DECODED 210 //! +---- len -----+- head -+--- Payload ---+ 211 //! | \x00\x00\x0B | \xCAFE | Hello world | 212 //! +--------------+--------+---------------+ 213 //! ``` 214 //! 215 //! A more advanced example that shows a case where there is extra frame 216 //! head data between the length field and the payload. In such cases, it is 217 //! usually desirable to include the frame head as part of the yielded 218 //! `BytesMut`. This lets consumers of the length delimited framer to 219 //! process the frame head as needed. 220 //! 221 //! The positive `length_adjustment` value lets `FramedRead` factor in the 222 //! additional head into the frame length calculation. 223 //! 224 //! ## Example 5 225 //! 226 //! The following will parse a `u16` length field at offset 1 of a 4 byte 227 //! frame head. The first byte and the length field will be omitted from the 228 //! yielded `BytesMut`, but the trailing 2 bytes of the frame head will be 229 //! included. 230 //! 231 //! ``` 232 //! # extern crate tokio; 233 //! # use tokio::io::AsyncRead; 234 //! # use tokio::codec::length_delimited; 235 //! # fn bind_read<T: AsyncRead>(io: T) { 236 //! length_delimited::Builder::new() 237 //! .length_field_offset(1) // length of hdr1 238 //! .length_field_length(2) 239 //! .length_adjustment(1) // length of hdr2 240 //! .num_skip(3) // length of hdr1 + LEN 241 //! .new_read(io); 242 //! # } 243 //! # pub fn main() {} 244 //! ``` 245 //! 246 //! The following frame will be decoded as such: 247 //! 248 //! ```text 249 //! INPUT 250 //! +- hdr1 -+-- len ---+- hdr2 -+--- Payload ---+ 251 //! | \xCA | \x00\x0B | \xFE | Hello world | 252 //! +--------+----------+--------+---------------+ 253 //! 254 //! DECODED 255 //! +- hdr2 -+--- Payload ---+ 256 //! | \xFE | Hello world | 257 //! +--------+---------------+ 258 //! ``` 259 //! 260 //! The length field is situated in the middle of the frame head. In this 261 //! case, the first byte in the frame head could be a version or some other 262 //! identifier that is not needed for processing. On the other hand, the 263 //! second half of the head is needed. 264 //! 265 //! `length_field_offset` indicates how many bytes to skip before starting 266 //! to read the length field. `length_adjustment` is the number of bytes to 267 //! skip starting at the end of the length field. In this case, it is the 268 //! second half of the head. 269 //! 270 //! ## Example 6 271 //! 272 //! The following will parse a `u16` length field at offset 1 of a 4 byte 273 //! frame head. The first byte and the length field will be omitted from the 274 //! yielded `BytesMut`, but the trailing 2 bytes of the frame head will be 275 //! included. In this case, the length field **includes** the frame head 276 //! length. 277 //! 278 //! ``` 279 //! # extern crate tokio; 280 //! # use tokio::io::AsyncRead; 281 //! # use tokio::codec::length_delimited; 282 //! # fn bind_read<T: AsyncRead>(io: T) { 283 //! length_delimited::Builder::new() 284 //! .length_field_offset(1) // length of hdr1 285 //! .length_field_length(2) 286 //! .length_adjustment(-3) // length of hdr1 + LEN, negative 287 //! .num_skip(3) 288 //! .new_read(io); 289 //! # } 290 //! # pub fn main() {} 291 //! ``` 292 //! 293 //! The following frame will be decoded as such: 294 //! 295 //! ```text 296 //! INPUT 297 //! +- hdr1 -+-- len ---+- hdr2 -+--- Payload ---+ 298 //! | \xCA | \x00\x0F | \xFE | Hello world | 299 //! +--------+----------+--------+---------------+ 300 //! 301 //! DECODED 302 //! +- hdr2 -+--- Payload ---+ 303 //! | \xFE | Hello world | 304 //! +--------+---------------+ 305 //! ``` 306 //! 307 //! Similar to the example above, the difference is that the length field 308 //! represents the length of the entire frame instead of just the payload. 309 //! The length of `hdr1` and `len` must be counted in `length_adjustment`. 310 //! Note that the length of `hdr2` does **not** need to be explicitly set 311 //! anywhere because it already is factored into the total frame length that 312 //! is read from the byte stream. 313 //! 314 //! # Encoding 315 //! 316 //! [`FramedWrite`] adapts an [`AsyncWrite`] into a `Sink` of [`BytesMut`], 317 //! such that each submitted [`BytesMut`] is prefaced by a length field. 318 //! There are fewer configuration options than [`FramedRead`]. Given 319 //! protocols that have more complex frame heads, an encoder should probably 320 //! be written by hand using [`Encoder`]. 321 //! 322 //! Here is a simple example, given a `FramedWrite` with the following 323 //! configuration: 324 //! 325 //! ``` 326 //! # extern crate tokio; 327 //! # extern crate bytes; 328 //! # use tokio::io::AsyncWrite; 329 //! # use tokio::codec::length_delimited; 330 //! # use bytes::BytesMut; 331 //! # fn write_frame<T: AsyncWrite>(io: T) { 332 //! # let _ = 333 //! length_delimited::Builder::new() 334 //! .length_field_length(2) 335 //! .new_write(io); 336 //! # } 337 //! # pub fn main() {} 338 //! ``` 339 //! 340 //! A payload of `hello world` will be encoded as: 341 //! 342 //! ```text 343 //! +- len: u16 -+---- data ----+ 344 //! | \x00\x0b | hello world | 345 //! +------------+--------------+ 346 //! ``` 347 //! 348 //! [`FramedRead`]: struct.FramedRead.html 349 //! [`FramedWrite`]: struct.FramedWrite.html 350 //! [`AsyncRead`]: ../../trait.AsyncRead.html 351 //! [`AsyncWrite`]: ../../trait.AsyncWrite.html 352 //! [`Encoder`]: ../trait.Encoder.html 353 //! [`BytesMut`]: https://docs.rs/bytes/0.4/bytes/struct.BytesMut.html 354 355 use { 356 codec::{ 357 Decoder, Encoder, FramedRead, FramedWrite, Framed 358 }, 359 io::{ 360 AsyncRead, AsyncWrite 361 }, 362 }; 363 364 use bytes::{Buf, BufMut, Bytes, BytesMut, IntoBuf}; 365 366 use std::{cmp, fmt}; 367 use std::error::Error as StdError; 368 use std::io::{self, Cursor}; 369 370 /// Configure length delimited `LengthDelimitedCodec`s. 371 /// 372 /// `Builder` enables constructing configured length delimited codecs. Note 373 /// that not all configuration settings apply to both encoding and decoding. See 374 /// the documentation for specific methods for more detail. 375 #[derive(Debug, Clone, Copy)] 376 pub struct Builder { 377 // Maximum frame length 378 max_frame_len: usize, 379 380 // Number of bytes representing the field length 381 length_field_len: usize, 382 383 // Number of bytes in the header before the length field 384 length_field_offset: usize, 385 386 // Adjust the length specified in the header field by this amount 387 length_adjustment: isize, 388 389 // Total number of bytes to skip before reading the payload, if not set, 390 // `length_field_len + length_field_offset` 391 num_skip: Option<usize>, 392 393 // Length field byte order (little or big endian) 394 length_field_is_big_endian: bool, 395 } 396 397 /// An error when the number of bytes read is more than max frame length. 398 pub struct FrameTooBig { 399 _priv: (), 400 } 401 402 /// A codec for frames delimited by a frame head specifying their lengths. 403 /// 404 /// This allows the consumer to work with entire frames without having to worry 405 /// about buffering or other framing logic. 406 /// 407 /// See [module level] documentation for more detail. 408 /// 409 /// [module level]: index.html 410 #[derive(Debug)] 411 pub struct LengthDelimitedCodec { 412 // Configuration values 413 builder: Builder, 414 415 // Read state 416 state: DecodeState, 417 } 418 419 #[derive(Debug, Clone, Copy)] 420 enum DecodeState { 421 Head, 422 Data(usize), 423 } 424 425 // ===== impl LengthDelimitedCodec ====== 426 427 impl LengthDelimitedCodec { 428 /// Creates a new `LengthDelimitedCodec` with the default configuration values. new() -> Self429 pub fn new() -> Self { 430 Self { 431 builder: Builder::new(), 432 state: DecodeState::Head, 433 } 434 } 435 436 /// Returns the current max frame setting 437 /// 438 /// This is the largest size this codec will accept from the wire. Larger 439 /// frames will be rejected. max_frame_length(&self) -> usize440 pub fn max_frame_length(&self) -> usize { 441 self.builder.max_frame_len 442 } 443 444 /// Updates the max frame setting. 445 /// 446 /// The change takes effect the next time a frame is decoded. In other 447 /// words, if a frame is currently in process of being decoded with a frame 448 /// size greater than `val` but less than the max frame length in effect 449 /// before calling this function, then the frame will be allowed. set_max_frame_length(&mut self, val: usize)450 pub fn set_max_frame_length(&mut self, val: usize) { 451 self.builder.max_frame_length(val); 452 } 453 decode_head(&mut self, src: &mut BytesMut) -> io::Result<Option<usize>>454 fn decode_head(&mut self, src: &mut BytesMut) -> io::Result<Option<usize>> { 455 let head_len = self.builder.num_head_bytes(); 456 let field_len = self.builder.length_field_len; 457 458 if src.len() < head_len { 459 // Not enough data 460 return Ok(None); 461 } 462 463 let n = { 464 let mut src = Cursor::new(&mut *src); 465 466 // Skip the required bytes 467 src.advance(self.builder.length_field_offset); 468 469 // match endianess 470 let n = if self.builder.length_field_is_big_endian { 471 src.get_uint_be(field_len) 472 } else { 473 src.get_uint_le(field_len) 474 }; 475 476 if n > self.builder.max_frame_len as u64 { 477 return Err(io::Error::new(io::ErrorKind::InvalidData, FrameTooBig { 478 _priv: (), 479 })); 480 } 481 482 // The check above ensures there is no overflow 483 let n = n as usize; 484 485 // Adjust `n` with bounds checking 486 let n = if self.builder.length_adjustment < 0 { 487 n.checked_sub(-self.builder.length_adjustment as usize) 488 } else { 489 n.checked_add(self.builder.length_adjustment as usize) 490 }; 491 492 // Error handling 493 match n { 494 Some(n) => n, 495 None => return Err(io::Error::new(io::ErrorKind::InvalidInput, "provided length would overflow after adjustment")), 496 } 497 }; 498 499 let num_skip = self.builder.get_num_skip(); 500 501 if num_skip > 0 { 502 let _ = src.split_to(num_skip); 503 } 504 505 // Ensure that the buffer has enough space to read the incoming 506 // payload 507 src.reserve(n); 508 509 return Ok(Some(n)); 510 } 511 decode_data(&self, n: usize, src: &mut BytesMut) -> io::Result<Option<BytesMut>>512 fn decode_data(&self, n: usize, src: &mut BytesMut) -> io::Result<Option<BytesMut>> { 513 // At this point, the buffer has already had the required capacity 514 // reserved. All there is to do is read. 515 if src.len() < n { 516 return Ok(None); 517 } 518 519 Ok(Some(src.split_to(n))) 520 } 521 } 522 523 impl Decoder for LengthDelimitedCodec { 524 type Item = BytesMut; 525 type Error = io::Error; 526 decode(&mut self, src: &mut BytesMut) -> io::Result<Option<BytesMut>>527 fn decode(&mut self, src: &mut BytesMut) -> io::Result<Option<BytesMut>> { 528 let n = match self.state { 529 DecodeState::Head => { 530 match try!(self.decode_head(src)) { 531 Some(n) => { 532 self.state = DecodeState::Data(n); 533 n 534 } 535 None => return Ok(None), 536 } 537 } 538 DecodeState::Data(n) => n, 539 }; 540 541 match try!(self.decode_data(n, src)) { 542 Some(data) => { 543 // Update the decode state 544 self.state = DecodeState::Head; 545 546 // Make sure the buffer has enough space to read the next head 547 src.reserve(self.builder.num_head_bytes()); 548 549 Ok(Some(data)) 550 } 551 None => Ok(None), 552 } 553 } 554 } 555 556 impl Encoder for LengthDelimitedCodec { 557 type Item = Bytes; 558 type Error = io::Error; 559 encode(&mut self, data: Bytes, dst: &mut BytesMut) -> Result<(), io::Error>560 fn encode(&mut self, data: Bytes, dst: &mut BytesMut) -> Result<(), io::Error> { 561 let n = (&data).into_buf().remaining(); 562 563 if n > self.builder.max_frame_len { 564 return Err(io::Error::new(io::ErrorKind::InvalidInput, FrameTooBig { 565 _priv: (), 566 })); 567 } 568 569 // Adjust `n` with bounds checking 570 let n = if self.builder.length_adjustment < 0 { 571 n.checked_add(-self.builder.length_adjustment as usize) 572 } else { 573 n.checked_sub(self.builder.length_adjustment as usize) 574 }; 575 576 let n = n.ok_or_else(|| io::Error::new( 577 io::ErrorKind::InvalidInput, 578 "provided length would overflow after adjustment", 579 ))?; 580 581 if self.builder.length_field_is_big_endian { 582 dst.put_uint_be(n as u64, self.builder.length_field_len); 583 } else { 584 dst.put_uint_le(n as u64, self.builder.length_field_len); 585 } 586 587 // Write the frame to the buffer 588 dst.extend_from_slice(&data[..]); 589 590 Ok(()) 591 } 592 } 593 594 // ===== impl Builder ===== 595 596 impl Builder { 597 /// Creates a new length delimited codec builder with default configuration 598 /// values. 599 /// 600 /// # Examples 601 /// 602 /// ``` 603 /// # extern crate tokio; 604 /// # use tokio::io::AsyncRead; 605 /// use tokio::codec::length_delimited::Builder; 606 /// 607 /// # fn bind_read<T: AsyncRead>(io: T) { 608 /// Builder::new() 609 /// .length_field_offset(0) 610 /// .length_field_length(2) 611 /// .length_adjustment(0) 612 /// .num_skip(0) 613 /// .new_read(io); 614 /// # } 615 /// # pub fn main() {} 616 /// ``` new() -> Builder617 pub fn new() -> Builder { 618 Builder { 619 // Default max frame length of 8MB 620 max_frame_len: 8 * 1_024 * 1_024, 621 622 // Default byte length of 4 623 length_field_len: 4, 624 625 // Default to the header field being at the start of the header. 626 length_field_offset: 0, 627 628 length_adjustment: 0, 629 630 // Total number of bytes to skip before reading the payload, if not set, 631 // `length_field_len + length_field_offset` 632 num_skip: None, 633 634 // Default to reading the length field in network (big) endian. 635 length_field_is_big_endian: true, 636 } 637 } 638 639 /// Read the length field as a big endian integer 640 /// 641 /// This is the default setting. 642 /// 643 /// This configuration option applies to both encoding and decoding. 644 /// 645 /// # Examples 646 /// 647 /// ``` 648 /// # extern crate tokio; 649 /// # use tokio::io::AsyncRead; 650 /// use tokio::codec::length_delimited::Builder; 651 /// 652 /// # fn bind_read<T: AsyncRead>(io: T) { 653 /// Builder::new() 654 /// .big_endian() 655 /// .new_read(io); 656 /// # } 657 /// # pub fn main() {} 658 /// ``` big_endian(&mut self) -> &mut Self659 pub fn big_endian(&mut self) -> &mut Self { 660 self.length_field_is_big_endian = true; 661 self 662 } 663 664 /// Read the length field as a little endian integer 665 /// 666 /// The default setting is big endian. 667 /// 668 /// This configuration option applies to both encoding and decoding. 669 /// 670 /// # Examples 671 /// 672 /// ``` 673 /// # extern crate tokio; 674 /// # use tokio::io::AsyncRead; 675 /// use tokio::codec::length_delimited::Builder; 676 /// 677 /// # fn bind_read<T: AsyncRead>(io: T) { 678 /// Builder::new() 679 /// .little_endian() 680 /// .new_read(io); 681 /// # } 682 /// # pub fn main() {} 683 /// ``` little_endian(&mut self) -> &mut Self684 pub fn little_endian(&mut self) -> &mut Self { 685 self.length_field_is_big_endian = false; 686 self 687 } 688 689 /// Read the length field as a native endian integer 690 /// 691 /// The default setting is big endian. 692 /// 693 /// This configuration option applies to both encoding and decoding. 694 /// 695 /// # Examples 696 /// 697 /// ``` 698 /// # extern crate tokio; 699 /// # use tokio::io::AsyncRead; 700 /// use tokio::codec::length_delimited::Builder; 701 /// 702 /// # fn bind_read<T: AsyncRead>(io: T) { 703 /// Builder::new() 704 /// .native_endian() 705 /// .new_read(io); 706 /// # } 707 /// # pub fn main() {} 708 /// ``` native_endian(&mut self) -> &mut Self709 pub fn native_endian(&mut self) -> &mut Self { 710 if cfg!(target_endian = "big") { 711 self.big_endian() 712 } else { 713 self.little_endian() 714 } 715 } 716 717 /// Sets the max frame length 718 /// 719 /// This configuration option applies to both encoding and decoding. The 720 /// default value is 8MB. 721 /// 722 /// When decoding, the length field read from the byte stream is checked 723 /// against this setting **before** any adjustments are applied. When 724 /// encoding, the length of the submitted payload is checked against this 725 /// setting. 726 /// 727 /// When frames exceed the max length, an `io::Error` with the custom value 728 /// of the `FrameTooBig` type will be returned. 729 /// 730 /// # Examples 731 /// 732 /// ``` 733 /// # extern crate tokio; 734 /// # use tokio::io::AsyncRead; 735 /// use tokio::codec::length_delimited::Builder; 736 /// 737 /// # fn bind_read<T: AsyncRead>(io: T) { 738 /// Builder::new() 739 /// .max_frame_length(8 * 1024) 740 /// .new_read(io); 741 /// # } 742 /// # pub fn main() {} 743 /// ``` max_frame_length(&mut self, val: usize) -> &mut Self744 pub fn max_frame_length(&mut self, val: usize) -> &mut Self { 745 self.max_frame_len = val; 746 self 747 } 748 749 /// Sets the number of bytes used to represent the length field 750 /// 751 /// The default value is `4`. The max value is `8`. 752 /// 753 /// This configuration option applies to both encoding and decoding. 754 /// 755 /// # Examples 756 /// 757 /// ``` 758 /// # extern crate tokio; 759 /// # use tokio::io::AsyncRead; 760 /// use tokio::codec::length_delimited::Builder; 761 /// 762 /// # fn bind_read<T: AsyncRead>(io: T) { 763 /// Builder::new() 764 /// .length_field_length(4) 765 /// .new_read(io); 766 /// # } 767 /// # pub fn main() {} 768 /// ``` length_field_length(&mut self, val: usize) -> &mut Self769 pub fn length_field_length(&mut self, val: usize) -> &mut Self { 770 assert!(val > 0 && val <= 8, "invalid length field length"); 771 self.length_field_len = val; 772 self 773 } 774 775 /// Sets the number of bytes in the header before the length field 776 /// 777 /// This configuration option only applies to decoding. 778 /// 779 /// # Examples 780 /// 781 /// ``` 782 /// # extern crate tokio; 783 /// # use tokio::io::AsyncRead; 784 /// use tokio::codec::length_delimited::Builder; 785 /// 786 /// # fn bind_read<T: AsyncRead>(io: T) { 787 /// Builder::new() 788 /// .length_field_offset(1) 789 /// .new_read(io); 790 /// # } 791 /// # pub fn main() {} 792 /// ``` length_field_offset(&mut self, val: usize) -> &mut Self793 pub fn length_field_offset(&mut self, val: usize) -> &mut Self { 794 self.length_field_offset = val; 795 self 796 } 797 798 /// Delta between the payload length specified in the header and the real 799 /// payload length 800 /// 801 /// # Examples 802 /// 803 /// ``` 804 /// # extern crate tokio; 805 /// # use tokio::io::AsyncRead; 806 /// use tokio::codec::length_delimited::Builder; 807 /// 808 /// # fn bind_read<T: AsyncRead>(io: T) { 809 /// Builder::new() 810 /// .length_adjustment(-2) 811 /// .new_read(io); 812 /// # } 813 /// # pub fn main() {} 814 /// ``` length_adjustment(&mut self, val: isize) -> &mut Self815 pub fn length_adjustment(&mut self, val: isize) -> &mut Self { 816 self.length_adjustment = val; 817 self 818 } 819 820 /// Sets the number of bytes to skip before reading the payload 821 /// 822 /// Default value is `length_field_len + length_field_offset` 823 /// 824 /// This configuration option only applies to decoding 825 /// 826 /// # Examples 827 /// 828 /// ``` 829 /// # extern crate tokio; 830 /// # use tokio::io::AsyncRead; 831 /// use tokio::codec::length_delimited::Builder; 832 /// 833 /// # fn bind_read<T: AsyncRead>(io: T) { 834 /// Builder::new() 835 /// .num_skip(4) 836 /// .new_read(io); 837 /// # } 838 /// # pub fn main() {} 839 /// ``` num_skip(&mut self, val: usize) -> &mut Self840 pub fn num_skip(&mut self, val: usize) -> &mut Self { 841 self.num_skip = Some(val); 842 self 843 } 844 845 /// Create a configured length delimited `LengthDelimitedCodec` 846 /// 847 /// # Examples 848 /// 849 /// ``` 850 /// # extern crate tokio; 851 /// # use tokio::io::AsyncRead; 852 /// use tokio::codec::length_delimited::Builder; 853 /// # pub fn main() { 854 /// Builder::new() 855 /// .length_field_offset(0) 856 /// .length_field_length(2) 857 /// .length_adjustment(0) 858 /// .num_skip(0) 859 /// .new_codec(); 860 /// # } 861 /// ``` new_codec(&self) -> LengthDelimitedCodec862 pub fn new_codec(&self) -> LengthDelimitedCodec { 863 LengthDelimitedCodec { 864 builder: *self, 865 state: DecodeState::Head, 866 } 867 } 868 869 /// Create a configured length delimited `FramedRead` 870 /// 871 /// # Examples 872 /// 873 /// ``` 874 /// # extern crate tokio; 875 /// # use tokio::io::AsyncRead; 876 /// use tokio::codec::length_delimited::Builder; 877 /// 878 /// # fn bind_read<T: AsyncRead>(io: T) { 879 /// Builder::new() 880 /// .length_field_offset(0) 881 /// .length_field_length(2) 882 /// .length_adjustment(0) 883 /// .num_skip(0) 884 /// .new_read(io); 885 /// # } 886 /// # pub fn main() {} 887 /// ``` new_read<T>(&self, upstream: T) -> FramedRead<T, LengthDelimitedCodec> where T: AsyncRead,888 pub fn new_read<T>(&self, upstream: T) -> FramedRead<T, LengthDelimitedCodec> 889 where T: AsyncRead, 890 { 891 FramedRead::new(upstream, self.new_codec()) 892 } 893 894 /// Create a configured length delimited `FramedWrite` 895 /// 896 /// # Examples 897 /// 898 /// ``` 899 /// # extern crate tokio; 900 /// # extern crate bytes; 901 /// # use tokio::io::AsyncWrite; 902 /// # use tokio::codec::length_delimited; 903 /// # use bytes::BytesMut; 904 /// # fn write_frame<T: AsyncWrite>(io: T) { 905 /// length_delimited::Builder::new() 906 /// .length_field_length(2) 907 /// .new_write(io); 908 /// # } 909 /// # pub fn main() {} 910 /// ``` new_write<T>(&self, inner: T) -> FramedWrite<T, LengthDelimitedCodec> where T: AsyncWrite,911 pub fn new_write<T>(&self, inner: T) -> FramedWrite<T, LengthDelimitedCodec> 912 where T: AsyncWrite, 913 { 914 FramedWrite::new(inner, self.new_codec()) 915 } 916 917 /// Create a configured length delimited `Framed` 918 /// 919 /// # Examples 920 /// 921 /// ``` 922 /// # extern crate tokio; 923 /// # extern crate bytes; 924 /// # use tokio::io::{AsyncRead, AsyncWrite}; 925 /// # use tokio::codec::length_delimited; 926 /// # use bytes::BytesMut; 927 /// # fn write_frame<T: AsyncRead + AsyncWrite>(io: T) { 928 /// # let _ = 929 /// length_delimited::Builder::new() 930 /// .length_field_length(2) 931 /// .new_framed(io); 932 /// # } 933 /// # pub fn main() {} 934 /// ``` new_framed<T>(&self, inner: T) -> Framed<T, LengthDelimitedCodec> where T: AsyncRead + AsyncWrite,935 pub fn new_framed<T>(&self, inner: T) -> Framed<T, LengthDelimitedCodec> 936 where T: AsyncRead + AsyncWrite, 937 { 938 Framed::new(inner, self.new_codec()) 939 } 940 num_head_bytes(&self) -> usize941 fn num_head_bytes(&self) -> usize { 942 let num = self.length_field_offset + self.length_field_len; 943 cmp::max(num, self.num_skip.unwrap_or(0)) 944 } 945 get_num_skip(&self) -> usize946 fn get_num_skip(&self) -> usize { 947 self.num_skip.unwrap_or(self.length_field_offset + self.length_field_len) 948 } 949 } 950 951 952 // ===== impl FrameTooBig ===== 953 954 impl fmt::Debug for FrameTooBig { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result955 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 956 f.debug_struct("FrameTooBig") 957 .finish() 958 } 959 } 960 961 impl fmt::Display for FrameTooBig { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result962 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 963 f.write_str(self.description()) 964 } 965 } 966 967 impl StdError for FrameTooBig { description(&self) -> &str968 fn description(&self) -> &str { 969 "frame size too big" 970 } 971 } 972