ns_http - Simple HTTP client functionality
This command provides a simple HTTP and HTTPS client functionality. It can be used to create, dispatch, wait on and/or cancel requests and process replies from web servers.
The command ns_http queue opens a connection to the web server denoted in the url and returns (unless a -donecallback is specified) an id, which might be used later in ns_http wait or ns_http cancel to refer to this request. The command supports both HTTP and HTTPS URIs. The request is run in the default task queue in a dedicated per-queue thread.
Send a HTTP request and wait for the result. The command ns_http run is similar to ns_http queue followed by ns_http wait. The http request is run in the same thread as the caller.
Waits for the queued command specified by the id returned from ns_http queue to complete. Returns a Tcl dictionary with the following keys: status, time, headers. The status contains HTTP/HTTPS status code (200, 201, 400, etc). The time contains elapsed request/response ns_time. The headers contains name of the set with response headers. If the request body was given over a Tcl channel, it will add key body_chan in the passed result dictionary. If the response was not spooled in the file nor channel, it will return body key with the response data. Otherwise it will return either file if the response was spooled into the named (or temporary) file or outputchan if the request was spooled into a Tcl channel. For HTTPS requests it will add https with some low-level TLS parameters in a Tcl dictionary format.
All options of this command are considered deprecated but are still supported, possibly in a limited fashion, for the sake of backward compatibility.
The reason is, at the time when ns_http wait is executed, the request may have been processed and completed already, so some of the above option have no meaning any more. Furthermore, the returned Tcl dictionary contains all information otherwise pushed into the optional Tcl variables, so all those are not strictly required.
On success ns_http wait returns the same dictionary as the ns_http run. On timeout it sets the Tcl variable to NS_TIMEOUT in addition to leaving descriptive error message in the interpreter result.
ID of the HTTP request to wait for.
Cancel queued HTTP/HTTPS request by the ID (of the request) as returned by ns_http queue command. The command returns empty result. The sense behind this command is to be able to terminate runaway requests or request that have been timed out. Even completed requests can be cancelled if nobody is interested in the request result.
ID of the HTTP request to cancel.
Cancel all pending HTTP/HTTPS requests issued in the current interpreter. All tasks are internally cancelled, then marked as completed and finally garbage collected. At this point, any Tcl channels that have been optionally assigned to a task, will be automatically closed.
Return the list of currently tracked requests in the form: "id1 url1 status2 id2 url2 status2 ... idN urlN statusN" where status can be one of: "done" or "running". If optional id was specified, only the selected task ID will be reported.
Optional ID of the HTTP request to list.
Returns statistics from the currently running request in the form of a list of Tcl dictionares. If optional id was specified, just one dictionary containing details about the requested task will be returned, or empty if the task cannot be found. Otherwise a list of dictionaries will be returned. One returned dictionary contains following keys: task, url, requestlength, replylength, sent, received, sendbodysize, replybodysize, replysize. The task returns the ID of the Http task. The url returns the URL for the given task. The requestlength returns the length of the complete http request, including header line, all of the headers plus optional request body. The replylength returns the value of the Content-Length as returned by the remote. This can be zero if the length of returned data is not known in advance. The sent returns number of bytes sent to the remote. This includes the header line, all of the headers plus optional request body. The received returns number of bytes received from the remote. This includes status line, all of the headers plus the optional reply body. The sendbodysize returns number of bytes of the request body sent to the remote so far. The replybodysize returns number of bvtes of the reply body received from the remote so far. The replysize returns number of bytes of the body received from the remote so far. Difference to the replybodysize is that this element tracks number of body bytes prior optional deflate step for compressed contents, whereas the replybodysize tracks the number of body bytes of the deflated contents. For uncompressed reply content, both replysize and replybodysize will have the same value.
Optional ID of the HTTP request to get statistics for.
First, a minimal GET example:
% ns_http queue http://www.google.com http0 % ns_http wait http0 status 302 time 0:97095 headers d0 body { ... }
The second example is a code snippet making a requests via HTTPS (note that HTTPS is supported only if the NaviServer was compiled with OpenSSL support.
% set result [ns_http run https://www.google.com] % dict get $result status 302
If the returned data is too large to be retained in memory you can use the -spoolsize to control when the content should be spooled to file. The spooled file name is contained in the resulting dict under the key file.
% set result [ns_http run -spoolsize 1kB https://www.google.com] % dict get $result file /tmp/http.83Rfc5
If you are connecting to a server with virtual hosting that provides multiple certificates via SNI (Server Name Indication) you have to provide the option -hostname.
The third example is a code snippet making a POST requests via HTTPS and provides url-encoded POST data. The examples sets a larger timeout on the request, provides requests headers and returns reply-headers.
####################### # construct POST data ####################### set post_data {} foreach {key value} {q NaviServer} { lappend post_data "[ns_urlencode $key]=[ns_urlencode $value]" } set post_data [join $post_data &] ####################### # submit POST request ####################### set requestHeaders [ns_set create] set replyHeaders [ns_set create] ns_set update $requestHeaders "Content-type" "application/x-www-form-urlencoded" set h [ns_http queue -method POST \ -headers $requestHeaders \ -timeout 10.0 \ -body $post_data https://duckduckgo.com/] set r [ns_http wait $h] ####################### # output results ####################### ns_log notice "status [dict get $r status[" ns_log notice "reply "[dict get $r [ ns_log notice "headers "[dict get $r headers[
The forth example is a code snippet that sets a larger timeout on the request, provides a ns_set for the reply headers, and spools results to a file if the result is larger than 1000 bytes.
set replyHeaders [ns_set create] ns_set update $requestHeaders Host localhost set h [ns_http queue -timeout 10.0 http://www.google.com] ns_http wait -result R -headers $replyHeaders -status S -spoolsize 1Kb -file F $h if {[info exists F]} { ns_log notice "Spooled [file size $F] bytes to $F" file delete -- $F } else { ns_log notice "Got [string length $R] bytes" }
Example for downloading a file from the web into a named file or passed Tcl channel. Note the -spoolsize of zero which will redirect all received data into the file/channel. Without the -spoolsize set, all the data would be otherwise stored in memory.
% ns_http run -outputfile /tmp/reply.html -spoolsize 0 http://www.google.com status 302 time 0:132577 headers d2 file /tmp/reply.html
% set chan [open /tmp/file.dat w] % ns_http run -outputchan $chan -spoolsize 0 http://www.google.com status 302 time 0:132577 headers d2 outputchan file22 % close $chan
GET, HTTP, HTTPS, POST, SNI, global built-in, http-client, nssock, spooling