Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/tcl8.5.2/tests/http.test @ 25

Last change on this file since 25 was 25, checked in by landauf, 16 years ago

added tcl to libs

File size: 16.8 KB
Line 
1# Commands covered:  http::config, http::geturl, http::wait, http::reset
2#
3# This file contains a collection of tests for the http script library.
4# Sourcing this file into Tcl runs the tests and
5# generates output for errors.  No output means no errors were found.
6#
7# Copyright (c) 1991-1993 The Regents of the University of California.
8# Copyright (c) 1994-1996 Sun Microsystems, Inc.
9# Copyright (c) 1998-2000 by Ajuba Solutions.
10#
11# See the file "license.terms" for information on usage and redistribution
12# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
13#
14#
15# RCS: @(#) $Id: http.test,v 1.48 2008/03/12 09:51:39 hobbs Exp $
16
17if {[lsearch [namespace children] ::tcltest] == -1} {
18    package require tcltest 2
19    namespace import -force ::tcltest::*
20}
21
22if {[catch {package require http 2} version]} {
23    if {[info exists http2]} {
24        catch {puts "Cannot load http 2.* package"}
25        return
26    } else {
27        catch {puts "Running http 2.* tests in slave interp"}
28        set interp [interp create http2]
29        $interp eval [list set http2 "running"]
30        $interp eval [list set argv $argv]
31        $interp eval [list source [info script]]
32        interp delete $interp
33        return
34    }
35}
36
37proc bgerror {args} {
38    global errorInfo
39    puts stderr "http.test bgerror"
40    puts stderr [join $args]
41    puts stderr $errorInfo
42}
43
44set port 8010
45set bindata "This is binary data\x0d\x0amore\x0dmore\x0amore\x00null"
46catch {unset data}
47
48# Ensure httpd file exists
49
50set origFile [file join [pwd] [file dirname [info script]] httpd]
51set httpdFile [file join [temporaryDirectory] httpd_[pid]]
52if {![file exists $httpdFile]} {
53    makeFile "" $httpdFile
54    file delete $httpdFile
55    file copy $origFile $httpdFile
56    set removeHttpd 1
57}
58
59if {[info commands testthread] == "testthread" && [file exists $httpdFile]} {
60    set httpthread [testthread create "
61        source [list $httpdFile]
62        testthread wait
63    "]
64    testthread send $httpthread [list set port $port]
65    testthread send $httpthread [list set bindata $bindata]
66    testthread send $httpthread {httpd_init $port}
67    puts "Running httpd in thread $httpthread"
68} else {
69    if {![file exists $httpdFile]} {
70        puts "Cannot read $httpdFile script, http test skipped"
71        unset port
72        return
73    }
74    source $httpdFile
75    # Let the OS pick the port; that's much more flexible
76    if {[catch {httpd_init 0} listen]} {
77        puts "Cannot start http server, http test skipped"
78        unset port
79        return
80    } else {
81        set port [lindex [fconfigure $listen -sockname] 2]
82    }
83}
84
85test http-1.1 {http::config} {
86    http::config
87} [list -accept */* -proxyfilter http::ProxyRequired -proxyhost {} -proxyport {} -urlencoding utf-8 -useragent "Tcl http client package $version"]
88test http-1.2 {http::config} {
89    http::config -proxyfilter
90} http::ProxyRequired
91test http-1.3 {http::config} {
92    catch {http::config -junk}
93} 1
94test http-1.4 {http::config} {
95    set savedconf [http::config]
96    http::config -proxyhost nowhere.come -proxyport 8080 \
97        -proxyfilter myFilter -useragent "Tcl Test Suite" \
98        -urlencoding iso8859-1
99    set x [http::config]
100    http::config {*}$savedconf
101    set x
102} {-accept */* -proxyfilter myFilter -proxyhost nowhere.come -proxyport 8080 -urlencoding iso8859-1 -useragent {Tcl Test Suite}}
103test http-1.5 {http::config} {
104    list [catch {http::config -proxyhost {} -junk 8080} msg] $msg
105} {1 {Unknown option -junk, must be: -accept, -proxyfilter, -proxyhost, -proxyport, -urlencoding, -useragent}}
106test http-1.6 {http::config} {
107    set enc [list [http::config -urlencoding]]
108    http::config -urlencoding iso8859-1
109    lappend enc [http::config -urlencoding]
110    http::config -urlencoding [lindex $enc 0]
111    set enc
112} {utf-8 iso8859-1}
113
114test http-2.1 {http::reset} {
115    catch {http::reset http#1}
116} 0
117
118test http-3.1 {http::geturl} {
119    list [catch {http::geturl -bogus flag} msg] $msg
120} {1 {Unknown option flag, can be: -binary, -blocksize, -channel, -command, -handler, -headers, -keepalive, -method, -myaddr, -progress, -protocol, -query, -queryblocksize, -querychannel, -queryprogress, -strict, -timeout, -type, -validate}}
121test http-3.2 {http::geturl} {
122    catch {http::geturl http:junk} err
123    set err
124} {Unsupported URL: http:junk}
125set url //[info hostname]:$port
126set badurl //[info hostname]:6666
127test http-3.3 {http::geturl} {
128    set token [http::geturl $url]
129    http::data $token
130} "<html><head><title>HTTP/1.0 TEST</title></head><body>
131<h1>Hello, World!</h1>
132<h2>GET /</h2>
133</body></html>"
134set tail /a/b/c
135set url //[info hostname]:$port/a/b/c
136set fullurl http://user:pass@[info hostname]:$port/a/b/c
137set binurl //[info hostname]:$port/binary
138set posturl //[info hostname]:$port/post
139set badposturl //[info hostname]:$port/droppost
140test http-3.4 {http::geturl} {
141    set token [http::geturl $url]
142    http::data $token
143} "<html><head><title>HTTP/1.0 TEST</title></head><body>
144<h1>Hello, World!</h1>
145<h2>GET $tail</h2>
146</body></html>"
147proc selfproxy {host} {
148    global port
149    return [list [info hostname] $port]
150}
151test http-3.5 {http::geturl} {
152    http::config -proxyfilter selfproxy
153    set token [http::geturl $url]
154    http::config -proxyfilter http::ProxyRequired
155    http::data $token
156} "<html><head><title>HTTP/1.0 TEST</title></head><body>
157<h1>Hello, World!</h1>
158<h2>GET http:$url</h2>
159</body></html>"
160test http-3.6 {http::geturl} {
161    http::config -proxyfilter bogus
162    set token [http::geturl $url]
163    http::config -proxyfilter http::ProxyRequired
164    http::data $token
165} "<html><head><title>HTTP/1.0 TEST</title></head><body>
166<h1>Hello, World!</h1>
167<h2>GET $tail</h2>
168</body></html>"
169test http-3.7 {http::geturl} {
170    set token [http::geturl $url -headers {Pragma no-cache}]
171    http::data $token
172} "<html><head><title>HTTP/1.0 TEST</title></head><body>
173<h1>Hello, World!</h1>
174<h2>GET $tail</h2>
175</body></html>"
176test http-3.8 {http::geturl} {
177    set token [http::geturl $url -query Name=Value&Foo=Bar -timeout 2000]
178    http::data $token
179} "<html><head><title>HTTP/1.0 TEST</title></head><body>
180<h1>Hello, World!</h1>
181<h2>POST $tail</h2>
182<h2>Query</h2>
183<dl>
184<dt>Name<dd>Value
185<dt>Foo<dd>Bar
186</dl>
187</body></html>"
188test http-3.9 {http::geturl} {
189    set token [http::geturl $url -validate 1]
190    http::code $token
191} "HTTP/1.0 200 OK"
192test http-3.10 {http::geturl queryprogress} {
193    set query foo=bar
194    set sep ""
195    set i 0
196    # Create about 120K of query data
197    while {$i < 14} {
198        incr i
199        append query $sep$query
200        set sep &
201    }
202
203    proc postProgress {token x y} {
204        global postProgress
205        lappend postProgress $y
206    }
207    set postProgress {}
208    set t [http::geturl $posturl -keepalive 0 -query $query \
209            -queryprogress postProgress -queryblocksize 16384]
210    http::wait $t
211    list [http::status $t] [string length $query] $postProgress [http::data $t]
212} {ok 122879 {16384 32768 49152 65536 81920 98304 114688 122879} {Got 122879 bytes}}
213test http-3.11 {http::geturl querychannel with -command} {
214    set query foo=bar
215    set sep ""
216    set i 0
217    # Create about 120K of query data
218    while {$i < 14} {
219        incr i
220        append query $sep$query
221        set sep &
222    }
223    set file [makeFile $query outdata]
224    set fp [open $file]
225
226    proc asyncCB {token} {
227        global postResult
228        lappend postResult [http::data $token]
229    }
230    set postResult [list ]
231    set t [http::geturl $posturl -querychannel $fp]
232    http::wait $t
233    set testRes [list [http::status $t] [string length $query] [http::data $t]]
234
235    # Now do async
236    http::cleanup $t
237    close $fp
238    set fp [open $file]
239    set t [http::geturl $posturl -querychannel $fp -command asyncCB]
240    set postResult [list PostStart]
241    http::wait $t
242    close $fp
243
244    lappend testRes [http::status $t] $postResult
245    removeFile outdata
246    set testRes
247} {ok 122879 {Got 122880 bytes} ok {PostStart {Got 122880 bytes}}}
248# On Linux platforms when the client and server are on the same host, the
249# client is unable to read the server's response one it hits the write error.
250# The status is "eof".
251# On Windows, the http::wait procedure gets a "connection reset by peer" error
252# while reading the reply.
253test http-3.12 {http::geturl querychannel with aborted request} {nonPortable} {
254    set query foo=bar
255    set sep ""
256    set i 0
257    # Create about 120K of query data
258    while {$i < 14} {
259        incr i
260        append query $sep$query
261        set sep &
262    }
263    set file [makeFile $query outdata]
264    set fp [open $file]
265
266    proc asyncCB {token} {
267        global postResult
268        lappend postResult [http::data $token]
269    }
270    proc postProgress {token x y} {
271        global postProgress
272        lappend postProgress $y
273    }
274    set postProgress {}
275    # Now do async
276    set postResult [list PostStart]
277    if {[catch {
278        set t [http::geturl $badposturl -querychannel $fp -command asyncCB \
279                -queryprogress postProgress]
280        http::wait $t
281        upvar #0 $t state
282    } err]} {
283        puts $::errorInfo
284        error $err
285    }
286
287    removeFile outdata
288    list [http::status $t] [http::code $t]
289} {ok {HTTP/1.0 200 Data follows}}
290test http-3.13 {http::geturl socket leak test} {
291    set chanCount [llength [file channels]]
292    for {set i 0} {$i < 3} {incr i} {
293        catch {http::geturl $badurl -timeout 5000}
294    }
295
296    # No extra channels should be taken
297    expr {[llength [file channels]] == $chanCount}
298} 1
299test http-3.14 "http::geturl $fullurl" {
300    set token [http::geturl $fullurl -validate 1]
301    http::code $token
302} "HTTP/1.0 200 OK"
303test http-3.15 {http::geturl parse failures} -body {
304    http::geturl "{invalid}:url"
305} -returnCodes error -result {Unsupported URL: {invalid}:url}
306test http-3.16 {http::geturl parse failures} -body {
307    http::geturl http:relative/url
308} -returnCodes error -result {Unsupported URL: http:relative/url}
309test http-3.17 {http::geturl parse failures} -body {
310    http::geturl /absolute/url
311} -returnCodes error -result {Missing host part: /absolute/url}
312test http-3.18 {http::geturl parse failures} -body {
313    http::geturl http://somewhere:123456789/
314} -returnCodes error -result {Invalid port number: 123456789}
315test http-3.19 {http::geturl parse failures} -body {
316    http::geturl http://{user}@somewhere
317} -returnCodes error -result {Illegal characters in URL user}
318test http-3.20 {http::geturl parse failures} -body {
319    http::geturl http://%user@somewhere
320} -returnCodes error -result {Illegal encoding character usage "%us" in URL user}
321test http-3.21 {http::geturl parse failures} -body {
322    http::geturl http://somewhere/{path}
323} -returnCodes error -result {Illegal characters in URL path}
324test http-3.22 {http::geturl parse failures} -body {
325    http::geturl http://somewhere/%path
326} -returnCodes error -result {Illegal encoding character usage "%pa" in URL path}
327test http-3.23 {http::geturl parse failures} -body {
328    http::geturl http://somewhere/path?{query}
329} -returnCodes error -result {Illegal characters in URL path}
330test http-3.24 {http::geturl parse failures} -body {
331    http::geturl http://somewhere/path?%query
332} -returnCodes error -result {Illegal encoding character usage "%qu" in URL path}
333
334test http-4.1 {http::Event} {
335    set token [http::geturl $url -keepalive 0]
336    upvar #0 $token data
337    array set meta $data(meta)
338    expr ($data(totalsize) == $meta(Content-Length))
339} 1
340test http-4.2 {http::Event} {
341    set token [http::geturl $url]
342    upvar #0 $token data
343    array set meta $data(meta)
344    string compare $data(type) [string trim $meta(Content-Type)]
345} 0
346test http-4.3 {http::Event} {
347    set token [http::geturl $url]
348    http::code $token
349} {HTTP/1.0 200 Data follows}
350test http-4.4 {http::Event} {
351    set testfile [makeFile "" testfile]
352    set out [open $testfile w]
353    set token [http::geturl $url -channel $out]
354    close $out
355    set in [open $testfile]
356    set x [read $in]
357    close $in
358    removeFile $testfile
359    set x
360} "<html><head><title>HTTP/1.0 TEST</title></head><body>
361<h1>Hello, World!</h1>
362<h2>GET $tail</h2>
363</body></html>"
364test http-4.5 {http::Event} {
365    set testfile [makeFile "" testfile]
366    set out [open $testfile w]
367    set token [http::geturl $url -channel $out]
368    close $out
369    upvar #0 $token data
370    removeFile $testfile
371    expr $data(currentsize) == $data(totalsize)
372} 1
373test http-4.6 {http::Event} {
374    set testfile [makeFile "" testfile]
375    set out [open $testfile w]
376    set token [http::geturl $binurl -channel $out]
377    close $out
378    set in [open $testfile]
379    fconfigure $in -translation binary
380    set x [read $in]
381    close $in
382    removeFile $testfile
383    set x
384} "$bindata[string trimleft $binurl /]"
385proc myProgress {token total current} {
386    global progress httpLog
387    if {[info exists httpLog] && $httpLog} {
388        puts "progress $total $current"
389    }
390    set progress [list $total $current]
391}
392if 0 {
393    # This test hangs on Windows95 because the client never gets EOF
394    set httpLog 1
395    test http-4.6.1 {http::Event} knownBug {
396        set token [http::geturl $url -blocksize 50 -progress myProgress]
397        set progress
398    } {111 111}
399}
400test http-4.7 {http::Event} {
401    set token [http::geturl $url -keepalive 0 -progress myProgress]
402    set progress
403} {111 111}
404test http-4.8 {http::Event} {
405    set token [http::geturl $url]
406    http::status $token
407} {ok}
408test http-4.9 {http::Event} {
409    set token [http::geturl $url -progress myProgress]
410    http::code $token
411} {HTTP/1.0 200 Data follows}
412test http-4.10 {http::Event} {
413    set token [http::geturl $url -progress myProgress]
414    http::size $token
415} {111}
416# Timeout cases
417#       Short timeout to working server (the test server). This lets us try a
418#       reset during the connection.
419test http-4.11 {http::Event} {
420    set token [http::geturl $url -timeout 1 -keepalive 0 -command {#}]
421    http::reset $token
422    http::status $token
423} {reset}
424#       Longer timeout with reset.
425test http-4.12 {http::Event} {
426    set token [http::geturl $url/?timeout=10 -keepalive 0 -command {#}]
427    http::reset $token
428    http::status $token
429} {reset}
430#       Medium timeout to working server that waits even longer. The timeout
431#       hits while waiting for a reply.
432test http-4.13 {http::Event} {
433    set token [http::geturl $url?timeout=30 -keepalive 0 -timeout 10 -command {#}]
434    http::wait $token
435    http::status $token
436} {timeout}
437#       Longer timeout to good host, bad port, gets an error after the
438#       connection "completes" but the socket is bad.
439test http-4.14 {http::Event} -body {
440    set token [http::geturl $badurl/?timeout=10 -timeout 10000 -command \#]
441    if {$token eq ""} {
442        error "bogus return from http::geturl"
443    }
444    http::wait $token
445    http::status $token
446    # error code varies among platforms.
447} -returnCodes 1 -match regexp -result {(connect failed|couldn't open socket)}
448# Bogus host
449test http-4.15 {http::Event} -body {
450    # This test may fail if you use a proxy server. That is to be
451    # expected and is not a problem with Tcl.
452    set token [http::geturl //not_a_host.tcl.tk -timeout 1000 -command \#]
453    http::wait $token
454    http::status $token
455    # error codes vary among platforms.
456} -returnCodes 1 -match glob -result "couldn't open socket*"
457
458test http-5.1 {http::formatQuery} {
459    http::formatQuery name1 value1 name2 "value two"
460} {name1=value1&name2=value%20two}
461# test http-5.2 obsoleted by 5.4 and 5.5 with http 2.5
462test http-5.3 {http::formatQuery} {
463    http::formatQuery lines "line1\nline2\nline3"
464} {lines=line1%0d%0aline2%0d%0aline3}
465test http-5.4 {http::formatQuery} {
466    http::formatQuery name1 ~bwelch name2 \xa1\xa2\xa2
467} {name1=~bwelch&name2=%c2%a1%c2%a2%c2%a2}
468test http-5.5 {http::formatQuery} {
469    set enc [http::config -urlencoding]
470    http::config -urlencoding iso8859-1
471    set res [http::formatQuery name1 ~bwelch name2 \xa1\xa2\xa2]
472    http::config -urlencoding $enc
473    set res
474} {name1=~bwelch&name2=%a1%a2%a2}
475
476test http-6.1 {http::ProxyRequired} {
477    http::config -proxyhost [info hostname] -proxyport $port
478    set token [http::geturl $url]
479    http::wait $token
480    http::config -proxyhost {} -proxyport {}
481    upvar #0 $token data
482    set data(body)
483} "<html><head><title>HTTP/1.0 TEST</title></head><body>
484<h1>Hello, World!</h1>
485<h2>GET http:$url</h2>
486</body></html>"
487
488test http-7.1 {http::mapReply} {
489    http::mapReply "abc\$\[\]\"\\()\}\{"
490} {abc%24%5b%5d%22%5c%28%29%7d%7b}
491test http-7.2 {http::mapReply} {
492    # RFC 2718 specifies that we pass urlencoding on utf-8 chars by default,
493    # so make sure this gets converted to utf-8 then urlencoded.
494    http::mapReply "\u2208"
495} {%e2%88%88}
496test http-7.3 {http::formatQuery} {
497    set enc [http::config -urlencoding]
498    # this would be reverting to http <=2.4 behavior
499    http::config -urlencoding ""
500    set res [list [catch {http::mapReply "\u2208"} msg] $msg]
501    http::config -urlencoding $enc
502    set res
503} [list 1 "can't read \"formMap(\u2208)\": no such element in array"]
504test http-7.4 {http::formatQuery} {
505    set enc [http::config -urlencoding]
506    # this would be reverting to http <=2.4 behavior w/o errors
507    # (unknown chars become '?')
508    http::config -urlencoding "iso8859-1"
509    set res [http::mapReply "\u2208"]
510    http::config -urlencoding $enc
511    set res
512} {%3f}
513
514# cleanup
515catch {unset url}
516catch {unset badurl}
517catch {unset port}
518catch {unset data}
519if {[info exists httpthread]} {
520    testthread send -async $httpthread {
521        testthread exit
522    }
523} else {
524    close $listen
525}
526
527if {[info exists removeHttpd]} {
528    removeFile $httpdFile
529}
530
531rename bgerror {}
532::tcltest::cleanupTests
Note: See TracBrowser for help on using the repository browser.