Skip to content

Commit 12bffee

Browse files
committed
响应结构调整
1 parent 6d1c6e1 commit 12bffee

File tree

9 files changed

+116
-66
lines changed

9 files changed

+116
-66
lines changed

silent/src/core/response.rs

Lines changed: 35 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,27 @@
11
use crate::core::res_body::{full, ResBody};
2+
use crate::{HeaderMap, StatusCode};
23
use bytes::Bytes;
34
use headers::{Header, HeaderMapExt};
4-
use hyper::Response as HyperResponse;
55
use std::fmt;
66
use std::fmt::{Display, Formatter};
7-
use std::ops::{Deref, DerefMut};
87

98
/// 响应体
109
/// ```
1110
/// use silent::Response;
1211
/// let req = Response::empty();
1312
/// ```
1413
pub struct Response {
15-
pub(crate) res: HyperResponse<ResBody>,
14+
/// The HTTP status code.
15+
pub(crate) status_code: StatusCode,
16+
/// The HTTP headers.
17+
pub(crate) headers: HeaderMap,
18+
pub(crate) body: ResBody,
1619
}
1720

1821
impl fmt::Debug for Response {
1922
#[inline]
2023
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
21-
writeln!(f, "HTTP/1.1 {}\n{:?}", self.status(), self.headers())
24+
writeln!(f, "HTTP/1.1 {}\n{:?}", self.status_code, self.headers)
2225
}
2326
}
2427

@@ -32,53 +35,58 @@ impl Display for Response {
3235
impl Response {
3336
/// 创建空响应体
3437
pub fn empty() -> Self {
35-
Response::from(Bytes::new())
38+
Self {
39+
status_code: StatusCode::OK,
40+
headers: HeaderMap::new(),
41+
body: ResBody::None,
42+
}
3643
}
3744
/// 设置响应状态
38-
pub fn set_status(&mut self, status: hyper::StatusCode) {
39-
*self.res.status_mut() = status;
45+
pub fn set_status(&mut self, status: StatusCode) {
46+
self.status_code = status;
4047
}
4148
/// 设置响应body
42-
pub fn set_body(mut self, body: ResBody) -> Self {
43-
*self.res.body_mut() = body;
44-
self
49+
pub fn set_body(&mut self, body: ResBody) {
50+
self.body = body;
4551
}
4652
/// 设置响应header
4753
pub fn set_header(
4854
mut self,
4955
key: hyper::header::HeaderName,
5056
value: hyper::header::HeaderValue,
5157
) -> Self {
52-
self.headers_mut().insert(key, value);
58+
self.headers.insert(key, value);
5359
self
5460
}
5561
/// 设置响应header
5662
pub fn set_typed_header<H>(&mut self, header: H)
5763
where
5864
H: Header,
5965
{
60-
self.headers_mut().typed_insert(header);
66+
self.headers.typed_insert(header);
6167
}
62-
}
6368

64-
impl<T: Into<Bytes>> From<T> for Response {
65-
fn from(chunk: T) -> Self {
66-
Self {
67-
res: HyperResponse::new(full(chunk)),
68-
}
69-
}
70-
}
69+
#[inline]
70+
pub(crate) fn into_hyper(self) -> hyper::Response<ResBody> {
71+
let Self {
72+
status_code,
73+
headers,
74+
body,
75+
} = self;
7176

72-
impl Deref for Response {
73-
type Target = HyperResponse<ResBody>;
77+
let mut res = hyper::Response::new(body);
78+
*res.headers_mut() = headers;
79+
// Default to a 404 if no response code was set
80+
*res.status_mut() = status_code;
7481

75-
fn deref(&self) -> &Self::Target {
76-
&self.res
82+
res
7783
}
7884
}
7985

80-
impl DerefMut for Response {
81-
fn deref_mut(&mut self) -> &mut Self::Target {
82-
&mut self.res
86+
impl<T: Into<Bytes>> From<T> for Response {
87+
fn from(chunk: T) -> Self {
88+
let mut res = Response::empty();
89+
res.set_body(full(chunk.into()));
90+
res
8391
}
8492
}

silent/src/handler/handler_wrapper_response.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,6 @@ mod tests {
7171
assert!(handler_wrapper.match_req(&req).await);
7272
let res = handler_wrapper.call(req).await;
7373
assert!(res.is_ok());
74-
assert_eq!(res.unwrap().status(), StatusCode::OK);
74+
assert_eq!(res.unwrap().status_code, StatusCode::OK);
7575
}
7676
}

silent/src/handler/handler_wrapper_static.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,9 @@ mod tests {
9898
req.set_path_params("path".to_owned(), PathParam::Path("index.html".to_string()));
9999
let mut res = handler.call(req).await.unwrap();
100100
clean_static(path);
101-
assert_eq!(res.status(), StatusCode::OK);
101+
assert_eq!(res.status_code, StatusCode::OK);
102102
assert_eq!(
103-
res.frame().await.unwrap().unwrap().data_ref().unwrap(),
103+
res.body.frame().await.unwrap().unwrap().data_ref().unwrap(),
104104
&Bytes::from(CONTENT)
105105
);
106106
}
@@ -114,9 +114,9 @@ mod tests {
114114
req.set_path_params("path".to_owned(), PathParam::Path("".to_string()));
115115
let mut res = handler.call(req).await.unwrap();
116116
clean_static(path);
117-
assert_eq!(res.status(), StatusCode::OK);
117+
assert_eq!(res.status_code, StatusCode::OK);
118118
assert_eq!(
119-
res.frame().await.unwrap().unwrap().data_ref().unwrap(),
119+
res.body.frame().await.unwrap().unwrap().data_ref().unwrap(),
120120
&Bytes::from(CONTENT)
121121
);
122122
}

silent/src/route/handler_match.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ mod tests {
236236
.handle(req, "127.0.0.1:8000".parse().unwrap())
237237
.await
238238
.unwrap()
239+
.body
239240
.frame()
240241
.await
241242
.unwrap()
@@ -260,6 +261,7 @@ mod tests {
260261
.handle(req, "127.0.0.1:8000".parse().unwrap())
261262
.await
262263
.unwrap()
264+
.body
263265
.frame()
264266
.await
265267
.unwrap()

silent/src/route/mod.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -137,14 +137,13 @@ impl Routes {
137137
}
138138
match handler.call(req).await {
139139
Ok(res) => {
140-
let (parts, body) = res.res.into_parts();
141-
let mut pre_res = pre_res.set_body(body);
142-
for (header_key, header_value) in parts.headers.into_iter() {
140+
for (header_key, header_value) in res.headers.clone().into_iter() {
143141
if let Some(key) = header_key {
144142
pre_res = pre_res.set_header(key, header_value);
145143
}
146144
}
147-
*pre_res.status_mut() = parts.status;
145+
pre_res.status_code = res.status_code;
146+
pre_res.set_body(res.body);
148147
for i in active_middlewares {
149148
if let Err(e) =
150149
route.middlewares[i].after_response(&mut pre_res).await
@@ -170,8 +169,8 @@ impl Routes {
170169
method,
171170
url,
172171
http_version,
173-
res.status(),
174-
res.headers().get(header::CONTENT_LENGTH),
172+
res.status_code,
173+
res.headers.get(header::CONTENT_LENGTH),
175174
req_time.num_nanoseconds().unwrap_or(0) as f64 / 1000000.0
176175
);
177176
Ok(res)
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
use crate::core::res_body::ResBody;
2+
use crate::route::Routes;
3+
use crate::{Request, Response};
4+
use hyper::body::Incoming;
5+
use hyper::service::Service as HyperService;
6+
use hyper::{Request as HyperRequest, Response as HyperResponse};
7+
use std::future::Future;
8+
use std::net::SocketAddr;
9+
use std::pin::Pin;
10+
11+
#[doc(hidden)]
12+
#[derive(Clone)]
13+
pub struct HyperHandler {
14+
pub(crate) remote_addr: SocketAddr,
15+
pub(crate) routes: Routes,
16+
}
17+
18+
impl HyperHandler {
19+
#[inline]
20+
pub fn new(remote_addr: SocketAddr, routes: Routes) -> Self {
21+
Self {
22+
remote_addr,
23+
routes,
24+
}
25+
}
26+
/// Handle [`Request`] and returns [`Response`].
27+
#[inline]
28+
pub fn handle(&self, req: Request) -> impl Future<Output = Response> {
29+
let mut response = Response::empty();
30+
let Self {
31+
remote_addr,
32+
routes,
33+
} = self.clone();
34+
async move {
35+
match routes.clone().handle(req, remote_addr).await {
36+
Ok(res) => {
37+
response.set_status(res.status_code);
38+
response.set_body(res.body);
39+
}
40+
Err((mes, code)) => {
41+
tracing::error!("Failed to handle request: {:?}", mes);
42+
response.set_body(mes.into());
43+
response.set_status(code);
44+
}
45+
}
46+
response
47+
}
48+
}
49+
}
50+
51+
impl HyperService<HyperRequest<Incoming>> for HyperHandler {
52+
type Response = HyperResponse<ResBody>;
53+
type Error = hyper::Error;
54+
type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send>>;
55+
56+
#[inline]
57+
fn call(&mut self, req: HyperRequest<Incoming>) -> Self::Future {
58+
let (parts, body) = req.into_parts();
59+
let req = HyperRequest::from_parts(parts, body.into()).into();
60+
let response = self.handle(req);
61+
Box::pin(async move { Ok(response.await.into_hyper()) })
62+
}
63+
}

silent/src/service/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
mod hyper_service;
12
mod serve;
23

34
use crate::conn::SilentConnection;

silent/src/service/serve.rs

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
use crate::conn::SilentConnection;
2-
use crate::core::res_body::ResBody;
3-
use crate::core::response::Response;
42
use crate::route::Routes;
5-
use hyper::body::Incoming;
6-
use hyper::service::service_fn;
7-
use hyper::{Request as HyperRequest, Response as HyperResponse};
3+
use crate::service::hyper_service::HyperHandler;
84
use std::net::SocketAddr;
95
use std::sync::Arc;
106
use tokio::net::TcpStream;
@@ -23,29 +19,10 @@ impl Serve {
2319
stream: TcpStream,
2420
peer_addr: SocketAddr,
2521
) -> Result<(), hyper::Error> {
26-
let service = service_fn(move |req| self.handle(req, peer_addr));
2722
self.conn
2823
.http1
29-
.serve_connection(stream, service)
24+
.serve_connection(stream, HyperHandler::new(peer_addr, self.routes.clone()))
3025
.with_upgrades()
3126
.await
3227
}
33-
34-
async fn handle(
35-
&self,
36-
req: HyperRequest<Incoming>,
37-
peer_addr: SocketAddr,
38-
) -> Result<HyperResponse<ResBody>, hyper::Error> {
39-
let (parts, body) = req.into_parts();
40-
let req = HyperRequest::from_parts(parts, body.into()).into();
41-
match self.routes.handle(req, peer_addr).await {
42-
Ok(res) => Ok(res.res),
43-
Err((mes, code)) => {
44-
tracing::error!("Failed to handle request: {:?}", mes);
45-
let mut res = Response::from(mes);
46-
res.set_status(code);
47-
Ok(res.res)
48-
}
49-
}
50-
}
5128
}

silent/src/ws/handler.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ pub fn websocket_handler(req: &Request) -> Result<Response> {
3030
});
3131
};
3232
res.set_status(StatusCode::SWITCHING_PROTOCOLS);
33-
res.headers_mut().typed_insert(Connection::upgrade());
34-
res.headers_mut().typed_insert(Upgrade::websocket());
35-
res.headers_mut()
33+
res.headers.typed_insert(Connection::upgrade());
34+
res.headers.typed_insert(Upgrade::websocket());
35+
res.headers
3636
.typed_insert(SecWebsocketAccept::from(sec_ws_key));
3737
Ok(res)
3838
}

0 commit comments

Comments
 (0)