fix(server): properly handle keep-alive for HTTP/1.0
Change behaviour of connection or server response when the request is version 1.0 and the Connection: keep-alive header is not present. 1. If the response is also version 1.0, then connection is closed if the server keep-alive header is not present. 2. If the response is version 1.1, then the keep-alive header is added when downgrading to version 1.0. Closes #1614
This commit is contained in:
@@ -5,10 +5,12 @@ use std::marker::PhantomData;
|
||||
use bytes::{Buf, Bytes};
|
||||
use futures::{Async, Poll};
|
||||
use http::{HeaderMap, Method, Version};
|
||||
use http::header::{HeaderValue, CONNECTION};
|
||||
use tokio_io::{AsyncRead, AsyncWrite};
|
||||
|
||||
use ::Chunk;
|
||||
use proto::{BodyLength, DecodedLength, MessageHead};
|
||||
use headers::connection_keep_alive;
|
||||
use super::io::{Buffered};
|
||||
use super::{EncodedBuf, Encode, Encoder, /*Decode,*/ Decoder, Http1Transaction, ParseContext};
|
||||
|
||||
@@ -438,12 +440,38 @@ where I: AsyncRead + AsyncWrite,
|
||||
}
|
||||
}
|
||||
|
||||
// Fix keep-alives when Connection: keep-alive header is not present
|
||||
fn fix_keep_alive(&mut self, head: &mut MessageHead<T::Outgoing>) {
|
||||
let outgoing_is_keep_alive = head
|
||||
.headers
|
||||
.get(CONNECTION)
|
||||
.and_then(|value| Some(connection_keep_alive(value)))
|
||||
.unwrap_or(false);
|
||||
|
||||
if !outgoing_is_keep_alive {
|
||||
match head.version {
|
||||
// If response is version 1.0 and keep-alive is not present in the response,
|
||||
// disable keep-alive so the server closes the connection
|
||||
Version::HTTP_10 => self.state.disable_keep_alive(),
|
||||
// If response is version 1.1 and keep-alive is wanted, add
|
||||
// Connection: keep-alive header when not present
|
||||
Version::HTTP_11 => if self.state.wants_keep_alive() {
|
||||
head.headers
|
||||
.insert(CONNECTION, HeaderValue::from_static("keep-alive"));
|
||||
},
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we know the remote speaks an older version, we try to fix up any messages
|
||||
// to work with our older peer.
|
||||
fn enforce_version(&mut self, head: &mut MessageHead<T::Outgoing>) {
|
||||
|
||||
match self.state.version {
|
||||
Version::HTTP_10 => {
|
||||
// Fixes response or connection when keep-alive header is not present
|
||||
self.fix_keep_alive(head);
|
||||
// If the remote only knows HTTP/1.0, we should force ourselves
|
||||
// to do only speak HTTP/1.0 as well.
|
||||
head.version = Version::HTTP_10;
|
||||
|
||||
Reference in New Issue
Block a user