diff options
Diffstat (limited to 'doc/rdoc/classes/Mongrel/URIClassifier.src')
4 files changed, 213 insertions, 0 deletions
diff --git a/doc/rdoc/classes/Mongrel/URIClassifier.src/M000013.html b/doc/rdoc/classes/Mongrel/URIClassifier.src/M000013.html new file mode 100644 index 0000000..a843bc8 --- /dev/null +++ b/doc/rdoc/classes/Mongrel/URIClassifier.src/M000013.html @@ -0,0 +1,54 @@ +<?xml version="1.0" encoding="iso-8859-1"?> +<!DOCTYPE html + PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html> +<head> + <title>new (Mongrel::URIClassifier)</title> + <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> + <link rel="stylesheet" href="../../.././rdoc-style.css" type="text/css" media="screen" /> +</head> +<body class="standalone-code"> + <pre>/** + * call-seq: + * URIClassifier.new -> URIClassifier + * + * Initializes a new URIClassifier object that you can use to associate URI sequences + * with objects. You can actually use it with any string sequence and any objects, + * but it's mostly used with URIs. + * + * It uses TST from http://www.octavian.org/cs/software.html to build an ternary search + * trie to hold all of the URIs. It uses this to do an initial search for the a URI + * prefix, and then to break the URI into SCRIPT_NAME and PATH_INFO portions. It actually + * will do two searches most of the time in order to find the right handler for the + * registered prefix portion. + * + * Here's how it all works. Let's say you register "/blog" with a BlogHandler. Great. + * Now, someone goes to "/blog/zedsucks/ass". You want SCRIPT_NAME to be "/blog" and + * PATH_INFO to be "/zedsucks/ass". URIClassifier first does a TST search and comes + * up with a failure, but knows that the failure ended at the "/blog" part. So, that's + * the SCRIPT_NAME. It then tries a second search for just "/blog". If that comes back + * good then it sets the rest ("/zedsucks/ass") to the PATH_INFO and returns the BlogHandler. + * + * The optimal approach would be to not do the search twice, but the TST lib doesn't + * really support returning prefixes. Might not be hard to add later. + * + * The key though is that it will try to match the *longest* match it can. If you + * also register "/blog/zed" then the above URI will give SCRIPT_NAME="/blog/zed", + * PATH_INFO="sucks/ass". Probably not what you want, so your handler will need to + * do the 404 thing. + * + * Take a look at the postamble of example/tepee.rb to see how this is handled for + * Camping. + */ +VALUE URIClassifier_init(VALUE self) +{ + VALUE hash; + + // we create an internal hash to protect stuff from the GC + hash = rb_hash_new(); + rb_iv_set(self, "handler_map", hash); +}</pre> +</body> +</html>
\ No newline at end of file diff --git a/doc/rdoc/classes/Mongrel/URIClassifier.src/M000014.html b/doc/rdoc/classes/Mongrel/URIClassifier.src/M000014.html new file mode 100644 index 0000000..5055109 --- /dev/null +++ b/doc/rdoc/classes/Mongrel/URIClassifier.src/M000014.html @@ -0,0 +1,50 @@ +<?xml version="1.0" encoding="iso-8859-1"?> +<!DOCTYPE html + PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html> +<head> + <title>register (Mongrel::URIClassifier)</title> + <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> + <link rel="stylesheet" href="../../.././rdoc-style.css" type="text/css" media="screen" /> +</head> +<body class="standalone-code"> + <pre>/** + * call-seq: + * uc.register("/someuri", SampleHandler.new) -> nil + * + * Registers the SampleHandler (one for all requests) with the "/someuri". + * When URIClassifier::resolve is called with "/someuri" it'll return + * SampleHandler immediately. When "/someuri/pathhere" is called it'll + * find SomeHandler after a second search, and setup PATH_INFO="/pathhere". + * + * You actually can reuse this class to register nearly anything and + * quickly resolve it. This could be used for caching, fast mapping, etc. + * The downside is it uses much more memory than a Hash, but it can be + * a lot faster. It's main advantage is that it works on prefixes, which + * is damn hard to get right with a Hash. + */ +VALUE URIClassifier_register(VALUE self, VALUE uri, VALUE handler) +{ + int rc = 0; + void *ptr = NULL; + struct tst *tst = NULL; + DATA_GET(self, struct tst, tst); + + rc = tst_insert((unsigned char *)StringValueCStr(uri), (void *)handler , tst, 0, &ptr); + + if(rc == TST_DUPLICATE_KEY) { + rb_raise(rb_eStandardError, "Handler already registered with that name"); + } else if(rc == TST_ERROR) { + rb_raise(rb_eStandardError, "Memory error registering handler"); + } else if(rc == TST_NULL_KEY) { + rb_raise(rb_eStandardError, "URI was empty"); + } + + rb_hash_aset(rb_iv_get(self, "handler_map"), uri, handler); + + return Qnil; +}</pre> +</body> +</html>
\ No newline at end of file diff --git a/doc/rdoc/classes/Mongrel/URIClassifier.src/M000015.html b/doc/rdoc/classes/Mongrel/URIClassifier.src/M000015.html new file mode 100644 index 0000000..4fafe2b --- /dev/null +++ b/doc/rdoc/classes/Mongrel/URIClassifier.src/M000015.html @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="iso-8859-1"?> +<!DOCTYPE html + PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html> +<head> + <title>unregister (Mongrel::URIClassifier)</title> + <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> + <link rel="stylesheet" href="../../.././rdoc-style.css" type="text/css" media="screen" /> +</head> +<body class="standalone-code"> + <pre>/** + * call-seq: + * uc.unregister("/someuri") + * + * Yep, just removes this uri and it's handler from the trie. + */ +VALUE URIClassifier_unregister(VALUE self, VALUE uri) +{ + void *handler = NULL; + struct tst *tst = NULL; + DATA_GET(self, struct tst, tst); + + handler = tst_delete((unsigned char *)StringValueCStr(uri), tst); + + if(handler) { + rb_hash_delete(rb_iv_get(self, "handler_map"), uri); + + return (VALUE)handler; + } else { + return Qnil; + } +}</pre> +</body> +</html>
\ No newline at end of file diff --git a/doc/rdoc/classes/Mongrel/URIClassifier.src/M000016.html b/doc/rdoc/classes/Mongrel/URIClassifier.src/M000016.html new file mode 100644 index 0000000..f545ea2 --- /dev/null +++ b/doc/rdoc/classes/Mongrel/URIClassifier.src/M000016.html @@ -0,0 +1,73 @@ +<?xml version="1.0" encoding="iso-8859-1"?> +<!DOCTYPE html + PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html> +<head> + <title>resolve (Mongrel::URIClassifier)</title> + <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> + <link rel="stylesheet" href="../../.././rdoc-style.css" type="text/css" media="screen" /> +</head> +<body class="standalone-code"> + <pre>/** + * call-seq: + * uc.resolve("/someuri") -> "/someuri", "", handler + * uc.resolve("/someuri/pathinfo") -> "/someuri", "/pathinfo", handler + * uc.resolve("/notfound/orhere") -> nil, nil, nil + * + * Attempts to resolve either the whole URI or at the longest prefix, returning + * the prefix (as script_info), path (as path_info), and registered handler + * (usually an HttpHandler). + * + * It expects strings. Don't try other string-line stuff yet. + */ +VALUE URIClassifier_resolve(VALUE self, VALUE uri) +{ + void *handler = NULL; + int pref_len = 0; + struct tst *tst = NULL; + VALUE result; + VALUE script_name; + VALUE path_info; + unsigned char *uri_str = NULL; + unsigned char *script_name_str = NULL; + + DATA_GET(self, struct tst, tst); + uri_str = (unsigned char *)StringValueCStr(uri); + + handler = tst_search(uri_str, tst, &pref_len); + + // setup for multiple return values + result = rb_ary_new(); + + + if(handler == NULL) { + script_name = rb_str_substr (uri, 0, pref_len); + script_name_str = (unsigned char *)StringValueCStr(script_name); + + handler = tst_search(script_name_str, tst, NULL); + + if(handler == NULL) { + // didn't find the script name at all + rb_ary_push(result, Qnil); + rb_ary_push(result, Qnil); + rb_ary_push(result, Qnil); + return result; + } else { + // found a handler, setup the path info and we're good + path_info = rb_str_substr(uri, pref_len, RSTRING(uri)->len); + } + } else { + // whole thing was found, so uri is the script name, path info empty + script_name = uri; + path_info = rb_str_new2(""); + } + + rb_ary_push(result, script_name); + rb_ary_push(result, path_info); + rb_ary_push(result, (VALUE)handler); + return result; +}</pre> +</body> +</html>
\ No newline at end of file |