Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Redirect config per request #277

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open

Redirect config per request #277

wants to merge 5 commits into from

Conversation

ncke
Copy link

@ncke ncke commented Jun 27, 2020

Allows redirect handling to be configured per request.

Motivation:

Redirect configuration is set globally when configuring the HTTPClient. However, it would also be useful to configure redirects on a per request basis. This would mean that a single HTTPClient could be configured and shared widely throughout an application, while retaining the flexibility to tailor specific requests with custom redirect handling should the need arise.

Modifications:

This change adds an optional redirectConfiguration parameter to all request methods of HTTPClient, with a nil default value. When the request is executed the prevailingConfiguration is determined using the redirectConfiguration argument, if set. Otherwise the global configuration is used.

Result:

Allows redirect handling to be configured on a per request basis, closes #196

ncke added 2 commits June 27, 2020 23:10
Motivation:

Redirect configuration is set globally when configuring the `HTTPClient`. However, it would also be useful to configure redirects on a per request basis. This would mean that a single `HTTPClient` could be configured and shared widely throughout an application, while retaining the flexibility to tailor specific requests with custom redirect handling should the need arise.

Modifications:

This change adds an optional `redirectConfiguration` parameter to all request methods of `HTTPClient`. When the request is executed the `prevailingConfiguration` is determined using the `redirectConfiguration` argument, if set. Otherwise the global configuration is used.

Result:

Allows redirect handling to be configured on a per request basis, closes #196
Motivation:

Test support for redirection configuration on a per request basis.

Modifications:

Test that the configured request will refuse to follow redirection cycles even when the client allows them.
Test that the configured request will throw due to reach the redirection limit even when the client does not follow redirections.
Test that the configured request does not follow redirections even when the client allows them.

Result:

Per request redirection configured tested.
@swift-server-bot
Copy link

Can one of the admins verify this patch?

3 similar comments
@swift-server-bot
Copy link

Can one of the admins verify this patch?

@swift-server-bot
Copy link

Can one of the admins verify this patch?

@swift-server-bot
Copy link

Can one of the admins verify this patch?

@Lukasa
Copy link
Collaborator

Lukasa commented Jun 29, 2020

@swift-server-bot test this please

@Lukasa
Copy link
Collaborator

Lukasa commented Jun 29, 2020

Before we go down this road, we should take this opportunity to ask ourselves whether there is any other configuration that can sensibly be provided "per call". If there is, we may want to whack it all in at once.

Copy link
Collaborator

@Lukasa Lukasa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the code front, can you clean up the formatter issues? They're shown in the CI output.

@Lukasa
Copy link
Collaborator

Lukasa commented Jun 29, 2020

I think I've talked myself into saying that redirect is special here. Most of the others are either managed by the connection pool or cannot safely be changed without invalidating the pool, or are otherwise already handled. So I think I'm ok with the shape of this change. @artemredkin any preference for anything else here?

@Lukasa
Copy link
Collaborator

Lukasa commented Jun 29, 2020

Oh, one note though @ncke: we can't add optional parameters to these methods, it's a semver major change to do it. We need to add new methods with extra arguments instead.

@ncke
Copy link
Author

ncke commented Jun 29, 2020

I'll add new methods rather than the arguments.

I was also wondering whether the Task might be a better place to store redirect state (e.g. count) rather than the Request. I'm concerned that replaying an executed (or executing) Request may copy the dirty redirect state rather than creating pristine state for the second execution, with unexpected results.

@Lukasa
Copy link
Collaborator

Lukasa commented Jun 29, 2020

Request is a value type: mutations made to that field by HTTPClient are not reflected in your local copy.

Motivation:

Redirect configuration is set globally when configuring the `HTTPClient`. However, it would also be useful to configure redirects on a per request basis. This would mean that a single `HTTPClient` could be configured and shared widely throughout an application, while retaining the flexibility to tailor specific requests with custom redirect handling should the need arise.

Modifications:

Adds new methods providing a `redirectConfiguration` argument to support per request redirection.

When the request is executed the `prevailingConfiguration` is determined using the `redirectConfiguration` argument, if set. Otherwise the global configuration is used.

Fixes code formatting.

Result:

Allows redirect handling to be configured on a per request basis, closes #196
@ncke ncke requested a review from Lukasa June 29, 2020 18:33
Copy link
Collaborator

@Lukasa Lukasa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great, I think this broadly looks good, just a single thing I'd like to see addressed.

/// - parameters:
/// - url: Remote URL.
/// - deadline: Point in time by which the request must complete.
/// - redirectConfiguration: The configuration of redirect handling for this request.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we update these docstrings to explain what nil means? This applies to all new methods.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. Can we also change the argument name from redirectConfiguration to redirects? I think there was an earlier suggestion that this is more pithy and I like the idea.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No objection from me.

@dimitribouniol
Copy link
Contributor

I think I've talked myself into saying that redirect is special here. Most of the others are either managed by the connection pool or cannot safely be changed without invalidating the pool, or are otherwise already handled. So I think I'm ok with the shape of this change. @artemredkin any preference for anything else here?

Perhaps we can have a configuration type specific to requests (ie. execute(..., configuration: RequestConfiguration? = nil))? One more option that would be configurable per request would be the ability to specify how Host is represented, as brought up here: #229 (comment), and having a configuration type we can extend and add to could be useful here.

@dimitribouniol
Copy link
Contributor

Oh, one note though @ncke: we can't add optional parameters to these methods, it's a semver major change to do it. We need to add new methods with extra arguments instead.

@Lukasa Most of these methods (ie. the ones that add logging and conveniences for socket paths) are new and haven't actually been released — would modifying those be ok?

Motivation:

Redirect configuration is set globally when configuring the `HTTPClient`. However, it would also be useful to configure redirects on a per request basis. This would mean that a single `HTTPClient` could be configured and shared widely throughout an application, while retaining the flexibility to tailor specific requests with custom redirect handling should the need arise.

Modifications:

Adds docstrings explanation for nil arguments.

Renames the new `redirectConfiguration` to `redirects`, where it is specialising a specific request.

Result:

Allows redirect handling to be configured on a per request basis, closes #196
@ncke ncke requested a review from Lukasa July 2, 2020 20:47
@ncke
Copy link
Author

ncke commented Jul 2, 2020

@dimitribouniol With regard to simplifying future extension I wondered about retaining the current httpClient.get(...) style for simple cases, but contriving to allow httpClient.with(configuration: ...).get(...) to allow the caller to chain modifications to the execution context before reaching the final verb?

@Lukasa
Copy link
Collaborator

Lukasa commented Jul 3, 2020

I definitely like the idea of having request configuration. I don't think I love the chaining idea though: I don't think it adds meaningful API clarity. Having a struct you can pass that defines a per-request configuration overload seems sensible though.

As for changing methods, anything that hasn't shipped in an existing release can be changed, yeah.

@ktoso ktoso changed the base branch from master to main August 20, 2020 01:30
@ktoso
Copy link
Contributor

ktoso commented Aug 20, 2020

Just as a heads up, the main development branch has been changed to main, following the Swift policy on this.

This PR has been re-targeted to main and should just work. However when performing rebases etc please keep this in mind -- you may want to fetch the main branch and rebase onto the main branch from now on since master is not up-to-date anymore and is going to be deleted shortly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

redirect configuration is only available top-level on HTTPClient
5 participants