From 15aa6b8a40bcad0c1c551944516f4bb43e0db196 Mon Sep 17 00:00:00 2001 From: Tiga Ultraman Date: Mon, 5 Feb 2024 15:32:23 +0800 Subject: [PATCH] repair request encoder UT error Signed-off-by: Tiga Ultraman --- ylong_http/src/body/mime/common/headers.rs | 2 +- ylong_http/src/h1/request/encoder.rs | 4 + ylong_http/src/h1/response/decoder.rs | 78 +--------------- ylong_http/src/h2/decoder.rs | 2 +- ylong_http/src/h2/hpack/decoder.rs | 2 +- ylong_http/src/h2/hpack/encoder.rs | 2 +- .../src/h2/hpack/representation/decoder.rs | 2 +- ylong_http/src/h3/qpack/decoder.rs | 2 +- ylong_http/src/h3/qpack/encoder.rs | 2 +- ylong_http/src/huffman/mod.rs | 2 +- ylong_http/src/lib.rs | 3 +- ylong_http/src/util/header_bytes.rs | 91 +++++++++++++++++++ ylong_http/src/util/mod.rs | 18 ++++ ylong_http/src/{ => util}/test_util.rs | 2 + .../src/async_impl/conn/http1.rs | 8 +- ylong_http_client/src/lib.rs | 1 + ylong_http_client/src/util/proxy.rs | 5 +- 17 files changed, 131 insertions(+), 95 deletions(-) create mode 100644 ylong_http/src/util/header_bytes.rs create mode 100644 ylong_http/src/util/mod.rs rename ylong_http/src/{ => util}/test_util.rs (96%) diff --git a/ylong_http/src/body/mime/common/headers.rs b/ylong_http/src/body/mime/common/headers.rs index db37a02..e5cfdde 100644 --- a/ylong_http/src/body/mime/common/headers.rs +++ b/ylong_http/src/body/mime/common/headers.rs @@ -20,8 +20,8 @@ use crate::body::mime::common::{ use crate::body::mime::{CR, LF}; use crate::body::TokenStatus; use crate::error::{ErrorKind, HttpError}; -use crate::h1::response::decoder::{HEADER_NAME_BYTES, HEADER_VALUE_BYTES}; use crate::headers::{HeaderName, HeaderValue, Headers}; +use crate::util::header_bytes::{HEADER_NAME_BYTES, HEADER_VALUE_BYTES}; #[derive(Debug, PartialEq)] pub(crate) enum HeaderStatus { diff --git a/ylong_http/src/h1/request/encoder.rs b/ylong_http/src/h1/request/encoder.rs index 38f2af9..9efcf15 100644 --- a/ylong_http/src/h1/request/encoder.rs +++ b/ylong_http/src/h1/request/encoder.rs @@ -33,6 +33,7 @@ //! // Gets `RequestPart`. //! let (part, _) = request.into_parts(); //! let mut encoder = RequestEncoder::new(part); +//! encoder.absolute_uri(true); //! //! // We use `message` to store all the body data. //! let mut message = Vec::new(); @@ -90,6 +91,7 @@ use crate::version::Version; /// // Gets `RequestPart`. /// let (part, _) = request.into_parts(); /// let mut encoder = RequestEncoder::new(part); +/// encoder.absolute_uri(true); /// /// // We use `message` to store all the body data. /// let mut message = Vec::new(); @@ -230,6 +232,7 @@ impl RequestEncoder { /// /// let (part, _) = request.into_parts(); /// let mut encoder = RequestEncoder::new(part); + /// encoder.absolute_uri(true); /// /// let mut buf = [0_u8; 10]; /// let mut message = Vec::new(); @@ -704,6 +707,7 @@ mod ut_request_encoder { let (part, _) = request.into_parts(); let mut encoder = RequestEncoder::new(part); + encoder.absolute_uri(true); let mut buf = [0u8; 5]; let mut res = Vec::new(); loop { diff --git a/ylong_http/src/h1/response/decoder.rs b/ylong_http/src/h1/response/decoder.rs index 9ed61f0..881d5f5 100644 --- a/ylong_http/src/h1/response/decoder.rs +++ b/ylong_http/src/h1/response/decoder.rs @@ -18,6 +18,7 @@ use crate::h1::H1Error; use crate::headers::Headers; use crate::response::status::StatusCode; use crate::response::ResponsePart; +use crate::util::header_bytes::{HEADER_NAME_BYTES, HEADER_VALUE_BYTES}; use crate::version::Version; /// `HTTP/1` response decoder, which support decoding multi-segment byte @@ -636,83 +637,6 @@ fn is_legal_reason_byte(byte: u8) -> bool { byte == 0x09 || byte == 0x20 || (0x21..=0x7E).contains(&byte) || (0x80..=0xFF).contains(&byte) } -// token = 1*tchar -// tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" -// / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~" -// / DIGIT / ALPHA -// ; any VCHAR, except delimiters -// delimitersd = DQUOTE and "(),/:;<=>?@[\]{}" -#[rustfmt::skip] -pub(crate) static HEADER_NAME_BYTES: [bool; 256] = { - const __: bool = false; - const TT: bool = true; - [ -// \0 HT LF CR - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, -// \w ! " # $ % & ' ( ) * + , - . / - __, TT, __, TT, TT, TT, TT, TT, __, __, TT, TT, __, TT, TT, __, -// 0 1 2 3 4 5 6 7 8 9 : ; < = > ? - TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, __, __, __, __, __, __, -// @ A B C D E F G H I J K L M N O - __, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, -// P Q R S T U V W X Y Z [ \ ] ^ _ - TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, __, __, __, TT, TT, -// ` a b c d e f g h i j k l m n o - TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, -// p q r s t u v w x y z { | } ~ del - TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, __, TT, __, TT, __, -// Expand ascii - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, - ] -}; - -// field-value = *( field-content / obs-fold ) -// field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ] -// field-vchar = VCHAR / obs-text -// -// obs-fold = CRLF 1*( SP / HTAB ) -// ; obsolete line folding -// ; see Section 3.2.4 -#[rustfmt::skip] -pub(crate) static HEADER_VALUE_BYTES: [bool; 256] = { - const __: bool = false; - const TT: bool = true; - [ -// \0 HT LF CR - __, __, __, __, __, __, __, __, __, TT, __, __, __, __, __, __, - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, -// \w ! " # $ % & ' ( ) * + , - . / - TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, -// 0 1 2 3 4 5 6 7 8 9 : ; < = > ? - TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, -// @ A B C D E F G H I J K L M N O - TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, -// P Q R S T U V W X Y Z [ \ ] ^ _ - TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, -// ` a b c d e f g h i j k l m n o - TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, -// p q r s t u v w x y z { | } ~ del - TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, __, -// Expand ascii - TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, - TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, - TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, - TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, - TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, - TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, - TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, - TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, - ] -}; - // TODO: Add more test cases. #[cfg(test)] mod ut_decoder { diff --git a/ylong_http/src/h2/decoder.rs b/ylong_http/src/h2/decoder.rs index fdde469..64f1643 100644 --- a/ylong_http/src/h2/decoder.rs +++ b/ylong_http/src/h2/decoder.rs @@ -883,7 +883,7 @@ mod ut_frame_decoder { use crate::h2::decoder::{get_setting, FrameDecoder, FrameHeader, FrameKind}; use crate::h2::frame::{Payload, Ping, Setting}; use crate::h2::{ErrorCode, H2Error, PseudoHeaders}; - use crate::test_util::decode; + use crate::util::test_util::decode; macro_rules! check_complete_frame { ( diff --git a/ylong_http/src/h2/hpack/decoder.rs b/ylong_http/src/h2/hpack/decoder.rs index 8022c9b..15d7f6e 100644 --- a/ylong_http/src/h2/hpack/decoder.rs +++ b/ylong_http/src/h2/hpack/decoder.rs @@ -208,7 +208,7 @@ fn header_line_length(key_size: usize, value_size: usize) -> usize { mod ut_hpack_decoder { use crate::h2::hpack::table::Header; use crate::h2::hpack::HpackDecoder; - use crate::test_util::decode; + use crate::util::test_util::decode; const MAX_HEADER_LIST_SIZE: usize = 16 << 20; diff --git a/ylong_http/src/h2/hpack/encoder.rs b/ylong_http/src/h2/hpack/encoder.rs index f1eccd9..3b2a71d 100644 --- a/ylong_http/src/h2/hpack/encoder.rs +++ b/ylong_http/src/h2/hpack/encoder.rs @@ -61,7 +61,7 @@ mod ut_hpack_encoder { use crate::h2::hpack::table::Header; use crate::h2::hpack::HpackEncoder; use crate::h2::Parts; - use crate::test_util::decode; + use crate::util::test_util::decode; #[test] fn ut_hpack_encoder() { diff --git a/ylong_http/src/h2/hpack/representation/decoder.rs b/ylong_http/src/h2/hpack/representation/decoder.rs index 1ac595f..952b18c 100644 --- a/ylong_http/src/h2/hpack/representation/decoder.rs +++ b/ylong_http/src/h2/hpack/representation/decoder.rs @@ -568,7 +568,7 @@ impl From for DecResult { #[cfg(test)] mod ut_repr_decoder { use super::*; - use crate::test_util::decode; + use crate::util::test_util::decode; /// UT test cases for `ReprDecoder`. /// diff --git a/ylong_http/src/h3/qpack/decoder.rs b/ylong_http/src/h3/qpack/decoder.rs index bf33bb4..c2ec906 100644 --- a/ylong_http/src/h3/qpack/decoder.rs +++ b/ylong_http/src/h3/qpack/decoder.rs @@ -589,7 +589,7 @@ mod ut_qpack_decoder { use crate::h3::qpack::format::decoder::ReprDecodeState; use crate::h3::qpack::table::{DynamicTable, Field}; use crate::h3::qpack::QpackDecoder; - use crate::test_util::decode; + use crate::util::test_util::decode; const MAX_HEADER_LIST_SIZE: usize = 16 << 20; diff --git a/ylong_http/src/h3/qpack/encoder.rs b/ylong_http/src/h3/qpack/encoder.rs index 5f01bc3..f1e2a23 100644 --- a/ylong_http/src/h3/qpack/encoder.rs +++ b/ylong_http/src/h3/qpack/encoder.rs @@ -304,7 +304,7 @@ mod ut_qpack_encoder { use crate::h3::qpack::encoder; use crate::h3::qpack::encoder::QpackEncoder; use crate::h3::qpack::table::{DynamicTable, Field}; - use crate::test_util::decode; + use crate::util::test_util::decode; macro_rules! qpack_test_cases { ($enc: expr,$encoder_buf:expr,$encoder_cur:expr, $len: expr, $res: literal,$encoder_res: literal, $size: expr, { $($h: expr, $v: expr $(,)?)*} $(,)?) => { let mut _encoder = $enc; diff --git a/ylong_http/src/huffman/mod.rs b/ylong_http/src/huffman/mod.rs index faa5d96..903eca0 100644 --- a/ylong_http/src/huffman/mod.rs +++ b/ylong_http/src/huffman/mod.rs @@ -246,7 +246,7 @@ pub(crate) enum HuffmanDecodeError { #[cfg(test)] mod ut_huffman { use super::{huffman_decode, huffman_encode, HuffmanDecoder}; - use crate::test_util::decode; + use crate::util::test_util::decode; /// UT test cases for `huffman_encode`. /// diff --git a/ylong_http/src/lib.rs b/ylong_http/src/lib.rs index 8a6f733..b99a3b3 100644 --- a/ylong_http/src/lib.rs +++ b/ylong_http/src/lib.rs @@ -42,8 +42,7 @@ pub mod request; pub mod response; pub mod version; -#[cfg(test)] -pub(crate) mod test_util; +pub(crate) mod util; #[cfg(feature = "tokio_base")] pub(crate) use tokio::io::{AsyncRead, AsyncReadExt, ReadBuf}; diff --git a/ylong_http/src/util/header_bytes.rs b/ylong_http/src/util/header_bytes.rs new file mode 100644 index 0000000..75aa7fa --- /dev/null +++ b/ylong_http/src/util/header_bytes.rs @@ -0,0 +1,91 @@ +// Copyright (c) 2023 Huawei Device Co., Ltd. +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! HTTP Legitimate Header characters. + +// token = 1*tchar +// tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" +// / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~" +// / DIGIT / ALPHA +// ; any VCHAR, except delimiters +// delimitersd = DQUOTE and "(),/:;<=>?@[\]{}" +#[rustfmt::skip] +pub(crate) static HEADER_NAME_BYTES: [bool; 256] = { + const __: bool = false; + const TT: bool = true; + [ +// \0 HT LF CR + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, +// \w ! " # $ % & ' ( ) * + , - . / + __, TT, __, TT, TT, TT, TT, TT, __, __, TT, TT, __, TT, TT, __, +// 0 1 2 3 4 5 6 7 8 9 : ; < = > ? + TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, __, __, __, __, __, __, +// @ A B C D E F G H I J K L M N O + __, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, +// P Q R S T U V W X Y Z [ \ ] ^ _ + TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, __, __, __, TT, TT, +// ` a b c d e f g h i j k l m n o + TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, +// p q r s t u v w x y z { | } ~ del + TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, __, TT, __, TT, __, +// Expand ascii + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + ] +}; + +// field-value = *( field-content / obs-fold ) +// field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ] +// field-vchar = VCHAR / obs-text +// +// obs-fold = CRLF 1*( SP / HTAB ) +// ; obsolete line folding +// ; see Section 3.2.4 +#[rustfmt::skip] +pub(crate) static HEADER_VALUE_BYTES: [bool; 256] = { + const __: bool = false; + const TT: bool = true; + [ +// \0 HT LF CR + __, __, __, __, __, __, __, __, __, TT, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, +// \w ! " # $ % & ' ( ) * + , - . / + TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, +// 0 1 2 3 4 5 6 7 8 9 : ; < = > ? + TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, +// @ A B C D E F G H I J K L M N O + TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, +// P Q R S T U V W X Y Z [ \ ] ^ _ + TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, +// ` a b c d e f g h i j k l m n o + TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, +// p q r s t u v w x y z { | } ~ del + TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, __, +// Expand ascii + TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, + TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, + TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, + TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, + TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, + TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, + TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, + TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, TT, + ] +}; diff --git a/ylong_http/src/util/mod.rs b/ylong_http/src/util/mod.rs new file mode 100644 index 0000000..7beb0b6 --- /dev/null +++ b/ylong_http/src/util/mod.rs @@ -0,0 +1,18 @@ +// Copyright (c) 2023 Huawei Device Co., Ltd. +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Common util module. + +pub(crate) mod header_bytes; +#[cfg(test)] +pub(crate) mod test_util; diff --git a/ylong_http/src/test_util.rs b/ylong_http/src/util/test_util.rs similarity index 96% rename from ylong_http/src/test_util.rs rename to ylong_http/src/util/test_util.rs index 0d55480..a45e2bc 100644 --- a/ylong_http/src/test_util.rs +++ b/ylong_http/src/util/test_util.rs @@ -11,6 +11,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +//! Convert a str slice to u8 vector. + pub fn decode(str: &str) -> Option> { if str.len() % 2 != 0 { return None; diff --git a/ylong_http_client/src/async_impl/conn/http1.rs b/ylong_http_client/src/async_impl/conn/http1.rs index d05403a..2de4fe9 100644 --- a/ylong_http_client/src/async_impl/conn/http1.rs +++ b/ylong_http_client/src/async_impl/conn/http1.rs @@ -120,13 +120,13 @@ where } }; + // The shutdown function only sets the current connection to the closed state + // and does not release the connection immediately. + // Instead, the connection will be completely closed + // when the body has finished reading or when the body is released. match part.headers.get("Connection") { None => { if part.version == Version::HTTP1_0 { - // The shutdown function only sets the current connection to the closed state - // and does not release the connection immediately. - // Instead, the connection will be completely closed - // when the body has finished reading or when the body is released. conn.shutdown() } } diff --git a/ylong_http_client/src/lib.rs b/ylong_http_client/src/lib.rs index 1cad613..c943878 100644 --- a/ylong_http_client/src/lib.rs +++ b/ylong_http_client/src/lib.rs @@ -20,6 +20,7 @@ // TODO: Need doc. // ylong_http crate re-export. +#[cfg(any(feature = "ylong_base", feature = "tokio_base"))] pub use ylong_http::body::{EmptyBody, TextBody}; pub use ylong_http::request::method::Method; pub use ylong_http::request::uri::{Scheme, Uri}; diff --git a/ylong_http_client/src/util/proxy.rs b/ylong_http_client/src/util/proxy.rs index d38d80d..3a7d5d9 100644 --- a/ylong_http_client/src/util/proxy.rs +++ b/ylong_http_client/src/util/proxy.rs @@ -258,10 +258,7 @@ impl NoProxy { } else if domain.ends_with(&block_domain) { // .example.com and www. if block_domain.starts_with('.') - || domain - .as_bytes() - .get(domain.len() - block_domain.len() - 1) - == Some(&b'.') + || domain.as_bytes().get(domain.len() - block_domain.len() - 1) == Some(&b'.') { return true; } -- Gitee