Client should validate request URI. (#181)

This patch adds checks for the request URI and rejects invalid URIs. In
the case of forwarding an HTTP 1.1 request with a path, an "http" pseudo
header is added to satisfy the HTTP/2.0 spec.

Closes #179
This commit is contained in:
Carl Lerche
2017-12-11 13:42:00 -06:00
committed by GitHub
parent 71888acea5
commit 9378846da8
10 changed files with 164 additions and 53 deletions

View File

@@ -121,7 +121,6 @@ fn request_stream_id_overflows() {
.body(())
.unwrap();
// second cannot use the next stream id, it's over
let poll_err = client.poll_ready().unwrap_err();
@@ -279,8 +278,71 @@ fn request_over_max_concurrent_streams_errors() {
}
#[test]
#[ignore]
fn request_without_scheme() {}
fn http_11_request_without_scheme_or_authority() {
let _ = ::env_logger::init();
let (io, srv) = mock::new();
let srv = srv.assert_client_handshake()
.unwrap()
.recv_settings()
.recv_frame(
frames::headers(1)
.request("GET", "/")
.scheme("http")
.eos(),
)
.send_frame(frames::headers(1).response(200).eos())
.close();
let h2 = Client::handshake(io)
.expect("handshake")
.and_then(|(mut client, h2)| {
// we send a simple req here just to drive the connection so we can
// receive the server settings.
let request = Request::builder()
.method(Method::GET)
.uri("/")
.body(())
.unwrap();
// first request is allowed
let (response, _) = client.send_request(request, true).unwrap();
h2.drive(response)
.map(move |(h2, _)| (client, h2))
});
h2.join(srv).wait().expect("wait");
}
#[test]
fn http_2_request_without_scheme_or_authority() {
let _ = ::env_logger::init();
let (io, srv) = mock::new();
let srv = srv.assert_client_handshake()
.unwrap()
.recv_settings()
.close();
let h2 = Client::handshake(io)
.expect("handshake")
.and_then(|(mut client, h2)| {
// we send a simple req here just to drive the connection so we can
// receive the server settings.
let request = Request::builder()
.version(Version::HTTP_2)
.method(Method::GET)
.uri("/")
.body(())
.unwrap();
// first request is allowed
assert!(client.send_request(request, true).is_err());
h2.expect("h2")
});
h2.join(srv).wait().expect("wait");
}
#[test]
#[ignore]

View File

@@ -137,6 +137,16 @@ impl Mock<frame::Headers> {
Mock(frame)
}
pub fn scheme(self, value: &str) -> Self
{
let (id, mut pseudo, fields) = self.into_parts();
let value = value.parse().unwrap();
pseudo.set_scheme(value);
Mock(frame::Headers::new(id, pseudo, fields))
}
pub fn eos(mut self) -> Self {
self.0.set_end_stream();
self

View File

@@ -32,7 +32,7 @@ pub use self::futures::{Future, IntoFuture, Sink, Stream};
pub use super::future_ext::{FutureExt, Unwrap};
// Re-export HTTP types
pub use self::http::{HeaderMap, Method, Request, Response, StatusCode};
pub use self::http::{HeaderMap, Method, Request, Response, StatusCode, Version};
pub use self::bytes::{Buf, BufMut, Bytes, BytesMut, IntoBuf};