Use rustfmt to enforce consistent formatting

This change adds a .rustfmt.toml that includes ALL supported settings,
12 of which we have overridden to attempt to cater to our own
proclivities.

rustfmt is checked in the rust-nightly CI job.
This commit is contained in:
Oliver Gould
2017-09-08 17:20:41 +00:00
parent 93925e6d1f
commit 897bf84163
60 changed files with 2087 additions and 1620 deletions

View File

@@ -1,15 +1,15 @@
use super::{huffman, Header};
use frame;
use http::{header};
use bytes::{Buf, Bytes, BytesMut};
use http::header;
use http::method::{self, Method};
use http::status::{self, StatusCode};
use bytes::{Buf, Bytes, BytesMut};
use string::String;
use std::cmp;
use std::io::Cursor;
use std::collections::VecDeque;
use std::io::Cursor;
use std::str::Utf8Error;
/// Decodes headers using HPACK
@@ -164,7 +164,8 @@ impl Decoder {
/// Decodes the headers found in the given buffer.
pub fn decode<F>(&mut self, src: &mut Cursor<Bytes>, mut f: F) -> Result<(), DecoderError>
where F: FnMut(Header)
where
F: FnMut(Header),
{
use self::Representation::*;
@@ -180,16 +181,16 @@ impl Decoder {
// At this point we are always at the beginning of the next block
// within the HPACK data. The type of the block can always be
// determined from the first byte.
match try!(Representation::load(peek_u8(src))) {
match Representation::load(peek_u8(src))? {
Indexed => {
trace!(" Indexed; rem={:?}", src.remaining());
can_resize = false;
f(try!(self.decode_indexed(src)));
f(self.decode_indexed(src)?);
}
LiteralWithIndexing => {
trace!(" LiteralWithIndexing; rem={:?}", src.remaining());
can_resize = false;
let entry = try!(self.decode_literal(src, true));
let entry = self.decode_literal(src, true)?;
// Insert the header into the table
self.table.insert(entry.clone());
@@ -199,13 +200,13 @@ impl Decoder {
LiteralWithoutIndexing => {
trace!(" LiteralWithoutIndexing; rem={:?}", src.remaining());
can_resize = false;
let entry = try!(self.decode_literal(src, false));
let entry = self.decode_literal(src, false)?;
f(entry);
}
LiteralNeverIndexed => {
trace!(" LiteralNeverIndexed; rem={:?}", src.remaining());
can_resize = false;
let entry = try!(self.decode_literal(src, false));
let entry = self.decode_literal(src, false)?;
// TODO: Track that this should never be indexed
@@ -218,7 +219,7 @@ impl Decoder {
}
// Handle the dynamic table size update
try!(self.process_size_update(src));
self.process_size_update(src)?;
}
}
}
@@ -226,52 +227,47 @@ impl Decoder {
Ok(())
}
fn process_size_update(&mut self, buf: &mut Cursor<Bytes>)
-> Result<(), DecoderError>
{
let new_size = try!(decode_int(buf, 5));
fn process_size_update(&mut self, buf: &mut Cursor<Bytes>) -> Result<(), DecoderError> {
let new_size = decode_int(buf, 5)?;
if new_size > self.last_max_update {
return Err(DecoderError::InvalidMaxDynamicSize);
}
debug!("Decoder changed max table size from {} to {}",
self.table.size(), new_size);
self.table.size(),
new_size);
self.table.set_max_size(new_size);
Ok(())
}
fn decode_indexed(&self, buf: &mut Cursor<Bytes>)
-> Result<Header, DecoderError>
{
let index = try!(decode_int(buf, 7));
fn decode_indexed(&self, buf: &mut Cursor<Bytes>) -> Result<Header, DecoderError> {
let index = decode_int(buf, 7)?;
self.table.get(index)
}
fn decode_literal(&mut self, buf: &mut Cursor<Bytes>, index: bool)
-> Result<Header, DecoderError>
{
let prefix = if index {
6
} else {
4
};
fn decode_literal(
&mut self,
buf: &mut Cursor<Bytes>,
index: bool,
) -> Result<Header, DecoderError> {
let prefix = if index { 6 } else { 4 };
// Extract the table index for the name, or 0 if not indexed
let table_idx = try!(decode_int(buf, prefix));
let table_idx = decode_int(buf, prefix)?;
// First, read the header name
if table_idx == 0 {
// Read the name as a literal
let name = try!(self.decode_string(buf));
let value = try!(self.decode_string(buf));
let name = self.decode_string(buf)?;
let value = self.decode_string(buf)?;
Header::new(name, value)
} else {
let e = try!(self.table.get(table_idx));
let value = try!(self.decode_string(buf));
let e = self.table.get(table_idx)?;
let value = self.decode_string(buf)?;
e.name().into_entry(value)
}
@@ -288,10 +284,12 @@ impl Decoder {
let huff = peek_u8(buf) & HUFF_FLAG == HUFF_FLAG;
// Decode the string length using 7 bit prefix
let len = try!(decode_int(buf, 7));
let len = decode_int(buf, 7)?;
if len > buf.remaining() {
trace!("decode_string underflow; len={}; remaining={}", len, buf.remaining());
trace!("decode_string underflow; len={}; remaining={}",
len,
buf.remaining());
return Err(DecoderError::StringUnderflow);
}
@@ -319,12 +317,12 @@ impl Default for Decoder {
impl Representation {
pub fn load(byte: u8) -> Result<Representation, DecoderError> {
const INDEXED: u8 = 0b10000000;
const LITERAL_WITH_INDEXING: u8 = 0b01000000;
const INDEXED: u8 = 0b10000000;
const LITERAL_WITH_INDEXING: u8 = 0b01000000;
const LITERAL_WITHOUT_INDEXING: u8 = 0b11110000;
const LITERAL_NEVER_INDEXED: u8 = 0b00010000;
const SIZE_UPDATE_MASK: u8 = 0b11100000;
const SIZE_UPDATE: u8 = 0b00100000;
const LITERAL_NEVER_INDEXED: u8 = 0b00010000;
const SIZE_UPDATE_MASK: u8 = 0b11100000;
const SIZE_UPDATE: u8 = 0b00100000;
// TODO: What did I even write here?
@@ -474,7 +472,8 @@ impl Table {
debug_assert!(size <= self.max_size);
while self.size + size > self.max_size {
let last = self.entries.pop_back()
let last = self.entries
.pop_back()
.expect("size of table != 0, but no headers left!");
self.size -= last.len();
@@ -564,194 +563,288 @@ pub fn get_static(idx: usize) -> Header {
12 => Header::Status(StatusCode::BAD_REQUEST),
13 => Header::Status(StatusCode::NOT_FOUND),
14 => Header::Status(StatusCode::INTERNAL_SERVER_ERROR),
15 => Header::Field {
name: header::ACCEPT_CHARSET,
value: HeaderValue::from_static(""),
},
16 => Header::Field {
name: header::ACCEPT_ENCODING,
value: HeaderValue::from_static("gzip, deflate"),
},
17 => Header::Field {
name: header::ACCEPT_LANGUAGE,
value: HeaderValue::from_static(""),
},
18 => Header::Field {
name: header::ACCEPT_RANGES,
value: HeaderValue::from_static(""),
},
19 => Header::Field {
name: header::ACCEPT,
value: HeaderValue::from_static(""),
},
20 => Header::Field {
name: header::ACCESS_CONTROL_ALLOW_ORIGIN,
value: HeaderValue::from_static(""),
},
21 => Header::Field {
name: header::AGE,
value: HeaderValue::from_static(""),
},
22 => Header::Field {
name: header::ALLOW,
value: HeaderValue::from_static(""),
},
23 => Header::Field {
name: header::AUTHORIZATION,
value: HeaderValue::from_static(""),
},
24 => Header::Field {
name: header::CACHE_CONTROL,
value: HeaderValue::from_static(""),
},
25 => Header::Field {
name: header::CONTENT_DISPOSITION,
value: HeaderValue::from_static(""),
},
26 => Header::Field {
name: header::CONTENT_ENCODING,
value: HeaderValue::from_static(""),
},
27 => Header::Field {
name: header::CONTENT_LANGUAGE,
value: HeaderValue::from_static(""),
},
28 => Header::Field {
name: header::CONTENT_LENGTH,
value: HeaderValue::from_static(""),
},
29 => Header::Field {
name: header::CONTENT_LOCATION,
value: HeaderValue::from_static(""),
},
30 => Header::Field {
name: header::CONTENT_RANGE,
value: HeaderValue::from_static(""),
},
31 => Header::Field {
name: header::CONTENT_TYPE,
value: HeaderValue::from_static(""),
},
32 => Header::Field {
name: header::COOKIE,
value: HeaderValue::from_static(""),
},
33 => Header::Field {
name: header::DATE,
value: HeaderValue::from_static(""),
},
34 => Header::Field {
name: header::ETAG,
value: HeaderValue::from_static(""),
},
35 => Header::Field {
name: header::EXPECT,
value: HeaderValue::from_static(""),
},
36 => Header::Field {
name: header::EXPIRES,
value: HeaderValue::from_static(""),
},
37 => Header::Field {
name: header::FROM,
value: HeaderValue::from_static(""),
},
38 => Header::Field {
name: header::HOST,
value: HeaderValue::from_static(""),
},
39 => Header::Field {
name: header::IF_MATCH,
value: HeaderValue::from_static(""),
},
40 => Header::Field {
name: header::IF_MODIFIED_SINCE,
value: HeaderValue::from_static(""),
},
41 => Header::Field {
name: header::IF_NONE_MATCH,
value: HeaderValue::from_static(""),
},
42 => Header::Field {
name: header::IF_RANGE,
value: HeaderValue::from_static(""),
},
43 => Header::Field {
name: header::IF_UNMODIFIED_SINCE,
value: HeaderValue::from_static(""),
},
44 => Header::Field {
name: header::LAST_MODIFIED,
value: HeaderValue::from_static(""),
},
45 => Header::Field {
name: header::LINK,
value: HeaderValue::from_static(""),
},
46 => Header::Field {
name: header::LOCATION,
value: HeaderValue::from_static(""),
},
47 => Header::Field {
name: header::MAX_FORWARDS,
value: HeaderValue::from_static(""),
},
48 => Header::Field {
name: header::PROXY_AUTHENTICATE,
value: HeaderValue::from_static(""),
},
49 => Header::Field {
name: header::PROXY_AUTHORIZATION,
value: HeaderValue::from_static(""),
},
50 => Header::Field {
name: header::RANGE,
value: HeaderValue::from_static(""),
},
51 => Header::Field {
name: header::REFERER,
value: HeaderValue::from_static(""),
},
52 => Header::Field {
name: header::REFRESH,
value: HeaderValue::from_static(""),
},
53 => Header::Field {
name: header::RETRY_AFTER,
value: HeaderValue::from_static(""),
},
54 => Header::Field {
name: header::SERVER,
value: HeaderValue::from_static(""),
},
55 => Header::Field {
name: header::SET_COOKIE,
value: HeaderValue::from_static(""),
},
56 => Header::Field {
name: header::STRICT_TRANSPORT_SECURITY,
value: HeaderValue::from_static(""),
},
57 => Header::Field {
name: header::TRANSFER_ENCODING,
value: HeaderValue::from_static(""),
},
58 => Header::Field {
name: header::USER_AGENT,
value: HeaderValue::from_static(""),
},
59 => Header::Field {
name: header::VARY,
value: HeaderValue::from_static(""),
},
60 => Header::Field {
name: header::VIA,
value: HeaderValue::from_static(""),
},
61 => Header::Field {
name: header::WWW_AUTHENTICATE,
value: HeaderValue::from_static(""),
},
15 => {
Header::Field {
name: header::ACCEPT_CHARSET,
value: HeaderValue::from_static(""),
}
}
16 => {
Header::Field {
name: header::ACCEPT_ENCODING,
value: HeaderValue::from_static("gzip, deflate"),
}
}
17 => {
Header::Field {
name: header::ACCEPT_LANGUAGE,
value: HeaderValue::from_static(""),
}
}
18 => {
Header::Field {
name: header::ACCEPT_RANGES,
value: HeaderValue::from_static(""),
}
}
19 => {
Header::Field {
name: header::ACCEPT,
value: HeaderValue::from_static(""),
}
}
20 => {
Header::Field {
name: header::ACCESS_CONTROL_ALLOW_ORIGIN,
value: HeaderValue::from_static(""),
}
}
21 => {
Header::Field {
name: header::AGE,
value: HeaderValue::from_static(""),
}
}
22 => {
Header::Field {
name: header::ALLOW,
value: HeaderValue::from_static(""),
}
}
23 => {
Header::Field {
name: header::AUTHORIZATION,
value: HeaderValue::from_static(""),
}
}
24 => {
Header::Field {
name: header::CACHE_CONTROL,
value: HeaderValue::from_static(""),
}
}
25 => {
Header::Field {
name: header::CONTENT_DISPOSITION,
value: HeaderValue::from_static(""),
}
}
26 => {
Header::Field {
name: header::CONTENT_ENCODING,
value: HeaderValue::from_static(""),
}
}
27 => {
Header::Field {
name: header::CONTENT_LANGUAGE,
value: HeaderValue::from_static(""),
}
}
28 => {
Header::Field {
name: header::CONTENT_LENGTH,
value: HeaderValue::from_static(""),
}
}
29 => {
Header::Field {
name: header::CONTENT_LOCATION,
value: HeaderValue::from_static(""),
}
}
30 => {
Header::Field {
name: header::CONTENT_RANGE,
value: HeaderValue::from_static(""),
}
}
31 => {
Header::Field {
name: header::CONTENT_TYPE,
value: HeaderValue::from_static(""),
}
}
32 => {
Header::Field {
name: header::COOKIE,
value: HeaderValue::from_static(""),
}
}
33 => {
Header::Field {
name: header::DATE,
value: HeaderValue::from_static(""),
}
}
34 => {
Header::Field {
name: header::ETAG,
value: HeaderValue::from_static(""),
}
}
35 => {
Header::Field {
name: header::EXPECT,
value: HeaderValue::from_static(""),
}
}
36 => {
Header::Field {
name: header::EXPIRES,
value: HeaderValue::from_static(""),
}
}
37 => {
Header::Field {
name: header::FROM,
value: HeaderValue::from_static(""),
}
}
38 => {
Header::Field {
name: header::HOST,
value: HeaderValue::from_static(""),
}
}
39 => {
Header::Field {
name: header::IF_MATCH,
value: HeaderValue::from_static(""),
}
}
40 => {
Header::Field {
name: header::IF_MODIFIED_SINCE,
value: HeaderValue::from_static(""),
}
}
41 => {
Header::Field {
name: header::IF_NONE_MATCH,
value: HeaderValue::from_static(""),
}
}
42 => {
Header::Field {
name: header::IF_RANGE,
value: HeaderValue::from_static(""),
}
}
43 => {
Header::Field {
name: header::IF_UNMODIFIED_SINCE,
value: HeaderValue::from_static(""),
}
}
44 => {
Header::Field {
name: header::LAST_MODIFIED,
value: HeaderValue::from_static(""),
}
}
45 => {
Header::Field {
name: header::LINK,
value: HeaderValue::from_static(""),
}
}
46 => {
Header::Field {
name: header::LOCATION,
value: HeaderValue::from_static(""),
}
}
47 => {
Header::Field {
name: header::MAX_FORWARDS,
value: HeaderValue::from_static(""),
}
}
48 => {
Header::Field {
name: header::PROXY_AUTHENTICATE,
value: HeaderValue::from_static(""),
}
}
49 => {
Header::Field {
name: header::PROXY_AUTHORIZATION,
value: HeaderValue::from_static(""),
}
}
50 => {
Header::Field {
name: header::RANGE,
value: HeaderValue::from_static(""),
}
}
51 => {
Header::Field {
name: header::REFERER,
value: HeaderValue::from_static(""),
}
}
52 => {
Header::Field {
name: header::REFRESH,
value: HeaderValue::from_static(""),
}
}
53 => {
Header::Field {
name: header::RETRY_AFTER,
value: HeaderValue::from_static(""),
}
}
54 => {
Header::Field {
name: header::SERVER,
value: HeaderValue::from_static(""),
}
}
55 => {
Header::Field {
name: header::SET_COOKIE,
value: HeaderValue::from_static(""),
}
}
56 => {
Header::Field {
name: header::STRICT_TRANSPORT_SECURITY,
value: HeaderValue::from_static(""),
}
}
57 => {
Header::Field {
name: header::TRANSFER_ENCODING,
value: HeaderValue::from_static(""),
}
}
58 => {
Header::Field {
name: header::USER_AGENT,
value: HeaderValue::from_static(""),
}
}
59 => {
Header::Field {
name: header::VARY,
value: HeaderValue::from_static(""),
}
}
60 => {
Header::Field {
name: header::VIA,
value: HeaderValue::from_static(""),
}
}
61 => {
Header::Field {
name: header::WWW_AUTHENTICATE,
value: HeaderValue::from_static(""),
}
}
_ => unreachable!(),
}
}

View File

@@ -1,8 +1,8 @@
use super::{huffman, Header};
use super::table::{Table, Index};
use super::table::{Index, Table};
use bytes::{BufMut, BytesMut};
use http::header::{HeaderName, HeaderValue};
use bytes::{BytesMut, BufMut};
#[derive(Debug)]
pub struct Encoder {
@@ -76,9 +76,14 @@ impl Encoder {
}
/// Encode a set of headers into the provide buffer
pub fn encode<I>(&mut self, resume: Option<EncodeState>, headers: &mut I, dst: &mut BytesMut)
-> Encode
where I: Iterator<Item=Header<Option<HeaderName>>>,
pub fn encode<I>(
&mut self,
resume: Option<EncodeState>,
headers: &mut I,
dst: &mut BytesMut,
) -> Encode
where
I: Iterator<Item = Header<Option<HeaderName>>>,
{
let len = dst.len();
@@ -94,15 +99,8 @@ impl Encoder {
let len = dst.len();
let res = match resume.value {
Some(ref value) => {
self.encode_header_without_name(
&resume.index,
value,
dst)
}
None => {
self.encode_header(&resume.index, dst)
}
Some(ref value) => self.encode_header_without_name(&resume.index, value, dst),
None => self.encode_header(&resume.index, dst),
};
if res.is_err() {
@@ -126,9 +124,9 @@ impl Encoder {
if res.is_err() {
dst.truncate(len);
return Encode::Partial(EncodeState {
index: index,
value: None,
});
index: index,
value: None,
});
}
last_index = Some(index);
@@ -138,17 +136,15 @@ impl Encoder {
// which case, we skip table lookup and just use the same index
// as the previous entry.
Err(value) => {
let res = self.encode_header_without_name(
last_index.as_ref().unwrap(),
&value,
dst);
let res =
self.encode_header_without_name(last_index.as_ref().unwrap(), &value, dst);
if res.is_err() {
dst.truncate(len);
return Encode::Partial(EncodeState {
index: last_index.unwrap(),
value: Some(value),
});
index: last_index.unwrap(),
value: Some(value),
});
}
}
};
@@ -161,13 +157,13 @@ impl Encoder {
match self.size_update.take() {
Some(SizeUpdate::One(val)) => {
self.table.resize(val);
try!(encode_size_update(val, dst));
encode_size_update(val, dst)?;
}
Some(SizeUpdate::Two(min, max)) => {
self.table.resize(min);
self.table.resize(max);
try!(encode_size_update(min, dst));
try!(encode_size_update(max, dst));
encode_size_update(min, dst)?;
encode_size_update(max, dst)?;
}
None => {}
}
@@ -175,21 +171,15 @@ impl Encoder {
Ok(())
}
fn encode_header(&mut self, index: &Index, dst: &mut BytesMut)
-> Result<(), EncoderError>
{
fn encode_header(&mut self, index: &Index, dst: &mut BytesMut) -> Result<(), EncoderError> {
match *index {
Index::Indexed(idx, _) => {
try!(encode_int(idx, 7, 0x80, dst));
encode_int(idx, 7, 0x80, dst)?;
}
Index::Name(idx, _) => {
let header = self.table.resolve(&index);
try!(encode_not_indexed(
idx,
header.value_slice(),
header.is_sensitive(),
dst));
encode_not_indexed(idx, header.value_slice(), header.is_sensitive(), dst)?;
}
Index::Inserted(_) => {
let header = self.table.resolve(&index);
@@ -202,57 +192,52 @@ impl Encoder {
dst.put_u8(0b01000000);
try!(encode_str(header.name().as_slice(), dst));
try!(encode_str(header.value_slice(), dst));
encode_str(header.name().as_slice(), dst)?;
encode_str(header.value_slice(), dst)?;
}
Index::InsertedValue(idx, _) => {
let header = self.table.resolve(&index);
assert!(!header.is_sensitive());
try!(encode_int(idx, 6, 0b01000000, dst));
try!(encode_str(header.value_slice(), dst));
encode_int(idx, 6, 0b01000000, dst)?;
encode_str(header.value_slice(), dst)?;
}
Index::NotIndexed(_) => {
let header = self.table.resolve(&index);
try!(encode_not_indexed2(
header.name().as_slice(),
header.value_slice(),
header.is_sensitive(),
dst));
encode_not_indexed2(header.name().as_slice(),
header.value_slice(),
header.is_sensitive(),
dst)?;
}
}
Ok(())
}
fn encode_header_without_name(&mut self, last: &Index,
value: &HeaderValue, dst: &mut BytesMut)
-> Result<(), EncoderError>
{
fn encode_header_without_name(
&mut self,
last: &Index,
value: &HeaderValue,
dst: &mut BytesMut,
) -> Result<(), EncoderError> {
match *last {
Index::Indexed(..) |
Index::Name(..) |
Index::Inserted(..) |
Index::InsertedValue(..) =>
{
Index::Name(..) |
Index::Inserted(..) |
Index::InsertedValue(..) => {
let idx = self.table.resolve_idx(last);
try!(encode_not_indexed(
idx,
value.as_ref(),
value.is_sensitive(),
dst));
encode_not_indexed(idx, value.as_ref(), value.is_sensitive(), dst)?;
}
Index::NotIndexed(_) => {
let last = self.table.resolve(last);
try!(encode_not_indexed2(
last.name().as_slice(),
value.as_ref(),
value.is_sensitive(),
dst));
encode_not_indexed2(last.name().as_slice(),
value.as_ref(),
value.is_sensitive(),
dst)?;
}
}
@@ -270,24 +255,28 @@ fn encode_size_update<B: BufMut>(val: usize, dst: &mut B) -> Result<(), EncoderE
encode_int(val, 5, 0b00100000, dst)
}
fn encode_not_indexed(name: usize, value: &[u8],
sensitive: bool, dst: &mut BytesMut)
-> Result<(), EncoderError>
{
fn encode_not_indexed(
name: usize,
value: &[u8],
sensitive: bool,
dst: &mut BytesMut,
) -> Result<(), EncoderError> {
if sensitive {
try!(encode_int(name, 4, 0b10000, dst));
encode_int(name, 4, 0b10000, dst)?;
} else {
try!(encode_int(name, 4, 0, dst));
encode_int(name, 4, 0, dst)?;
}
try!(encode_str(value, dst));
encode_str(value, dst)?;
Ok(())
}
fn encode_not_indexed2(name: &[u8], value: &[u8],
sensitive: bool, dst: &mut BytesMut)
-> Result<(), EncoderError>
{
fn encode_not_indexed2(
name: &[u8],
value: &[u8],
sensitive: bool,
dst: &mut BytesMut,
) -> Result<(), EncoderError> {
if !dst.has_remaining_mut() {
return Err(EncoderError::BufferOverflow);
}
@@ -298,8 +287,8 @@ fn encode_not_indexed2(name: &[u8], value: &[u8],
dst.put_u8(0);
}
try!(encode_str(name, dst));
try!(encode_str(value, dst));
encode_str(name, dst)?;
encode_str(value, dst)?;
Ok(())
}
@@ -317,7 +306,7 @@ fn encode_str(val: &[u8], dst: &mut BytesMut) -> Result<(), EncoderError> {
dst.put_u8(0);
// Encode with huffman
try!(huffman::encode(val, dst));
huffman::encode(val, dst)?;
let huff_len = dst.len() - (idx + 1);
@@ -330,7 +319,7 @@ fn encode_str(val: &[u8], dst: &mut BytesMut) -> Result<(), EncoderError> {
let head_len = {
let mut head_dst = Cursor::new(&mut buf);
try!(encode_int(huff_len, 7, 0x80, &mut head_dst));
encode_int(huff_len, 7, 0x80, &mut head_dst)?;
head_dst.position() as usize
};
@@ -343,8 +332,8 @@ fn encode_str(val: &[u8], dst: &mut BytesMut) -> Result<(), EncoderError> {
// Shift the header forward
for i in 0..huff_len {
let src_i = idx + 1 + (huff_len - (i+1));
let dst_i = idx + head_len + (huff_len - (i+1));
let src_i = idx + 1 + (huff_len - (i + 1));
let dst_i = idx + head_len + (huff_len - (i + 1));
dst[dst_i] = dst[src_i];
}
@@ -366,9 +355,8 @@ fn encode_int<B: BufMut>(
mut value: usize, // The integer to encode
prefix_bits: usize, // The number of bits in the prefix
first_byte: u8, // The base upon which to start encoding the int
dst: &mut B) // The destination buffer
-> Result<(), EncoderError>
{
dst: &mut B,
) -> Result<(), EncoderError> {
let mut rem = dst.remaining_mut();
if rem == 0 {
@@ -444,7 +432,7 @@ mod test {
let res = encode(&mut encoder, vec![method("PATCH")]);
assert_eq!(res[0], 0b01000000 | 2); // Incremental indexing w/ name pulled from table
assert_eq!(res[1], 0x80 | 5); // header value w/ huffman coding
assert_eq!(res[1], 0x80 | 5); // header value w/ huffman coding
assert_eq!("PATCH", huff_decode(&res[2..7]));
assert_eq!(encoder.table.len(), 1);
@@ -522,7 +510,7 @@ mod test {
for i in 1..65 {
let key = format!("x-hello-world-{:02}", i);
let res = encode(&mut encoder, vec![header(&key, &key)]);
assert_eq!(0x80 | (61 + (65-i)), res[0]);
assert_eq!(0x80 | (61 + (65 - i)), res[0]);
}
}
@@ -547,7 +535,10 @@ mod test {
let mut value = HeaderValue::from_bytes(b"12345").unwrap();
value.set_sensitive(true);
let header = Header::Field { name: Some(name), value: value };
let header = Header::Field {
name: Some(name),
value: value,
};
// Now, try to encode the sensitive header
@@ -564,7 +555,10 @@ mod test {
let mut value = HeaderValue::from_bytes(b"12345").unwrap();
value.set_sensitive(true);
let header = Header::Field { name: Some(name), value: value };
let header = Header::Field {
name: Some(name),
value: value,
};
let mut encoder = Encoder::default();
let res = encode(&mut encoder, vec![header]);
@@ -576,13 +570,17 @@ mod test {
// Using the name component of a previously indexed header (without
// sensitive flag set)
let _ = encode(&mut encoder, vec![self::header("my-password", "not-so-secret")]);
let _ = encode(&mut encoder,
vec![self::header("my-password", "not-so-secret")]);
let name = "my-password".parse().unwrap();
let mut value = HeaderValue::from_bytes(b"12345").unwrap();
value.set_sensitive(true);
let header = Header::Field { name: Some(name), value: value };
let header = Header::Field {
name: Some(name),
value: value,
};
let res = encode(&mut encoder, vec![header]);
assert_eq!(&[0b11111, 47], &res[..2]);
@@ -743,16 +741,19 @@ mod test {
fn test_nameless_header() {
let mut encoder = Encoder::default();
let res = encode(&mut encoder, vec![
Header::Field {
name: Some("hello".parse().unwrap()),
value: HeaderValue::from_bytes(b"world").unwrap(),
},
Header::Field {
name: None,
value: HeaderValue::from_bytes(b"zomg").unwrap(),
},
]);
let res = encode(
&mut encoder,
vec![
Header::Field {
name: Some("hello".parse().unwrap()),
value: HeaderValue::from_bytes(b"world").unwrap(),
},
Header::Field {
name: None,
value: HeaderValue::from_bytes(b"zomg").unwrap(),
},
],
);
assert_eq!(&[0x40, 0x80 | 4], &res[0..2]);
assert_eq!("hello", huff_decode(&res[2..6]));
@@ -824,7 +825,10 @@ mod test {
let name = HeaderName::from_bytes(name.as_bytes()).unwrap();
let value = HeaderValue::from_bytes(val.as_bytes()).unwrap();
Header::Field { name: Some(name), value: value }
Header::Field {
name: Some(name),
value: value,
}
}
fn huff_decode(src: &[u8]) -> BytesMut {

View File

@@ -1,17 +1,14 @@
use super::DecoderError;
use bytes::Bytes;
use http::{Method, StatusCode};
use http::header::{HeaderName, HeaderValue};
use bytes::Bytes;
use string::{String, TryFrom};
/// HTTP/2.0 Header
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum Header<T = HeaderName> {
Field {
name: T,
value: HeaderValue,
},
Field { name: T, value: HeaderValue },
// TODO: Change these types to `http::uri` types.
Authority(String<Bytes>),
Method(Method),
@@ -41,14 +38,25 @@ impl Header<Option<HeaderName>> {
use self::Header::*;
Ok(match self {
Field { name: Some(n), value } => Field { name: n, value: value },
Field { name: None, value } => return Err(value),
Authority(v) => Authority(v),
Method(v) => Method(v),
Scheme(v) => Scheme(v),
Path(v) => Path(v),
Status(v) => Status(v),
})
Field {
name: Some(n),
value,
} => {
Field {
name: n,
value: value,
}
}
Field {
name: None,
value,
} => return Err(value),
Authority(v) => Authority(v),
Method(v) => Method(v),
Scheme(v) => Scheme(v),
Path(v) => Path(v),
Status(v) => Status(v),
})
}
}
@@ -57,65 +65,59 @@ impl Header {
if name[0] == b':' {
match &name[1..] {
b"authority" => {
let value = try!(String::try_from(value));
let value = String::try_from(value)?;
Ok(Header::Authority(value))
}
b"method" => {
let method = try!(Method::from_bytes(&value));
let method = Method::from_bytes(&value)?;
Ok(Header::Method(method))
}
b"scheme" => {
let value = try!(String::try_from(value));
let value = String::try_from(value)?;
Ok(Header::Scheme(value))
}
b"path" => {
let value = try!(String::try_from(value));
let value = String::try_from(value)?;
Ok(Header::Path(value))
}
b"status" => {
let status = try!(StatusCode::from_bytes(&value));
let status = StatusCode::from_bytes(&value)?;
Ok(Header::Status(status))
}
_ => {
Err(DecoderError::InvalidPseudoheader)
}
_ => Err(DecoderError::InvalidPseudoheader),
}
} else {
// HTTP/2 requires lower case header names
let name = try!(HeaderName::from_lowercase(&name));
let value = try!(HeaderValue::from_bytes(&value));
let name = HeaderName::from_lowercase(&name)?;
let value = HeaderValue::from_bytes(&value)?;
Ok(Header::Field { name: name, value: value })
Ok(Header::Field {
name: name,
value: value,
})
}
}
pub fn len(&self) -> usize {
match *self {
Header::Field { ref name, ref value } => {
len(name, value)
}
Header::Authority(ref v) => {
32 + 10 + v.len()
}
Header::Method(ref v) => {
32 + 7 + v.as_ref().len()
}
Header::Scheme(ref v) => {
32 + 7 + v.len()
}
Header::Path(ref v) => {
32 + 5 + v.len()
}
Header::Status(_) => {
32 + 7 + 3
}
Header::Field {
ref name,
ref value,
} => len(name, value),
Header::Authority(ref v) => 32 + 10 + v.len(),
Header::Method(ref v) => 32 + 7 + v.as_ref().len(),
Header::Scheme(ref v) => 32 + 7 + v.len(),
Header::Path(ref v) => 32 + 5 + v.len(),
Header::Status(_) => 32 + 7 + 3,
}
}
/// Returns the header name
pub fn name(&self) -> Name {
match *self {
Header::Field { ref name, .. } => Name::Field(name),
Header::Field {
ref name, ..
} => Name::Field(name),
Header::Authority(..) => Name::Authority,
Header::Method(..) => Name::Method,
Header::Scheme(..) => Name::Scheme,
@@ -126,7 +128,9 @@ impl Header {
pub fn value_slice(&self) -> &[u8] {
match *self {
Header::Field { ref value, .. } => value.as_ref(),
Header::Field {
ref value, ..
} => value.as_ref(),
Header::Authority(ref v) => v.as_ref(),
Header::Method(ref v) => v.as_ref().as_ref(),
Header::Scheme(ref v) => v.as_ref(),
@@ -137,10 +141,14 @@ impl Header {
pub fn value_eq(&self, other: &Header) -> bool {
match *self {
Header::Field { ref value, .. } => {
Header::Field {
ref value, ..
} => {
let a = value;
match *other {
Header::Field { ref value, .. } => a == value,
Header::Field {
ref value, ..
} => a == value,
_ => false,
}
}
@@ -179,7 +187,9 @@ impl Header {
pub fn is_sensitive(&self) -> bool {
match *self {
Header::Field { ref value, .. } => value.is_sensitive(),
Header::Field {
ref value, ..
} => value.is_sensitive(),
// TODO: Technically these other header values can be sensitive too.
_ => false,
}
@@ -189,17 +199,19 @@ impl Header {
use http::header;
match *self {
Header::Field { ref name, .. } => {
Header::Field {
ref name, ..
} => {
match *name {
header::AGE |
header::AUTHORIZATION |
header::CONTENT_LENGTH |
header::ETAG |
header::IF_MODIFIED_SINCE |
header::IF_NONE_MATCH |
header::LOCATION |
header::COOKIE |
header::SET_COOKIE => true,
header::AUTHORIZATION |
header::CONTENT_LENGTH |
header::ETAG |
header::IF_MODIFIED_SINCE |
header::IF_NONE_MATCH |
header::LOCATION |
header::COOKIE |
header::SET_COOKIE => true,
_ => false,
}
}
@@ -213,7 +225,15 @@ impl Header {
impl From<Header> for Header<Option<HeaderName>> {
fn from(src: Header) -> Self {
match src {
Header::Field { name, value } => Header::Field { name: Some(name), value },
Header::Field {
name,
value,
} => {
Header::Field {
name: Some(name),
value,
}
}
Header::Authority(v) => Header::Authority(v),
Header::Method(v) => Header::Method(v),
Header::Scheme(v) => Header::Scheme(v),
@@ -228,22 +248,14 @@ impl<'a> Name<'a> {
match self {
Name::Field(name) => {
Ok(Header::Field {
name: name.clone(),
value: try!(HeaderValue::from_bytes(&*value)),
})
}
Name::Authority => {
Ok(Header::Authority(try!(String::try_from(value))))
}
Name::Method => {
Ok(Header::Method(try!(Method::from_bytes(&*value))))
}
Name::Scheme => {
Ok(Header::Scheme(try!(String::try_from(value))))
}
Name::Path => {
Ok(Header::Path(try!(String::try_from(value))))
name: name.clone(),
value: HeaderValue::from_bytes(&*value)?,
})
}
Name::Authority => Ok(Header::Authority(String::try_from(value)?)),
Name::Method => Ok(Header::Method(Method::from_bytes(&*value)?)),
Name::Scheme => Ok(Header::Scheme(String::try_from(value)?)),
Name::Path => Ok(Header::Path(String::try_from(value)?)),
Name::Status => {
match StatusCode::from_bytes(&value) {
Ok(status) => Ok(Header::Status(status)),

View File

@@ -1,9 +1,9 @@
mod table;
use self::table::{ENCODE_TABLE, DECODE_TABLE};
use self::table::{DECODE_TABLE, ENCODE_TABLE};
use hpack::{DecoderError, EncoderError};
use bytes::{BytesMut, BufMut};
use bytes::{BufMut, BytesMut};
// Constructed in the generated `table.rs` file
struct Decoder {
@@ -24,11 +24,11 @@ pub fn decode(src: &[u8], buf: &mut BytesMut) -> Result<BytesMut, DecoderError>
buf.reserve(src.len() << 1);
for b in src {
if let Some(b) = try!(decoder.decode4(b >> 4)) {
if let Some(b) = decoder.decode4(b >> 4)? {
buf.put_u8(b);
}
if let Some(b) = try!(decoder.decode4(b & 0xf)) {
if let Some(b) = decoder.decode4(b & 0xf)? {
buf.put_u8(b);
}
}
@@ -161,10 +161,27 @@ mod test {
#[test]
fn encode_decode_str() {
const DATA: &'static [&'static str] = &[
"hello world", ":method", ":scheme", ":authority", "yahoo.co.jp", "GET", "http", ":path", "/images/top/sp2/cmn/logo-ns-130528.png",
"example.com", "hpack-test", "xxxxxxx1", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:16.0) Gecko/20100101 Firefox/16.0",
"accept", "Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "cookie", "B=76j09a189a6h4&b=3&s=0b",
"TE", "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi non bibendum libero. Etiam ultrices lorem ut",
"hello world",
":method",
":scheme",
":authority",
"yahoo.co.jp",
"GET",
"http",
":path",
"/images/top/sp2/cmn/logo-ns-130528.png",
"example.com",
"hpack-test",
"xxxxxxx1",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:16.0) Gecko/20100101 Firefox/16.0",
"accept",
"Accept",
"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"cookie",
"B=76j09a189a6h4&b=3&s=0b",
"TE",
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi non bibendum libero. \
Etiam ultrices lorem ut.",
];
for s in DATA {
@@ -180,9 +197,8 @@ mod test {
#[test]
fn encode_decode_u8() {
const DATA: &'static [&'static [u8]] = &[
b"\0", b"\0\0\0", b"\0\x01\x02\x03\x04\x05", b"\xFF\xF8",
];
const DATA: &'static [&'static [u8]] =
&[b"\0", b"\0\0\0", b"\0\x01\x02\x03\x04\x05", b"\xFF\xF8"];
for s in DATA {
let mut dst = Vec::with_capacity(s.len());

View File

@@ -7,6 +7,6 @@ mod table;
#[cfg(test)]
mod test;
pub use self::encoder::{Encoder, Encode, EncoderError, EncodeState};
pub use self::header::Header;
pub use self::decoder::{Decoder, DecoderError};
pub use self::encoder::{Encode, EncodeState, Encoder, EncoderError};
pub use self::header::Header;

View File

@@ -83,9 +83,7 @@ impl Table {
max_size: max_size,
}
} else {
let capacity = cmp::max(
to_raw_capacity(capacity).next_power_of_two(),
8);
let capacity = cmp::max(to_raw_capacity(capacity).next_power_of_two(), 8);
Table {
mask: capacity.wrapping_sub(1),
@@ -203,12 +201,7 @@ impl Table {
});
}
fn index_occupied(&mut self,
header: Header,
hash: HashValue,
mut index: usize)
-> Index
{
fn index_occupied(&mut self, header: Header, hash: HashValue, mut index: usize) -> Index {
debug_assert!(self.assert_valid_state("top"));
// There already is a match for the given header name. Check if a value
@@ -256,14 +249,14 @@ impl Table {
}
}
fn index_vacant(&mut self,
header: Header,
hash: HashValue,
mut dist: usize,
mut probe: usize,
statik: Option<(usize, bool)>)
-> Index
{
fn index_vacant(
&mut self,
header: Header,
hash: HashValue,
mut dist: usize,
mut probe: usize,
statik: Option<(usize, bool)>,
) -> Index {
if header.is_sensitive() {
return Index::new(statik, header);
}
@@ -299,10 +292,11 @@ impl Table {
let pos_idx = 0usize.wrapping_sub(self.inserted);
let prev = mem::replace(&mut self.indices[probe], Some(Pos {
index: pos_idx,
hash: hash,
}));
let prev = mem::replace(&mut self.indices[probe],
Some(Pos {
index: pos_idx,
hash: hash,
}));
if let Some(mut prev) = prev {
// Shift forward
@@ -331,10 +325,10 @@ impl Table {
self.inserted = self.inserted.wrapping_add(1);
self.slots.push_front(Slot {
hash: hash,
header: header,
next: None,
});
hash: hash,
header: header,
next: None,
});
}
pub fn resize(&mut self, size: usize) {
@@ -383,11 +377,12 @@ impl Table {
// Update the size
self.size -= slot.header.len();
debug_assert_eq!(
self.indices.iter().filter_map(|p| *p)
.filter(|p| p.index == pos_idx)
.count(),
1);
debug_assert_eq!(self.indices
.iter()
.filter_map(|p| *p)
.filter(|p| p.index == pos_idx)
.count(),
1);
// Find the associated position
probe_loop!(probe < self.indices.len(), {
@@ -500,12 +495,12 @@ impl Table {
}
debug_assert!({
let them = self.indices[probe].unwrap();
let their_distance = probe_distance(self.mask, them.hash, probe);
let our_distance = probe_distance(self.mask, pos.hash, probe);
let them = self.indices[probe].unwrap();
let their_distance = probe_distance(self.mask, them.hash, probe);
let our_distance = probe_distance(self.mask, pos.hash, probe);
their_distance >= our_distance
});
their_distance >= our_distance
});
});
}
}
@@ -584,8 +579,10 @@ impl Table {
}
assert!(dist <= their_dist,
"could not find entry; actual={}; desired={}; probe={}, dist={}; their_dist={}; index={}; msg={}",
actual, desired, probe, dist, their_dist, index.wrapping_sub(self.inserted), msg);
"could not find entry; actual={}; desired={};" +
"probe={}, dist={}; their_dist={}; index={}; msg={}",
actual, desired, probe, dist, their_dist,
index.wrapping_sub(self.inserted), msg);
dist += 1;
});
@@ -661,7 +658,10 @@ fn hash_header(header: &Header) -> HashValue {
/// boolean representing if the value matched as well.
fn index_static(header: &Header) -> Option<(usize, bool)> {
match *header {
Header::Field { ref name, ref value } => {
Header::Field {
ref name,
ref value,
} => {
match *name {
header::ACCEPT_CHARSET => Some((15, false)),
header::ACCEPT_ENCODING => {

View File

@@ -2,15 +2,15 @@ extern crate bytes;
extern crate hex;
extern crate serde_json;
use hpack::{Header, Decoder, Encoder};
use hpack::{Decoder, Encoder, Header};
use self::bytes::BytesMut;
use self::hex::FromHex;
use self::serde_json::Value;
use std::fs::File;
use std::io::prelude::*;
use std::io::Cursor;
use std::io::prelude::*;
use std::path::Path;
use std::str;
@@ -27,7 +27,10 @@ fn test_story(story: Value) {
let story = story.as_object().unwrap();
if let Some(cases) = story.get("cases") {
let mut cases: Vec<_> = cases.as_array().unwrap().iter()
let mut cases: Vec<_> = cases
.as_array()
.unwrap()
.iter()
.map(|case| {
let case = case.as_object().unwrap();
@@ -37,8 +40,11 @@ fn test_story(story: Value) {
let wire = case.get("wire").unwrap().as_str().unwrap();
let wire: Vec<u8> = FromHex::from_hex(wire.as_bytes()).unwrap();
let expect: Vec<_> = case.get("headers").unwrap()
.as_array().unwrap().iter()
let expect: Vec<_> = case.get("headers")
.unwrap()
.as_array()
.unwrap()
.iter()
.map(|h| {
let h = h.as_object().unwrap();
let (name, val) = h.iter().next().unwrap();
@@ -67,11 +73,13 @@ fn test_story(story: Value) {
decoder.queue_size_update(size);
}
decoder.decode(&mut Cursor::new(case.wire.clone().into()), |e| {
let (name, value) = expect.remove(0);
assert_eq!(name, key_str(&e));
assert_eq!(value, value_str(&e));
}).unwrap();
decoder
.decode(&mut Cursor::new(case.wire.clone().into()), |e| {
let (name, value) = expect.remove(0);
assert_eq!(name, key_str(&e));
assert_eq!(value, value_str(&e));
})
.unwrap();
assert_eq!(0, expect.len());
}
@@ -88,15 +96,22 @@ fn test_story(story: Value) {
decoder.queue_size_update(size);
}
let mut input: Vec<_> = case.expect.iter().map(|&(ref name, ref value)| {
Header::new(name.clone().into(), value.clone().into()).unwrap().into()
}).collect();
let mut input: Vec<_> = case.expect
.iter()
.map(|&(ref name, ref value)| {
Header::new(name.clone().into(), value.clone().into())
.unwrap()
.into()
})
.collect();
encoder.encode(None, &mut input.clone().into_iter(), &mut buf);
decoder.decode(&mut Cursor::new(buf.into()), |e| {
assert_eq!(e, input.remove(0).reify().unwrap());
}).unwrap();
decoder
.decode(&mut Cursor::new(buf.into()), |e| {
assert_eq!(e, input.remove(0).reify().unwrap());
})
.unwrap();
assert_eq!(0, input.len());
}
@@ -112,7 +127,9 @@ struct Case {
fn key_str(e: &Header) -> &str {
match *e {
Header::Field { ref name, .. } => name.as_str(),
Header::Field {
ref name, ..
} => name.as_str(),
Header::Authority(..) => ":authority",
Header::Method(..) => ":method",
Header::Scheme(..) => ":scheme",
@@ -123,7 +140,9 @@ fn key_str(e: &Header) -> &str {
fn value_str(e: &Header) -> &str {
match *e {
Header::Field { ref value, .. } => value.to_str().unwrap(),
Header::Field {
ref value, ..
} => value.to_str().unwrap(),
Header::Authority(ref v) => &**v,
Header::Method(ref m) => m.as_str(),
Header::Scheme(ref v) => &**v,

View File

@@ -2,13 +2,13 @@ extern crate bytes;
extern crate quickcheck;
extern crate rand;
use hpack::{Header, Decoder, Encoder, Encode};
use hpack::{Decoder, Encode, Encoder, Header};
use http::header::{HeaderName, HeaderValue};
use self::bytes::{BytesMut, Bytes};
use self::quickcheck::{QuickCheck, Arbitrary, Gen, TestResult};
use self::rand::{StdRng, Rng, SeedableRng};
use self::bytes::{Bytes, BytesMut};
use self::quickcheck::{Arbitrary, Gen, QuickCheck, TestResult};
use self::rand::{Rng, SeedableRng, StdRng};
use std::io::Cursor;
@@ -130,8 +130,7 @@ impl FuzzHpack {
let mut index = None;
let mut input = frame.headers.into_iter();
let mut buf = BytesMut::with_capacity(
chunks.pop().unwrap_or(MAX_CHUNK));
let mut buf = BytesMut::with_capacity(chunks.pop().unwrap_or(MAX_CHUNK));
if let Some(max) = frame.resizes.iter().max() {
decoder.queue_size_update(*max);
@@ -149,20 +148,23 @@ impl FuzzHpack {
index = Some(i);
// Decode the chunk!
decoder.decode(&mut Cursor::new(buf.into()), |e| {
assert_eq!(e, expect.remove(0).reify().unwrap());
}).unwrap();
decoder
.decode(&mut Cursor::new(buf.into()), |e| {
assert_eq!(e, expect.remove(0).reify().unwrap());
})
.unwrap();
buf = BytesMut::with_capacity(
chunks.pop().unwrap_or(MAX_CHUNK));
buf = BytesMut::with_capacity(chunks.pop().unwrap_or(MAX_CHUNK));
}
}
}
// Decode the chunk!
decoder.decode(&mut Cursor::new(buf.into()), |e| {
assert_eq!(e, expect.remove(0).reify().unwrap());
}).unwrap();
decoder
.decode(&mut Cursor::new(buf.into()), |e| {
assert_eq!(e, expect.remove(0).reify().unwrap());
})
.unwrap();
}
assert_eq!(0, expect.len());
@@ -193,9 +195,9 @@ fn gen_header(g: &mut StdRng) -> Header<Option<HeaderName>> {
4 => Method::DELETE,
5 => {
let n: usize = g.gen_range(3, 7);
let bytes: Vec<u8> = (0..n).map(|_| {
g.choose(b"ABCDEFGHIJKLMNOPQRSTUVWXYZ").unwrap().clone()
}).collect();
let bytes: Vec<u8> = (0..n)
.map(|_| g.choose(b"ABCDEFGHIJKLMNOPQRSTUVWXYZ").unwrap().clone())
.collect();
Method::from_bytes(&bytes).unwrap()
}
@@ -237,7 +239,10 @@ fn gen_header(g: &mut StdRng) -> Header<Option<HeaderName>> {
value.set_sensitive(true);
}
Header::Field { name: Some(name), value: value }
Header::Field {
name: Some(name),
value: value,
}
}
}
@@ -320,7 +325,8 @@ fn gen_header_name(g: &mut StdRng) -> HeaderName {
header::X_DNS_PREFETCH_CONTROL,
header::X_FRAME_OPTIONS,
header::X_XSS_PROTECTION,
]).unwrap().clone()
]).unwrap()
.clone()
} else {
let value = gen_string(g, 1, 25);
HeaderName::from_bytes(value.as_bytes()).unwrap()
@@ -333,10 +339,14 @@ fn gen_header_value(g: &mut StdRng) -> HeaderValue {
}
fn gen_string(g: &mut StdRng, min: usize, max: usize) -> String {
let bytes: Vec<_> = (min..max).map(|_| {
// Chars to pick from
g.choose(b"ABCDEFGHIJKLMNOPQRSTUVabcdefghilpqrstuvwxyz----").unwrap().clone()
}).collect();
let bytes: Vec<_> = (min..max)
.map(|_| {
// Chars to pick from
g.choose(b"ABCDEFGHIJKLMNOPQRSTUVabcdefghilpqrstuvwxyz----")
.unwrap()
.clone()
})
.collect();
String::from_utf8(bytes).unwrap()
}