Skip to content

Commit 7c4b814

Browse files
committed
fix(client): don't read extra bytes on idle connections
1 parent f7532b7 commit 7c4b814

File tree

4 files changed

+77
-17
lines changed

4 files changed

+77
-17
lines changed

src/proto/conn.rs

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,16 @@ where I: AsyncRead + AsyncWrite,
102102

103103
pub fn can_read_head(&self) -> bool {
104104
match self.state.reading {
105-
Reading::Init => true,
105+
Reading::Init => {
106+
if T::should_read_first() {
107+
true
108+
} else {
109+
match self.state.writing {
110+
Writing::Init => false,
111+
_ => true,
112+
}
113+
}
114+
}
106115
_ => false,
107116
}
108117
}
@@ -840,25 +849,35 @@ mod tests {
840849

841850
#[test]
842851
fn test_conn_init_read_eof_busy() {
843-
// server ignores
844-
let io = AsyncIo::new_buf(vec![], 1);
845-
let mut conn = Conn::<_, proto::Chunk, ServerTransaction>::new(io, Default::default());
846-
conn.state.busy();
852+
let _: Result<(), ()> = future::lazy(|| {
853+
// server ignores
854+
let io = AsyncIo::new_buf(vec![], 1);
855+
let mut conn = Conn::<_, proto::Chunk, ServerTransaction>::new(io, Default::default());
856+
conn.state.busy();
847857

848-
match conn.poll().unwrap() {
849-
Async::Ready(None) => {},
850-
other => panic!("unexpected frame: {:?}", other)
851-
}
858+
match conn.poll().unwrap() {
859+
Async::Ready(None) => {},
860+
other => panic!("unexpected frame: {:?}", other)
861+
}
852862

853-
// client, when busy, returns the error
854-
let io = AsyncIo::new_buf(vec![], 1);
855-
let mut conn = Conn::<_, proto::Chunk, ClientTransaction>::new(io, Default::default());
856-
conn.state.busy();
863+
// client
864+
let io = AsyncIo::new_buf(vec![], 1);
865+
let mut conn = Conn::<_, proto::Chunk, ClientTransaction>::new(io, Default::default());
866+
conn.state.busy();
857867

858-
match conn.poll() {
859-
Err(ref err) if err.kind() == ::std::io::ErrorKind::UnexpectedEof => {},
860-
other => panic!("unexpected frame: {:?}", other)
861-
}
868+
match conn.poll() {
869+
Ok(Async::NotReady) => {},
870+
other => panic!("unexpected frame: {:?}", other)
871+
}
872+
873+
// once mid-request, returns the error
874+
conn.state.writing = super::Writing::KeepAlive;
875+
match conn.poll() {
876+
Err(ref err) if err.kind() == ::std::io::ErrorKind::UnexpectedEof => {},
877+
other => panic!("unexpected frame: {:?}", other)
878+
}
879+
Ok(())
880+
}).wait();
862881
}
863882

864883
#[test]

src/proto/h1/parse.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,10 @@ impl Http1Transaction for ServerTransaction {
136136
fn should_error_on_parse_eof() -> bool {
137137
false
138138
}
139+
140+
fn should_read_first() -> bool {
141+
true
142+
}
139143
}
140144

141145
impl ServerTransaction {
@@ -289,6 +293,10 @@ impl Http1Transaction for ClientTransaction {
289293
fn should_error_on_parse_eof() -> bool {
290294
true
291295
}
296+
297+
fn should_read_first() -> bool {
298+
false
299+
}
292300
}
293301

294302
impl ClientTransaction {

src/proto/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ pub trait Http1Transaction {
149149
fn encode(head: MessageHead<Self::Outgoing>, has_body: bool, method: &mut Option<Method>, dst: &mut Vec<u8>) -> h1::Encoder;
150150

151151
fn should_error_on_parse_eof() -> bool;
152+
fn should_read_first() -> bool;
152153
}
153154

154155
pub type ParseResult<T> = ::Result<Option<(MessageHead<T>, usize)>>;

tests/client.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,38 @@ test! {
353353
body: None,
354354
}
355355

356+
test! {
357+
name: client_pipeline_responses_extra,
358+
359+
server:
360+
expected: "\
361+
GET /pipe HTTP/1.1\r\n\
362+
Host: {addr}\r\n\
363+
\r\n\
364+
",
365+
reply: "\
366+
HTTP/1.1 200 OK\r\n\
367+
Content-Length: 0\r\n\
368+
\r\n\
369+
HTTP/1.1 200 OK\r\n\
370+
Content-Length: 0\r\n\
371+
\r\n\
372+
",
373+
374+
client:
375+
request:
376+
method: Get,
377+
url: "http://{addr}/pipe",
378+
headers: [],
379+
body: None,
380+
proxy: false,
381+
response:
382+
status: Ok,
383+
headers: [],
384+
body: None,
385+
}
386+
387+
356388
test! {
357389
name: client_error_unexpected_eof,
358390

0 commit comments

Comments
 (0)