Skip to content

Commit 63e97d3

Browse files
committed
client: encode -> Encoder::encode
1 parent 88a3399 commit 63e97d3

File tree

2 files changed

+65
-71
lines changed

2 files changed

+65
-71
lines changed

src/client/encode.rs

Lines changed: 63 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -8,69 +8,6 @@ use std::pin::Pin;
88

99
use crate::date::fmt_http_date;
1010

11-
/// Encode an HTTP request on the client.
12-
#[doc(hidden)]
13-
pub async fn encode(req: Request) -> http_types::Result<Encoder> {
14-
let mut buf: Vec<u8> = vec![];
15-
16-
let mut url = req.url().path().to_owned();
17-
if let Some(fragment) = req.url().fragment() {
18-
url.push('#');
19-
url.push_str(fragment);
20-
}
21-
if let Some(query) = req.url().query() {
22-
url.push('?');
23-
url.push_str(query);
24-
}
25-
26-
let val = format!("{} {} HTTP/1.1\r\n", req.method(), url);
27-
log::trace!("> {}", &val);
28-
buf.write_all(val.as_bytes()).await?;
29-
30-
// Insert Host header
31-
// Insert host
32-
let host = req.url().host_str();
33-
let host = host.ok_or_else(|| format_err!("Missing hostname"))?;
34-
let val = if let Some(port) = req.url().port() {
35-
format!("host: {}:{}\r\n", host, port)
36-
} else {
37-
format!("host: {}\r\n", host)
38-
};
39-
40-
log::trace!("> {}", &val);
41-
buf.write_all(val.as_bytes()).await?;
42-
43-
// If the body isn't streaming, we can set the content-length ahead of time. Else we need to
44-
// send all items in chunks.
45-
if let Some(len) = req.len() {
46-
let val = format!("content-length: {}\r\n", len);
47-
log::trace!("> {}", &val);
48-
buf.write_all(val.as_bytes()).await?;
49-
} else {
50-
// write!(&mut buf, "Transfer-Encoding: chunked\r\n")?;
51-
panic!("chunked encoding is not implemented yet");
52-
// See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Transfer-Encoding
53-
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Trailer
54-
}
55-
56-
let date = fmt_http_date(std::time::SystemTime::now());
57-
buf.write_all(b"date: ").await?;
58-
buf.write_all(date.as_bytes()).await?;
59-
buf.write_all(b"\r\n").await?;
60-
61-
for (header, values) in req.iter() {
62-
for value in values.iter() {
63-
let val = format!("{}: {}\r\n", header, value);
64-
log::trace!("> {}", &val);
65-
buf.write_all(val.as_bytes()).await?;
66-
}
67-
}
68-
69-
buf.write_all(b"\r\n").await?;
70-
71-
Ok(Encoder::new(buf, req))
72-
}
73-
7411
/// An HTTP encoder.
7512
#[doc(hidden)]
7613
#[derive(Debug)]
@@ -90,16 +27,73 @@ pub struct Encoder {
9027
}
9128

9229
impl Encoder {
93-
/// Create a new instance.
94-
pub(crate) fn new(headers: Vec<u8>, request: Request) -> Self {
95-
Self {
96-
request,
97-
headers,
30+
/// Encode an HTTP request on the client.
31+
pub async fn encode(req: Request) -> http_types::Result<Self> {
32+
let mut buf: Vec<u8> = vec![];
33+
34+
let mut url = req.url().path().to_owned();
35+
if let Some(fragment) = req.url().fragment() {
36+
url.push('#');
37+
url.push_str(fragment);
38+
}
39+
if let Some(query) = req.url().query() {
40+
url.push('?');
41+
url.push_str(query);
42+
}
43+
44+
let val = format!("{} {} HTTP/1.1\r\n", req.method(), url);
45+
log::trace!("> {}", &val);
46+
buf.write_all(val.as_bytes()).await?;
47+
48+
// Insert Host header
49+
// Insert host
50+
let host = req.url().host_str();
51+
let host = host.ok_or_else(|| format_err!("Missing hostname"))?;
52+
let val = if let Some(port) = req.url().port() {
53+
format!("host: {}:{}\r\n", host, port)
54+
} else {
55+
format!("host: {}\r\n", host)
56+
};
57+
58+
log::trace!("> {}", &val);
59+
buf.write_all(val.as_bytes()).await?;
60+
61+
// If the body isn't streaming, we can set the content-length ahead of time. Else we need to
62+
// send all items in chunks.
63+
if let Some(len) = req.len() {
64+
let val = format!("content-length: {}\r\n", len);
65+
log::trace!("> {}", &val);
66+
buf.write_all(val.as_bytes()).await?;
67+
} else {
68+
// write!(&mut buf, "Transfer-Encoding: chunked\r\n")?;
69+
panic!("chunked encoding is not implemented yet");
70+
// See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Transfer-Encoding
71+
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Trailer
72+
}
73+
74+
let date = fmt_http_date(std::time::SystemTime::now());
75+
buf.write_all(b"date: ").await?;
76+
buf.write_all(date.as_bytes()).await?;
77+
buf.write_all(b"\r\n").await?;
78+
79+
for (header, values) in req.iter() {
80+
for value in values.iter() {
81+
let val = format!("{}: {}\r\n", header, value);
82+
log::trace!("> {}", &val);
83+
buf.write_all(val.as_bytes()).await?;
84+
}
85+
}
86+
87+
buf.write_all(b"\r\n").await?;
88+
89+
Ok(Self {
90+
request: req,
91+
headers: buf,
9892
cursor: 0,
9993
headers_done: false,
10094
body_done: false,
10195
body_bytes_read: 0,
102-
}
96+
})
10397
}
10498
}
10599

src/client/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@ mod decode;
77
mod encode;
88

99
pub use decode::decode;
10-
pub use encode::encode;
10+
pub use encode::Encoder;
1111

1212
/// Opens an HTTP/1.1 connection to a remote host.
1313
pub async fn connect<RW>(mut stream: RW, req: Request) -> http_types::Result<Response>
1414
where
1515
RW: Read + Write + Send + Sync + Unpin + 'static,
1616
{
17-
let mut req = encode(req).await?;
17+
let mut req = Encoder::encode(req).await?;
1818
log::trace!("> {:?}", &req);
1919

2020
io::copy(&mut req, &mut stream).await?;

0 commit comments

Comments
 (0)