summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkjnash <k.j.nash@usa.net>2018-03-27 08:29:43 (GMT)
committerkjnash <k.j.nash@usa.net>2018-03-27 08:29:43 (GMT)
commit767cf6314a06f14d275746f66df21ef6ee324715 (patch)
tree1745f0d4696a6e723c844961daf3aff39f3e4325
parentb00317d1742830de2509ee2020d19c46ff0dd665 (diff)
downloadtcl-767cf6314a06f14d275746f66df21ef6ee324715.zip
tcl-767cf6314a06f14d275746f66df21ef6ee324715.tar.gz
tcl-767cf6314a06f14d275746f66df21ef6ee324715.tar.bz2
Workaround for bug with https and unchunked response. A [read] does not deliver until the server closes the socket. The workaround is to specify the buffer size as the precise length required.
-rw-r--r--library/http/http.tcl18
1 files changed, 17 insertions, 1 deletions
diff --git a/library/http/http.tcl b/library/http/http.tcl
index 5b9d03a..d67e217 100644
--- a/library/http/http.tcl
+++ b/library/http/http.tcl
@@ -1263,11 +1263,23 @@ proc http::Event {sock token} {
# We know the transfer is complete only when the server
# closes the connection.
set state(state) complete
+ set reqSize $state(-blocksize)
+ } else {
+ # Ask for the whole of the unserved response-body.
+ # This works around a problem with a tls::socket - for https
+ # in keep-alive mode, and a request for $state(-blocksize)
+ # bytes, the last part of the resource does not get read
+ # until the server times out.
+ set reqSize [expr {$state(totalsize) - $state(currentsize)}]
+
+ # The workaround fails if reqSize is
+ # capped at $state(-blocksize).
+ # set reqSize [expr {min($reqSize, $state(-blocksize))}]
}
set c $state(currentsize)
set t $state(totalsize)
##Log non-chunk currentsize $c of totalsize $t - token $token
- set block [read $sock $state(-blocksize)]
+ set block [read $sock $reqSize]
set n [string length $block]
if {$n >= 0} {
append state(body) $block
@@ -1404,6 +1416,10 @@ proc http::CopyStart {sock token {initial 1}} {
}
}
if {[catch {
+ # FIXME Keep-Alive on https tls::socket with unchunked transfer
+ # hangs until the server times out. A workaround is possible, as for
+ # the case without -channel, but it does not use the neat "fcopy"
+ # solution.
fcopy $sock $state(-channel) -size $state(-blocksize) -command \
[list http::CopyDone $token]
} err]} {