about summary refs log tree commit homepage
path: root/doc/rdoc/classes/Mongrel/URIClassifier.src
diff options
context:
space:
mode:
Diffstat (limited to 'doc/rdoc/classes/Mongrel/URIClassifier.src')
-rw-r--r--doc/rdoc/classes/Mongrel/URIClassifier.src/M000013.html54
-rw-r--r--doc/rdoc/classes/Mongrel/URIClassifier.src/M000014.html50
-rw-r--r--doc/rdoc/classes/Mongrel/URIClassifier.src/M000015.html36
-rw-r--r--doc/rdoc/classes/Mongrel/URIClassifier.src/M000016.html73
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 -&gt; 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 &quot;/blog&quot; with a BlogHandler.  Great.
+ * Now, someone goes to &quot;/blog/zedsucks/ass&quot;.  You want SCRIPT_NAME to be &quot;/blog&quot; and
+ * PATH_INFO to be &quot;/zedsucks/ass&quot;.  URIClassifier first does a TST search and comes
+ * up with a failure, but knows that the failure ended at the &quot;/blog&quot; part.  So, that's
+ * the SCRIPT_NAME.  It then tries a second search for just &quot;/blog&quot;.  If that comes back
+ * good then it sets the rest (&quot;/zedsucks/ass&quot;) 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 &quot;/blog/zed&quot; then the above URI will give SCRIPT_NAME=&quot;/blog/zed&quot;,
+ * PATH_INFO=&quot;sucks/ass&quot;.  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, &quot;handler_map&quot;, 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(&quot;/someuri&quot;, SampleHandler.new) -&gt; nil
+ *
+ * Registers the SampleHandler (one for all requests) with the &quot;/someuri&quot;.
+ * When URIClassifier::resolve is called with &quot;/someuri&quot; it'll return
+ * SampleHandler immediately.  When &quot;/someuri/pathhere&quot; is called it'll
+ * find SomeHandler after a second search, and setup PATH_INFO=&quot;/pathhere&quot;.
+ *
+ * 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, &amp;ptr);
+
+  if(rc == TST_DUPLICATE_KEY) {
+    rb_raise(rb_eStandardError, &quot;Handler already registered with that name&quot;);
+  } else if(rc == TST_ERROR) {
+    rb_raise(rb_eStandardError, &quot;Memory error registering handler&quot;);
+  } else if(rc == TST_NULL_KEY) {
+    rb_raise(rb_eStandardError, &quot;URI was empty&quot;);
+  }
+  
+  rb_hash_aset(rb_iv_get(self, &quot;handler_map&quot;), 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(&quot;/someuri&quot;)
+ *
+ * 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, &quot;handler_map&quot;), 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(&quot;/someuri&quot;) -&gt; &quot;/someuri&quot;, &quot;&quot;, handler
+ *    uc.resolve(&quot;/someuri/pathinfo&quot;) -&gt; &quot;/someuri&quot;, &quot;/pathinfo&quot;, handler
+ *    uc.resolve(&quot;/notfound/orhere&quot;) -&gt; 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, &amp;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)-&gt;len);
+    }
+  } else {
+    // whole thing was found, so uri is the script name, path info empty
+    script_name = uri;
+    path_info = rb_str_new2(&quot;&quot;);
+  }
+
+  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