apsis-book/tests/http_request.rs

75 lines
2.5 KiB
Rust
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//! Tests for the request parser.
//! 请求解析器的测试。
//!
//! They live here rather than inside the module so that `src/` holds no test
//! code, as it does in `apsis-rs`. An integration test is a separate crate and
//! reaches only what the library makes public, so the few internal items the
//! tests need are opened through `apsis_book::testkit`.
//!
//! 它们放在这里而不是模块内部,使 `src/` 不含测试代码,与 `apsis-rs` 一致。
//! 集成测试是独立的 crate,只能触达库公开的部分,因此测试所需的那少数内部条目
//! 经 `apsis_book::testkit` 开放。
use apsis_book::http::request::*;
use std::io::Cursor;
#[test]
fn parses_a_get_request() {
let raw = b"GET /health?verbose=1 HTTP/1.1\r\nHost: localhost\r\nX-Test: a\r\n\r\n";
let request = read_request(&mut Cursor::new(raw), Limits::default()).unwrap();
assert_eq!(request.method, Method::Get);
assert_eq!(request.path, "/health");
assert_eq!(request.query.as_deref(), Some("verbose=1"));
assert_eq!(request.header("x-test"), Some("a"));
assert_eq!(request.header("X-Test"), Some("a"));
assert_eq!(
request.query_pairs().get("verbose").map(String::as_str),
Some("1")
);
}
#[test]
fn parses_a_post_body() {
let raw = b"POST /api/tools/x HTTP/1.1\r\nContent-Length: 5\r\n\r\nhello";
let request = read_request(&mut Cursor::new(raw), Limits::default()).unwrap();
assert_eq!(request.method, Method::Post);
assert_eq!(request.body_text(), Some("hello"));
}
#[test]
fn rejects_malformed_input() {
let cases: &[&[u8]] = &[
b"GET\r\n\r\n",
b"GET / HTTP/2.0\r\n\r\n",
b"GET / HTTP/1.1\r\nbroken\r\n\r\n",
b"GET / HTTP/1.1\r\nContent-Length: nope\r\n\r\n",
];
for case in cases {
assert!(read_request(&mut Cursor::new(*case), Limits::default()).is_err());
}
}
#[test]
fn decodes_percent_escapes() {
let raw = b"GET /search?q=a%20b+%E2%82%AC HTTP/1.1\r\n\r\n";
let request = read_request(&mut Cursor::new(raw), Limits::default()).unwrap();
assert_eq!(
request.query_pairs().get("q").map(String::as_str),
Some("a b €")
);
}
#[test]
fn rejects_an_oversized_body() {
let raw = b"POST /x HTTP/1.1\r\nContent-Length: 100\r\n\r\n";
let limits = Limits {
max_body_bytes: 4,
..Limits::default()
};
assert!(matches!(
read_request(&mut Cursor::new(raw), limits),
Err(RequestError::TooLarge(_))
));
}