Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Allow URLs that don't have a path, but a query query, e.g. http://example.com?foo=bar . |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
a0172365d23a179bc7c43ddd082f5de5 |
User & Date: | max 2013-04-04 14:42:19 |
Context
2013-04-04
| ||
14:52 | Bump http to 2.8.7 check-in: 6021cc928a user: max tags: trunk | |
14:42 | Allow URLs that don't have a path, but a query query, e.g. http://example.com?foo=bar . check-in: a0172365d2 user: max tags: trunk | |
07:07 | Make Tcl_EvalObj/Tcl_GlobalEvalObj a macro always, not only when using stubs. check-in: 45d8edf1bb user: jan.nijtmans tags: trunk | |
Changes
Changes to ChangeLog.
1 2 3 4 5 6 7 | 2013-03-22 Venkat Iyer <[email protected]> * library/tzdata/Africa/Cairo: Update to tzdata2013b. * library/tzdata/Africa/Casablanca: * library/tzdata/Africa/Gaborone: * library/tzdata/Africa/Tripoli: * library/tzdata/America/Asuncion: * library/tzdata/America/Barbados: | > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 | 2013-04-04 Reinhard Max <[email protected]> * library/http/http.tcl (http::geturl): Allow URLs that don't have a path, but a query query, e.g. http://example.com?foo=bar . 2013-03-22 Venkat Iyer <[email protected]> * library/tzdata/Africa/Cairo: Update to tzdata2013b. * library/tzdata/Africa/Casablanca: * library/tzdata/Africa/Gaborone: * library/tzdata/Africa/Tripoli: * library/tzdata/America/Asuncion: * library/tzdata/America/Barbados: |
︙ | ︙ |
Changes to library/http/http.tcl.
︙ | ︙ | |||
390 391 392 393 394 395 396 | # Recognize user:pass@host URLs also, although we do not do anything with # that info yet. # URLs have basically four parts. # First, before the colon, is the protocol scheme (e.g. http) # Second, for HTTP-like protocols, is the authority # The authority is preceded by // and lasts up to (but not including) | | | | > > > | 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 | # Recognize user:pass@host URLs also, although we do not do anything with # that info yet. # URLs have basically four parts. # First, before the colon, is the protocol scheme (e.g. http) # Second, for HTTP-like protocols, is the authority # The authority is preceded by // and lasts up to (but not including) # the following / or ? and it identifies up to four parts, of which # only one, the host, is required (if an authority is present at all). # All other parts of the authority (user name, password, port number) # are optional. # Third is the resource name, which is split into two parts at a ? # The first part (from the single "/" up to "?") is the path, and the # second part (from that "?" up to "#") is the query. *HOWEVER*, we do # not need to separate them; we send the whole lot to the server. # Both, path and query are allowed to be missing, including their # delimiting character. # Fourth is the fragment identifier, which is everything after the first # "#" in the URL. The fragment identifier MUST NOT be sent to the server # and indeed, we don't bother to validate it (it could be an error to # pass it in here, but it's cheap to strip). # # An example of a URL that has all the parts: # |
︙ | ︙ | |||
433 434 435 436 437 438 439 | )? ( # <host part of authority> [^/:\#?]+ | # host name or IPv4 address \[ [^/\#?]+ \] # IPv6 address in square brackets ) (?: : (\d+) )? # <port part of authority> )? | | | 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 | )? ( # <host part of authority> [^/:\#?]+ | # host name or IPv4 address \[ [^/\#?]+ \] # IPv6 address in square brackets ) (?: : (\d+) )? # <port part of authority> )? ( [/\?] [^\#]*)? # <path> (including query) (?: \# (.*) )? # <fragment> $ } # Phase one: parse if {![regexp -- $URLmatcher $url -> proto user host port srvurl]} { unset $token |
︙ | ︙ | |||
477 478 479 480 481 482 483 484 485 486 487 488 489 490 | return -code error \ "Illegal encoding character usage \"$bad\" in URL user" } return -code error "Illegal characters in URL user" } } if {$srvurl ne ""} { # Check for validity according to RFC 3986, Appendix A set validityRE {(?xi) ^ # Path part (already must start with / character) (?: [-\w.~!$&'()*+,;=:@/] | %[0-9a-f][0-9a-f] )* # Query part (optional, permits ? characters) (?: \? (?: [-\w.~!$&'()*+,;=:@/?] | %[0-9a-f][0-9a-f] )* )? | > > > > > > | 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 | return -code error \ "Illegal encoding character usage \"$bad\" in URL user" } return -code error "Illegal characters in URL user" } } if {$srvurl ne ""} { # RFC 3986 allows empty paths (not even a /), but servers # return 400 if the path in the HTTP request doesn't start # with / , so add it here if needed. if {[string index $srvurl 0] ne "/"} { set srvurl /$srvurl } # Check for validity according to RFC 3986, Appendix A set validityRE {(?xi) ^ # Path part (already must start with / character) (?: [-\w.~!$&'()*+,;=:@/] | %[0-9a-f][0-9a-f] )* # Query part (optional, permits ? characters) (?: \? (?: [-\w.~!$&'()*+,;=:@/?] | %[0-9a-f][0-9a-f] )* )? |
︙ | ︙ |
Changes to tests/http.test.
︙ | ︙ | |||
131 132 133 134 135 136 137 138 139 140 141 142 143 144 | </body></html>" set tail /a/b/c set url //[info hostname]:$port/a/b/c set fullurl http://user:pass@[info hostname]:$port/a/b/c set binurl //[info hostname]:$port/binary set posturl //[info hostname]:$port/post set badposturl //[info hostname]:$port/droppost set ipv6url http://\[::1\]:$port/ test http-3.4 {http::geturl} -body { set token [http::geturl $url] http::data $token } -cleanup { http::cleanup $token } -result "<html><head><title>HTTP/1.0 TEST</title></head><body> | > | 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | </body></html>" set tail /a/b/c set url //[info hostname]:$port/a/b/c set fullurl http://user:pass@[info hostname]:$port/a/b/c set binurl //[info hostname]:$port/binary set posturl //[info hostname]:$port/post set badposturl //[info hostname]:$port/droppost set authorityurl //[info hostname]:$port set ipv6url http://\[::1\]:$port/ test http-3.4 {http::geturl} -body { set token [http::geturl $url] http::data $token } -cleanup { http::cleanup $token } -result "<html><head><title>HTTP/1.0 TEST</title></head><body> |
︙ | ︙ | |||
387 388 389 390 391 392 393 | } -match regexp -result {(?n)Accept \*/\* Host .* User-Agent .* Connection close Content-Type {text/plain;charset=utf-8} Accept-Encoding .* Content-Length 5} | | | > > > > > > > > > > > | 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 | } -match regexp -result {(?n)Accept \*/\* Host .* User-Agent .* Connection close Content-Type {text/plain;charset=utf-8} Accept-Encoding .* Content-Length 5} test http-3.29 {http::geturl IPv6 address} -body { # We only want to see if the URL gets parsed correctly. This is # the case if http::geturl succeeds or returns a socket related # error. If the parsing is wrong, we'll get a parse error. # It'd be better to separate the URL parser from http::geturl, so # that it can be tested without also trying to make a connection. set error [catch {http::geturl $ipv6url -validate 1} token] if {$error && [string match "couldn't open socket: *" $token]} { set error 0 } set error } -cleanup { catch { http::cleanup $token } } -result 0 test http-3.30 {http::geturl query without path} -body { set token [http::geturl $authorityurl?var=val] http::ncode $token } -cleanup { catch { http::cleanup $token } } -result 200 test http-3.31 {http::geturl fragment without path} -body { set token [http::geturl "$authorityurl#fragment42"] http::ncode $token } -cleanup { catch { http::cleanup $token } } -result 200 test http-4.1 {http::Event} -body { set token [http::geturl $url -keepalive 0] upvar #0 $token data array set meta $data(meta) expr {($data(totalsize) == $meta(Content-Length))} } -cleanup { http::cleanup $token |
︙ | ︙ |