#2166 Wisp:: Setting response charset on non-persistent connection

SlimerDude Mon 8 Jul 2013

I'm looking at the code that sets the charset for http response outstreams, in particular wisp::WispRes#commit:

if (isPersistent)
{
  cout := WebUtil.makeContentOutStream(&headers, sout)
  if (cout != null) webOut = WebOutStream(cout)
}
else
{
  webOut = WebOutStream(sout)
}

If the connection is persistent, then makeContentOutStream() wraps the socket OutStream (sout), setting the charset from the Content-Type:

Charset cs := Charset.utf8
ct := headers["Content-Type"]
if (ct != null) cs = MimeType(ct).charset

len := headers["Content-Length"]
if (len != null)
  return makeFixedOutStream(out, len.toInt) { charset = cs }
// if content-type then assumed chunked output
if (ct != null)
{
  headers["Transfer-Encoding"] = "chunked"
  return makeChunkedOutStream(out) { charset = cs }
}

But, going back to the first code snippet, how / where is the charset set for non-persistent connections?

Is this an oversight, or should I be looking elsewhere?

brian Tue 9 Jul 2013

Thanks for pointing this out! I actually think there was two problems that prevented that from ever working right:

  1. Even in persistent connections, the fixed/chunked output stream got wrapped by WebOutStream which then went back to UTF-8
  2. You are right that non-persistent connections never got their charset set correctly.

To solve #1 I changed default behavior of sys::OutStream to takes its charset from the stream its wrapping.

To solve #2 I added WebUtil.headersToCharset and then added charset check in WispRes.

I would appreciate review of my code.

changeset

SlimerDude Tue 9 Jul 2013

Hi Brain,

The changeset looks okay to me!

Looking at WebUtil::makeContentOutStream() I wasn't aware that methods could take implicit it blocks!

return makeFixedOutStream(out, len.toInt) { charset = cs }
...

static OutStream makeChunkedOutStream(OutStream out)  // Look! No func param!
{
  return ChunkOutStream(out)
}

That seems a little, err, strange!

brian Tue 9 Jul 2013

Basically you can stick a with block on anything because of Obj.with!

Login or Signup to reply.