Closed ubnt-intrepid closed 5 years ago
modification in HttpConnection
:
trait HttpConnection<I: AsyncRead + AsyncWrite> {
type Response: HttpResponse;
type Upgrade: HttpUpgrade<I>;
type Error;
type Future: Future<Item = Either<Self::Response, Self::Upgrade>, Error = Self::Error>;
fn respond(&mut self, request: HttpRequest) -> Self::Future;
}
where HttpUpgrade
is defined as follows:
trait HttpUpgrade<I: AsyncRead + AsyncWrite> {
type Task: HttpUpgradeTask<I>;
fn into_response(self) -> (Response<()>, Self::Task);
}
trait HttpUpgradeTask<I> {
type Future: Future<Item = (), Error = ()>;
fn upgrade(self, io: Upgraded<I>) -> Self::Future;
}
struct Upgraded<I> {
io: I,
read_buf: Bytes,
}
// impl io::Read, io::Write, tokio::io::AsyncRead, tokio::io::AsyncWrite, ...
struct InnerService<S: HttpService<I>, I: AsyncRead + AsyncWrite> {
connection: S::Connection,
...
rx_upgraded: Option<oneshot::Receiver<<S::Connection as HttpConnection<I>>::Upgrade>>,
}
HttpUpgrade
was added to izanami_http
.
Pros:
HttpUpgrade::Upgraded
) is driven on the task same asConnection
belongs. It means that it is easier to control the behavior of task per connection (timeout, etc.)hyper::upgrade
, the post-upgrade process is located on a spawned task by the user and different from the task ofConnection
.Cons:
HttpService
andHttpConnection
will become complicated due to abstraction around upgrade mechanism. This might affect the design of Web frameworks.