1 #![cfg(not(target_arch = "wasm32"))]
2 mod support;
3 use futures_util::stream::StreamExt;
4 use support::*;
5
6 #[tokio::test]
text_part()7 async fn text_part() {
8 let _ = env_logger::try_init();
9
10 let form = reqwest::multipart::Form::new().text("foo", "bar");
11
12 let expected_body = format!(
13 "\
14 --{0}\r\n\
15 Content-Disposition: form-data; name=\"foo\"\r\n\r\n\
16 bar\r\n\
17 --{0}--\r\n\
18 ",
19 form.boundary()
20 );
21
22 let ct = format!("multipart/form-data; boundary={}", form.boundary());
23
24 let server = server::http(move |mut req| {
25 let ct = ct.clone();
26 let expected_body = expected_body.clone();
27 async move {
28 assert_eq!(req.method(), "POST");
29 assert_eq!(req.headers()["content-type"], ct);
30 assert_eq!(
31 req.headers()["content-length"],
32 expected_body.len().to_string()
33 );
34
35 let mut full: Vec<u8> = Vec::new();
36 while let Some(item) = req.body_mut().next().await {
37 full.extend(&*item.unwrap());
38 }
39
40 assert_eq!(full, expected_body.as_bytes());
41
42 http::Response::default()
43 }
44 });
45
46 let url = format!("http://{}/multipart/1", server.addr());
47
48 let res = reqwest::Client::new()
49 .post(&url)
50 .multipart(form)
51 .send()
52 .await
53 .unwrap();
54
55 assert_eq!(res.url().as_str(), &url);
56 assert_eq!(res.status(), reqwest::StatusCode::OK);
57 }
58
59 #[cfg(feature = "stream")]
60 #[tokio::test]
stream_part()61 async fn stream_part() {
62 use futures_util::{future, stream};
63
64 let _ = env_logger::try_init();
65
66 let stream = reqwest::Body::wrap_stream(stream::once(future::ready(Ok::<_, reqwest::Error>(
67 "part1 part2".to_owned(),
68 ))));
69 let part = reqwest::multipart::Part::stream(stream);
70
71 let form = reqwest::multipart::Form::new()
72 .text("foo", "bar")
73 .part("part_stream", part);
74
75 let expected_body = format!(
76 "\
77 --{0}\r\n\
78 Content-Disposition: form-data; name=\"foo\"\r\n\
79 \r\n\
80 bar\r\n\
81 --{0}\r\n\
82 Content-Disposition: form-data; name=\"part_stream\"\r\n\
83 \r\n\
84 part1 part2\r\n\
85 --{0}--\r\n\
86 ",
87 form.boundary()
88 );
89
90 let ct = format!("multipart/form-data; boundary={}", form.boundary());
91
92 let server = server::http(move |mut req| {
93 let ct = ct.clone();
94 let expected_body = expected_body.clone();
95 async move {
96 assert_eq!(req.method(), "POST");
97 assert_eq!(req.headers()["content-type"], ct);
98 assert_eq!(req.headers()["transfer-encoding"], "chunked");
99
100 let mut full: Vec<u8> = Vec::new();
101 while let Some(item) = req.body_mut().next().await {
102 full.extend(&*item.unwrap());
103 }
104
105 assert_eq!(full, expected_body.as_bytes());
106
107 http::Response::default()
108 }
109 });
110
111 let url = format!("http://{}/multipart/1", server.addr());
112
113 let client = reqwest::Client::new();
114
115 let res = client
116 .post(&url)
117 .multipart(form)
118 .send()
119 .await
120 .expect("Failed to post multipart");
121 assert_eq!(res.url().as_str(), &url);
122 assert_eq!(res.status(), reqwest::StatusCode::OK);
123 }
124
125 #[cfg(feature = "blocking")]
126 #[test]
blocking_file_part()127 fn blocking_file_part() {
128 let _ = env_logger::try_init();
129
130 let form = reqwest::blocking::multipart::Form::new()
131 .file("foo", "Cargo.lock")
132 .unwrap();
133
134 let fcontents = std::fs::read_to_string("Cargo.lock").unwrap();
135
136 let expected_body = format!(
137 "\
138 --{0}\r\n\
139 Content-Disposition: form-data; name=\"foo\"; filename=\"Cargo.lock\"\r\n\
140 Content-Type: application/octet-stream\r\n\r\n\
141 {1}\r\n\
142 --{0}--\r\n\
143 ",
144 form.boundary(),
145 fcontents
146 );
147
148 let ct = format!("multipart/form-data; boundary={}", form.boundary());
149
150 let server = server::http(move |mut req| {
151 let ct = ct.clone();
152 let expected_body = expected_body.clone();
153 async move {
154 assert_eq!(req.method(), "POST");
155 assert_eq!(req.headers()["content-type"], ct);
156 // files know their exact size
157 assert_eq!(
158 req.headers()["content-length"],
159 expected_body.len().to_string()
160 );
161
162 let mut full: Vec<u8> = Vec::new();
163 while let Some(item) = req.body_mut().next().await {
164 full.extend(&*item.unwrap());
165 }
166
167 assert_eq!(full, expected_body.as_bytes());
168
169 http::Response::default()
170 }
171 });
172
173 let url = format!("http://{}/multipart/2", server.addr());
174
175 let res = reqwest::blocking::Client::new()
176 .post(&url)
177 .multipart(form)
178 .send()
179 .unwrap();
180
181 assert_eq!(res.url().as_str(), &url);
182 assert_eq!(res.status(), reqwest::StatusCode::OK);
183 }
184