1

I am using a Spring-Web application using jetty:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jetty</artifactId>
</dependency>

Assume this http endpoint:

@RestController
public class ExampleController {

  @GetMapping(value = "/example", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
  public ExampleResponse example() {
      return new ExampleResponse();
  }

  public static class ExampleResponse {
      private String dummy = "example";

      public String getDummy() {
          return dummy;
      }
  }
}

and curl against the Endpoint and inspect the header curl -v localhost:8080/example:

* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /example HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.58.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Date: Tue, 08 Oct 2019 13:52:10 GMT
< Content-Type: application/json;charset=utf-8
< Transfer-Encoding: chunked
< 
* Connection #0 to host localhost left intact

Notice the charset=**utf-8** in the response header, but I am setting the header via the annotation produces=MediaType.APPLICATION_JSON_UTF8_VALUE to the value application/json;charset=UTF-8. So Jetty (using tomcat everything works fine) lowercases the charset in the response header.

Why is that a problem? Some people working against my endpoints and validate this with a JSON Valiadtor (like: https://jsonformatter.curiousconcept.com/).

This validator expects the charset in UPPERCASE. (See https://stackoverflow.com/a/48466826/3046582). So what can I do about this?

Update:

like @Kayaman says System.setProperty("org.eclipse.jetty.http.HttpGenerator.STRICT", "true"); bevor the Spring-Application run wil fix this.

I also found a workaround: MimeTypes.CACHE.remove("application/json;charset=utf-8"); will solve this.

user3046582
  • 341
  • 3
  • 15

1 Answers1

3

Then that validator is broken. The spec mandates case insensitivity.

Note that both character set names and language tags are restricted to the US-ASCII character set, and are matched case-insensitively (see [RFC2978], Section 2.3 and [RFC5646], Section 2.1.1).

And the W3 Org's example uses Content-Type: text/html; charset=utf-8 as a "typical" header.

But if the question is, why does Jetty lowercase it? Well, I decided to skulk around in the sources, and found where the charset is sanitized.

And from there, going to HttpGenerator we find

If the system property "org.eclipse.jetty.http.HttpGenerator.STRICT" is set to true, then the generator will strictly pass on the exact strings received from methods and header fields. Otherwise a fast case insensitive string lookup is used that may alter the case and white space of some methods/headers

Community
  • 1
  • 1
Kayaman
  • 72,141
  • 5
  • 83
  • 121
  • I totally agree with you but, nevertheless why does jetty overwrite media type, when I explicit define it? – user3046582 Oct 08 '19 at 14:50
  • Well, it could be as simple as Jetty doing `.toLowerCase()` somewhere. You could take a look at [Jetty's source code](https://github.com/eclipse/jetty.project) to see where it's handling the response headers, if you're so inclined. But Jetty is working perfectly validly, so you should be more interested in the parties that require `UTF8` to be in uppercase. – Kayaman Oct 08 '19 at 14:53
  • @user3046582 fixed it for ya. – Kayaman Oct 08 '19 at 15:28
  • 2
    Jetty 9.4 follows the recommendations at [RFC7231 HTTP/1.1 Semantics and Content - Section 3.1.1.1 for Media Types](https://tools.ietf.org/html/rfc7231#section-3.1.1.1) - also note, `org.eclipse.jetty.http.HttpGenerator.STRICT` is deprecated, and moved to the `HttpCompliance` settings now (and in the future). – Joakim Erdfelt Oct 10 '19 at 11:15