Skip to content

PATCH request is forbidden by RestClient but allowed by WebTestClient #31590

New issue

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

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

Already on GitHub? # to your account

Closed
donalmurtagh opened this issue Nov 10, 2023 · 4 comments
Closed
Assignees
Labels
for: external-project Needs a fix in external project

Comments

@donalmurtagh
Copy link

donalmurtagh commented Nov 10, 2023

Affects: spring 6.1.0-RC2 with spring boot 3.2.0-RC2 and JDK21

Description
I've attached a sample Spring Boot application with a single endpoint that accepts PATCH requests. When the endpoint is invoked with a PATCH request from a WebTestClient it is allowed, but when it is invoked with a PATCH request from a RestClient, it fails with the following exception

org.springframework.web.client.ResourceAccessException: I/O error on PATCH request for "http://localhost:61668/api/endpoint": Invalid HTTP method: PATCH
	at org.springframework.web.client.DefaultRestClient$DefaultRequestBodyUriSpec.createResourceAccessException(DefaultRestClient.java:489)
	at org.springframework.web.client.DefaultRestClient$DefaultRequestBodyUriSpec.exchangeInternal(DefaultRestClient.java:414)
	at org.springframework.web.client.DefaultRestClient$DefaultRequestBodyUriSpec.retrieve(DefaultRestClient.java:380)

In SecurityConfiguration.java I've added PATCH to the allowed methods, so I guess RestClient is ignoring this configuration.

Steps to Reproduce
demo.zip

The application contains 2 integration tests, one of which invokes the endpoint with a RestClient and the other uses WebTestClient. The latter test passes, but the former fails.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Nov 10, 2023
@donalmurtagh donalmurtagh changed the title Allowed HTTP methods configuration is ignored by RestClient PATCH request is forbidden by RestClient but allowed by WebTestClient Nov 11, 2023
@poutsma poutsma self-assigned this Nov 14, 2023
@poutsma poutsma added status: invalid An issue that we don't feel is valid and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Nov 14, 2023
@poutsma
Copy link
Contributor

poutsma commented Nov 14, 2023

Spring Boot's RestClient support uses the SimpleClientHttpRequestFactory by default, which is based on the dated java.net.HttpURLConnection, and does not have support for PATCH.

Switching to the more modern Java HttpClient fixes it:

@PostConstruct
private void buildRestClient() {
    restClient = restClientBuilder.baseUrl("http://localhost:" + port)
            .requestFactory(new JdkClientHttpRequestFactory())
            .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
            .build();
}

@poutsma poutsma closed this as not planned Won't fix, can't repro, duplicate, stale Nov 14, 2023
@andrei-ivanov
Copy link

Wouldn't it make sense to change the default client?

@donalmurtagh
Copy link
Author

donalmurtagh commented Nov 14, 2023

Spring Boot's RestClient support uses the SimpleClientHttpRequestFactory by default, which is based on the dated java.net.HttpURLConnection, and does not have support for PATCH.

Switching to the more modern Java HttpClient fixes it:

@poutsma Thanks very much for your reply, I've confirmed that switching the request factory resolves the problem.

Given that RestClient is brand new, shouldn't it use JdkClientHttpRequestFactory by default i.e. there doesn't appear to be a backwards compatibility argument for using HttpURLConnection

@poutsma
Copy link
Contributor

poutsma commented Nov 14, 2023

Wouldn't it make sense to change the default client?

FWIW, RestClient's default request factory—without Boot—is the JdkClientHttpRequestFactory.

It is because Boot uses the same ClientHttpRequestFactorySettings between RestTemplate and RestClient that the SimpleClientHttpRequestFactory is used, doing otherwise would break backward compatibility for RestTemplate users because the factories have different behavior with regards to redirects.

There are plans to improve the situation, see spring-projects/spring-boot#36266

@rstoyanchev rstoyanchev added for: external-project Needs a fix in external project and removed status: invalid An issue that we don't feel is valid labels Nov 14, 2023
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
for: external-project Needs a fix in external project
Projects
None yet
Development

No branches or pull requests

5 participants