Skip to content

Commit c3fc1a8

Browse files
committed
Optimize: send method reduces overhead of creating new copy of string
1 parent 8127c5e commit c3fc1a8

2 files changed

Lines changed: 42 additions & 8 deletions

File tree

src/http/response.rs

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
use super::StatusCode;
2-
use std::fmt::{Display, Formatter, Result as FmtResult};
2+
use std::{
3+
fmt::{Display, Formatter, Result as FmtResult},
4+
io::{Result as IoResult, Write},
5+
};
36

47
#[derive(Debug)]
58
pub struct Response {
@@ -11,17 +14,50 @@ impl Response {
1114
pub fn new(status_code: StatusCode, body: Option<String>) -> Self {
1215
Self { status_code, body }
1316
}
14-
}
1517

16-
impl Display for Response {
17-
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
18+
/// Sends the response to the client, without creating a new string.
19+
/// This method invokes write! macro directly passing its internal data, instead of returning a copy of the response string.
20+
///
21+
/// # Note
22+
///
23+
/// This method is more efficient than using `Display` because it avoids the overhead of creating a new string.
24+
/// Especially when the response body is large (e.g. HTML pages with megabytes size of HTML content).
25+
///
26+
/// # Example
27+
///
28+
/// ```
29+
/// let response = Response::new(StatusCode::Ok, Some("Hello".to_string()));
30+
/// response.send(&mut stream);
31+
/// ```
32+
///
33+
/// # Arguments
34+
///
35+
/// * `stream` - The stream to write the response to.
36+
///
37+
/// # Returns
38+
/// * `IoResult<()>` - The result of the write operation.
39+
pub fn send(&self, stream: &mut impl Write) -> IoResult<()> {
1840
let body = self.body.as_deref().unwrap_or("");
1941
write!(
20-
f,
42+
stream,
2143
"HTTP/1.1 {} {}\r\n\r\n{}",
2244
self.status_code,
2345
self.status_code.reason_phrase(),
2446
body
2547
)
2648
}
2749
}
50+
51+
// DEPRECATED: use `Response::send` instead
52+
// impl Display for Response {
53+
// fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
54+
// let body = self.body.as_deref().unwrap_or("");
55+
// write!(
56+
// f,
57+
// "HTTP/1.1 {} {}\r\n\r\n{}",
58+
// self.status_code,
59+
// self.status_code.reason_phrase(),
60+
// body
61+
// )
62+
// }
63+
// }

src/server.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,7 @@ impl Server {
6363
Some(DEFAULT_BODY.to_string()),
6464
);
6565
// Write the response to the client
66-
if let Err(e) =
67-
sock_stream.write_all(response.to_string().as_bytes())
68-
{
66+
if let Err(e) = response.send(&mut sock_stream) {
6967
// If there's an error writing to the client, print the error
7068
println!(
7169
"========== Error: Failed to write response to client ==========\n{}",

0 commit comments

Comments
 (0)