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

RestTemplate with interceptor calling response getBody() throws IOException even if BufferingClientHttpRequestFactory is set #33662

Closed
Hotvianskyi opened this issue Oct 7, 2024 · 4 comments
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) status: duplicate A duplicate of another issue

Comments

@Hotvianskyi
Copy link

Hotvianskyi commented Oct 7, 2024

Affects: at least 3.2.1 to 3.3.4

The issue occurs when using RestTemplate to call another server as a client. There is a specific use case doesn't work as expected:

Steps to reproduce:
RestTemplate includes this line: restTemplate.setRequestFactory(new BufferingClientHttpRequestFactory(new SimpleClientHttpRequestFactory())); or an equivalent
Interceptor is created with a call getBody() on the result of ClientHttpRequestExecution.execute() inside of intercept() method override (for example, for logging purposes)
RestTemplate includes this interceptor
There is a call to restTemplate.exchange() with POST or PUT request, this request is expected to return an error (4xx or 5xx)

Expected result:
getBody() for the result of ClientHttpRequestExecution.execute() inside of the interceptor override is succesfully processed and the execution proceeds as usual, as BufferingClientHttpRequestFactory should provide the wrapped buffered response.

Actual result:
getBody() throws an IOException
Error demonstration:
https://github.com/Hotvianskyi/rest-remplate-bug

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Oct 7, 2024
@bclozel
Copy link
Member

bclozel commented Oct 7, 2024

Have you tried following Andy's advice here? Is it working out for you?

@bclozel bclozel added status: waiting-for-feedback We need additional information before we can continue in: web Issues in web modules (web, webmvc, webflux, websocket) labels Oct 7, 2024
@Hotvianskyi
Copy link
Author

I don't think ignoring IOException is a solution that I am willing to apply. It ether should be another more specific exception or no exception at all at that stage.
Shouldn't this case in general be prevented by usage of BufferingClientHttpRequestFactory? From description of it, it was specifically created to disable streaming mode and allow to always have access to response body, as long as that response object is accessible. there shouldn't be an IO error with cannot retry due to server authentication, in streaming mode

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Oct 7, 2024
@nrayburn-tech
Copy link

This might be the same as #33020.

@bclozel
Copy link
Member

bclozel commented Oct 8, 2024

Thanks for the comment @nrayburn-tech , I think this is right.

@Hotvianskyi I have upgraded your sample to Spring Boot 3.4.0-M3 and updated your test case with the following:

    @Test
    void helloWorldBufferSimpleInterceptor() throws Exception {
        mockMvc.perform(get("/hello-buffer-simple-intercept"))
              .andExpect(content().string("401  on POST request for \"http://localhost:8800/hello-world-401\": [no body]"));
    }

    @Test
    void helloWorldBufferSimple() throws Exception {
        mockMvc.perform(get("/hello-buffer-simple"))
              .andExpect(content().string("401  on POST request for \"http://localhost:8800/hello-world-401\": [no body]"));
    }

    @Test
    void helloWorldBufferHttpComponents() throws Exception {
        mockMvc.perform(get("/hello-buffer-httpcomponents"))
              .andExpect(content().string("401  on POST request for \"http://localhost:8800/hello-world-401\": \"Unauthorized\""));
    }

We're not getting IOException anymore.

While the behavior is not great, this is an important behavior change and I believe this is why this was not backported to a maintenance version in 6.1.x. I'm closing this issue as a duplicate then. Thanks for this report!

@bclozel bclozel closed this as not planned Won't fix, can't repro, duplicate, stale Oct 8, 2024
@bclozel bclozel added status: duplicate A duplicate of another issue and removed status: waiting-for-triage An issue we've not yet triaged or decided on status: feedback-provided Feedback has been provided labels Oct 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) status: duplicate A duplicate of another issue
Projects
None yet
Development

No branches or pull requests

4 participants