Index: openacs-4/packages/acs-tcl/tcl/http-client-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-tcl/tcl/http-client-procs.tcl,v diff -u -r1.30.2.30 -r1.30.2.31 --- openacs-4/packages/acs-tcl/tcl/http-client-procs.tcl 5 Jul 2024 13:43:26 -0000 1.30.2.30 +++ openacs-4/packages/acs-tcl/tcl/http-client-procs.tcl 8 Jul 2024 13:20:05 -0000 1.30.2.31 @@ -1133,9 +1133,9 @@ # https://www.rfc-editor.org/rfc/rfc7231#section-7.1.2, the # location header may return a relative URL as well. # - set location [util::complete_location \ - -location $location \ - -complete_url $url] + set location [util::absolute_url \ + -url $location \ + -base_url $url] if {$method eq "GET"} { return [$this_proc \ Index: openacs-4/packages/acs-tcl/tcl/utilities-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-tcl/tcl/utilities-procs.tcl,v diff -u -r1.189.2.176 -r1.189.2.177 --- openacs-4/packages/acs-tcl/tcl/utilities-procs.tcl 5 Jul 2024 13:43:29 -0000 1.189.2.176 +++ openacs-4/packages/acs-tcl/tcl/utilities-procs.tcl 8 Jul 2024 13:20:06 -0000 1.189.2.177 @@ -1964,51 +1964,51 @@ return $result } -ad_proc util::complete_location { - -location:required - -complete_url +ad_proc util::absolute_url { + -url:required + -base_url } { - Completes specified relative URL. When no complete URL is - specified for reference, it will assume the current host as the - server. + Value added version of "ns_absoluteurl" with the following differences + + - keep protocol relative URLs unchanged (no scheme is completed) + - use [util_current_location] as default "base_url" + - allow variable "url" to be empty (replaced by /) + + Completes specified URL when necessary. When no base URL is + specified, it will default to the current location (scheme and host). + The purpose of this utility is to be used by HTTP clients to complete URLs coming from the Location response header in case of a redirect, which according to RFC 7231 may also be relative. - @param location a supposedly relative URL to complete. When the - URL is already complete, it will be returned - as-is. - @param complete_url URL of the redirected request. A complete URL + @param url a supposedly relative URL to complete. When the + URL is already complete, it will be returned + as-is. + @param base_url URL of the redirected request. A complete URL from which we want to read the host. When missing, the URL will be completed using the result of util_current_location. @return a complete absolute URL @see https://www.rfc-editor.org/rfc/rfc7231#section-7.1.2 + @see https://naviserver.sourceforge.io/n/naviserver/files/ns_absoluteurl.html } { - if {![info exists complete_url]} { - set complete_url [util_current_location] - } elseif {![dict exists [ns_parseurl -strict $complete_url] host]} { - error "util::complete_location: '$complete_url' is not a valid complete URL" + if {![info exists base_url]} { + set base_url [util_current_location] } - - set parsed_location [ns_parseurl -strict $location] - if {[dict exists $parsed_location host]} { - return $location + if {[dict exists [ns_parseurl -strict $url] host]} { + return $url } - - util::split_location $complete_url proto hostname port - - set host_url [util::join_location \ - -proto $proto \ - -hostname $hostname \ - -port $port] - - return [ns_absoluteurl $location $host_url] + if {$url eq ""} { + set url / + } + #ns_log notice "================ XXX [list ns_absoluteurl $url $base_url] -> <[ns_absoluteurl $url $base_url]>" + return [ns_absoluteurl $url $base_url] } + ad_proc -public util::configured_location {{-suppress_port:boolean}} { Return the configured location as configured for the current Index: openacs-4/packages/acs-tcl/tcl/test/utilities-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-tcl/tcl/test/utilities-procs.tcl,v diff -u -r1.1.2.21 -r1.1.2.22 --- openacs-4/packages/acs-tcl/tcl/test/utilities-procs.tcl 5 Jul 2024 13:43:29 -0000 1.1.2.21 +++ openacs-4/packages/acs-tcl/tcl/test/utilities-procs.tcl 8 Jul 2024 13:20:09 -0000 1.1.2.22 @@ -440,98 +440,102 @@ api production_safe } -procs { - util::complete_location -} util__complete_url { - Test util::complete_location + util::absolute_url +} util__absolute_url { + Test util::absolute_url } { aa_equals "Basic case" \ - [string trimright [util::complete_location -location ""] /] \ + [string trimright [util::absolute_url -url ""] /] \ [util_current_location] - aa_equals "Complete with current location" \ - [string trimright [util::complete_location -location "/a/b/c"] /] \ + aa_equals "Complete URL with current location" \ + [string trimright [util::absolute_url -url "/a/b/c"] /] \ [util_current_location]/a/b/c \ - aa_equals "Complete an already complete location (normie case)" \ - [util::complete_location -location "https://example.com/a/b/c"] \ + aa_equals "Complete an already complete URL (normie case)" \ + [util::absolute_url -url "https://example.com/a/b/c"] \ "https://example.com/a/b/c" \ - aa_equals "Complete an already complete location (protocol relative)" \ - [util::complete_location -location "//a/b/c"] \ - //a/b/c \ + aa_equals "Complete an already complete URL (protocol relative)" \ + [util::absolute_url -url "//host.org/b/c"] \ + //host.org/b/c \ - aa_true "Complete an invalid location (relative) - Should fail" \ + aa_true "Complete an invalid URL (relative) - Should fail" \ [catch { - util::complete_location -location "/file\[/\].html" + util::absolute_url -url "/file\[/\].html" }] - aa_true "Complete an invalid location (absolute) - Should fail" \ + aa_true "Complete an invalid URL (absolute) - Should fail" \ [catch { - util::complete_location -location "http://example.com/file\[/\].html" + util::absolute_url -url "http://example.com/file\[/\].html" }] - aa_equals "Basic case with external location" \ - [string trimright [util::complete_location \ - -complete_url "http://example.com" \ - -location ""] /] \ + aa_equals "Basic case with external base URL" \ + [string trimright [util::absolute_url \ + -url "" \ + -base_url "http://example.com"] \ + /] \ http://example.com - aa_equals "Basic case with external location (complete_url has a path)" \ - [string trimright [util::complete_location \ - -complete_url "http://example.com/a/b/c" \ - -location ""] /] \ + aa_equals "Basic case with external base URL (complete_url has a path)" \ + [string trimright [util::absolute_url \ + -url "" \ + -base_url "http://example.com/a/b/c"] \ + /] \ http://example.com - aa_equals "Complete with external location (complete_url just the host)" \ - [string trimright [util::complete_location \ - -complete_url "http://example.com" \ - -location "/a/b/c"] /] \ - http://example.com/a/b/c \ + aa_equals "Complete with external base URL (complete_url just the host)" \ + [string trimright [util::absolute_url \ + -url "/a/b/c" \ + -base_url "http://example.com"] \ + /] \ + http://example.com/a/b/c - aa_equals "Complete with external location (complete_url with a path)" \ - [string trimright [util::complete_location \ - -complete_url "http://example.com/d/e/f" \ - -location "/a/b/c"] /] \ - http://example.com/a/b/c \ + aa_equals "Complete with external base URL (complete_url with a path)" \ + [string trimright [util::absolute_url \ + -url "/a/b/c" \ + -base_url "http://example.com/d/e/f"] \ + /] \ + http://example.com/a/b/c - aa_equals "Complete an already complete location (normie case)" \ - [util::complete_location \ - -complete_url "http://anotherexample.com/d/e/f" \ - -location "https://example.com/a/b/c"] \ - "https://example.com/a/b/c" \ + aa_equals "Complete an already complete URL (normie case)" \ + [util::absolute_url \ + -url "https://example.com/a/b/c" \ + -base_url "http://anotherexample.com/d/e/f"] \ + https://example.com/a/b/c - aa_equals "Complete an already complete location (protocol relative)" \ - [util::complete_location \ - -complete_url "http://anotherexample.com/d/e/f" \ - -location "//a/b/c"] \ - //a/b/c \ + aa_equals "Complete an already complete URL (protocol relative)" \ + [util::absolute_url \ + -url "//host.org/b/c" \ + -base_url "http://anotherexample.com/d/e/f"] \ + //host.org/b/c - aa_true "Complete an invalid location (relative) - Should fail" \ + aa_true "Complete an invalid URL (relative) - Should fail" \ [catch { - util::complete_location \ - -complete_url "http://example.com/d/e/f" \ - -location "/file\[/\].html" + util::absolute_url \ + -url "/file\[/\].html" \ + -base_url "http://example.com/d/e/f" }] - aa_true "Complete an invalid location (absolute) - Should fail" \ + aa_true "Complete an invalid URL (absolute) - Should fail" \ [catch { - util::complete_location \ - -complete_url "http://example.com/d/e/f" \ - -location "http://example.com/file\[/\].html" + util::absolute_url \ + -url "http://example.com/file\[/\].html" \ + -base_url "http://example.com/d/e/f" }] - aa_true "Complete with an invalid complete_url - Should fail" \ + aa_true "Complete with an invalid base URL - Should fail" \ [catch { - util::complete_location \ - -complete_url "http://example.com/file\[/\].html" \ - -location "/file/a/b" + util::absolute_url \ + -url "/file/a/b" \ + -base_url "://example.com/file.html" }] - aa_true "Complete with a relative complete_url - Should fail" \ + aa_true "Complete with a relative base URL - Should fail" \ [catch { - util::complete_location \ - -complete_url "/c/d/e" \ - -location "/file/a/b" + util::absolute_url \ + -url "/file/a/b" \ + -base_url "/c/d/e" }] }