Skip to content

Commit 08b8d21

Browse files
fix: auto::Connection can handle requests shorter than h2 preface (#97)
1 parent 703d8da commit 08b8d21

File tree

1 file changed

+15
-22
lines changed

1 file changed

+15
-22
lines changed

src/server/conn/auto.rs

Lines changed: 15 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,11 @@
33
use futures_util::ready;
44
use hyper::service::HttpService;
55
use std::future::Future;
6-
use std::io::{Error as IoError, ErrorKind, Result as IoResult};
76
use std::marker::PhantomPinned;
87
use std::mem::MaybeUninit;
98
use std::pin::Pin;
109
use std::task::{Context, Poll};
11-
use std::{error::Error as StdError, marker::Unpin, time::Duration};
10+
use std::{error::Error as StdError, io, marker::Unpin, time::Duration};
1211

1312
use bytes::Bytes;
1413
use http::{Request, Response};
@@ -174,7 +173,7 @@ where
174173
io: Some(io),
175174
buf: [MaybeUninit::uninit(); 24],
176175
filled: 0,
177-
version: Version::H1,
176+
version: Version::H2,
178177
_pin: PhantomPinned,
179178
}
180179
}
@@ -196,7 +195,7 @@ impl<I> Future for ReadVersion<I>
196195
where
197196
I: Read + Unpin,
198197
{
199-
type Output = IoResult<(Version, Rewind<I>)>;
198+
type Output = io::Result<(Version, Rewind<I>)>;
200199

201200
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
202201
let this = self.project();
@@ -208,27 +207,21 @@ where
208207
buf.unfilled().advance(*this.filled);
209208
};
210209

210+
// We start as H2 and switch to H1 as soon as we don't have the preface.
211211
while buf.filled().len() < H2_PREFACE.len() {
212-
if buf.filled() != &H2_PREFACE[0..buf.filled().len()] {
213-
let io = this.io.take().unwrap();
214-
let buf = buf.filled().to_vec();
215-
return Poll::Ready(Ok((
216-
*this.version,
217-
Rewind::new_buffered(io, Bytes::from(buf)),
218-
)));
219-
} else {
220-
// if our buffer is empty, then we need to read some data to continue.
221-
let len = buf.filled().len();
222-
ready!(Pin::new(this.io.as_mut().unwrap()).poll_read(cx, buf.unfilled()))?;
223-
*this.filled = buf.filled().len();
224-
if buf.filled().len() == len {
225-
return Err(IoError::new(ErrorKind::UnexpectedEof, "early eof")).into();
226-
}
212+
let len = buf.filled().len();
213+
ready!(Pin::new(this.io.as_mut().unwrap()).poll_read(cx, buf.unfilled()))?;
214+
*this.filled = buf.filled().len();
215+
216+
// We starts as H2 and switch to H1 when we don't get the preface.
217+
if buf.filled().len() == len
218+
|| &buf.filled()[len..] != &H2_PREFACE[len..buf.filled().len()]
219+
{
220+
*this.version = Version::H1;
221+
break;
227222
}
228223
}
229-
if buf.filled() == H2_PREFACE {
230-
*this.version = Version::H2;
231-
}
224+
232225
let io = this.io.take().unwrap();
233226
let buf = buf.filled().to_vec();
234227
Poll::Ready(Ok((

0 commit comments

Comments
 (0)