From: Gustaf N. <ne...@wu...> - 2017-01-17 12:12:38
|
Dear John, I've prototyped something along these lines, which looks promising so far. Premises: - fit into urlspace mechanism - not limited in applicability to .adp - no full rewrite of urlspace (which is already complex enough) - keep speed of existing implementation - provide a mostly conservative extensions Some of these premises overlap. One option would be to switch from glob string matching to regexp, but that would be significantly slower and would require a larger changes to avoid frequent regexp compilations. The implemented approach allows to specify in addition to a (positive) match pattern (such as "foo*") optionally a negative match pattern (such as ^*.*), which can be used to say "match which such names except with some others". One can specify e.g. "foo*^*.*" which means files starting with "foo" but which must not have an extension (must not match with "*.*"). One can use as well rules like "must not contain a dash", or "must not start with an upper case character" or whatever. Both match pattern are applied with Tcl's string match implementation, which is quite efficient. To see this in action, look at the following test case, where an urlspace entry s set with an extension (foo*.tcl), one other is set with a wild card (/bar*) and one is set with a wild card and a negative pattern. These urlspace entries are matched with URLs with and without extension. Either - only the URL with the extension is matched (first two cases), or - both URLs are matched (second two cases), or - just the entry without the extension is matched (last two cases) ======================================================================= test ns_urlspace-5.1 {wild-card-filter with negative patterns} -setup { ns_urlspace set /foo*.tcl 1 ns_urlspace set /bar* 2 ns_urlspace set /baz*^*.* 3 } -body { foreach url { /foo1.tcl /foo1 /bar1.tcl /bar1 /baz1.tcl /baz1 } { lappend _ [ns_urlspace get $url] } set _ } -cleanup { unset -nocomplain _ } -result {1 {} 2 2 {} 3} ======================================================================= The path matching is untouched, as well as the features noinherit, exact, etc. To apply this approach to the .adp case, one can now call ns_register_adp (in addition to the standard cases) with a negative pattern, add optionally in the ADP PageRequest() the .adp if the first match fails, and we are done. In the test cases, there exists a /helloworld.adp file, which can be called now via /helloworld, whereas /hellow returns a 404 like usual. ======================================================================= test adp-2.1 {ADP page map} -setup { ns_register_adp GET /hello*^*.* } -body { nstest::http -getbody 1 GET /helloworld } -cleanup { ns_unregister_op GET /hello*^*.* } -result {200 {Hello World!}} ======================================================================= I have not looked at the consequences for subsumption of patterns, or deletion/querying of patterns etc, but this seems doable. Syntax-wise, we could consider as well the following candidates {/hello*^[*.*]} "/hello* ^*.*" /hello*^{*.*} /hello*{^}*.* /hello*{NOT}*.* "/hello* -not *.*" "/hello* -not *.* -noinherit" However, i am not too happy about requiring quoting with double quotes or braces. The single character "^" has advantages for escaping, when it should be taken literally (and not as start character for a negative pattern). The last syntax option has the advantage to specify also "-noinherit" in the string provided to e.g. map in the config file, which is currently not possible (meaning: do not apply this matching rule for the underlying directories). OTOH, the -noinherit etc. is already supported by the API, so, why reinvent some (redundant) syntax, we could as well use instead of "map" a "mapcmd" with a generalized "ns_register" (setting per default the methods GET POST HEAD) ns_section ns/server/default/adp ns_param mapcmd {ns_register ... -pattern /*.adp -noinherit} ns_param mapcmd {ns_register ... -pattern /* -except *.*} this way, we get standardized error messages, etc... The old "map" syntax can be supported as well for a while... The same can be made as well for other "maps" (e.g. connection pool mappings) Comments are always welcome. all the best -g |