Skip to content

Commit 6b2a73e

Browse files
author
jayjamesjay
authored
Merge pull request #19 from jayjamesjay/v0.5.0
V0.5.0
2 parents 38e2c25 + a9e101c commit 6b2a73e

File tree

9 files changed

+236
-216
lines changed

9 files changed

+236
-216
lines changed

Cargo.lock

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "http_req"
3-
version = "0.4.11"
3+
version = "0.5.0"
44
license = "MIT"
55
description = "simple and lightweight HTTP client with built-in HTTPS support"
66
repository = "https://github.com/jayjamesjay/http_req"
@@ -11,7 +11,7 @@ keywords = ["http", "client", "request"]
1111
edition = "2018"
1212

1313
[dependencies]
14-
unicase = "^2.3"
14+
unicase = "^2.4"
1515

1616
[features]
1717
default = ["native-tls"]

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# http_req
22
[![Build Status](https://travis-ci.org/jayjamesjay/http_req.svg?branch=master)](https://travis-ci.org/jayjamesjay/http_req)
3-
[![Crates.io](https://img.shields.io/badge/crates.io-v0.4.11-orange.svg?longCache=true)](https://crates.io/crates/http_req)
4-
[![Docs.rs](https://docs.rs/http_req/badge.svg)](https://docs.rs/http_req/0.4.11/http_req/)
3+
[![Crates.io](https://img.shields.io/badge/crates.io-v0.5.0-orange.svg?longCache=true)](https://crates.io/crates/http_req)
4+
[![Docs.rs](https://docs.rs/http_req/badge.svg)](https://docs.rs/http_req/0.5.0/http_req/)
55

66
Simple and lightweight HTTP client with built-in HTTPS support.
77
Currently it's in heavy development and may frequently change.
@@ -28,7 +28,7 @@ fn main() {
2828
In order to use `http_req` with `rustls` in your project, add following lines to `Cargo.toml`:
2929
```toml
3030
[dependencies]
31-
http_req = {version="^0.4", default-features = false, features = ["rust-tls"]}
31+
http_req = {version="^0.5", default-features = false, features = ["rust-tls"]}
3232
```
3333

3434
## License

benches/res.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2060,4 +2060,4 @@ repeated concatenation.</p>
20602060
</div><h4 id='method.clone_into' class="method"><span id='clone_into.v' class='invisible'><table class='table-display'><tbody><tr><td><code>fn <a href='../../std/borrow/trait.ToOwned.html#method.clone_into' class='fnname'>clone_into</a>(&amp;self, target: <a class="primitive" href="../primitive.reference.html">&amp;mut </a>T)</code></span></td><td><span class='out-of-band'><div class='ghost'></div><a class='srclink' href='../../src/alloc/borrow.rs.html#98-100' title='goto source code'>[src]</a></td></tr></tbody></table></span></h4><div class='stability'><div class='stab unstable'><details><summary><span class=microscope>🔬</span> This is a nightly-only experimental API. (<code>toowned_clone_into </code><a href="https://github.com/rust-lang/rust/issues/41263">#41263</a>)</summary><p>recently added</p>
20612061
</details></div></div><div class='docblock'><p>Uses borrowed data to replace owned data, usually by cloning. <a href="../../std/borrow/trait.ToOwned.html#method.clone_into">Read more</a></p>
20622062
</div></div><h3 id='impl-ToString-1' class='impl'><span class='in-band'><table class='table-display'><tbody><tr><td><code>impl&lt;T&gt; <a class="trait" href="../../std/string/trait.ToString.html" title="trait std::string::ToString">ToString</a> for T <span class="where fmt-newline">where<br>&nbsp;&nbsp;&nbsp;&nbsp;T: <a class="trait" href="../../std/fmt/trait.Display.html" title="trait std::fmt::Display">Display</a> + ?<a class="trait" href="../../std/marker/trait.Sized.html" title="trait std::marker::Sized">Sized</a>,&nbsp;</span></code><a href='#impl-ToString-1' class='anchor'></a></span></td><td><span class='out-of-band'><div class='ghost'></div><a class='srclink' href='../../src/alloc/string.rs.html#2145-2155' title='goto source code'>[src]</a></span></td></tr></tbody></table></h3><div class='impl-items'><h4 id='method.to_string-1' class="method"><span id='to_string.v-1' class='invisible'><table class='table-display'><tbody><tr><td><code>fn <a href='../../std/string/trait.ToString.html#tymethod.to_string' class='fnname'>to_string</a>(&amp;self) -&gt; <a class="struct" href="../../std/string/struct.String.html" title="struct std::string::String">String</a></code></span></td><td><span class='out-of-band'><div class='ghost'></div><a class='srclink' href='../../src/alloc/string.rs.html#2147-2154' title='goto source code'>[src]</a></td></tr></tbody></table></span></h4><div class='docblock'><p>Converts the given value to a <code>String</code>. <a href="../../std/string/trait.ToString.html#tymethod.to_string">Read more</a></p>
2063-
</div></div></div></section><section id="search" class="content hidden"></section><section class="footer"></section><aside id="help" class="hidden"><div><h1 class="hidden">Help</h1><div class="shortcuts"><h2>Keyboard Shortcuts</h2><dl><dt><kbd>?</kbd></dt><dd>Show this help dialog</dd><dt><kbd>S</kbd></dt><dd>Focus the search field</dd><dt><kbd>↑</kbd></dt><dd>Move up in search results</dd><dt><kbd>↓</kbd></dt><dd>Move down in search results</dd><dt><kbd>↹</kbd></dt><dd>Switch tab</dd><dt><kbd>&#9166;</kbd></dt><dd>Go to active search result</dd><dt><kbd>+</kbd></dt><dd>Expand all sections</dd><dt><kbd>-</kbd></dt><dd>Collapse all sections</dd></dl></div><div class="infos"><h2>Search Tricks</h2><p>Prefix searches with a type followed by a colon (e.g. <code>fn:</code>) to restrict the search to a given type.</p><p>Accepted types are: <code>fn</code>, <code>mod</code>, <code>struct</code>, <code>enum</code>, <code>trait</code>, <code>type</code>, <code>macro</code>, and <code>const</code>.</p><p>Search functions by type signature (e.g. <code>vec -> usize</code> or <code>* -> vec</code>)</p><p>Search multiple things at once by splitting your query with comma (e.g. <code>str,u8</code> or <code>String,struct:Vec,test</code>)</p></div></div></aside><script>window.rootPath = "../../";window.currentCrate = "std";</script><script src="../../aliases.js"></script><script src="../../main.js"></script><script defer src="../../search-index.js"></script></body></html>
2063+
</div></div></div></section><section id="search" class="content hidden"></section><section class="footer"></section><aside id="help" class="hidden"><div><h1 class="hidden">Help</h1><div class="shortcuts"><h2>Keyboard Shortcuts</h2><dl><dt><kbd>?</kbd></dt><dd>Show this help dialog</dd><dt><kbd>S</kbd></dt><dd>Focus the search field</dd><dt><kbd>↑</kbd></dt><dd>Move up in search results</dd><dt><kbd>↓</kbd></dt><dd>Move down in search results</dd><dt><kbd>↹</kbd></dt><dd>Switch tab</dd><dt><kbd>&#9166;</kbd></dt><dd>Go to active search result</dd><dt><kbd>+</kbd></dt><dd>Expand all sections</dd><dt><kbd>-</kbd></dt><dd>Collapse all sections</dd></dl></div><div class="infos"><h2>Search Tricks</h2><p>Prefix searches with a type followed by a colon (e.g. <code>fn:</code>) to restrict the search to a given type.</p><p>Accepted types are: <code>fn</code>, <code>mod</code>, <code>struct</code>, <code>enum</code>, <code>trait</code>, <code>type</code>, <code>macro</code>, and <code>const</code>.</p><p>Search functions by type signature (e.g. <code>vec -> usize</code> or <code>* -> vec</code>)</p><p>Search multiple things at once by splitting your query with comma (e.g. <code>str,u8</code> or <code>String,struct:Vec,test</code>)</p></div></div></aside><script>window.rootPath = "../../";window.currentCrate = "std";</script><script src="../../aliases.js"></script><script src="../../main.js"></script><script defer src="../../search-index.js"></script></body></html>

examples/get.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@ fn main() {
55
let res = request::get("https://doc.rust-lang.org/", &mut writer).unwrap();
66

77
println!("Status: {} {}", res.status_code(), res.reason());
8-
println!("{:?}", res.headers());
8+
println!("Headers {}", res.headers());
99
//println!("{}", String::from_utf8_lossy(&writer));
1010
}

src/error.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@ use std::{error::Error as StdErr, fmt, io, num, str};
55
pub enum ParseErr {
66
Utf8(str::Utf8Error),
77
Int(num::ParseIntError),
8-
Empty,
8+
StatusErr,
9+
HeadersErr,
10+
UriErr,
911
Invalid,
12+
Empty,
1013
}
1114

1215
impl fmt::Display for ParseErr {
@@ -22,8 +25,11 @@ impl StdErr for ParseErr {
2225
match self {
2326
Utf8(_) => "invalid character",
2427
Int(_) => "cannot parse number",
25-
Empty => "nothing to parse",
2628
Invalid => "invalid value",
29+
Empty => "nothing to parse",
30+
StatusErr => "status line contains invalid values",
31+
HeadersErr => "headers contain invalid values",
32+
UriErr => "uri contains invalid characters",
2733
}
2834
}
2935
}

src/request.rs

Lines changed: 3 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ where
4545
}
4646

4747
///HTTP request methods
48-
#[derive(Debug, PartialEq, Clone)]
48+
#[derive(Debug, PartialEq, Clone, Copy)]
4949
pub enum Method {
5050
GET,
5151
HEAD,
@@ -112,7 +112,7 @@ impl<'a> RequestBuilder<'a> {
112112
///Creates new `RequestBuilder` with default parameters
113113
pub fn new(uri: &'a Uri) -> RequestBuilder<'a> {
114114
RequestBuilder {
115-
headers: Headers::default_http(&uri),
115+
headers: Headers::default_http(uri),
116116
uri,
117117
method: Method::GET,
118118
version: HTTP_V,
@@ -284,7 +284,6 @@ impl<'a> Request<'a> {
284284
U: ToString + ?Sized,
285285
{
286286
self.inner.header(key, val);
287-
288287
self
289288
}
290289

@@ -294,18 +293,9 @@ impl<'a> Request<'a> {
294293
Method: From<T>,
295294
{
296295
self.inner.method(method);
297-
298296
self
299297
}
300298

301-
#[deprecated(note = "Please use method instead")]
302-
pub fn set_method<T>(&mut self, method: T)
303-
where
304-
Method: From<T>,
305-
{
306-
self.inner.method(method);
307-
}
308-
309299
///Sets body for request
310300
pub fn body(&mut self, body: &'a [u8]) -> &mut Self {
311301
self.inner.body(body);
@@ -330,11 +320,6 @@ impl<'a> Request<'a> {
330320
self
331321
}
332322

333-
#[deprecated(note = "Please use the read_timeout instead")]
334-
pub fn set_connect_timeout(&mut self, timeout: Option<Duration>) -> &mut Self {
335-
self.connect_timeout(timeout)
336-
}
337-
338323
///Sets read timeout on internal `TcpStream` instance
339324
///
340325
///`timeout` will be passed to
@@ -349,11 +334,6 @@ impl<'a> Request<'a> {
349334
self
350335
}
351336

352-
#[deprecated(note = "Please use the read_timeout instead")]
353-
pub fn set_read_timeout(&mut self, timeout: Option<Duration>) -> &mut Self {
354-
self.read_timeout(timeout)
355-
}
356-
357337
///Sets write timeout on internal `TcpStream` instance
358338
///
359339
///`timeout` will be passed to
@@ -368,11 +348,6 @@ impl<'a> Request<'a> {
368348
self
369349
}
370350

371-
#[deprecated(note = "Please use the write_timeout instead")]
372-
pub fn set_write_timeout(&mut self, timeout: Option<Duration>) -> &mut Self {
373-
self.write_timeout(timeout)
374-
}
375-
376351
///Add a file containing the PEM-encoded certificates that should be added in the trusted root store.
377352
pub fn root_cert_file_pem(&mut self, file_path: &'a Path) -> &mut Self {
378353
self.root_cert_file_pem = Some(file_path);
@@ -442,9 +417,8 @@ where
442417
///Creates and sends GET request. Returns response for this request.
443418
pub fn get<T: AsRef<str>, U: Write>(uri: T, writer: &mut U) -> Result<Response, error::Error> {
444419
let uri = uri.as_ref().parse::<Uri>()?;
445-
let request = Request::new(&uri);
446420

447-
request.send(writer)
421+
Request::new(&uri).send(writer)
448422
}
449423

450424
///Creates and sends HEAD request. Returns response for this request.

src/response.rs

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,12 @@ impl Response {
2727
pub fn from_head(head: &[u8]) -> Result<Response, Error> {
2828
let mut head = str::from_utf8(head)?.splitn(2, '\n');
2929

30-
let status = head.next().ok_or(ParseErr::Invalid)?.parse()?;
31-
let headers = head.next().ok_or(ParseErr::Invalid)?.parse()?;
30+
let status = head.next().ok_or(ParseErr::StatusErr)?.parse()?;
31+
let headers = head.next().ok_or(ParseErr::HeadersErr)?.parse()?;
3232

3333
Ok(Response { status, headers })
3434
}
3535

36-
#[deprecated(note = "Please use the from_head instead")]
37-
pub fn parse_head(head: &[u8]) -> Result<(Status, Headers), ParseErr> {
38-
let head = Self::from_head(head).map_err(|_| ParseErr::Invalid)?;
39-
40-
Ok((head.status, head.headers))
41-
}
42-
4336
///Parses `Response` from slice of bytes. Writes it's body to `writer`.
4437
pub fn try_from<T: Write>(res: &[u8], writer: &mut T) -> Result<Response, Error> {
4538
if res.is_empty() {
@@ -116,8 +109,8 @@ impl str::FromStr for Status {
116109
fn from_str(status_line: &str) -> Result<Status, Self::Err> {
117110
let mut status_line = status_line.trim().splitn(3, ' ');
118111

119-
let version = status_line.next().ok_or(ParseErr::Invalid)?;
120-
let code: StatusCode = status_line.next().ok_or(ParseErr::Invalid)?.parse()?;
112+
let version = status_line.next().ok_or(ParseErr::StatusErr)?;
113+
let code: StatusCode = status_line.next().ok_or(ParseErr::StatusErr)?.parse()?;
121114
let reason = status_line
122115
.next()
123116
.unwrap_or_else(|| code.reason().unwrap_or("Unknown"));
@@ -126,7 +119,7 @@ impl str::FromStr for Status {
126119
}
127120
}
128121

129-
///Wrapper around HashMap<String, String> with additional functionality for parsing HTTP headers
122+
///Wrapper around HashMap<Ascii<String>, String> with additional functionality for parsing HTTP headers
130123
///
131124
///# Example
132125
///```
@@ -164,7 +157,7 @@ impl Headers {
164157
}
165158

166159
///Returns a reference to the value corresponding to the key.
167-
pub fn get<T: ToString>(&self, k: T) -> Option<&std::string::String> {
160+
pub fn get<T: ToString + ?Sized>(&self, k: &T) -> Option<&std::string::String> {
168161
self.0.get(&Ascii::new(k.to_string()))
169162
}
170163

@@ -187,7 +180,7 @@ impl Headers {
187180
let mut headers = Headers::with_capacity(4);
188181

189182
headers.insert("Host", &uri.host_header().unwrap_or_default());
190-
headers.insert("Referer", uri);
183+
headers.insert("Referer", &uri);
191184

192185
headers
193186
}
@@ -203,15 +196,15 @@ impl str::FromStr for Headers {
203196
let headers = headers
204197
.lines()
205198
.map(|elem| {
206-
let idx = elem.find(":").unwrap();
199+
let idx = elem.find(':').unwrap();
207200
let (key, value) = elem.split_at(idx);
208201
(Ascii::new(key.to_string()), value[1..].trim().to_string())
209202
})
210203
.collect();
211204

212205
Ok(Headers(headers))
213206
} else {
214-
Err(ParseErr::Invalid)
207+
Err(ParseErr::HeadersErr)
215208
}
216209
}
217210
}
@@ -228,6 +221,17 @@ impl From<Headers> for HashMap<Ascii<String>, String> {
228221
}
229222
}
230223

224+
impl fmt::Display for Headers {
225+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
226+
let headers: String = self
227+
.iter()
228+
.map(|(key, val)| format!(" {}: {}\r\n", key, val))
229+
.collect();
230+
231+
write!(f, "{{\r\n{}}}", headers)
232+
}
233+
}
234+
231235
///Code sent by a server in response to a client's request.
232236
///
233237
///# Example

0 commit comments

Comments
 (0)