Answer doesn't load when using utf-8 characters in header with spring-boot rest and Swagger

I have a spring boot application with swagger. When I test my rest services without utf-8 headers in the header, everything works fine. Swagger generates a command that I can use to test it:

curl -X GET --header 'Accept: application/json' --header 'user: me' --header 'reason: zst' --header 'Authorization: Basic dG9tYXM6dG9tYXMxMjM=' 'http://localhost:8080/my-app/uuid/756531B55A3D029A0894D7C9C4ACDF3EC0' 

but when I use utf-8 characters in swagger, I did not get a response. Swagger is just loading something. When I look in the firefox console, I see only one request:

 http://localhost:8080/my-app/webjars/springfox-swagger-ui/images/throbber.gif 

no answer.

When I try to edit the curl command above:

 curl -X GET --header 'Accept: application/json' --header 'user: me' --header 'reason: žšť' --header 'Authorization: Basic dG9tYXM6dG9tYXMxMjM=' 'http://localhost:8080/my-app/uuid/756531B55A3D029A0894D7C9C4ACDF3EC0' 

everything works fine, so I think there are no problems with my backend. Is there any way how I can fix / debug this problem?

+5
source share
1 answer

In accordance with RFC 2616, Section 4 , Message headers are defined as follows:

 message-header = field-name ":" [ field-value ] field-name = token field-value = *( field-content | LWS ) field-content = <the OCTETs making up the field-value and consisting of either *TEXT or combinations of token, separators, and quoted-string> 

Knowing that according to section 2 :

 token = 1*<any CHAR except CTLs or separators> separators = "(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\" | <"> | "/" | "[" | "]" | "?" | "=" | "{" | "}" | SP | HT CHAR = <any US-ASCII character (octets 0 - 127)> quoted-string = ( <"> *(qdtext | quoted-pair ) <"> ) qdtext = <any TEXT except <">> 

The TEXT rule is used only for the descriptive content of a field and values ​​that are not intended to be interpreted by the message analyzer. The words of * TEXT MAY contain characters from character sets other than ISO-8859-1 only when encoded in accordance with RFC 2047 .

 TEXT = <any OCTET except CTLs, but including LWS> 

In other words, the header value can only be encoded in ISO-8859-1 if you want to encode characters that are not included in this encoding, which seems to be here, you should encode it in accordance with RFC 2047 , also known as MIME ( Multipurpose Internet Email Extensions). Part Three: Message Header Extensions for Non-ASCII Text

So instead

 reason: žšť 

He must be

 reason: =?utf-8?q?=C5=BE=C5=A1=C5=A5?= 

In practice, it is even recommended to encode a value if you do not have only US-ASCII .

The last thing to check on your side is that your JAX-RS implementation supports RFC 2047 , if not, you will need to decode it manually, for example, using the MimeUtility.decodeText(String etext) utility.

Here is a concrete example:

 @GET public Response showHeader(@HeaderParam("reason") String reason) throws UnsupportedEncodingException { // Decode it reason = MimeUtility.decodeText(reason); // Return the value of the decoded String return Response.status(Response.Status.OK) .entity(String.format("Value of reason = '%s'", reason)) .build(); } 

Calling this resource method using curl with --header 'reason: =?utf-8?q?=C5=BE=C5=A1=C5=A5?=' Gives as expected:

 Value of reason = 'žšť' 

NB: To encode your header value from your js interface, you can use the q- library, here is a live demo .

+3
source

Source: https://habr.com/ru/post/1260659/


All Articles