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

Consumes condition support for optional content [SPR-17478] #22010

Closed
spring-projects-issues opened this issue Nov 8, 2018 · 4 comments
Closed

Consumes condition support for optional content [SPR-17478] #22010

spring-projects-issues opened this issue Nov 8, 2018 · 4 comments
Assignees
Labels
in: web type: enhancement
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

@spring-projects-issues spring-projects-issues commented Nov 8, 2018

Vitalii Ishchenko opened SPR-17478 and commented

Request validation behaves badly for cases when RequestBody is optional and not provided, but consumes is specified in RequestMapping annotation

i.e. having following method in controller, annotated with PostMapping, request will fail with empty body and no Content-Type. Sending dummy content type will resolve the issue

 

@PostMapping(value = "/records", consumes = "application/json")
public List<String> queryRecords(@RequestBody(required = false) Map<String, String> filter) {
    return Collections.emptyList();
}

Fails:

curl -X "POST" "http://localhost:8080/records"

> POST /records HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 415
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Thu, 08 Nov 2018 08:01:09 GMT
<
* Connection #0 to host localhost left intact
{"timestamp":"2018-11-08T08:01:09.927+0000","status":415,"error":"Unsupported Media Type","message":"Content type '' not supported","path":"/records"}

Succeeds:

curl -X "POST" "http://localhost:8080/records" \
     -H 'Content-Type: application/json'

> POST /records HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.54.0
> Accept: */*
> Content-Type: application/json
>
< HTTP/1.1 200
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Thu, 08 Nov 2018 08:03:31 GMT
<
* Connection #0 to host localhost left intact
[]

Sample Spring Boot app is attached


Affects: 5.1.2

Attachments:

Issue Links:

  • #21955 @RequestBody(required=false) and no Content-Type Header Issue ("duplicates")
@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Nov 19, 2018

Rossen Stoyanchev commented

This is the same as #21955. I am scheduling for 5.2 tentatively to explore a potential solution to this, where the consumes condition checks the "content-length" and/or "transfer-encoding" headers for cases when there is no body.

We'll probably need to decide what to do if two methods both match the request (e.g. one json, one xml) and there is no content. Perhaps rejecting that as ambiguous mapping might not be so bad, or maybe that's how it already behaves today.

@spring-projects-issues spring-projects-issues added type: enhancement in: web labels Jan 11, 2019
@spring-projects-issues spring-projects-issues added this to the 5.2 RC1 milestone Jan 11, 2019
@rstoyanchev rstoyanchev removed their assignment Jan 28, 2019
@jhoeller jhoeller removed this from the 5.2 M1 milestone Mar 23, 2019
@jhoeller jhoeller added this to the 5.2 M2 milestone Mar 23, 2019
@shollander
Copy link

@shollander shollander commented Mar 28, 2019

I am having a similar issue. I would add that this bug will also affects GET methods that don't declare any @RequestBody. For example:

@RestController
@RequestMapping(path="/widgets", consumes= "application/vnd.mywidgets+json")
class WidgetController {

    @PostMapping("/find")
    List<Widget> query(@RequestBody WidgetQuery) {
    }

    @GetMapping("/find")
    List<Widget> query() {
    }
}

Calling GET /widgets/find will fail with an HTTP 415 error if the Content-Type header is not set on the request. I believe this behavior is incorrect since there is no content being sent.

@rstoyanchev rstoyanchev self-assigned this May 6, 2019
@rstoyanchev
Copy link
Contributor

@rstoyanchev rstoyanchev commented May 7, 2019

@shollander, in your case the consumes condition at the controller level is declared too broadly.

@rstoyanchev rstoyanchev changed the title Request validation behaves badly for cases when RequestBody is optional and not provided in request [SPR-17478] Consumes condition support for optional content [SPR-17478] May 7, 2019
@shollander
Copy link

@shollander shollander commented May 8, 2019

@rstoyanchev, why is the consumes condition declared too broadly? If I have multiple methods that all have the same consumes condition, then I would like to be able to declare it at the class level instead of duplicating it for every method. The framework should be smart enough to figure out that if there is no @RequestBody then the consumes condition should be ignored. I don't see why this case is any different than the case of the OP where the request body is optional.

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

No branches or pull requests

4 participants