Commit Graph

69 Commits

Author SHA1 Message Date
Martin Algesten
8d33318a23 Rename setter to be consistent with other builder settter 2021-12-19 11:00:39 +01:00
Martin Algesten
b033e0f614 Doc fixes to RedirectAuthHeaders 2021-12-19 11:00:39 +01:00
llde
653f791638 Create new configuration option for redirect preserving authorization header in Agent. Handle new option in Unit 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
Jochen Kupperschmidt
69ad3aabb0 Add shortcuts for PATCH (again)` 2021-11-26 13:50:29 +01:00
Jacob Hoffman-Andrews
f22e67be4c Fix agent test. 2021-10-21 07:38:59 +02:00
Martin Algesten
526eb7b9e0 Fix clippy lints 2021-08-23 20:45:33 +02:00
Berrysoft
c06c345f28 Remove extra clone when request with Url 2021-05-11 20:18:34 +02:00
Michael Diamond
0c467fee13 Add a user_agent() method to AgentBuilder to configure the default User-Agent header. (#311) 2021-01-29 17:23:30 -08:00
Jacob Hoffman-Andrews
b9e3d3e76c Fix test 2020-12-06 14:55:55 -08:00
Jacob Hoffman-Andrews
ac93fa7e18 Remove references to error_on_non_2xx 2020-12-05 20:32:30 -08:00
Joshua Nelson
4a3d3c49a1 Note that 307 redirects aren't followed in the docs 2020-12-05 15:03:47 +01:00
Jacob Hoffman-Andrews
e92bf0b4bb Add ureq::request_url and Agent::request_url. (#226)
These let a user pass an already-parsed Url.
2020-11-21 22:11:15 -08:00
Jacob Hoffman-Andrews
0321ea043d Add some short docstrings for types. (#225)
These types were missing a short docstring, leaving the comment space to
their right blank on the crate page.

Also, this takes advantage of intra-rustdoc links to link terms:
https://github.com/rust-lang/rfcs/blob/master/text/1946-intra-rustdoc-links.md
2020-11-21 22:10:37 -08: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
Martin Algesten
d0789ae8e9 Rename AgentBuilder set_tls_config -> tls_config
For consistency. We don't use set_xxx on the builder.
2020-11-08 11:31:49 +01:00
Martin Algesten
a8ee8ab75e Provide AgentBuilder::cookie_store setter 2020-11-08 11:31:49 +01:00
Martin Algesten
c2bbd57acc Agent::cookie_store to persist cookies 2020-11-08 11:31:49 +01:00
Martin Algesten
18201a08c5 Remove Agent::set_cookie
Preloading an agent with cookies can be done by providing a prepared
cookie store using `AgentBuilder`. At this point, we don't want direct
state mutation on the `Agent`, so this fn goes away.

Context:
https://github.com/algesten/ureq/issues/203#issuecomment-716385310
2020-11-08 11:31:49 +01:00
Martin Algesten
e37acc85b2 Remove AgentBuilder::set headers
The headers are not scoped by host, which means using them for
something like `Authorization` would effectively "leak" to all
requests using the agent.

Context:
https://github.com/algesten/ureq/issues/203#issuecomment-716385310
2020-11-08 11:31:49 +01:00
Jacob Hoffman-Andrews
d83de53bcd Restore HEAD and DELETE
Also, remove OPTIONS, TRACE, and PATCH from lib.rs.
2020-10-30 05:49:01 +01:00
Jacob Hoffman-Andrews
aae05c5614 Agent tweaks for 2.0
Replace `this` idiom with `mut self`.

Move idle connections constants from pool.rs to agent.rs.

Remove Agent.set and some convenience request methods
(leaving get, post, and put).

Move max_idle_connections setting from AgentConfig to AgentBuilder
(since the builder passes these to ConnectionPool and the Agent
doesn't subsequently need them).

Eliminate duplicate copy of proxy in AgentState; use the one in
AgentConfig.
2020-10-30 05:49:01 +01: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
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
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
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
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
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
Jacob Hoffman-Andrews
e3138b0ace Add proxy on agent. (#178) 2020-10-06 00:12:26 -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
Ulrik Mikaelsson
11413726cd Implement Pluggable Name-resolution (#148)
This defines a new trait `Resolver`, which turns an address into a
Vec<SocketAddr>. It also provides an implementation of Resolver for
`Fn(&str)` so it's easy to define simple resolvers with a closure.


Fixes #82

Co-authored-by: Ulrik <ulrikm@spotify.com>
2020-09-26 16:35:13 -07:00
Martin Algesten
05ffe53e4c CI: error on dead/unused code for features (#146)
By using `RUSTFLAGS="-D dead_code -D unused-variables -D unused"`, we tell
the compiler to upgrade warnings for unused code to errors. This combined
with a more elaborate test matrix means we can have the CI catch feature
flag combos that cause warnings.
2020-09-18 13:55:23 -07:00
Ulrik Mikaelsson
f599828c6d Turn Option<AgentState> into AgentState (#149)
`Some(AgentState)` seem to be assumed pretty much everywhere. I could not
find any test or piece of code hinting at how `None` should be interpreted,
or even see how a state of `None` could even be constructed.

Co-authored-by: Ulrik <ulrikm@spotify.com>
2020-09-18 13:47:11 -07:00
Alex L
d52fa78ebc Allow saving multiple idle streams per host. (#133)
Adds set_max_idle_connections and set_max_idle_connections_per_host.

This turns the values of Pool.recycle into a VecDeque of Streams for the same PoolKey.
The freshest stream (most recently used) is at the back; the stalest stream is at the front.

This also removes the invariant "Each PoolKey exists in recycle at most once and lru at
most once," replacing it with "each PoolKey has the same number of entries in lru as in
recycle."

Fixes #110
2020-09-12 23:16:27 -07:00
Jacob Hoffman-Andrews
6a88c2c8bf Clean up unused code and long imports. (#137)
This removes some commented out methods, and also changes instances of
::std::foo to use a more idiomatic import path.
2020-09-12 18:42:15 -07:00
Jacob Hoffman-Andrews
3014f58a28 Add scheme to PoolKey and let port be None. (#84)
PoolKey calls unwrap() on an option that can be None. Specifically, the
local variable `port` can be None when PoolKey is constructed with a Url
whose scheme is unrecognized in url.port_or_known_default().

To fix that, make port an Option. Also, make scheme part of the PoolKey.
This prevents, for instance, a stream opened for `https://example.com:9999`
being reused on a request for `http://example.com:9999`.

Remove the test-only pool.get() accessor. This was used in only one test,
agent_pool in range.rs. This seemed like it was testing the agent more
than it was testing ranges, so I moved it to agent.rs and edited to
remove the range-testing parts.

Also, reject unrecognized URLs earlier in connect_socket so they don't
reach try_get_connection.
2020-06-22 23:23:39 -07:00
Jacob Hoffman-Andrews
7adbd57308 Fix up cargo test --no-default-features. (#75)
Adds some feature guards, and removes an unnecessary feature guard
around a call to connect_https (there's an implementation available for
non-TLS that returns UnknownScheme).

Also, remove unnecessary agent.state() method that was only available in
TLS builds. The state field is directly accessible within the crate, and
can be used in both TLS and non-TLS builds.

Co-authored-by: Martin Algesten <martin@algesten.se>
2020-06-21 09:54:03 +02:00
k3d3
9f7f712dde Add optional native-tls support, clear up warnings for flag configurations 2020-06-15 09:25:49 +02:00
Martin Algesten
a4bae72fcb cargo fmt 2020-01-07 08:08:12 +01:00
Tom Forbes
da42f2ed8f Make cookies conditional 2019-10-20 20:17:35 +02:00
Martin Algesten
e936d5ea74 cargo fmt 2019-10-20 10:41:35 +02:00
Chris West (Faux)
ceb7c3ac14 use pub(crate) instead of include!() 2019-05-27 17:44:14 +01:00
Martin Algesten
07fd4d2cd5 pub(crate) where we can 2018-12-20 11:08:20 +01:00
Martin Algesten
5ba6b3cd4d edition 2018, clippy, fmt 2018-12-18 13:17:19 +01:00
Martin Algesten
b16b14c6aa simpler api 2018-09-04 10:59:10 +02:00
Martin Algesten
9cf33365e5 avoid panic for headers 2018-07-02 09:10:31 +02:00
Martin Algesten
51744804da avoid parsing when setting headers 2018-07-01 18:33:50 +02:00
Martin Algesten
2d2daf58ba doc 2018-07-01 11:13:21 +02:00