2010-06-10 64 views
2

我通过nio.SocketChannel使用HTTP,所以我得到的数据块大小为Array[Byte]。我想把这些块放到一个解析器中,并在每个块放好之后继续解析。解析HTTP - Bytes.length!= String.length

HTTP本身似乎使用ISO8859字符集,但Payload/Body本身可以任意编码: 如果HTTP Content-Length指定X字节,则UTF8解码的Body可能具有更少的字符(1个字符可能是以2个字节以UTF8表示,等等)。

那么什么是一个很好的解析策略,以表彰一个明确指定的Content-Length和/或Transfer-Encoding:Chunked,它指定了要被尊重的块长度。

  • 追加每个数据块到mutable.ArrayBuffer[Byte],搜索CRLF中的字节,直到CRLF解码了从0到字符串,匹配常规表达式就像StatusRegex,HeaderRegex等?
  • 使用适当的字符集(例如iso8859,utf8等)解码每个数据块并添加到StringBuilder。有了这个解决方案,我无法兑现任何内容长度或块大小,但是..我必须关心它吗?
  • 任何其他解决方案...?

回答

0

我积累了ArrayBuffer中的所有Array [Byte],它允许我计算字节数。 HTTP协议解码(状态+标题)是通过搜索CRLF位置然后解码0直到CRLF与ISO8859完成。

分块的实体在ArrayBuffer中累积,并且只有在块已经完全保存在ArrayBuffer中时才使用指定的charset进行解码。如果解码在2字节字符中间正确分割的utf8数据,则会绕过CharsetDecoder的MALFORMED异常。

对于流式HTML,我还没有很好的解决方案,正常的HTML缓存在ArrayBuffer中,并在收到整个文档(如块)后进行解码。

1

您可以使用UTF-16,它是Java的内部字符串表示形式。每个角色都有2个字节,除非有代理。因此,您可以扫描字符串中的代理字符长度,并根据需要对它们进行解释,然后复制子字符串。

+0

感谢您的提示,将需要寻找这些替代品... 目前我有严重的问题正确使用CharsetDecoder,它不时抛出MALFORMED [1]。我的尝试在那里:http://github.com/hotzen/Thesis/blob/master/src/dataflow/io/http/Parser.scala#L416 欣赏任何评论。 – hotzen 2010-06-11 10:03:41