JSONUtil writeJSONToResponse does not respect content ecoding when GZip output 
is enabled
-----------------------------------------------------------------------------------------

                 Key: WW-3519
                 URL: https://issues.apache.org/jira/browse/WW-3519
             Project: Struts 2
          Issue Type: Bug
    Affects Versions: 2.1.8.1
            Reporter: David Connard


When JSONUtil is used to write JSON to a response output stream via GZIP 
encoding, and that JSON contains extended UTF-8 characters, then the JSON can 
fail to decode correctly.

We are seeing this occur when we use the JSONResult class to send an action 
result to be converted to JSON.  If our result data contains a weird character, 
eg.  Â in this case, then iPhone clients fail to parse that JSON result.

The issue is that the response headers say:

    Content-Type=application/json;charset=UTF-8

which matches the Struts default.  This works fine when you are not GZip 
encoded, as the else condition in the following code block (nb. from JSONUtil, 
starting line 231) is executed:

        if (serializationParams.isGzip()) {
            response.addHeader("Content-Encoding", "gzip");
            GZIPOutputStream out = null;
            InputStream in = null;
            try {
                out = new GZIPOutputStream(response.getOutputStream());
                in = new 
ByteArrayInputStream(json.getBytes(serializationParams.getEncoding()));
                byte[] buf = new byte[1024];
                int len;
                while ((len = in.read(buf)) > 0) {
                    out.write(buf, 0, len);
                }
            } finally {
                if (in != null)
                    in.close();
                if (out != null) {
                    out.finish();
                    out.close();
                }
            }

        } else {
            
response.setContentLength(json.getBytes(serializationParams.getEncoding()).length);
            PrintWriter out = response.getWriter();
            out.print(json);
        }

... and this uses the response writer, which handles the encoding for you.

However, if you have GZip enabled, then the if condition is executed instead, 
whereby you encode the string to bytes, and you are not doing so using the 
correct encoding type.  Platform default will be used instead, yet this 
conflicts with the response headers.

The solution to this is to patch org.apache.struts2.json.JSONUtil.java, line 
237, to add the missing encoding parameter from the json.getBytes() call

                out = new GZIPOutputStream(response.getOutputStream());
-->              in = new 
ByteArrayInputStream(json.getBytes(serializationParams.getEncoding()));
                byte[] buf = new byte[1024];


-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to