Index: demos/README.txt ================================================================== --- demos/README.txt +++ demos/README.txt @@ -11,16 +11,22 @@ Download a webpage using gets, no variable arg, and non-blocking I/O. gets_nonblocking_with_variable.tcl Download a webpage using gets, variable arg, and non-blocking I/O. +gets_with_debug_data.tcl +Download a webpage using gets with additional debug output. + +http_debug_example.tcl +Download a webpage using http package with additional debug output. + http_get_file.tcl Download a webpage using the http package. http_get_webpage.tcl Download a file using the http package. - + http_get_webpage_proxy.tcl Download a file using the http and autoproxy packages. read_blocking_webpage.tcl Download a webpage using read and blocking I/O. ADDED demos/gets_with_debug_data.tcl Index: demos/gets_with_debug_data.tcl ================================================================== --- /dev/null +++ demos/gets_with_debug_data.tcl @@ -0,0 +1,78 @@ +################################################# +# +# Example 4: Non-blocking channel gets with variable +# +################################################# + +package require Tcl 8.6- +package require tls + +set host "www.google.com" +set port 443 +set path "/" +set protocol "http/1.1" + +# +# Send HTTP Get Request +# +proc http_get {ch host path protocol} { + puts $ch [format "GET %s %s" $path [string toupper $protocol]] + puts $ch [format "User-Agent: Mozilla/4.0 (compatible; %s)" $::tcl_platform(os)] + puts $ch [format "Host: %s" $host] + puts $ch [format "Connection: close"] + puts $ch "" + 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 crlf + puts $ch $data + close $ch +} + + + +proc handler {ch} { + if {[gets $ch line] < 0 && [eof $ch]} { + # EOF + close $ch + set ::wait 1 + return + } elseif {![fblocked $ch]} { + # Full or empty line + append ::data $line "\n" + } else { + # Partial line + append ::data $line + } +} + +proc gets_non_blocking_with_variable {host port path protocol} { + set ::wait 0 + + # Open socket + set ch [::tls::socket -servername $host -request 1 -require 1 -alpn [list [string tolower $protocol]] \ + -command ::tls::callback -password ::tls::password -validatecommand ::tls::validate_command $host $port] + chan configure $ch -blocking 0 -buffering line -buffersize 16384 -encoding utf-8 -translation {auto crlf} + 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 "" +gets_non_blocking_with_variable $host $port $path $protocol +save_file "gets_with_debug_data.txt" $data + ADDED demos/http_debug_example.tcl Index: demos/http_debug_example.tcl ================================================================== --- /dev/null +++ demos/http_debug_example.tcl @@ -0,0 +1,37 @@ +################################################# +# +# Download webpage using HTTP package with debug output +# +################################################# + +package require Tcl 8.6- +package require tls +package require http + +set url "https://www.tcl.tk/" +set port 443 +set protocol "http/1.1" + +# Register https protocol handler with http package +http::register https 443 [list ::tls::socket -autoservername 1 -require 1 -alpn [list [string tolower $protocol]] \ + -command ::tls::callback -password ::tls::password -validatecommand ::tls::validate_command] + +# Get webpage +set token [::http::geturl $url -blocksize 16384] +if {[http::status $token] ne "ok"} { + puts [format "Error: \"%s\"" [http::status $token]] + ::http::cleanup $token + exit +} + +# Get web page +set data [http::data $token] + +# Cleanup +::http::cleanup $token + +# Save data to file +set ch [open "tcl_tk_home.html" wb] +puts $ch $data +close $ch + Index: doc/tls.html ================================================================== --- doc/tls.html +++ doc/tls.html @@ -123,13 +123,12 @@
  • Values for Password Callback
  • Values for Validate Command Callback
  • Debug
  • -
  • Debug Examples
  • -
  • HTTP Package Examples
  • -
  • Special Considerations
  • +
  • HTTP Package Examples
  • +
  • Special Considerations
  • See Also
  • Keywords
  • Category
  • Copyright
  • @@ -759,98 +758,65 @@ --enable-debug can be used to get detailed execution flow status.

    TLS key logging can be enabled by setting the environment variable SSLKEYLOGFILE to the name of the file to log to. Then whenever TLS key material is generated or received it will be logged to the file. This is useful for logging key data for network logging tools to use to decrypt the data.

    -

    The tls::debug variable provides some additional control over these -reference callbacks. Its value is zero by default. Higher values produce more -diagnostic output, and will also force the verify method in tls::callback -to accept the certificate, even when it is invalid if the --validatecommand option is set to tls::validate_command.

    -

    The use of the variable tls::debug is not recommended. -It may be removed from future releases.

    - -

    Debug Examples

    -

    These examples use the default Unix platform SSL certificates. For standard -installations, -cadir and -cafile should not be needed. If your certificates -are in non-standard locations, specify -cadir or -cafile as needed. See the -demos directory for more elaborate examples.

    -

    Example #1: Use HTTP package

    -
    -package require http
    -package require tls
    -set url "https://www.tcl.tk/"
    -http::register https 443 [list ::tls::socket -autoservername 1 -require 1  -command ::tls::callback -password ::tls::password  -validatecommand ::tls::validate_command]
    -# Check for error
    -set token [http::geturl $url]
    -if {[http::status $token] ne "ok"} {
    -    puts [format "Error %s" [http::status $token]]
    -}
    -# Get web page
    -set data [http::data $token]
    -puts [string length $data]
    -# Cleanup
    -::http::cleanup $token
    -
    -

    Example #2: Use raw socket

    -
    -package require tls
    -set url "www.tcl-lang.org"
    -set port 443
    -set ch [tls::socket -autoservername 1 -servername $url -require 1  -alpn {http/1.1} -command ::tls::callback -password ::tls::password  -validatecommand ::tls::validate_command $url $port]
    -chan configure $ch -buffersize 65536
    -tls::handshake $ch
    -puts $ch "GET / HTTP/1.1"
    -flush $ch
    -after 500
    -set data [read $ch]
    -array set status [tls::status $ch]
    -array set conn [tls::connection $ch]
    -array set chan [chan configure $ch]
    -close $ch
    -parray status
    -parray conn
    -parray chan
    -
    -
    -

    HTTP Package Examples

    -

    These examples use the default Unix platform SSL certificates. For standard -installations, -cadir and -cafile should not be needed. If your certificates -are in non-standard locations, set -cadir or use -cafile as needed.

    -

    Example #3: Get web page

    -
    -package require http
    -package require tls
    -set url "https://www.tcl.tk/"
    -http::register https 443 [list ::tls::socket -autoservername 1 -require 1]
    -# Check for error
    -set token [http::geturl $url]
    -if {[http::status $token] ne "ok"} {
    -    puts [format "Error %s" [http::status $token]]
    -}
    -# Get web page
    -set data [http::data $token]
    -puts $data
    -# Cleanup
    -::http::cleanup $token
    -
    -

    Example #4: Download file

    -
    -package require http
    -package require tls
    -set url "https://wiki.tcl-lang.org/sitemap.xml"
    -set filename [file tail $url]
    -http::register https 443 [list ::tls::socket -autoservername 1 -require 1]
    -# Get file
    -set ch [open $filename wb]
    -set token [::http::geturl $url -blocksize 65536 -channel $ch]
    -# Cleanup
    -close $ch
    -::http::cleanup $token
    -
    -
    -

    Special Considerations

    +

    The tls::debug variable provides some additional control over the +debug logging in the tls::callback, tls::password, and +tls::validate_command default handlers in "tls.tcl". +The default value is 0 with higher values producing more diagnostic output, +and will also force the verify method in tls::callback to accept the +certificate, even if it is invalid when the -validatecommand +option is set to tls::validate_command.

    +

    The use of the variable tls::debug is not recommended. +It may be removed from future releases.

    +
    +

    HTTP Package Examples

    +

    The following are example scripts to download a webpage and file using the +http package. See Certificate Validation for whether the +-cadir, -cafile, and -castore options are also +needed. See the demos directory for more example scripts.

    +

    Example #1: Download a web page

    +
    +package require http
    +package require tls
    +set url "https://www.tcl.tk/"
    +http::register https 443 [list ::tls::socket -autoservername 1 -require 1]
    +# Get URL
    +set token [http::geturl $url]
    +# Check for error
    +if {[http::status $token] ne "ok"} {
    +    puts [format "Error %s" [http::status $token]]
    +}
    +# Save web page to file
    +set ch [open example.html wb]
    +puts $ch [http::data $token]
    +close $ch
    +# Cleanup
    +::http::cleanup $token
    +
    +

    Example #2: Download a file

    +
    +package require http
    +package require tls
    +set url "https://wiki.tcl-lang.org/sitemap.xml"
    +http::register https 443 [list ::tls::socket -autoservername 1 -require 1]
    +# Open output file
    +set filename [file tail $url]
    +set ch [open $filename wb]
    +# Get file
    +set token [::http::geturl $url -blocksize 65536 -channel $ch]
    +# Check for error
    +if {[http::status $token] ne "ok"} {
    +    puts [format "Error %s" [http::status $token]]
    +}
    +# Cleanup
    +close $ch
    +::http::cleanup $token
    +
    +
    +

    Special Considerations

    The capabilities of this package can vary enormously based upon how the linked to OpenSSL library was configured and built. New versions may obsolete older protocol versions, add or remove ciphers, change default values, etc. Use the tls::protocols commands to obtain the supported protocol versions.

    Index: doc/tls.man ================================================================== --- doc/tls.man +++ doc/tls.man @@ -847,132 +847,80 @@ material is generated or received it will be logged to the file. This is useful for logging key data for network logging tools to use to decrypt the data. [para] -The [var tls::debug] variable provides some additional control over these -reference callbacks. Its value is zero by default. Higher values produce more -diagnostic output, and will also force the verify method in [cmd tls::callback] -to accept the certificate, even when it is invalid if the -[option -validatecommand] option is set to [cmd tls::validate_command]. +The [var tls::debug] variable provides some additional control over the +debug logging in the [cmd tls::callback], [cmd tls::password], and +[cmd tls::validate_command] default handlers in [file tls.tcl]. +The default value is 0 with higher values producing more diagnostic output, +and will also force the verify method in [cmd tls::callback] to accept the +certificate, even if it is invalid when the [option -validatecommand] +option is set to [cmd tls::validate_command]. [para] [emph "The use of the variable [var tls::debug] is not recommended. It may be removed from future releases."] -[section "Debug Examples"] - -These examples use the default Unix platform SSL certificates. For standard -installations, -cadir and -cafile should not be needed. If your certificates -are in non-standard locations, specify -cadir or -cafile as needed. See the -demos directory for more elaborate examples. - -[para] - -Example #1: Use HTTP package - -[example { - -package require http -package require tls -set url "https://www.tcl.tk/" - -http::register https 443 [list ::tls::socket -autoservername 1 -require 1 \ - -command ::tls::callback -password ::tls::password \ - -validatecommand ::tls::validate_command] - -# Check for error -set token [http::geturl $url] -if {[http::status $token] ne "ok"} { - puts [format "Error %s" [http::status $token]] -} - -# Get web page -set data [http::data $token] -puts [string length $data] - -# Cleanup -::http::cleanup $token -}] - -Example #2: Use raw socket - -[example { - -package require tls - -set url "www.tcl-lang.org" -set port 443 - -set ch [tls::socket -autoservername 1 -servername $url -require 1 \ - -alpn {http/1.1} -command ::tls::callback -password ::tls::password \ - -validatecommand ::tls::validate_command $url $port] -chan configure $ch -buffersize 65536 -tls::handshake $ch - -puts $ch "GET / HTTP/1.1" -flush $ch -after 500 -set data [read $ch] - -array set status [tls::status $ch] -array set conn [tls::connection $ch] -array set chan [chan configure $ch] -close $ch -parray status -parray conn -parray chan -}] - -[section "HTTP Package Examples"] - -These examples use the default Unix platform SSL certificates. For standard -installations, -cadir and -cafile should not be needed. If your certificates -are in non-standard locations, set -cadir or use -cafile as needed. - -[para] - -Example #3: Get web page - -[example { - -package require http -package require tls -set url "https://www.tcl.tk/" - -http::register https 443 [list ::tls::socket -autoservername 1 -require 1] - -# Check for error -set token [http::geturl $url] -if {[http::status $token] ne "ok"} { - puts [format "Error %s" [http::status $token]] -} - -# Get web page -set data [http::data $token] -puts $data - -# Cleanup -::http::cleanup $token -}] - -Example #4: Download file +[section "HTTP Package Examples"] + +The following are example scripts to download a webpage and file using the +http package. See [sectref "Certificate Validation"] for whether the +[option -cadir], [option -cafile], and [option -castore] options are also +needed. See the demos directory for more example scripts. + +[para] + +Example #1: Download a web page + +[example { + +package require http +package require tls + +set url "https://www.tcl.tk/" +http::register https 443 [list ::tls::socket -autoservername 1 -require 1] + +# Get URL +set token [http::geturl $url] + +# Check for error +if {[http::status $token] ne "ok"} { + puts [format "Error %s" [http::status $token]] +} + +# Save web page to file +set ch [open example.html wb] +puts $ch [http::data $token] +close $ch + +# Cleanup +::http::cleanup $token +}] + +Example #2: Download a file [example { package require http package require tls set url "https://wiki.tcl-lang.org/sitemap.xml" -set filename [file tail $url] - http::register https 443 [list ::tls::socket -autoservername 1 -require 1] -# Get file +# Open output file +set filename [file tail $url] set ch [open $filename wb] + +# Get file set token [::http::geturl $url -blocksize 65536 -channel $ch] + +# Check for error +if {[http::status $token] ne "ok"} { + puts [format "Error %s" [http::status $token]] +} # Cleanup close $ch ::http::cleanup $token }] Index: doc/tls.n ================================================================== --- doc/tls.n +++ doc/tls.n @@ -1044,123 +1044,76 @@ TLS key logging can be enabled by setting the environment variable \fBSSLKEYLOGFILE\fR to the name of the file to log to\&. Then whenever TLS key material is generated or received it will be logged to the file\&. This is useful for logging key data for network logging tools to use to decrypt the data\&. .PP -The \fBtls::debug\fR variable provides some additional control over these -reference callbacks\&. Its value is zero by default\&. Higher values produce more -diagnostic output, and will also force the verify method in \fBtls::callback\fR -to accept the certificate, even when it is invalid if the -\fB-validatecommand\fR option is set to \fBtls::validate_command\fR\&. +The \fBtls::debug\fR variable provides some additional control over the +debug logging in the \fBtls::callback\fR, \fBtls::password\fR, and +\fBtls::validate_command\fR default handlers in "\fItls\&.tcl\fR"\&. +The default value is 0 with higher values producing more diagnostic output, +and will also force the verify method in \fBtls::callback\fR to accept the +certificate, even if it is invalid when the \fB-validatecommand\fR +option is set to \fBtls::validate_command\fR\&. .PP \fIThe use of the variable \fBtls::debug\fR is not recommended\&. It may be removed from future releases\&.\fR -.SH "DEBUG EXAMPLES" -These examples use the default Unix platform SSL certificates\&. For standard -installations, -cadir and -cafile should not be needed\&. If your certificates -are in non-standard locations, specify -cadir or -cafile as needed\&. See the -demos directory for more elaborate examples\&. +.SH "HTTP PACKAGE EXAMPLES" +The following are example scripts to download a webpage and file using the +http package\&. See \fBCertificate Validation\fR for whether the +\fB-cadir\fR, \fB-cafile\fR, and \fB-castore\fR options are also +needed\&. See the demos directory for more example scripts\&. .PP -Example #1: Use HTTP package +Example #1: Download a web page .CS package require http package require tls -set url "https://www\&.tcl\&.tk/" - -http::register https 443 [list ::tls::socket -autoservername 1 -require 1 -command ::tls::callback -password ::tls::password -validatecommand ::tls::validate_command] - -# Check for error -set token [http::geturl $url] -if {[http::status $token] ne "ok"} { - puts [format "Error %s" [http::status $token]] -} - -# Get web page -set data [http::data $token] -puts [string length $data] - -# Cleanup -::http::cleanup $token - -.CE -Example #2: Use raw socket -.CS - - - -package require tls - -set url "www\&.tcl-lang\&.org" -set port 443 - -set ch [tls::socket -autoservername 1 -servername $url -require 1 -alpn {http/1\&.1} -command ::tls::callback -password ::tls::password -validatecommand ::tls::validate_command $url $port] -chan configure $ch -buffersize 65536 -tls::handshake $ch - -puts $ch "GET / HTTP/1\&.1" -flush $ch -after 500 -set data [read $ch] - -array set status [tls::status $ch] -array set conn [tls::connection $ch] -array set chan [chan configure $ch] -close $ch -parray status -parray conn -parray chan - -.CE -.SH "HTTP PACKAGE EXAMPLES" -These examples use the default Unix platform SSL certificates\&. For standard -installations, -cadir and -cafile should not be needed\&. If your certificates -are in non-standard locations, set -cadir or use -cafile as needed\&. -.PP -Example #3: Get web page -.CS - - - -package require http -package require tls -set url "https://www\&.tcl\&.tk/" - -http::register https 443 [list ::tls::socket -autoservername 1 -require 1] - -# Check for error -set token [http::geturl $url] -if {[http::status $token] ne "ok"} { - puts [format "Error %s" [http::status $token]] -} - -# Get web page -set data [http::data $token] -puts $data - -# Cleanup -::http::cleanup $token - -.CE -Example #4: Download file + +set url "https://www\&.tcl\&.tk/" +http::register https 443 [list ::tls::socket -autoservername 1 -require 1] + +# Get URL +set token [http::geturl $url] + +# Check for error +if {[http::status $token] ne "ok"} { + puts [format "Error %s" [http::status $token]] +} + +# Save web page to file +set ch [open example\&.html wb] +puts $ch [http::data $token] +close $ch + +# Cleanup +::http::cleanup $token + +.CE +Example #2: Download a file .CS package require http package require tls set url "https://wiki\&.tcl-lang\&.org/sitemap\&.xml" -set filename [file tail $url] - http::register https 443 [list ::tls::socket -autoservername 1 -require 1] -# Get file +# Open output file +set filename [file tail $url] set ch [open $filename wb] + +# Get file set token [::http::geturl $url -blocksize 65536 -channel $ch] + +# Check for error +if {[http::status $token] ne "ok"} { + puts [format "Error %s" [http::status $token]] +} # Cleanup close $ch ::http::cleanup $token