【发布时间】:2019-11-06 10:18:21
【问题描述】:
我的 Tcl 源文件是 utf-8 格式。 Tclhttpd 不能正确发送国家字符,所以我对其进行了一些修改。但是,我也发送二进制文件,如 jpg 图像,有时二进制块存在于我的其他 utf-8 HTML 中。我很难计算出正确的 Content-length 以完全匹配浏览器接收到的内容(否则一些尾随字符会破坏下一个请求标头,或者浏览器会等待每个请求 30 秒,直到超时)。
也就是说,请问puts $socket 向套接字写入了多少字节?
我发现了一个特殊的 11 字节序列,它搞砸了计数:
proc dump3 string {
binary scan $string c* c
binary scan $string H* hex
return [sdump $string]\n$c\n$hex
};#dump3
proc Httpd_ReturnData {sock type content {code 200} {close 0}} {
global Httpd
upvar #0 Httpd$sock data
#...skip non-pertinent code...
set content \x4f\x4e\xc2\x00\x03\xff\xff\x80\x00\x3c\x2f
#content=ONÂÿÿ�</
#79 78 -62 0 3 -1 -1 -128 0 60 47
#4f4ec20003ffff80003c2f
puts content=[dump3 $content]
puts utf8=[dump3 [encoding convertto utf-8 $content]]
if {[catch {
puts "string length=[string length $content] type=$type"
puts "stringblength=[string bytelength $content]"
set len [string length $content]
if [string match -nocase *utf-8* $type] {
fconfigure $sock -encoding utf-8
set len [string bytelength $content]
}
puts "len=$len fcon=[fconfigure $sock]"
HttpdRespondHeader $sock $type $close $len $code
HttpdSetCookie $sock
puts $sock ""
if {$data(proto) != "HEAD"} {
##fconfigure $sock -translation binary -blocking $Httpd(sockblock)
##native: -translation {auto crlf}
fconfigure $sock -translation lf -blocking $Httpd(sockblock)
puts -nonewline $sock $content
}
Httpd_SockClose $sock $close
} err]} {
HttpdCloseFinal $sock $err
}
}
控制台的输出是:
内容=ONÂÿÿ� 79 78 -62 0 3 -1 -1 -128 0 60 47 4f4ec20003ffff80003c2f utf8=ONÃ�ÿÿÂ� 79 78 -61 -126 0 3 -61 -65 -61 -65 -62 -128 0 60 47 4f4ec3820003c3bfc3bfc280003c2f 字符串长度=11 类型=文本/html;字符集=utf-8 字符串长度=17 len=17 fcon=-blocking 0 -buffering full -buffersize 16384 -encoding utf-8 -eofchar {{} {}} -translation {auto crlf} -peername {128.0.0.71 128.0.0.71 55305} -sockname {128.0.0.8第 8016 代} HttpdRespondHeader 17结果 Content-Length: 17 太多了,浏览器一直在等待。如果我能事先知道,puts 将从我的字符串中产生多少字节,剩下的就很容易了。有什么办法吗?
【问题讨论】:
标签: utf-8 tcl content-length http-content-length