Spring-hateoas: Special characters in request parameters not fully encoded when generating links from controller methods

Created on 9 Mar 2021  ·  7Comments  ·  Source: spring-projects/spring-hateoas

Hello,

when generating Links with WebMvcLinkBuilder containing OffsetDateTime the date does not get transformed correctly resulting in a malfunctioning link.

Example:
Passing an OffsetDateTime like 2020-01-01T14:00:00.000+01:00 results in:

https://myurl.com/service?date=2020-01-01T14:00:00.000+01:00
where the "+" before the offset gets interpreted by the browser as a space " " instead of:
https://myurl.com/service?date=2020-01-01T14:00:00.000%2b01:00.

Setup:

Links are generated with spring-boot-starter-hateoas in version 2.4.3 without custom config.
Example:

public void addLinks(MyModel model, OffsetDateTime date) {
      model.add(
          linkTo(
              methodOn(Controller.class)
                  .getFunction(date))
              .withRel("myLink"));
    } 

Is this expected behavior or in fact a bug?

Thank you.

bug core

All 7 comments

It looks like another case of this issue was reported against Spring Boot: spring-projects/spring-framework#27078

Any update on this ?. It causes no clean upgrade path from previous versions.

This seems to be slightly more tricky than anticipated. We're using Spring Framework's UriUtils.encodeQueryParam(…) method to encode all query parameters. That (of course) only encodes characters deemed invalud for the URI component and a + is indeed an allowed character for query parameters (see the BNF section here and the definition of pchar) and thus, doesn't process it. I.e. this problem doesn't seem to be Spring HATEOAS specific: neither explicitly setting ….encode() on the UriComponentsBuilder changes the output, nor does URI creation via Spring Framework's own MvcUriComponentsBuilder create a different result. Interestingly, UriComponentsBuilder.fromUriString(…) also properly extracts the original String value (i.e. does not try to unencode the plus sign). I guess I'll have to take this to the team for further discussion.

I wonder whether the original expectation is actually correct. + is a valid URI parameter character and if at all, also the colon and the dots would have to be encoded.

Since “+” is effectively a reserved word in URIs, it needs to be encoded. Or else it will be misprocessed. But we may need to encode not at the quert parameter level. Maybe the whole thing?

Maybe we need to spot the usage of “+” on a parameter and do this. Can we spot when to decode a whole URI?

I don't think we (as in "the Spring HATEOAS codebase") should do anything about encoding in particular, except using Spring Framework APIs. Let's wait for the team discussion for now.

This should be fixed in the latest 1.4 snapshots. Note that we now fully encode the request parameters according to URI template RFC rules, which means that not only the plus gets encoded but also the colon.

Was this page helpful?
0 / 5 - 0 ratings