Skip to content

Commit e36ab16

Browse files
Update HttpStream
1 parent c960675 commit e36ab16

File tree

6 files changed

+54
-37
lines changed

6 files changed

+54
-37
lines changed

crates/http/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,6 @@ url = { package = "url-utils", version = ">=0.1.0", path = "../url" }
2020
package = "builders"
2121
default-features = false
2222
features = ["builder"]
23-
version = ">=0.1.0"
23+
version = ">=0.5.0"
2424
git = "https://github.com/saulvaldelvira/builders"
2525

crates/http/src/request/mod.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::{
55
collections::HashMap,
66
env,
77
ffi::OsStr,
8-
io::{BufReader, Read, Write},
8+
io::{BufRead, BufReader, Read, Write},
99
path::Path,
1010
};
1111

@@ -43,20 +43,21 @@ impl HttpRequest {
4343
let stream = BufReader::new(stream.into());
4444
parse_request(stream)
4545
}
46+
4647
#[inline]
4748
pub fn keep_alive(self) -> Result<Self> {
4849
let mut req = parse_request(self.stream)?;
4950
req.set_header("Connection", "keep-alive");
5051
Ok(req)
5152
}
53+
5254
#[inline]
53-
#[must_use]
5455
pub fn stream(&self) -> &HttpStream {
5556
self.stream.get_ref()
5657
}
58+
5759
/// Url of the request
5860
#[inline]
59-
#[must_use]
6061
pub fn url(&self) -> &str {
6162
&self.url
6263
}
@@ -230,8 +231,8 @@ impl HttpRequest {
230231
/// [`stream`]'s availability
231232
///
232233
/// [`stream`]: HttpStream
233-
pub fn has_body(&self) -> Result<bool> {
234-
Ok(self.body.is_some() || self.stream.get_ref().is_ready()?)
234+
pub fn has_body(&mut self) -> Result<bool> {
235+
Ok(self.body.is_some() || !self.stream.fill_buf()?.is_empty())
235236
}
236237

237238
/// Reads the request body into [writer](Write)

crates/http/src/response/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::{
22
collections::HashMap,
3-
io::{self, BufReader, Read, Write},
3+
io::{self, BufRead, BufReader, Read, Write},
44
};
55

66
use builders::Builder;
@@ -115,8 +115,8 @@ impl HttpResponse {
115115
/// [`stream`]'s availability
116116
///
117117
/// [`stream`]: HttpStream
118-
pub fn has_body(&self) -> Result<bool> {
119-
Ok(self.stream.get_ref().is_ready()?)
118+
pub fn has_body(&mut self) -> Result<bool> {
119+
Ok(self.body.is_some() || !self.stream.fill_buf()?.is_empty())
120120
}
121121

122122
/// Reads the response's body into [writer](Write)

crates/http/src/stream.rs

Lines changed: 38 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1+
use core::fmt;
12
use std::{
2-
cmp::min,
33
io::{self, Read, Write},
44
net::TcpStream,
55
time::Duration,
66
};
77

8+
pub trait ReadWrite: Read + Write {}
9+
impl<T: Read + Write> ReadWrite for T {}
10+
811
#[derive(Debug)]
912
struct StringStream(Vec<u8>, usize);
1013

@@ -27,24 +30,31 @@ impl Read for StringStream {
2730
}
2831

2932
impl StringStream {
30-
fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
31-
if buf.is_empty() || self.1 >= self.0.len() {
32-
return Ok(0);
33-
}
34-
let src = &self.0[self.1..];
35-
let n = min(buf.len(), src.len());
36-
buf[..n].copy_from_slice(src);
37-
Ok(n)
33+
pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
34+
let min = usize::min(buf.len(), self.0.len() - self.1);
35+
buf[..min].copy_from_slice(&self.0[self.1..self.1 + min]);
36+
Ok(min)
3837
}
3938
}
4039

41-
#[derive(Debug)]
4240
enum HttpStreamInner {
4341
Tcp(TcpStream),
4442
String(StringStream, Vec<u8>),
43+
Dyn(Box<dyn ReadWrite>),
4544
Dummy,
4645
}
4746

47+
impl fmt::Debug for HttpStreamInner {
48+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
49+
match self {
50+
Self::Tcp(arg0) => f.debug_tuple("Tcp").field(arg0).finish(),
51+
Self::String(arg0, arg1) => f.debug_tuple("String").field(arg0).field(arg1).finish(),
52+
Self::Dyn(_) => write!(f, "Dyn"),
53+
Self::Dummy => write!(f, "Dummy"),
54+
}
55+
}
56+
}
57+
4858
/// Holds a "stream" for a [`request`]
4959
/// This is an object where the http request can read and write to.
5060
///
@@ -86,32 +96,27 @@ impl HttpStream {
8696
pub fn set_read_timeout(&self, d: Option<Duration>) -> io::Result<()> {
8797
match &self.inner {
8898
HttpStreamInner::Tcp(tcp_stream) => tcp_stream.set_read_timeout(d),
89-
HttpStreamInner::Dummy | HttpStreamInner::String(..) => Ok(()),
99+
HttpStreamInner::Dyn(_) | HttpStreamInner::Dummy | HttpStreamInner::String(..) => {
100+
Ok(())
101+
}
90102
}
91103
}
92-
pub fn peek(&self, buf: &mut [u8]) -> std::io::Result<usize> {
104+
105+
pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
93106
match &self.inner {
94-
HttpStreamInner::Tcp(tcp_stream) => tcp_stream.peek(buf),
95-
HttpStreamInner::Dummy => Ok(0),
96-
HttpStreamInner::String(read, _) => read.peek(buf),
107+
HttpStreamInner::Tcp(tcp) => tcp.peek(buf),
108+
HttpStreamInner::String(input, _) => input.peek(buf),
109+
HttpStreamInner::Dyn(_) | HttpStreamInner::Dummy => Ok(0),
97110
}
98111
}
99-
pub fn is_ready(&self) -> std::io::Result<bool> {
100-
let mut buf = [0_u8; 1];
101-
let n = match &self.inner {
102-
HttpStreamInner::Tcp(tcp_stream) => tcp_stream.peek(&mut buf)?,
103-
HttpStreamInner::String(string_stream, _) => string_stream.peek(&mut buf)?,
104-
HttpStreamInner::Dummy => 0,
105-
};
106-
Ok(n > 0)
107-
}
108112
}
109113

110114
impl Read for HttpStream {
111115
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
112116
match &mut self.inner {
113117
HttpStreamInner::Tcp(tcp_stream) => tcp_stream.read(buf),
114118
HttpStreamInner::Dummy => Ok(0),
119+
HttpStreamInner::Dyn(d) => d.read(buf),
115120
HttpStreamInner::String(buf_reader, _) => buf_reader.read(buf),
116121
}
117122
}
@@ -122,13 +127,15 @@ impl Write for HttpStream {
122127
match &mut self.inner {
123128
HttpStreamInner::Tcp(tcp_stream) => tcp_stream.write(buf),
124129
HttpStreamInner::Dummy => Ok(0),
130+
HttpStreamInner::Dyn(d) => d.write(buf),
125131
HttpStreamInner::String(_, w) => w.write(buf),
126132
}
127133
}
128134

129135
fn flush(&mut self) -> std::io::Result<()> {
130136
match &mut self.inner {
131137
HttpStreamInner::Tcp(tcp_stream) => tcp_stream.flush(),
138+
HttpStreamInner::Dyn(d) => d.flush(),
132139
HttpStreamInner::Dummy | HttpStreamInner::String(..) => Ok(()),
133140
}
134141
}
@@ -165,4 +172,11 @@ impl HttpStream {
165172
inner: HttpStreamInner::Dummy,
166173
}
167174
}
175+
176+
#[must_use]
177+
pub fn from_boxed_dyn(d: Box<dyn ReadWrite>) -> Self {
178+
Self {
179+
inner: HttpStreamInner::Dyn(d),
180+
}
181+
}
168182
}

crates/server/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
name = "http-srv"
33
description = "Http Server"
44
authors = ["Saúl Valdelvira <saul@saulv.es>"]
5-
version = "0.7.0"
5+
version = "0.8.0"
66
edition = "2024"
77
license = "GPL-3.0-only"
88
readme = "README"
@@ -12,7 +12,7 @@ repository = "https://github.com/saulvaldelvira/http-server"
1212
http.workspace = true
1313
mime = { package = "rmime", version = ">=0.1.0", path = "../mime" }
1414
regexpr = { version = ">=0.3.3", git = "https://github.com/saulvaldelvira/regexpr", optional = true }
15-
pool = { package = "job-pool", version = ">=0.1.0", git = "https://github.com/saulvaldelvira/job-pool" }
15+
pool = { package = "job-pool", version = ">=0.4.0", git = "https://github.com/saulvaldelvira/job-pool" }
1616
jsonrs = { package = "jsonrs", version = ">=0.1.4", git = "https://github.com/saulvaldelvira/json.rs" }
1717
delay_init = { package = "delay_init" , version = ">=0.2.0", git = "https://github.com/saulvaldelvira/delay-init" }
1818
base64 = { package = "rb64", version = ">=0.1.0", git = "https://github.com/saulvaldelvira/rb64" }

crates/server/src/config.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ fn get_default_conf_file() -> Option<PathBuf> {
6060
///
6161
/// let pool_conf = PoolConfig::builder()
6262
/// .n_workers(120_u16)
63-
/// .build().unwrap();
63+
/// .build();
6464
/// let conf =
6565
/// ServerConfig::default()
6666
/// .port(8080)
@@ -117,7 +117,7 @@ impl ServerConfig {
117117
match arg.as_ref() {
118118
"-p" | "--port" => conf.port = parse_next!(),
119119
"-n" | "-n-workers" => {
120-
pool_conf_builder.n_workers(parse_next!(as u16));
120+
pool_conf_builder.set_n_workers(parse_next!(as u16));
121121
}
122122
"-d" | "--dir" => {
123123
let path: String = parse_next!();
@@ -140,6 +140,8 @@ impl ServerConfig {
140140
"-h" | "--help" => help(),
141141
unknown => return Err(format!("Unknow argument: {unknown}").into()),
142142
}
143+
144+
conf.pool_conf = pool_conf_builder.build();
143145
}
144146

145147
log_info!("{conf:#?}");

0 commit comments

Comments
 (0)