Commit Graph

103 Commits

Author SHA1 Message Date
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
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
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
Deluvi
e224a6d126 Set chunked Transfer-Encoding when using send
Previously, using `.send()` on `Request` would require to set either the
Transfer-Encoding or the Content-Length header.

In an effort to provide better ergonomics for this library and to avoid
making users fall in a not-so obvious pitfall, the library should build a
valid Request without asking the user to mess around with the headers.

This commit attempts to fix this issue: if the user use `.send()` to
provide an unknown sized reader, the chunked Transfer-Encoding will be
used. Of course, there are prior checks to ensure we do not override the
user wish, like if the user already set a Content-Length or a
Transfer-Encoding.

This commit fix an edge case where the Content-Length would not be
automatically set if the Transfer-Encoding is set but not chunked.
2020-09-27 10:50:24 +02: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
Jacob Hoffman-Andrews
fdc1f37662 Update documentation. (#73)
* Update documentation.

Synchronize goals section between README and rustdoc, and add two goals
(blocking API; no unsafe) that were mentioned elsewhere in the README.

Add error handling to examples for the module and for the Response
object.

And a section on synthetic errors to the top-level module documentation.

* Add back missing close brace.

* Add main function that returns Result.

* Add links to send_bytes and send_form.

* Document chunked encoding for send.

* Use a larger vec of bytes for send.
2020-06-21 09:55:50 +02:00
Jacob Hoffman-Andrews
e366c8fcd0 Remove compile error on native-tls / tls conflict. (#74)
The docs.rs build uses the --all-features flag, which causes its
documentation builds to fail when this macro is present.

Fixes #71.
2020-06-21 09:51:46 +02:00
Drake Tetreault
af6491cd59 Remove unsafe usage by taking advantage of new Decoder::unwrap function. 2020-06-16 10:02:57 +02:00
k3d3
b79383bbb4 Remove extra line added when merging causing a doc test error 2020-06-15 09:25:49 +02:00
k3d3
de3416e260 Fix cfg for test
Fix up cfg attributes to work on an xor basis.

Previously, the cfg(any()) attributes would cause issues when
both native-tls and tls features were enabled. Now, https functions
and enum variants will only be created when tls xor native-tls are
enabled. Additionally, a compile error has been added for when
both tls and native-tls features are enabled.
2020-06-15 09:25:49 +02:00
k3d3
9f7f712dde Add optional native-tls support, clear up warnings for flag configurations 2020-06-15 09:25:49 +02:00
Rob Young
b61991d87e Fix a couple of feature flag uses
Wrap a json doc-test in cfg block to stop in failing when tests are
run with --no-default-features
2020-05-20 20:55:19 +02:00
Koga Kazuo
e5fa36f98e Fix panic on invalid authority 2020-04-12 09:41:35 +02:00
rustysec
3b0df412ef initial proxy impl 2020-03-14 09:54:54 +01:00
Martin Algesten
63cfcfb23e doc format 2020-01-07 08:07:51 +01:00
Martin Algesten
4b9cfe2b67 fix clippy lints 2020-01-07 07:59:29 +01:00
Tom Forbes
da42f2ed8f Make cookies conditional 2019-10-20 20:17:35 +02:00
Chris West (Faux)
ceb7c3ac14 use pub(crate) instead of include!() 2019-05-27 17:44:14 +01:00
Martin Algesten
131476bd1a remove extern crate 2018-12-18 13:45:13 +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
cc000da9bc doc 2018-07-01 19:06:22 +02:00
Martin Algesten
a14e75fcbc dont require agent().build() 2018-07-01 10:24:42 +02:00
Martin Algesten
3a82ad05ab conn -> pool 2018-06-30 14:14:39 +02:00
Martin Algesten
54558fbb26 refactor to body 2018-06-30 14:11:54 +02:00
Martin Algesten
ff582b8c6f separate out stream 2018-06-30 13:47:37 +02:00
Martin Algesten
3b249e0313 separate out ConnectionPool 2018-06-30 13:41:52 +02:00
Martin Algesten
b54f747d16 separate out response 2018-06-30 13:36:41 +02:00
Martin Algesten
fc4a78b962 ToSocketAddrs instead of dns lookup 2018-06-26 08:26:44 +02:00
Martin Algesten
cd4a1722fa reduce dependency tree by features 2018-06-22 15:02:13 +02:00
Martin Algesten
e9ccf1c2cc use charset encoding for send_string 2018-06-22 11:38:44 +02:00
Martin Algesten
48dcdeb92a doc fixes 2018-06-22 11:11:59 +02:00
Martin Algesten
67e7919b06 remove frivolous mime guessing dep 2018-06-22 10:49:43 +02:00
Martin Algesten
72bcbe45db doc fixes 2018-06-22 10:49:03 +02:00
Martin Algesten
0a828bb4a5 cargo fmt 2018-06-22 10:16:37 +02:00
Martin Algesten
5f975270bf send_str to send_string 2018-06-22 10:13:31 +02:00
Martin Algesten
7e3ad42674 content length 2018-06-16 12:35:51 +02:00
Martin Algesten
0d9d5d3096 more doc 2018-06-16 12:07:21 +02:00
Martin Algesten
4791db3a63 more doc 2018-06-16 11:01:28 +02:00
Martin Algesten
5b237066e5 more doc 2018-06-16 10:50:23 +02:00
Martin Algesten
f2c3f351ca remove util submod 2018-06-14 15:18:01 +02:00
Martin Algesten
7177a99d1f move connect calls to stream 2018-06-14 14:38:00 +02:00
Martin Algesten
ef6f8c6259 rustls -> native_tls 2018-06-14 14:17:39 +02:00
Martin Algesten
d4126027c8 cookie jar 2018-06-12 23:09:17 +02:00
Martin Algesten
729f907fe0 get -> header 2018-06-12 19:48:34 +02:00
Martin Algesten
d548b3ef4f simple test harness 2018-06-12 01:30:46 +02:00