Skip to content

Commit da2e6e9

Browse files
committed
fix: test
1 parent 9fc81a1 commit da2e6e9

File tree

3 files changed

+101
-15
lines changed

3 files changed

+101
-15
lines changed

.github/workflows/check_guides.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ EOF
2323
tokio = { version = "1", features = ["full"] }
2424
http-body-util = "0.1"
2525
hyper-util = { version = "0.1", features = ["full"] }
26+
tower = "0.4"
2627
EOF
2728
cargo build --manifest-path "$value/Cargo.toml"
2829
fi

_config.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ docs_url: https://docs.rs/hyper
5757
examples_url: https://github.com/hyperium/hyper/tree/master/examples
5858
http_body_util_url: https://docs.rs/http-body-util
5959
hyper_tls_url: https://docs.rs/hyper-tls
60+
hyper_util_url: https://docs.rs/hyper-util
6061

6162
futures_url: https://docs.rs/futures/0.3.*
6263
legacy_docs_url: https://docs.rs/hyper/0.14.*

_stable/server/middleware.md

Lines changed: 99 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,35 +3,39 @@ title: Getting Started with a Server Middleware
33
layout: guide
44
---
55

6-
As [Upgrade](https://hyper.rs/guides/1/upgrading/) mentioned, hyper v1 is not depended on tower for the Service trait. When we want to add tower-like middleware, there are 2 kind of approach to make it.
6+
As [Upgrade](upgrading) mentioned, hyper v1 is not depended on tower for the Service trait. When we want to add tower-like middleware, there are 2 kind of approach to make it.
77

8-
Let's create a Logger middleware in [hello-world server](https://hyper.rs/guides/1/server/hello-world/) for instance:
8+
Let's create a Logger middleware in [hello-world server](hello-world) for instance:
99

1010
Add tower dependency first
1111

12-
```rust
12+
```toml
1313
[dependencies]
1414
hyper = { version = "1", features = ["full"] }
1515
tokio = { version = "1", features = ["full"] }
1616
http-body-util = "0.1"
1717
hyper-util = { version = "0.1", features = ["full"] }
18-
tower = { version = "0.4.13" } // here
18+
tower = "0.4" # here
1919
```
2020

2121
## Option 1: Use hyper Service trait
2222

2323
Implement hyper Logger middleware
2424

2525
```rust
26-
use hyper::{body::Incoming, service::Service}; // using hyper Service trait
27-
use tower::{Layer, Service};
26+
# extern crate hyper;
27+
use hyper::{Request, body::Incoming, service::Service};
2828

2929
#[derive(Debug, Clone)]
3030
pub struct Logger<S> {
3131
inner: S,
3232
}
33-
34-
type Req = hyper::Request<Incoming>;
33+
impl<S> Logger<S> {
34+
pub fn new(inner: S) -> Self {
35+
Logger { inner }
36+
}
37+
}
38+
type Req = Request<Incoming>;
3539

3640
impl<S> Service<Req> for Logger<S>
3741
where
@@ -45,23 +49,53 @@ where
4549
self.inner.call(req)
4650
}
4751
}
52+
# fn main() {}
4853
```
4954

5055
Then this can be used in server:
5156

5257
```rust
58+
# extern crate tower;
59+
# extern crate hyper;
60+
# extern crate http_body_util;
61+
# extern crate tokio;
62+
# extern crate hyper_util;
63+
# mod no_run {
5364
use std::{convert::Infallible, net::SocketAddr};
54-
5565
use hyper::{
66+
service::Service,
5667
body::{Bytes, Incoming},
5768
server::conn::http1,
5869
Request, Response,
5970
};
60-
6171
use http_body_util::Full;
6272
use hyper_util::rt::TokioIo;
6373
use tokio::net::TcpListener;
6474
use tower::ServiceBuilder;
75+
76+
# #[derive(Debug, Clone)]
77+
# pub struct Logger<S> {
78+
# inner: S,
79+
# }
80+
# impl<S> Logger<S> {
81+
# pub fn new(inner: S) -> Self {
82+
# Logger { inner }
83+
# }
84+
# }
85+
# type Req = Request<Incoming>;
86+
87+
# impl<S> Service<Req> for Logger<S>
88+
# where
89+
# S: Service<Req>,
90+
# {
91+
# type Response = S::Response;
92+
# type Error = S::Error;
93+
# type Future = S::Future;
94+
# fn call(&self, req: Req) -> Self::Future {
95+
# println!("processing request: {} {}", req.method(), req.uri().path());
96+
# self.inner.call(req)
97+
# }
98+
# }
6599
async fn hello(_: Request<Incoming>) -> Result<Response<Full<Bytes>>, Infallible> {
66100
Ok(Response::new(Full::new(Bytes::from("Hello, World!"))))
67101
}
@@ -82,16 +116,20 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
82116
});
83117
}
84118
}
119+
# }
120+
# fn main() {}
85121
```
86122

87123
## Option 2: use hyper TowerToHyperService trait
88124

89-
[hyper_util::service::TowerToHyperService](https://docs.rs/hyper-util/latest/hyper_util/service/struct.TowerToHyperService.html) trait is an adapter to convert tower Service to hyper Service.
125+
[hyper_util::service::TowerToHyperService](adapter-trait) trait is an adapter to convert tower Service to hyper Service.
90126

91127
Now implement a tower Logger middleware
92128

93129
```rust
94-
use hyper::body::Incoming;
130+
# extern crate tower;
131+
# extern crate hyper;
132+
use hyper::{Request, body::Incoming};
95133
use tower::Service;
96134

97135
#[derive(Debug, Clone)]
@@ -103,7 +141,7 @@ impl<S> Logger<S> {
103141
Logger { inner }
104142
}
105143
}
106-
type Req = hyper::Request<Incoming>;
144+
type Req = Request<Incoming>;
107145
impl<S> Service<Req> for Logger<S>
108146
where
109147
S: Service<Req> + Clone,
@@ -126,11 +164,18 @@ where
126164
self.inner.call(req)
127165
}
128166
}
167+
# fn main() {}
129168
```
130169

131170
Then use it in the server:
132171

133172
```rust
173+
# extern crate hyper;
174+
# extern crate http_body_util;
175+
# extern crate hyper_util;
176+
# extern crate tokio;
177+
# extern crate tower;
178+
# mod no_run {
134179
use std::{convert::Infallible, net::SocketAddr};
135180

136181
use hyper::{
@@ -142,8 +187,41 @@ use hyper::{
142187
use http_body_util::Full;
143188
use hyper_util::{rt::TokioIo, service::TowerToHyperService};
144189
use tokio::net::TcpListener;
145-
use tower::ServiceBuilder;
146-
use crate::logger::Logger as Logger;
190+
use tower::{ServiceBuilder, Service};
191+
192+
# #[derive(Debug, Clone)]
193+
# pub struct Logger<S> {
194+
# inner: S,
195+
# }
196+
# impl<S> Logger<S> {
197+
# pub fn new(inner: S) -> Self {
198+
# Logger { inner }
199+
# }
200+
# }
201+
# type Req = Request<Incoming>;
202+
# impl<S> Service<Req> for Logger<S>
203+
# where
204+
# S: Service<Req> + Clone,
205+
# {
206+
# type Response = S::Response;
207+
208+
# type Error = S::Error;
209+
210+
# type Future = S::Future;
211+
212+
# fn poll_ready(
213+
# &mut self,
214+
# cx: &mut std::task::Context<'_>,
215+
# ) -> std::task::Poll<Result<(), Self::Error>> {
216+
# self.inner.poll_ready(cx)
217+
# }
218+
219+
# fn call(&mut self, req: Req) -> Self::Future {
220+
# println!("processing request: {} {}", req.method(), req.uri().path());
221+
# self.inner.call(req)
222+
# }
223+
# }
224+
147225
async fn hello(_: Request<Incoming>) -> Result<Response<Full<Bytes>>, Infallible> {
148226
Ok(Response::new(Full::new(Bytes::from("Hello, World!"))))
149227
}
@@ -166,4 +244,10 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
166244
});
167245
}
168246
}
247+
}
248+
# fn main() {}
169249
```
250+
251+
[hellp-world]: {{ site.url }}/guides/1/server/hello-world/
252+
[upgrading]: {{ site.url }}/guides/1/upgrading/
253+
[adapter-trait]: {{ site.hyper_util_url }}/latest/hyper_util/service/struct.TowerToHyperService.html

0 commit comments

Comments
 (0)