Skip to content

Conversation

@cochi2
Copy link
Contributor

@cochi2 cochi2 commented Jul 19, 2021

Creating a new http policy that, if added, will redirect any request, upon reception of an 302 Http Response, to the new URL received under the "Location" header.

@ghost ghost added the Communication label Jul 19, 2021
@cochi2 cochi2 force-pushed the fmorales/download-sdk-redirection branch from c7ed80b to fa78f06 Compare July 19, 2021 20:27
@cochi2 cochi2 marked this pull request as ready for review July 20, 2021 17:15
* Location header.
*/
public final class RedirectPolicy implements HttpPipelinePolicy {
private static final int MAX_REDIRECTS = 10;
Copy link
Member

Choose a reason for hiding this comment

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

Any concerns around potentially running into a scenario where there are many redirects as well as retries? Since this and the retry policy will both attempt to retry and could result in a multiplicative scenario, ex 3 retry attempts and 10 redirect attempts could result in 30 (possibly 40) network calls before failing.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well no, the policy updates the request when doing the redirection. If there is an error, it is the latest version of the request which will retry.

Copy link
Member

Choose a reason for hiding this comment

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

Good point, I also realized that this is short-circuiting redirect location, so having a request amplification isn't as likely.

Copy link
Member

Choose a reason for hiding this comment

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

If this is moved to azure-core as suggested above, we should make this customizable (as a constructor arg)


private boolean shouldRedirect(HttpResponse response, int redirectNumber) {
return response.getStatusCode() == 302
&& !locations.contains(response.getHeaderValue(LOCATION_HEADER_NAME))
Copy link
Member

Choose a reason for hiding this comment

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

Based on this a request isn't able to be redirected back to a previously used redirection? Is there a possibility that this causes an error?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Assuming that the services are deterministic, if we allow to try a previously used location we will end up on some loop. So, we are short circuiting at the first opportunity.

Copy link
Member

Choose a reason for hiding this comment

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

I think starting with that logic works, another possibility is making the previously used and failed redirects a chain, so if the service attempts to redirect you to somewhere that has been known to redirect can short-circuit the redirection chain isn't of failing the request outright, ex:

location 1 -> 2 -> 3 -> 4 -> 5 -> success

If the redirect is for 3 we could short-circuit to 5. But this introduces a lot more complexity and chances of incorrect behavior.

Copy link
Member

Choose a reason for hiding this comment

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

We should at least log when a previously attempted redirect link is returned again as the redirect link and reach out to service teams when we notice this behavior. This seems like a bug on the service side that's resulting in a cycle.

@cochi2 cochi2 force-pushed the fmorales/download-sdk-redirection branch from f252251 to 94a831e Compare July 21, 2021 20:37
cochi2 added 4 commits July 21, 2021 14:56
* Replacing List with Set for locations.
* Moving locations variable to be a method parameter instead of a
  class's attribute.
* Refactored testing.
@cochi2 cochi2 force-pushed the fmorales/download-sdk-redirection branch from 94a831e to 3c09f60 Compare July 21, 2021 21:56
@ghost
Copy link

ghost commented Jul 22, 2021

Hello @cochi2!

Because this pull request has the auto-merge label, I will be glad to assist with helping to merge this pull request once all check-in policies pass.

p.s. you can customize the way I help with merging this pull request, such as holding this pull request until a specific person approves. Simply @mention me (@msftbot) and give me an instruction to get started! Learn more here.

@ghost ghost merged commit 4c9537d into main Jul 22, 2021
@ghost ghost deleted the fmorales/download-sdk-redirection branch July 22, 2021 22:16

private boolean shouldRedirect(HttpResponse response, int redirectNumber) {
return response.getStatusCode() == 302
&& !locations.contains(response.getHeaderValue(LOCATION_HEADER_NAME))
Copy link
Member

Choose a reason for hiding this comment

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

We should at least log when a previously attempted redirect link is returned again as the redirect link and reach out to service teams when we notice this behavior. This seems like a bug on the service side that's resulting in a cycle.

* HttpPipelinePolicy to redirect requests when 302 message is received to the new location marked by the
* Location header.
*/
public final class RedirectPolicy implements HttpPipelinePolicy {
Copy link
Member

Choose a reason for hiding this comment

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

This policy is a duplicate of what we have in another service - azure-monitor-opentelemetry-exporter. We should move this to azure-core, so that both services (and potentially others) can share.

Copy link
Member

Choose a reason for hiding this comment

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

});
}

private boolean shouldRedirect(HttpResponse response, int redirectNumber, Set<String> locations) {
Copy link
Member

Choose a reason for hiding this comment

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

nit: name redirectNumber as redirectAttempt or tryCount.

}

private Mono<HttpResponse> attemptRedirection(HttpPipelineCallContext context, HttpPipelineNextPolicy next,
int redirectNumber, Set<String> locations) {
Copy link
Member

Choose a reason for hiding this comment

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

name locations as attemptedRedirectLocations

* Location header.
*/
public final class RedirectPolicy implements HttpPipelinePolicy {
private static final int MAX_REDIRECTS = 10;
Copy link
Member

Choose a reason for hiding this comment

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

If this is moved to azure-core as suggested above, we should make this customizable (as a constructor arg)

}

private boolean shouldRedirect(HttpResponse response, int redirectNumber, Set<String> locations) {
return response.getStatusCode() == 302
Copy link
Member

Choose a reason for hiding this comment

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

What about other status codes like 301 (moved permanently), 307 (temporary redirect) and 308 (permanent redirect)? Also, instead of using magic numbers, use named constants.

This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants