#################################################
#
# Read using blocking channel
#
#################################################

package require Tcl 8.6-
package require tls

set host "www.google.com"
set port 443
set path "/"
set protocol "h2"

#
# Send HTTP Get Request
#
proc http_get {ch host path protocol} {
    # Preface
    puts -nonewline $ch "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"

    # SETTINGS frame
    set len 12; # Must be a multiple of 6 bytes
    set type 4; # SETTINGS frame
    set ack 0; # Not ack
    set flags [expr {$ack & 0x01}]
    set stream_id 0; # 0=all, Client is odd, server is even
    set id 0
    set value 0
    set frame [binary format "IX1ccIccc" [expr {$len << 8}] $type $flags [expr {$stream_id & 0x7fffffff}] 0 0 0]
    
    puts -nonewline $ch $frame
    flush $ch
}

# Save returned data to file
proc save_file {filename data} {
    if {[catch {open $filename wb} ch]} {
	return -code error $ch
    }
    fconfigure $ch -buffersize 16384 -encoding utf-8 -translation binary
    puts $ch $data
    close $ch
}



proc handler {ch} {
    append ::data [read $ch 4096]
    if {[eof $ch]} {
	close $ch
	set ::wait 1
    }
}

proc read_nonblocking {host port path protocol} {
    set result ""

    # Open socket
    set ch [::tls::socket -servername $host -request 1 -require 1 -alpn [list [string tolower $protocol]] $host $port]
    chan configure $ch -blocking 1 -buffering full -buffersize 16384 -translation binary
    fileevent $ch readable [list handler $ch]

    # Initiate handshake
    ::tls::handshake $ch
    after 1000

    # Send get request
    after 5000 [list set ::wait 1]
    http_get $ch $host $path $protocol

    vwait ::wait
    catch {close $ch}
}

set data ""
read_nonblocking $host $port $path $protocol
save_file "read_nonblocking_webpage_h2.bin" $data

