summaryrefslogtreecommitdiffstats
path: root/library/http/http.tcl
diff options
context:
space:
mode:
authorkjnash <k.j.nash@usa.net>2022-09-11 10:57:34 (GMT)
committerkjnash <k.j.nash@usa.net>2022-09-11 10:57:34 (GMT)
commitb34f06a4afa5f57846efbe55f8dccb29e4611e2b (patch)
tree336541f650ed96c8a3dc35d732ef20ec0388d0d4 /library/http/http.tcl
parentd288bedb47342cb10920f38467bcbfcded335e97 (diff)
downloadtcl-b34f06a4afa5f57846efbe55f8dccb29e4611e2b.zip
tcl-b34f06a4afa5f57846efbe55f8dccb29e4611e2b.tar.gz
tcl-b34f06a4afa5f57846efbe55f8dccb29e4611e2b.tar.bz2
Fix bug [a13b9d0ce1] on HTTP compression: remove "compress", amend "deflate".
Diffstat (limited to 'library/http/http.tcl')
-rw-r--r--library/http/http.tcl62
1 files changed, 56 insertions, 6 deletions
diff --git a/library/http/http.tcl b/library/http/http.tcl
index a76ce15..691355c 100644
--- a/library/http/http.tcl
+++ b/library/http/http.tcl
@@ -2128,7 +2128,7 @@ proc http::Connected {token proto phost srvurl} {
&& (![info exists state(-handler)])
&& $http(-zip)
} {
- puts $sock "Accept-Encoding: gzip,deflate,compress"
+ puts $sock "Accept-Encoding: gzip,deflate"
}
if {$isQueryChannel && ($state(querylength) == 0)} {
# Try to determine size of data in channel. If we cannot seek, the
@@ -4010,13 +4010,25 @@ proc http::CopyStart {sock token {initial 1}} {
upvar 0 $token state
if {[info exists state(transfer)] && $state(transfer) eq "chunked"} {
foreach coding [ContentEncoding $token] {
- lappend state(zlib) [zlib stream $coding]
+ if {$coding eq {deflateX}} {
+ # Use the standards-compliant choice.
+ set coding2 decompress
+ } else {
+ set coding2 $coding
+ }
+ lappend state(zlib) [zlib stream $coding2]
}
make-transformation-chunked $sock [namespace code [list CopyChunk $token]]
} else {
if {$initial} {
foreach coding [ContentEncoding $token] {
- zlib push $coding $sock
+ if {$coding eq {deflateX}} {
+ # Use the standards-compliant choice.
+ set coding2 decompress
+ } else {
+ set coding2 $coding
+ }
+ zlib push $coding2 $sock
}
}
if {[catch {
@@ -4137,7 +4149,20 @@ proc http::Eot {token {reason {}}} {
if {[string length $state(body)] > 0} {
if {[catch {
foreach coding [ContentEncoding $token] {
- set state(body) [zlib $coding $state(body)]
+ if {$coding eq {deflateX}} {
+ # First try the standards-compliant choice.
+ set coding2 decompress
+ if {[catch {zlib $coding2 $state(body)} result]} {
+ # If that fails, try the MS non-compliant choice.
+ set coding2 inflate
+ set state(body) [zlib $coding2 $state(body)]
+ } else {
+ # error {failed at standards-compliant deflate}
+ set state(body) $result
+ }
+ } else {
+ set state(body) [zlib $coding $state(body)]
+ }
}
} err]} {
Log "error doing decompression for token $token: $err"
@@ -4387,16 +4412,41 @@ proc http::CharsetToEncoding {charset} {
}
}
+
+# ------------------------------------------------------------------------------
+# Proc http::ContentEncoding
+# ------------------------------------------------------------------------------
# Return the list of content-encoding transformations we need to do in order.
+#
+ # --------------------------------------------------------------------------
+ # Options for Accept-Encoding, Content-Encoding: the switch command
+ # --------------------------------------------------------------------------
+ # The symbol deflateX allows http to attempt both versions of "deflate",
+ # unless there is a -channel - for a -channel, only "decompress" is tried.
+ # Alternative/extra lines for switch:
+ # The standards-compliant version of "deflate" can be chosen with:
+ # deflate { lappend r decompress }
+ # The Microsoft non-compliant version of "deflate" can be chosen with:
+ # deflate { lappend r inflate }
+ # The previously used implementation of "compress", which appears to be
+ # incorrect and is rarely used by web servers, can be chosen with:
+ # compress - x-compress { lappend r decompress }
+ # --------------------------------------------------------------------------
+#
+# Arguments:
+# token - Connection token.
+#
+# Return Value: list
+# ------------------------------------------------------------------------------
+
proc http::ContentEncoding {token} {
upvar 0 $token state
set r {}
if {[info exists state(coding)]} {
foreach coding [split $state(coding) ,] {
switch -exact -- $coding {
- deflate { lappend r inflate }
+ deflate { lappend r deflateX }
gzip - x-gzip { lappend r gunzip }
- compress - x-compress { lappend r decompress }
identity {}
br {
return -code error\