changeset 774:412ccd97ab71

url demo
author Adam Chlipala <adamc@hcoop.net>
date Sun, 03 May 2009 12:24:39 -0400
parents 74a090ff296e
children a8bdd5a0d9b0
files demo/prose demo/url.ur demo/url.urp demo/url.urs src/demo.sml
diffstat 5 files changed, 54 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/demo/prose	Sun May 03 12:01:55 2009 -0400
+++ b/demo/prose	Sun May 03 12:24:39 2009 -0400
@@ -64,6 +64,12 @@
 
 <p>After setting the cookie, try browsing back to this demo from the main index.  The data you entered should still be there.</p>
 
+url.urp
+
+<p>Up to this point, we haven't included a single URL in our source code.  This may be very surprising to programmers used to working with traditional web frameworks!  In Ur/Web, we avoid writing URLs explicitly wherever possible.  To link to an external web page, we rely on an abstract type <tt>url</tt>.  Strings can't be treated implicitly as URLs; rather, they must be "blessed" explicitly.  This helps avoid some classes of code injection attacks.</p>
+
+<p>Further, each Ur/Web application enforces a global condition on which strings are allowed as URLs.  The <tt>.urp</tt> file for this demo shows an example that specifies particular rules about which URLs are allowed.  You can try entering a variety of URLs on the form on the front page.  Only those satisfying the <tt>allow url</tt>/<tt>deny url</tt> conditions should be permitted.</p>
+
 listShop.urp
 
 <p>This example shows off algebraic datatypes, parametric polymorphism, and functors.</p>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/demo/url.ur	Sun May 03 12:24:39 2009 -0400
@@ -0,0 +1,13 @@
+fun yourChoice r = return <xml><body>
+  {case checkUrl r.Url of
+       None => <xml>You aren't allowed to link to there.</xml>
+     | Some url => <xml><a href={url}>Enjoy!</a></xml>}
+</body></xml>
+
+fun main () = return <xml><body>
+  <a href="http://en.wikipedia.org/wiki/Type_inference">Learn something</a><br/>
+  <br/>
+  <form>
+    URL of your choice: <textbox{#Url}/> <submit action={yourChoice}/>
+  </form>
+</body></xml>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/demo/url.urp	Sun May 03 12:24:39 2009 -0400
@@ -0,0 +1,4 @@
+deny url http://en.wikipedia.org/wiki/PHP
+allow url http://en.wikipedia.org/wiki/*
+
+url
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/demo/url.urs	Sun May 03 12:24:39 2009 -0400
@@ -0,0 +1,1 @@
+val main : unit -> transaction page
--- a/src/demo.sml	Sun May 03 12:01:55 2009 -0400
+++ b/src/demo.sml	Sun May 03 12:24:39 2009 -0400
@@ -104,7 +104,7 @@
             clientOnly = [],
             serverOnly = [],
             jsFuncs = [],
-            rewrites = [],
+            rewrites = #rewrites combined @ #rewrites urp,
             filterUrl = #filterUrl combined @ #filterUrl urp,
             filterMime = #filterMime combined @ #filterMime urp
         }
@@ -372,6 +372,35 @@
                 TextIO.output (outf, "prefix ");
                 TextIO.output (outf, prefix);
                 TextIO.output (outf, "\n");
+                app (fn rule =>
+                        (TextIO.output (outf, "rewrite ");
+                         TextIO.output (outf, case #pkind rule of
+                                                  Settings.Any => "any"
+                                                | Settings.Url => "url"
+                                                | Settings.Table => "table"
+                                                | Settings.Sequence => "sequence"
+                                                | Settings.View => "view"
+                                                | Settings.Relation => "relation"
+                                                | Settings.Cookie => "cookie"
+                                                | Settings.Style => "style");
+                         TextIO.output (outf, " ");
+                         TextIO.output (outf, #from rule);
+                         case #kind rule of
+                             Settings.Exact => ()
+                           | Settings.Prefix => TextIO.output (outf, "*");
+                         TextIO.output (outf, " ");
+                         TextIO.output (outf, #to rule);
+                         TextIO.output (outf, "\n"))) (#rewrites combined);
+                app (fn rule =>
+                        (TextIO.output (outf, case #action rule of
+                                                  Settings.Allow => "allow"
+                                                | Settings.Deny => "deny");
+                         TextIO.output (outf, " url ");
+                         TextIO.output (outf, #pattern rule);
+                         case #kind rule of
+                             Settings.Exact => ()
+                           | Settings.Prefix => TextIO.output (outf, "*");
+                         TextIO.output (outf, "\n"))) (#filterUrl combined);
                 TextIO.output (outf, "\n");
 
                 app (fn s =>