Skip to content

Commit 50e0c7a

Browse files
authored
Merge pull request #58 from JEnoch/curl_client_issue
Fix read of response body for curl-client and add tests. #57
2 parents 749e374 + 4381236 commit 50e0c7a

File tree

3 files changed

+133
-3
lines changed

3 files changed

+133
-3
lines changed

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,4 +83,7 @@ portpicker = "0.1.0"
8383
tide = { version = "0.15.0" }
8484
tide-rustls = { version = "0.1.4" }
8585
tokio = { version = "0.2.21", features = ["macros"] }
86+
serde = "1.0"
8687
serde_json = "1.0"
88+
cfg-if = "0.1.10"
89+
mockito = "0.23.3"

src/isahc.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ impl HttpClient for IsahcClient {
3939
}
4040

4141
let body = req.take_body();
42-
4342
let body = match body.len() {
4443
Some(len) => isahc::Body::from_reader_sized(body, len as u64),
4544
None => isahc::Body::from_reader(body),
@@ -48,8 +47,7 @@ impl HttpClient for IsahcClient {
4847
let request = builder.body(body).unwrap();
4948
let res = self.0.send_async(request).await.map_err(Error::from)?;
5049
let (parts, body) = res.into_parts();
51-
let len = body.len().map(|len| len as usize);
52-
let body = Body::from_reader(BufReader::new(body), len);
50+
let body = Body::from_reader(BufReader::new(body), None);
5351
let mut response = http_types::Response::new(parts.status.as_u16());
5452
for (name, value) in &parts.headers {
5553
response.insert_header(name.as_str(), value.to_str().unwrap());

tests/test.rs

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
use mockito::mock;
2+
3+
use http_client::HttpClient;
4+
use http_types::{Body, Request, Response, Url};
5+
6+
use cfg_if::cfg_if;
7+
8+
cfg_if! {
9+
if #[cfg(feature = "curl_client")] {
10+
use http_client::isahc::IsahcClient as DefaultClient;
11+
} else if #[cfg(feature = "wasm_client")] {
12+
use http_client::wasm::WasmClient as DefaultClient;
13+
} else if #[cfg(any(feature = "h1_client", feature = "h1_client_rustls"))] {
14+
use http_client::h1::H1Client as DefaultClient;
15+
} else if #[cfg(feature = "hyper_client")] {
16+
use http_client::hyper::HyperClient as DefaultClient;
17+
}
18+
}
19+
20+
#[async_std::test]
21+
async fn post_json() -> Result<(), http_types::Error> {
22+
#[derive(serde::Deserialize, serde::Serialize)]
23+
struct Cat {
24+
name: String,
25+
}
26+
27+
let cat = Cat {
28+
name: "Chashu".to_string(),
29+
};
30+
31+
let m = mock("POST", "/")
32+
.with_status(200)
33+
.match_body(&serde_json::to_string(&cat)?[..])
34+
.with_body(&serde_json::to_string(&cat)?[..])
35+
.create();
36+
let mut req = Request::new(
37+
http_types::Method::Post,
38+
Url::parse(&mockito::server_url()).unwrap(),
39+
);
40+
req.append_header("Accept", "application/json");
41+
req.set_body(Body::from_json(&cat)?);
42+
let res: Response = DefaultClient::new().send(req).await?;
43+
m.assert();
44+
assert_eq!(res.status(), http_types::StatusCode::Ok);
45+
Ok(())
46+
}
47+
48+
#[async_std::test]
49+
async fn get_json() -> Result<(), http_types::Error> {
50+
#[derive(serde::Deserialize)]
51+
struct Message {
52+
message: String,
53+
}
54+
let m = mock("GET", "/")
55+
.with_status(200)
56+
.with_body(r#"{"message": "hello, world!"}"#)
57+
.create();
58+
let req = Request::new(
59+
http_types::Method::Get,
60+
Url::parse(&mockito::server_url()).unwrap(),
61+
);
62+
let mut res: Response = DefaultClient::new().send(req).await?;
63+
let msg: Message = serde_json::from_str(&res.body_string().await?)?;
64+
m.assert();
65+
assert_eq!(msg.message, "hello, world!");
66+
Ok(())
67+
}
68+
69+
#[async_std::test]
70+
async fn get_google() -> Result<(), http_types::Error> {
71+
let url = "https://www.google.com";
72+
let req = Request::new(http_types::Method::Get, Url::parse(url).unwrap());
73+
let mut res: Response = DefaultClient::new().send(req).await?;
74+
assert_eq!(res.status(), http_types::StatusCode::Ok);
75+
76+
let msg = res.body_bytes().await?;
77+
let msg = String::from_utf8_lossy(&msg);
78+
println!("recieved: '{}'", msg);
79+
assert!(msg.contains("<!doctype html>"));
80+
assert!(msg.contains("<title>Google</title>"));
81+
assert!(msg.contains("<head>"));
82+
assert!(msg.contains("</head>"));
83+
assert!(msg.contains("</script>"));
84+
assert!(msg.contains("</script>"));
85+
86+
assert!(msg.contains("<body"));
87+
assert!(msg.contains("</body>"));
88+
assert!(msg.contains("</html>"));
89+
90+
Ok(())
91+
}
92+
93+
#[async_std::test]
94+
async fn get_github() -> Result<(), http_types::Error> {
95+
let url = "https://raw.githubusercontent.com/http-rs/surf/6627d9fc15437aea3c0a69e0b620ae7769ea6765/LICENSE-MIT";
96+
let req = Request::new(http_types::Method::Get, Url::parse(url).unwrap());
97+
let mut res: Response = DefaultClient::new().send(req).await?;
98+
assert_eq!(res.status(), http_types::StatusCode::Ok, "{:?}", &res);
99+
100+
let msg = res.body_string().await?;
101+
102+
assert_eq!(
103+
msg,
104+
"The MIT License (MIT)
105+
106+
Copyright (c) 2019 Yoshua Wuyts
107+
108+
Permission is hereby granted, free of charge, to any person obtaining a copy
109+
of this software and associated documentation files (the \"Software\"), to deal
110+
in the Software without restriction, including without limitation the rights
111+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
112+
copies of the Software, and to permit persons to whom the Software is
113+
furnished to do so, subject to the following conditions:
114+
115+
The above copyright notice and this permission notice shall be included in all
116+
copies or substantial portions of the Software.
117+
118+
THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
119+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
120+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
121+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
122+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
123+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
124+
SOFTWARE.
125+
"
126+
);
127+
128+
Ok(())
129+
}

0 commit comments

Comments
 (0)