Commit Graph

120 Commits

Author SHA1 Message Date
Martin Algesten
7b2f28bbc2 Tidy up Response::url initialization 2021-12-22 07:58:45 +01:00
Jacob Hoffman-Andrews
2df70168c4 Use ? instead of unwrap in examples (#458)
This is recommended by the Rust API Guidelines:

https://rust-lang.github.io/api-guidelines/documentation.html#examples-use--not-try-not-unwrap-c-question-mark

One exception: When we need to unwrap an Option, the examples still use
.unwrap(). The alternative would be something like
`.ok_or(SomeErrorHere)?`, which feels like an awkward way to deal with
an Option. This might get better with NoneError:

https://docs.rs/rustc-std-workspace-std/1.0.1/std/option/struct.NoneError.html

I also rearranged some examples that used turbofish to use type
annotations. I think type annotations are more familiar to early Rust
users (and they use fewer characters and less punctuation, which is
always nice).
2021-12-19 20:04:30 -08:00
Martin Algesten
f3857eed00 Ensure we provide a Transport::message() when we can 2021-12-19 21:17:26 +01:00
Martin Algesten
158a6c6f03 Clarify serde doc on Response::into_json (#451)
Close #428
2021-12-19 11:41:44 -08:00
Malloc Voidstar
598ebf4393 Remove Content-Encoding and length when decompressing
This should lower the chance of breakage. Probably also more proper for a client library.
2021-12-19 14:01:56 +01:00
Malloc Voidstar
23e993689a Rename Decompressor to BrotliDecoder to align with gzip 2021-12-19 14:01:56 +01:00
Malloc Voidstar
873e6066f3 Add support for gzip and brotli
Automatically sends the Accept-Encoding header on requests.

Not runtime-configurable, only with Cargo features.
2021-12-19 14:01:56 +01:00
Martin Algesten
c59632bd97 Use Url (instead of String) in internal history var 2021-12-19 11:00:39 +01:00
Jacob Hoffman-Andrews
56276c3742 Add support for alternate TLs implementations. 2021-12-17 17:47:30 +01:00
Jon Gjengset
1ec60e1c15 Remove trailing newline from testing response
The newline becomes part of the response body, even though it was not passed in
as `body`, which makes `Response::new` difficult to use with anything that
checksums data contents for example. Arguably there should also be a mechanism
for passing in `[u8]` bodies, but that's for a separate feature request.
2021-10-02 18:51:59 +02:00
Niketh Murali
4665b0aa5a Fix clippy warnings
Fix linter warning from clippy about unnecessary borrows - "This expression borrows a reference ... that is immediately dereferenced by the compiler"
2021-08-13 09:26:04 +02:00
12932
db5203d1a0 fix typo "memroy" to "memory" (#379) 2021-04-26 11:41:26 -07:00
Martin Algesten
3cfa9e6b35 Refactor into_string body reading 2021-03-25 21:49:39 +01:00
Martin Algesten
7c6ed53df3 Move Response::unit and stream to the heap 2021-03-25 21:04:12 +01:00
Martin Algesten
cfaca317c6 Provide url in Response Debug impl 2021-03-25 07:45:34 +01:00
Jacob Hoffman-Andrews
3044ae7efd Add size limits on responses (#351)
This prevents a malicious server from running the client out of memory
by returning a very large body.

Limit into_string() to 1 megabyte.
Limit individual header fields to 100 kilobytes.
Limit number of header fields to 100.

Part of #267
2021-03-24 13:28:23 -07:00
Martin Algesten
026cf75690 Handle non-utf8 status and headers
Non-utf8 headers are ignored and reading the value for them will
yield `None`.
2021-03-14 23:14:43 +01:00
Martin Algesten
0dc609fc30 Ensure Error and Response implement Send+Sync
This is to ensure we don't accidentally introduce breaking changes
with respects to Send and Sync.
2021-03-14 19:00:04 +01:00
Martin Algesten
91cb0ce5fc Move unit tests inside conditionally compiled mod tests { } blocks
Idiomatic rust organizes unit tests into `mod tests { }` blocks
using conditional compilation `[cfg(test)]` to decide whether to
compile the code in that block.

This commit moves "bare" test functions into such blocks, and puts
the block at the bottom of respective file.
2021-03-14 18:56:09 +01:00
Martin Algesten
566295bebb Provide context for errors when reading status line and headers
The HTTP spec allows for non-ascii values both in the status line and
in headers. ureq does not handle that, we can however provide better
context for when it happens.
2021-03-13 23:03:25 +01:00
Martin Algesten
7222931b24 Update src/response.rs
Co-authored-by: Jacob Hoffman-Andrews <github@hoffman-andrews.com>
2021-02-21 23:20:58 +01:00
Martin Algesten
ea83edc609 Allow status lines with missing reason phrase
The spec says the reason phrase at least must be a space. However in
the wild, there are sites that just ends after the status code.
To be more compatible, this commit relaxes ureq's parsing.

Close #316
2021-02-21 23:20:58 +01:00
Martin Algesten
dc0069670d Update src/response.rs
Co-authored-by: Jacob Hoffman-Andrews <github@hoffman-andrews.com>
2021-02-21 23:20:20 +01:00
Martin Algesten
281a8462b5 Clarify doc
Close #326
2021-02-21 23:20:20 +01:00
Nicolas
1857061859 Add a test case for LF line ending response headers 2021-02-21 09:21:18 +01:00
Nicolas
a73ff2e465 Fix #321: LF header line ending 2021-02-21 09:21:10 +01:00
Jarobi
4aadda8ad3 Fix typo in doc of into_json 2021-01-17 13:51:19 +01:00
Jacob Hoffman-Andrews
932c180d1d Response: Use ErrorKind::UnexpectedEof for "premature close" (#293)
In a client application, we're explicitly trying to differentiate "invalid data"
scenarios from "broken transfer".
2021-01-10 13:25:42 -08:00
Joshua Nelson
d0bd2d5ea9 Use iteration instead of recursion for connect (#291)
This allows handling larger redirect chains.

Fixes #290
2021-01-05 13:55:26 -08:00
Ulrik
0ee024f8c2 Response: Use ErrorKind::UnexpectedEof for "premature close" 2021-01-05 12:07:11 +01:00
Joshua Nelson
f0245aad23 Fix some clippy lints (#292)
This commit can be replicated with `cargo +nightly clippy --fix -Z unstable-options`,
plus an edit to fix another `return` missed by clippy.
2021-01-03 20:10:43 -08:00
Martin Algesten
8f9f3e5827 Fix main lib.rs and README.md example (#284)
Small fixes to just ensure lib.rs and README.md are run via cargo readme.
2021-01-03 10:38:10 -08:00
Jacob Hoffman-Andrews
de1805190e Do more validation on status line. (#266)
Status code must be exactly three digits.
HTTP version must be "HTTP/", digit, dot, digit.

https://tools.ietf.org/html/rfc7230#section-3.1.2
status-line = HTTP-version SP status-code SP reason-phrase CRLF
2020-12-18 22:18:25 -08:00
Jacob Hoffman-Andrews
8cb4f401e3 Add history to response objects (#275)
This allows Error to report both the URL that caused an error, and the
original URL that was requested.

Change unit::connect to use the Response history for tracking number of
redirects, instead of passing the count as a separate parameter.

Incidentally, move handling of the `stream` fully inside `Response`.
Instead of `do_from_read` + `set_stream`, we now have `do_from_stream`,
which takes ownership of the stream and keeps it. We also have
`do_from_request`, which does all of `do_from_stream`, but also sets the
`previous` field.
2020-12-13 11:59:11 -08:00
Jacob Hoffman-Andrews
57f251d766 Remove Response::status_line. (#263)
The necessary functionality is available via status_text, and removing
this method means we have more flexibility in our internal storage.
2020-12-05 12:01:56 -08:00
Jacob Hoffman-Andrews
c3a6f50dbe Remove status methods on Response. (#258)
Now that Responses with non-2xx statuses get turned into `Error`,
there is less need for these. Also, surveying the set of public crates
that depend on ureq, none of them use these methods. It seems that
users tend to prefer checking the status code directly.

Here is my thinking on each of these individually:

.ok() -- With the new Result API, any Request you get back will be
.ok(). Also, I think the name .ok() is a little confusing with
Result::ok().

.error() - with the new Result API, this is an exact overlap with
anything that would return Error. People will just check for whether a
Result is Err(...) rather than call .error().

.client_error() - most of the time, if someone wants to specially handle
a 4xx error, they want to handle specific ones, because the response to
them is different. For instance a specialized response to a 404 would be
"delete this from the list of URLs to check in the future," where a
specialized response to a 401 would be "try and load updated
credentials." For instance:

4200edb9ed/healthchecks/src/manage.rs (L70-L84)

75d4b363b6/src/lib.rs (L59-L63)

1d7daea38b/src/netlify.rs (L101-L112)

.server_error() - I don't have as much objection to this one, since it's
reasonable to want to treat all server errors (500, 502, 503) more or
less the same. Although even at that, 501 Not Implemented seems like
people would want to handle it differently. I guess that doesn't come up
much in practice - I've never seen a 501 in the wild.

.redirect() - Usually redirects are handled under the hood, unless
someone disables automatic redirect handling. I'm not terribly opposed
to this one, but given that no-one's using it and it's just as easy to
do 300..399.contains(resp.status()), I'm mildly inclined towards
deletion.
2020-12-05 11:32:25 -08:00
Jacob Hoffman-Andrews
18a9b08973 Revert deletions of client_error and friends. 2020-12-05 15:29:11 +01:00
Jacob Hoffman-Andrews
4c3b93d86d Add Error::{kind, status, into_response}.
Also, remove Response::{ok, error, client_error, server_error,
redirect}. The idea is that you would access these through the
Error object instead.

I fetched all the reverse dependencies of ureq on crates.io and looked
for uses of the methods being removed. I found none.

I'm also considering removing the error_on_non_2xx method entirely. If
it's easy to get the underlying response for errors, it would be nice to
make that the single way to do things rather than support two separate
ways of handling HTTP errors.
2020-12-05 15:29:11 +01:00
Jacob Hoffman-Andrews
7afc4b04f3 Use BufRead in more places (#261)
This moves Stream's enum into an `Inner` enum, and wraps a single
BufReader around the whole thing. This makes it easier to consistently
treat the contents of Stream as being wrapped in a BufReader.

Also, implement BufRead for DeadlineStream. This means when a timeout
is set, we don't have to set that timeout on the socket with every
small read, just when we fill up the buffer. This reduces the number
of syscalls.

Remove the `Cursor` variant from Stream. It was strictly less powerful
than that `Test` variant, so I've replaced the handful of Cursor uses
with `Test`. Because some of those cases weren't test, I removed the
`#[cfg(test)]` param on the `Test` variant.

Now that all inputs to `do_from_read` are `impl BufRead`, add that
as a type constraint. Change `read_next_line` to take advantage of
`BufRead::read_line`, which may be somewhat faster (though I haven't
benchmarked).
2020-11-30 09:23:19 -08:00
messense
df1f4bd0e1 Replace unmaintained encoding crate with encoding_rs 2020-11-29 19:38:39 +01:00
Jacob Hoffman-Andrews
6a22c54ba2 Small cleanups. 2020-11-28 22:34:32 -08:00
Jacob Hoffman-Andrews
50cb5cecd1 Fix buffered DeadlineStream 2020-11-28 17:47:17 -08:00
Jacob Hoffman-Andrews
131a0264d1 Move BufReader up the stack in Stream.
Stream now has an `Inner` enum, and wraps an instance of that enum in a
BufReader. This allows Stream itself to implement BufRead trivially, and
simplify some of the match dispatching. Having Stream implement BufRead
means we can make use of `read_line` instead of our own `read_next_line`
(not done in this PR yet).

Also, removes the `Cursor` variant of the Inner enum in favor of using
the `Test` variant everywhere, since it's strictly more powerful.
2020-11-28 12:04:28 -08:00
Jacob Hoffman-Andrews
420c3e2483 Merge branch 'release-2.0' into json_deserialize 2020-11-21 16:25:14 -08:00
Jacob Hoffman-Andrews
fade03b54e Rewrite the Error type. (#234)
This adds a source field to keep track of upstream errors and allow
backtraces, plus a URL field to indicate what URL an error was
associated with.

The enum variants we used to use for Error are now part of a new
ErrorKind type. For convenience within ureq, ErrorKinds can be turned
into an Error with `.new()` or `.msg("some additional information")`.

Error acts as a builder, so additional information can be added after
initial construction. For instance, we return a DnsFailed error when
name resolution fails. When that error bubbles up to Request's
`do_call`, Request adds the URL.

Fixes #232.
2020-11-21 16:14:44 -08:00
Jacob Hoffman-Andrews
271e650662 Merge into_json_deserialize into into_json. 2020-11-21 15:47:49 -08:00
Jacob Hoffman-Andrews
daa63d3bc6 Update some more doctests.
I missed these in my previous doctest PR.

The doctests all now run without accessing the network. Tested by
turning off networking and running them.

Request.call's doctest wouldn't run because it relied on making a custom
AgentBuilder and building it, which bypasses the test_agent. I concluded
that this doctest was mostly illustrating behavior of AgentBuilder, not
call(), and simplified it to be more like the other calling methods on
request.
2020-11-15 09:14:19 +01:00
Jacob Hoffman-Andrews
203573d27c Implement more realistic doctests. (#222)
Add is_test and fn main headers to various doctests, and use real
URLs along with the ? operator.
2020-11-14 09:53:15 -08:00
Jacob Hoffman-Andrews
ec8dace1af Turn Unit into a built Request (#223)
This involved removing the Request reference from Unit, and adding an
Agent, a method, and headers.

Also, move is_retryable to Unit.
2020-11-14 01:12:01 -08:00
Jacob Hoffman-Andrews
a52c6021cf Merge branch 'master' into release-2.0 2020-10-25 14:07:32 -07:00