Skip to content

fix(runtime): set Response.url and Response.redirected correctly after fetch redirects#5320

Open
Cypher-CP0 wants to merge 1 commit intoboa-dev:mainfrom
Cypher-CP0:fix/fetch-response-redirected
Open

fix(runtime): set Response.url and Response.redirected correctly after fetch redirects#5320
Cypher-CP0 wants to merge 1 commit intoboa-dev:mainfrom
Cypher-CP0:fix/fetch-response-redirected

Conversation

@Cypher-CP0
Copy link
Copy Markdown

This Pull Request fixes/closes #5310.

It changes the following:

  • Added a redirected: bool field to JsResponse struct in response.rs
  • Updated JsResponse::basic() to accept a redirected parameter and store it
  • Fixed the Response.redirected getter to return the stored value instead of always returning false
  • Updated fetchers.rs to capture the final URL from reqwest before consuming
    the response body, and derive redirected by comparing it to the original request URL
  • Updated Response.url to return the final URL after redirects instead of the original request URL
  • Added response_redirected_flag test in e2e.rs covering both the redirected and non-redirected cases

@Cypher-CP0 Cypher-CP0 requested a review from a team as a code owner April 11, 2026 17:49
@github-actions github-actions bot added the Waiting On Review Waiting on reviews from the maintainers label Apr 11, 2026
@github-actions github-actions bot added this to the v1.0.0 milestone Apr 11, 2026
@github-actions github-actions bot added C-Tests Issues and PRs related to the tests. C-Runtime Issues and PRs related to Boa's runtime features labels Apr 11, 2026
// The spec says: return true if this's response's URL list's size is greater than 1.
// TODO: track the full URL list to implement this properly.
false
self.redirected
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

how does your change align with the TODO comment and spec?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

TODO was about tracking every hop in the redirect chain, but Response.redirected only needs to know if there was any redirect, not the full list. Since reqwest already follows redirects and exposes the final URL, comparing that to the original request URL gives us exactly what we need. Full URL list tracking could still be a follow-up if needed for other spec requirements.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Response.redirected only needs to know if there was any redirect, not the full list

But according to the comment here, spec requires the check to be done via url list, and not a "quick" check like this?

E.g. what if A redirects to B and B redirects back to A? Does your check consider scenario like this?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Thanks for catching that!
You're right, A→B→A would break my check. What approach would you recommend, manual redirect handling to build the full URL list, or something simpler?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Currently the response only has url, but according to spec and the TODO comment, url list is also required: https://fetch.spec.whatwg.org/#concept-response-url-list . So i guess you should implement that and follow the spec for where to modify it in what way.

But fetch api is in general not complete in boa, so idk how much work that actually might be

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I am guessing once you have the list, then A -> B -> A would be handled correctly because of the url list containing multiple urls even though the resulting url might be the same as the original.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Yup, we need to keep a list of urls as described in the specification, since we are using reqwest we can create a client that has custom redirect policy, that will collect the url attempts.

    // part of fetcher initialization:
    let url_list = Arc::new(Mutex::new(Vec::new()));
    let url_list_clone = Arc::clone(&history);

    let custom_policy = redirect::Policy::custom(move |attempt| {
        url_list_clone.lock().expect("should not be poisoned").push(attempt.url().clone());
        reqwest::redirect::Policy::default().redirect(attempt)
    });

    let client = Client::builder()
        .redirect(custom_policy)
        .build()?;

    // making the request
    let result = self.client.execute(req);
    
    // clears and takes the list for the previous request.
    let url_list = std::mem::take(&mut *self.url_list.lock().expect("should not be poisoned"));

    let response = result.map_err(JsError::from_rust)?;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

C-Runtime Issues and PRs related to Boa's runtime features C-Tests Issues and PRs related to the tests. Waiting On Review Waiting on reviews from the maintainers

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fetch() keeps the original URL after redirects

3 participants