Commit Graph

630 Commits

Author SHA1 Message Date
Jacob Hoffman-Andrews
9484d86584 Merge branch 'release-2.0' into rm-rayon 2020-10-29 00:18:43 -07:00
Jacob Hoffman-Andrews
73af61132e Merge branch 'master' into release-2.0 2020-10-28 23:00:01 -07:00
Jacob Hoffman-Andrews
4a304fe937 Merge pull request #206 from jsha/merge-master-into-release-2.0
Merge master into release 2.0
2020-10-25 16:46:32 -07:00
Jacob Hoffman-Andrews
6781122b46 Merge pull request #205 from steffahn/generalize_send_reader_lifetime
Make Request::send more general.
2020-10-25 16:46:13 -07:00
Jacob Hoffman-Andrews
632825314c Merge pull request #207 from jsha/import-paths-tweaks
Tweak import paths
2020-10-25 16:45:36 -07:00
Jacob Hoffman-Andrews
17ab5110a3 Use lifetimes for more elements of Payload
Text and Bytes can both have their lifetimes parameterized.
2020-10-25 15:52:02 -07:00
Jacob Hoffman-Andrews
72e7e06334 Tweak import paths
Group together all cookie imports in agent.rs; consistently use `Duration`.
2020-10-25 15:10:03 -07:00
Jacob Hoffman-Andrews
a52c6021cf Merge branch 'master' into release-2.0 2020-10-25 14:07:32 -07:00
Frank Steffahn
c8cd130770 Make Request::send more general.
Removes `+ 'static` constraint from the `impl Read` parameter.
For this, lifetime parameters are added to `Payload` and `SizedReader`.
2020-10-25 21:51:04 +01:00
Jacob Hoffman-Andrews
0cfa06c80c API changes for 2.0 (#201)
* Remove Request::build
* All mutations on Request follow builder pattern

The previous `build()` on request was necessary because mutating
functions did not follow a proper builder pattern (taking `&mut self`
instead of `mut self`). With a proper builder pattern, the need for
`.build()` goes away.

* All Request body and call methods consume self

Anything which "executes" the request will now consume the `Request`
to produce a `Result<Response>`.

* Move all config from request to agent builder

Timeouts, redirect config, proxy settings and TLS config are now on
`AgentBuilder`.

* Rename max_pool_connections -> max_idle_connections
* Rename max_pool_connections_per_host ->  max_idle_connections_per_host

Consistent internal and external naming.

* Introduce new AgentConfig for static config created by builder.

`Agent` can be seen as having two parts. Static config and a mutable
shared state between all states. The static config goes into
`AgentConfig` and the mutable shared state into `AgentState`.

* Replace all use of `Default` for `new`.

Deriving or implementing `Default` makes for a secondary instantiation
API.  It is useful in some cases, but gets very confusing when there
is both `new` _and_ a `Default`. It's especially devious for derived
values where a reasonable default is not `0`, `false` or `None`.

* Remove feature native_tls, we want only native rustls.

This feature made for very clunky handling throughout the code. From a
security point of view, it's better to stick with one single TLS API.
Rustls recently got an official audit (very positive).

https://github.com/ctz/rustls/tree/master/audit

Rustls deliberately omits support for older, insecure TLS such as TLS
1.1 or RC4. This might be a problem for a user of ureq, but on balance
not considered important enough to keep native_tls.

* Remove auth and support for basic auth.

The API just wasn't enough. A future reintroduction should at least
also provide a `Bearer` mechanism and possibly more.

* Rename jar -> cookie_store
* Rename jar -> cookie_tin

Just make some field names sync up with the type.

* Drop "cookies" as default feature

The need for handling cookies is probably rare, let's not enable it by
default.

* Change all feature checks for "cookie" to "cookies"

The outward facing feature is "cookies" and I think it's better form
that the code uses the official feature name instead of the optional
library "cookies".

* Keep `set` on Agent level as well as AgentBuilder.

The idea is that an auth exchange might result in a header that need
to be set _after_ the agent has been built.

* Change ordering on TestServer's atomic bool to SeqCst
2020-10-25 11:40:10 -07:00
Martin Algesten
1369c32351 API changes for 2.0
* Remove Request::build
* All mutations on Request follow builder pattern

The previous `build()` on request was necessary because mutating
functions did not follow a proper builder pattern (taking `&mut self`
instead of `mut self`). With a proper builder pattern, the need for
`.build()` goes away.

* All Request body and call methods consume self

Anything which "executes" the request will now consume the `Request`
to produce a `Result<Response>`.

* Move all config from request to agent builder

Timeouts, redirect config, proxy settings and TLS config are now on
`AgentBuilder`.

* Rename max_pool_connections -> max_idle_connections
* Rename max_pool_connections_per_host ->  max_idle_connections_per_host

Consistent internal and external naming.

* Introduce new AgentConfig for static config created by builder.

`Agent` can be seen as having two parts. Static config and a mutable
shared state between all states. The static config goes into
`AgentConfig` and the mutable shared state into `AgentState`.

* Replace all use of `Default` for `new`.

Deriving or implementing `Default` makes for a secondary instantiation
API.  It is useful in some cases, but gets very confusing when there
is both `new` _and_ a `Default`. It's especially devious for derived
values where a reasonable default is not `0`, `false` or `None`.

* Remove feature native_tls, we want only native rustls.

This feature made for very clunky handling throughout the code. From a
security point of view, it's better to stick with one single TLS API.
Rustls recently got an official audit (very positive).

https://github.com/ctz/rustls/tree/master/audit

Rustls deliberately omits support for older, insecure TLS such as TLS
1.1 or RC4. This might be a problem for a user of ureq, but on balance
not considered important enough to keep native_tls.

* Remove auth and support for basic auth.

The API just wasn't enough. A future reintroduction should at least
also provide a `Bearer` mechanism and possibly more.

* Rename jar -> cookie_store
* Rename jar -> cookie_tin

Just make some field names sync up with the type.

* Drop "cookies" as default feature

The need for handling cookies is probably rare, let's not enable it by
default.

* Change all feature checks for "cookie" to "cookies"

The outward facing feature is "cookies" and I think it's better form
that the code uses the official feature name instead of the optional
library "cookies".

* Keep `set` on Agent level as well as AgentBuilder.

The idea is that an auth exchange might result in a header that need
to be set _after_ the agent has been built.
2020-10-25 11:47:38 +01:00
Jacob Hoffman-Andrews
304981377b Restore serde dev_dependency. 2020-10-24 10:04:55 -07:00
Jacob Hoffman-Andrews
22e3839340 Review feedback. 2020-10-24 12:12:07 +02:00
Jacob Hoffman-Andrews
2bf9362eff Reinstate read timeouts on body.
This feature was broken in #67, which reset timeouts on the
stream before passing it to set_stream.

As part of this change, refactor the internal storage of
timeouts on the Request object to use Option<Duration>.

Remove the deadline field on Response. It wasn't used. The
deadline field on unit was used instead.

Add a unittest.
2020-10-24 12:12:07 +02:00
Jacob Hoffman-Andrews
32f9ebc04a Separate overall_timeout checks. 2020-10-24 12:08:27 +02:00
Jacob Hoffman-Andrews
1f5f65877a Update overall_timeout_during_headers test. 2020-10-24 12:08:27 +02:00
Jacob Hoffman-Andrews
14475cb5c7 Add test for read_timeout during headers. 2020-10-24 12:08:27 +02:00
Jacob Hoffman-Andrews
67c28d28a3 Check for synthetic_error early in unit::connect 2020-10-24 12:08:27 +02:00
Jacob Hoffman-Andrews
1c5dcc0096 Remove some dev-dependencies.
We don't really need rayon for the parallelism in smoke-test.

Also, now that we use log, smoke-test can just use that.
2020-10-22 22:55:16 -07:00
Jacob Hoffman-Andrews
703ca41960 Push mutexes down into pool and cookie store. (#193)
Previously, Agent stored most of its state in one big
Arc<Mutex<AgentState>>. This separates the Arc from the Mutexes.
Now, Agent is a thin wrapper around an Arc<AgentState>. The individual
components that need locking, ConnectionPool and CookieStore, now are
responsible for their own locking.

There were a couple of reasons for this. Internal components that needed
an Agent were often instead carrying around an Arc<Mutex<AgentState>>.
This felt like the components were too intertwined: those other
components shouldn't have to care quite so much about how Agent is
implemented. Also, this led to compromises of convenience: the Proxy on
Agent wound up stored inside the `Arc<Mutex<AgentState>>` even though it
didn't need locking. It was more convenient that way because that was
what Request and Unit had access too.

The other reason to push things down like this is that it can reduce
lock contention. Mutations to the cookie store don't need to lock the
connection pool, and vice versa. This was a secondary concern, since I
haven't actually profiled these things and found them to be a problem,
but it's a happy result of the refactoring.

Now all the components outside of Agent take an Agent instead of
AgentState.

In the process I removed `Agent.cookie()`. Its API was hard to use
correctly, since it didn't distinguish between cookies on different
hosts. And it would have required updates as part of this refactoring.
I'm open to reinstating some similar functionality with a refreshed API.

I kept `Agent.set_cookie`, but updated its method signature to take a
URL as well as a cookie.

Many of ConnectionPool's methods went from `&mut self` to `&self`,
because ConnectionPool is now using interior mutability.
2020-10-20 00:03:45 -07:00
Jacob Hoffman-Andrews
75bc803cf1 Use a testserver in tests. (#194)
This is a step towards allowing our tests to run without network access,
which will make them more resilient and faster.

Replace the URL in one instance of an HTTPS test that didn't need HTTPS.
2020-10-19 00:27:40 -07:00
dependabot-preview[bot]
bd2761e280 Update env_logger requirement from 0.7.1 to 0.8.1
Updates the requirements on [env_logger](https://github.com/env-logger-rs/env_logger) to permit the latest version.
- [Release notes](https://github.com/env-logger-rs/env_logger/releases)
- [Changelog](https://github.com/env-logger-rs/env_logger/blob/master/CHANGELOG.md)
- [Commits](https://github.com/env-logger-rs/env_logger/compare/v0.7.1...v0.8.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-19 09:11:35 +02:00
Martin Algesten
6e997909bf Document release process 2020-10-19 01:18:56 +02:00
Jacob Hoffman-Andrews
30162bf3bb Move Agent construction to new AgentBuilder.
In the process, rename set_foo methods to just foo, since methods on the
builder will always be setters.

Adds a new() method on ConnectionPool so it can be constructed directly
with the desired limits. Removes the setter methods on ConnectionPool
for those limits. This means that connection limits can only be set when
an Agent is built.

There were two tests that verify Send and Sync implementations, one for
Agent and one for Request. This PR moves the Request test to request.rs,
and changes both tests to more directly verify the traits. There may be
another way to do this, I'm not sure.
2020-10-18 12:12:07 +02:00
Jacob Hoffman-Andrews
0f083a4436 Add jsha to Authors list.
Per suggestion by Martin. :-)
2020-10-18 11:30:38 +02:00
Jacob Hoffman-Andrews
044f25b02a Add more header validation (#188)
This adds validation of header values on receive, and of both header
names and header values on send. This doesn't change the return
type of set to be a Result, it just validates when the request is
sent. Also removes the section in the README describing handling
of invalid headers, and updates a test that verified acceptance of
non-ASCII headers so that it verifies rejection of them instead.
2020-10-17 17:59:29 -07:00
Jacob Hoffman-Andrews
e36c1c2aa1 Switch to Result-based API. (#132)
Gets rid of synthetic_error, and makes the various send_* methods return `Result<Response, Error>`.
Introduces a new error type "HTTP", which represents an error due to status codes 4xx or 5xx.
The HTTP error type contains a boxed Response, so users can read the actual response if they want.
Adds an `error_for_status` setting to disable the functionality of treating 4xx and 5xx as errors.
Adds .unwrap() to a lot of tests.

Fixes #128.
2020-10-17 00:40:48 -07:00
Jacob Hoffman-Andrews
257d4e54dd Switch timeout APIs to use Duration. 2020-10-17 09:23:01 +02:00
Jacob Hoffman-Andrews
00e3294ac1 Remove convenience methods for CONNECT verb. (#177)
CONNECT, specified at https://tools.ietf.org/html/rfc7231#section-4.3.6,
says:

> if successful, thereafter restrict its behavior to blind forwarding
> of packets, in both directions, until the tunnel is closed.

ureq doesn't actually support the semantics of CONNECT, since it doesn't
offer a bidirectional channel on a Response. So I'm fairly confident no
one is using these methods.
2020-10-07 22:54:31 -07:00
Martin Algesten
e763446d72 1.5.1 2020-10-06 10:06:36 +02:00
Martin Algesten
95cbb15a68 Changelog for 1.5.1 2020-10-06 10:05:48 +02:00
Jacob Hoffman-Andrews
e3138b0ace Add proxy on agent. (#178) 2020-10-06 00:12:26 -07:00
Jacob Hoffman-Andrews
5b75deccef Use correct host on redirect. (#180) 2020-10-06 00:10:56 -07:00
Jacob Hoffman-Andrews
2d4b42e298 Use cookie_store crate instead of cookie::CookieJar (#169)
CookieJar doesn't support the path-match and domain-match algorithms from [RFC 6265](https://tools.ietf.org/html/rfc6265#section-5.1.3), while cookie_store does.

This fixes some issues with the cookie matching algorithm currently in ureq. For instance,
the domain-match uses substring matching rather than the RFC 6265 algorithm.

This deletes two tests:

match_cookies_returns_nothing_when_no_cookies didn't test much
agent_cookies was failing because cookie_store rejects cookies on the `test:` scheme.
  The way around this is to set up a testserver - but it turns out cookies_on_redirect already
  does that, and covers the same cases and more.

This changes some cookie-related behavior:

 - Cookies could previously be sent to a wrong domain - e.g. a cookie set on `example.com`
  could go to `example.com.evil.com` or `evilexample.com`. Probably no one was relying on
  this, since it's quite broken.
 - A cookie with a path of `/foo` could be sent on a request to `/foobar`, but now it can't.
 - Cookies could previously be set on IP addresses, but now they can't.
 - Cookies could previously be set for domains other than the one on the request (or its
  parents), but now they can't.
 - When a cookie had no domain attribute, it would previously get the domain from the
  request, and subsequently be sent to that domain and all subdomains. Now, it will only
  be sent to that exact domain (host-only).

That last one is probably the most likely to break people, since someone could depend
on it without realizing it was broken behavior.
2020-10-04 10:21:09 -07:00
Martin Algesten
0bf981031b Replace lazy_static! with once_cell Lazy (#176)
Modern rust code bases prefer once_cell::sync::Lazy over the older
macro based lazy_static.
2020-10-04 09:35:31 -07:00
Jacob Hoffman-Andrews
b58a3a53b0 Add test.sh. (#173)
This emulates the test matrix that gets run in CI, making it easier to
find failures locally.

There was one conflict in the matrix: when JSON is enabled and TLS is
disabled, two of the doctests would fail. This was previous worked
around as an exclude in the github workflow. I changed the JSON doctest
to use HTTP instead.
2020-10-03 20:47:35 -07:00
dependabot-preview[bot]
b8d02f9785 Update base64 requirement from 0.12 to 0.13
Updates the requirements on [base64](https://github.com/marshallpierce/rust-base64) to permit the latest version.
- [Release notes](https://github.com/marshallpierce/rust-base64/releases)
- [Changelog](https://github.com/marshallpierce/rust-base64/blob/master/RELEASE-NOTES.md)
- [Commits](https://github.com/marshallpierce/rust-base64/compare/v0.12.0...v0.13.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-03 10:44:31 +02:00
Jacob Hoffman-Andrews
d4dfe4096f Feature-gate AgentState 2020-10-01 14:27:59 -07:00
Martin Algesten
573b175cf7 1.5.0 2020-09-29 11:12:00 +02:00
Martin Algesten
0346794e87 Fix bug in force-unwrapping when resetting timers
When running tests locally, this error can surface.

```
---- test::agent_test::custom_resolver stdout ----
thread 'test::agent_test::custom_resolver' panicked at 'called `Result::unwrap()` on an `Err` value: Os { code: 22, kind: InvalidInput, message: "Invalid argument" }', src/stream.rs:60:13
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
```

The problem is that setting the timeouts might fail, and this is done
in a From trait where there is not possibility to "bubble" the
io::Error.

```
socket.set_read_timeout(None).unwrap();
socket.set_write_timeout(None).unwrap();
```

This commit moves the resetting of timers to an explicit `Stream::reset()` fn
that must be called every time we're unwrapping the inner stream.
2020-09-29 11:10:16 +02:00
Jacob Hoffman-Andrews
6f70349172 Update 1.5.0 changelog. 2020-09-29 11:01:44 +02:00
Jacob Hoffman-Andrews
17d7e147eb Handle ConnectionReset+ConnectionAbort at any time (#168)
Previously we had a special case for BadStatusRead that would happen
only when we got a ConnectionAborted error reading the status line.
However, sometimes we get ConnectionReset instead. Also the HTTP
spec says that idempotent requests may be retried anytime a connection
is closed prematurely.

The change treats as retryable any ConnectionAborted OR ConnectionReset
error while reading the status line and headers. It removes the special
case BadStatusRead error.

Fixes #165 (I think).
2020-09-29 01:55:34 -07:00
Jacob Hoffman-Andrews
06d6435374 Merge branch 'master' of https://github.com/algesten/ureq into cookie_store 2020-09-29 01:45:52 -07:00
Jacob Hoffman-Andrews
9300c50461 Make cookie_store optional 2020-09-29 01:45:26 -07:00
Jacob Hoffman-Andrews
065b560dfb Add log dependency. (#170)
Also add log statements to unit. Each request gets one info line;
retries, redirects, and responses get logged at debug level.
2020-09-29 01:37:39 -07:00
Jacob Hoffman-Andrews
9b39e55d1c Use cookie_store 2020-09-29 00:34:29 -07:00
Jacob Hoffman-Andrews
4b95d4d29e Cookie refactor 2020-09-28 22:41:29 -07:00
Jacob Hoffman-Andrews
995f6e44a9 Pass through io::Errors when reading headers. (#166)
Previously any io::Error on reading a status line or response headers
would be unconditionally mapping into BadStatus or BadHeader. I think
it's better to pass through the actual io::Error.

BadStatusRead is still kept, since it has special status when dealing
with timed out connections, and BadStatus is still used when the status
line is malformed.
2020-09-28 09:14:26 -07:00
Jacob Hoffman-Andrews
e4d2ce8494 Add changelog for 1.5.0. (#164) 2020-09-27 19:50:51 -07:00
Jacob Hoffman-Andrews
264abdf452 Add PRs to changelog. 2020-09-27 11:36:55 -07:00