I have a groovy/grails application that needs to serve images
It works fine on my dev box, the image is returned properly. Here's the start of the returned JPEG, as seen by od -cx
0000000 377 330 377 340 \0 020 J F I F \0 001 001 001 001 ,
d8ff e0ff 1000 464a 4649 0100 0101 2c01
but on the production box, there's some garbage in front, and the d8ff e0ff before the 1000 is missing
0000000 � ** ** � ** ** � ** ** � ** ** \0 020 J F
bfef efbd bdbf bfef efbd bdbf 1000 464a
0000020 I F \0 001 001 001 \0 H \0 H \0 \0 � ** ** �
4649 0100 0101 4800 4800 0000 bfef efbd
It's the exact same code. I just moved the .war over and run it on a different machine. (Isn't Java supposed to be write once, run everywhere?)
Any ideas? An "encoding" problem?
The code is sent to the response like this:
response.contentType = "image/jpeg"; response.outputStream << out;
Here's the code that locates the image on an internal application server and re-serves the image. I've pared down the code a bit to remove the error handling, etc, to make it easier to read.
def show = {
def address = "http://internal.application.server:9899/img?photoid=${params.id}"
def out = new ByteArrayOutputStream()
out << new URL(address).openStream()
response.contentLength = out.size();
// XXX If you don't do this hack, "head" requests won't work!
if (request.method == 'HEAD')
{ render( text : "", contentType : "image/jpeg" ); }
else {
response.contentType = "image/jpeg"; response.outputStream << out;
}
}
Update: I tried setting the CharacterEncoding
response.setCharacterEncoding("ISO-8859-1");
if (request.method == 'HEAD')
{ render( text : "", contentType : "image/jpeg" ); }
else {
response.contentType = "image/jpeg;charset=ISO-8859-1"; response.outputStream << out;
}
but it made no difference in the output. On my production machine, the binary bytes in the image are re-encoded/escaped as if they were UTF-8 (see Michael's explanation below). It works fine on my development machine.