Make :status in requests be a stream error
This commit is contained in:
committed by
Sean McArthur
parent
8520f06f93
commit
c38c94cb16
@@ -575,6 +575,11 @@ impl Pseudo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "unstable")]
|
||||||
|
pub fn set_status(&mut self, value: StatusCode) {
|
||||||
|
self.status = Some(value);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set_scheme(&mut self, scheme: uri::Scheme) {
|
pub fn set_scheme(&mut self, scheme: uri::Scheme) {
|
||||||
let bytes_str = match scheme.as_str() {
|
let bytes_str = match scheme.as_str() {
|
||||||
"http" => BytesStr::from_static("http"),
|
"http" => BytesStr::from_static("http"),
|
||||||
|
|||||||
@@ -1410,10 +1410,8 @@ impl proto::Peer for Peer {
|
|||||||
malformed!("malformed headers: missing method");
|
malformed!("malformed headers: missing method");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Specifying :status for a request is a protocol error
|
|
||||||
if pseudo.status.is_some() {
|
if pseudo.status.is_some() {
|
||||||
tracing::trace!("malformed headers: :status field on request; PROTOCOL_ERROR");
|
malformed!("malformed headers: :status field on request");
|
||||||
return Err(Error::library_go_away(Reason::PROTOCOL_ERROR));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert the URI
|
// Convert the URI
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use std::convert::TryInto;
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use http::{self, HeaderMap};
|
use http::{self, HeaderMap, StatusCode};
|
||||||
|
|
||||||
use h2::frame::{self, Frame, StreamId};
|
use h2::frame::{self, Frame, StreamId};
|
||||||
|
|
||||||
@@ -162,6 +162,14 @@ impl Mock<frame::Headers> {
|
|||||||
Mock(frame)
|
Mock(frame)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn status(self, value: StatusCode) -> Self {
|
||||||
|
let (id, mut pseudo, fields) = self.into_parts();
|
||||||
|
|
||||||
|
pseudo.set_status(value);
|
||||||
|
|
||||||
|
Mock(frame::Headers::new(id, pseudo, fields))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn scheme(self, value: &str) -> Self {
|
pub fn scheme(self, value: &str) -> Self {
|
||||||
let (id, mut pseudo, fields) = self.into_parts();
|
let (id, mut pseudo, fields) = self.into_parts();
|
||||||
let value = value.parse().unwrap();
|
let value = value.parse().unwrap();
|
||||||
|
|||||||
@@ -1025,6 +1025,30 @@ async fn server_error_on_unclean_shutdown() {
|
|||||||
srv.await.expect_err("should error");
|
srv.await.expect_err("should error");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn server_error_on_status_in_request() {
|
||||||
|
h2_support::trace_init!();
|
||||||
|
|
||||||
|
let (io, mut client) = mock::new();
|
||||||
|
|
||||||
|
let client = async move {
|
||||||
|
let settings = client.assert_server_handshake().await;
|
||||||
|
assert_default_settings!(settings);
|
||||||
|
client
|
||||||
|
.send_frame(frames::headers(1).status(StatusCode::OK))
|
||||||
|
.await;
|
||||||
|
client.recv_frame(frames::reset(1).protocol_error()).await;
|
||||||
|
};
|
||||||
|
|
||||||
|
let srv = async move {
|
||||||
|
let mut srv = server::handshake(io).await.expect("handshake");
|
||||||
|
|
||||||
|
assert!(srv.next().await.is_none());
|
||||||
|
};
|
||||||
|
|
||||||
|
join(client, srv).await;
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn request_without_authority() {
|
async fn request_without_authority() {
|
||||||
h2_support::trace_init!();
|
h2_support::trace_init!();
|
||||||
|
|||||||
Reference in New Issue
Block a user