View Ticket
Not logged in
Ticket Hash: 1901276a50931802841d0d0c4d4bd9134b81ab49
Title: http::geturl with -handler fails in 2.9.0 when retrieved data is larger than 16k ?
Status: Closed Type: Documentation
Severity: Cosmetic Priority: Zero
Subsystem: Resolution: External_Bug
Last Modified: 2019-08-18 12:24:40
Version Found In: vanillawish-e5dc71ed9d
User Comments:
anonymous added on 2019-08-13 10:10:54:
We are using the http package like follows:

set ut [::http::geturl ${to_get} -handler _proc_data ...]

When the data to be retrieved is less than approx. 16k in size (tested on Linux 64 Bit and Win64) the handler is called correctly, if the size is larger than 16k the handler ist called, but gets an immediate [eof] condition after the [read] on the supplied socket !!
It seems someone else is reading the channel before or passes the wrong channel :-(
When using the http 2.8 package, in the same environment, everything works as expected. 

Due to the large diffs between 2.8 and 2.9 we were not able to trace the issue further. 

Regards

Benno Lange

chw added on 2019-08-16 09:42:46:
Please provide a test snippet which reliably reproduces your problem.

anonymous added on 2019-08-18 12:24:40:
We could NOT reproduce the error using an internet hosted server with the below test-script :-(
The error only happened using a https connection with an internal embedded web server (10+ year old legacy application).
Further investigation showed that the server does not correctly flush the socket, which leads to the loss of all http contents :-(
So this was, as often, a user error.
We apologize for bothering ....

While testing we only noticed, that the -handler procedure is sometimes called even when no data is available (even with http 2.8 !), which is not exactly what the documentation says ...


bug_http.tcl:
----------------------------------------------------------------------------
set httpvers [package require http 2]
puts "GOT HTTP <$httpvers>"

set trr [package require tls]
puts "GOT TLS <$trr>"


http::register https 443 [list ::tls::socket -tls1 1 -ssl2 0 -ssl3 0]
puts "registered HTTPS <[::tls::version]>"

::http::config -urlencoding {iso8859-1}
set ::http::defaultCharset {iso8859-1}

set method "https"

if { [lindex $argv 0] == "l" }\
{
    # large build-undroidwish-freebsd.sh
    set to_get ${method}://www.androwish.org/index.html/artifact/219f6dc8a1c3f904
}\
else\
{
    # small README.txt
    set to_get ${method}://www.androwish.org/home/artifact/671fd46bcbb56ef8
}


set ::use_nonblock 0

proc _proc_data { sock token }\
{
    puts "_proc_data <$sock> <$token>"

    set al 0
    if { $::use_nonblock }\
    {
        fconfigure $sock -blocking false
    }
    while {1} \
    {
        set rd [read $sock 4096]
        set ll [string length $rd]
        puts "GOT len=<$ll>"
        if { $ll > 0 && "$rd" != "" } \
        {
            # add to whole length
            incr al $ll
        }\
        else\
        {
            if { [eof $sock] }\
            {
                puts "RCV got EOF"
                set ::forever 1
            }
            break
        }
    }
    puts "RCV done <$al> eof=<[eof $sock]>"
    if { $::use_nonblock }\
    {
        fconfigure $sock -blocking true
    }

    if { [eof $sock] }\
    {
        exit 0
    }

    return $al
}

puts "GET <$to_get>"

set ut [::http::geturl ${to_get} -handler _proc_data]

vwait ::forever
--------------------------------------------------------------------------

Sometimes the output looks like:

---------------------------------------------------
~/vanillawish-e5dc71ed9d-linux64 ./bug_http.tcl l
GOT HTTP <2.9.0>
GOT TLS <1.6.7>
registered HTTPS <LibreSSL 2.9.2>
GET <https://www.androwish.org/index.html/artifact/219f6dc8a1c3f904>
_proc_data <sock19de680> <::http::1>
GOT len=<4096>
GOT len=<4096>
GOT len=<3951>
GOT len=<0>
RCV done <12143> eof=<0>
_proc_data <sock19de680> <::http::1>
GOT len=<0>                           <<<<< called with no data available !
RCV done <0> eof=<0>
_proc_data <sock19de680> <::http::1>
GOT len=<4096>
GOT len=<4096>
GOT len=<4096>
GOT len=<4096>
GOT len=<2534>
GOT len=<0>
RCV got EOF
RCV done <18918> eof=<1>
----------------------------------------------

Regards

Benno