use crate::Error;
use crate::server::{RecvRequestResult, Reply};
#[test]
fn parse_request() {
let mut reply = Reply::new().unwrap();
let input = b"GET /path HTTP/1.1\r\nhost: example.com\r\n\r\n";
let (input_used, request) = reply.try_request(input).unwrap();
assert_eq!(input_used, 41);
let request = request.unwrap();
assert_eq!(request.uri().path(), "/path");
assert_eq!(request.method(), "GET");
assert_eq!(request.headers().get("host").unwrap(), "example.com");
}
#[test]
fn incomplete_request() {
let mut reply = Reply::new().unwrap();
let input = b"GET /path HTTP/1.1\r\nhost: example.com\r\n";
let (input_used, request) = reply.try_request(input).unwrap();
assert_eq!(input_used, 0);
assert!(request.is_none());
}
#[test]
fn malformed_request() {
let mut reply = Reply::new().unwrap();
let input = b"GET /path INVALID/1.1\r\nhost: example.com\r\n\r\n";
let result = reply.try_request(input);
assert!(result.is_err());
}
#[test]
fn proceed_to_send_100() {
let mut reply = Reply::new().unwrap();
let input = b"POST /path HTTP/1.1\r\nhost: example.com\r\nexpect: 100-continue\r\n\r\n";
let (_, request) = reply.try_request(input).unwrap();
assert!(request.is_some());
match reply.proceed().unwrap() {
RecvRequestResult::Send100(_) => {}
_ => panic!("Expected Send100 state"),
}
}
#[test]
fn proceed_to_recv_body() {
let mut reply = Reply::new().unwrap();
let input = b"POST /path HTTP/1.1\r\nhost: example.com\r\n\r\n";
let (_, request) = reply.try_request(input).unwrap();
assert!(request.is_some());
match reply.proceed().unwrap() {
RecvRequestResult::RecvBody(_) => {}
_ => panic!("Expected RecvBody state"),
}
}
#[test]
fn proceed_to_provide_response() {
let mut reply = Reply::new().unwrap();
let input = b"GET /path HTTP/1.1\r\nhost: example.com\r\n\r\n";
let (_, request) = reply.try_request(input).unwrap();
assert!(request.is_some());
match reply.proceed().unwrap() {
RecvRequestResult::ProvideResponse(_) => {}
_ => panic!("Expected ProvideResponse state"),
}
}
#[test]
fn cannot_proceed_without_request() {
let reply = Reply::new().unwrap();
assert!(!reply.can_proceed());
assert!(reply.proceed().is_none());
}
#[test]
fn proceed_to_provide_response_with_zero_length() {
let mut reply = Reply::new().unwrap();
let input = b"POST /path HTTP/1.1\r\nhost: example.com\r\ncontent-length: 0\r\n\r\n";
let (_, request) = reply.try_request(input).unwrap();
assert!(request.is_some());
match reply.proceed().unwrap() {
RecvRequestResult::ProvideResponse(_) => {}
_ => panic!("Expected ProvideResponse state"),
}
}
#[test]
fn proceed_to_recv_body_with_get() {
let mut reply = Reply::new().unwrap();
let input = b"GET /path HTTP/1.1\r\nhost: example.com\r\ncontent-length: 5\r\n\r\n";
let (_, request) = reply.try_request(input).unwrap();
assert!(request.is_some());
match reply.proceed().unwrap() {
RecvRequestResult::RecvBody(_) => {}
_ => panic!("Expected RecvBody state"),
}
}
#[test]
fn proceed_to_provide_response_with_head() {
let mut reply = Reply::new().unwrap();
let input = b"HEAD /path HTTP/1.1\r\nhost: example.com\r\ncontent-length: 5\r\n\r\n";
let (_, request) = reply.try_request(input).unwrap();
assert!(request.is_some());
match reply.proceed().unwrap() {
RecvRequestResult::ProvideResponse(_) => {}
_ => panic!("Expected ProvideResponse state"),
}
}
#[test]
fn proceed_to_provide_response_with_head_expect() {
let mut reply = Reply::new().unwrap();
let input = b"HEAD /path HTTP/1.1\r\nhost: example.com\r\nexpect: 100-continue\r\n\r\n";
let (_, request) = reply.try_request(input).unwrap();
assert!(request.is_some());
match reply.proceed().unwrap() {
RecvRequestResult::ProvideResponse(_) => {}
_ => panic!("Expected ProvideResponse state"),
}
}
#[test]
fn proceed_to_send_100_with_get_chunked() {
let mut reply = Reply::new().unwrap();
let input = b"GET /path HTTP/1.1\r\nhost: example.com\r\ntransfer-encoding: chunked\r\nexpect: 100-continue\r\n\r\n";
let (_, request) = reply.try_request(input).unwrap();
assert!(request.is_some());
match reply.proceed().unwrap() {
RecvRequestResult::Send100(_) => {}
_ => panic!("Expected Send100 state"),
}
}
#[test]
fn duplicate_identical_content_length_is_accepted() {
let mut reply = Reply::new().unwrap();
let input = b"POST /path HTTP/1.1\r\nhost: example.com\r\n\
content-length: 42\r\ncontent-length: 042\r\n\r\n";
let (input_used, request) = reply.try_request(input).unwrap();
assert_eq!(input_used, input.len());
assert!(request.is_some());
}
#[test]
fn duplicate_differing_content_length_is_rejected() {
let mut reply = Reply::new().unwrap();
let input = b"POST /path HTTP/1.1\r\nhost: example.com\r\n\
content-length: 42\r\ncontent-length: 43\r\n\r\n";
let err = reply.try_request(input).unwrap_err();
assert_eq!(err, Error::TooManyContentLengthHeaders);
}
#[test]
fn content_length_with_sign_is_rejected() {
let mut reply = Reply::new().unwrap();
let input = b"POST /path HTTP/1.1\r\nhost: example.com\r\ncontent-length: +42\r\n\r\n";
let err = reply.try_request(input).unwrap_err();
assert_eq!(err, Error::BadContentLengthHeader);
}
#[test]
fn content_length_list_with_differing_values_is_rejected() {
let mut reply = Reply::new().unwrap();
let input = b"POST /path HTTP/1.1\r\nhost: example.com\r\ncontent-length: 42, 43\r\n\r\n";
let err = reply.try_request(input).unwrap_err();
assert_eq!(err, Error::TooManyContentLengthHeaders);
}
#[test]
fn empty_content_length_is_rejected() {
let mut reply = Reply::new().unwrap();
let input = b"POST /path HTTP/1.1\r\nhost: example.com\r\ncontent-length:\r\n\r\n";
let err = reply.try_request(input).unwrap_err();
assert_eq!(err, Error::BadContentLengthHeader);
}