http.server.rewrite: facility for making URLs prettier, and dynamic dispatching on the first part of a host name. Doug go nuts
parent
3857006b71
commit
181d9ca07d
|
@ -0,0 +1,72 @@
|
|||
IN: http.server.rewrite
|
||||
USING: help.syntax help.markup http.server ;
|
||||
|
||||
HELP: rewrite
|
||||
{ $class-description "The class of directory rewrite responders. The slots are as follows:"
|
||||
{ $list
|
||||
{ { $slot "default" } " - the responder to call if no file name is provided." }
|
||||
{ { $slot "child" } " - the responder to call if a file name is provided." }
|
||||
{ { $slot "param" } " - the name of a request parameter which will store the first path component of the file name passed to the responder." }
|
||||
} } ;
|
||||
|
||||
HELP: <rewrite>
|
||||
{ $values { "rewrite" rewrite } }
|
||||
{ $description "Creates a new " { $link rewrite } " responder." }
|
||||
{ $examples
|
||||
{ $code
|
||||
"<rewrite>"
|
||||
" <display-post-action> >>default"
|
||||
" <display-comment-action> >>child"
|
||||
" \"comment_id\" >>param"
|
||||
}
|
||||
} ;
|
||||
|
||||
HELP: vhost-rewrite
|
||||
{ $class-description "The class of virtual host rewrite responders. The slots are as follows:"
|
||||
{ $list
|
||||
{ { $slot "default" } " - the responder to call if no host name prefix is provided." }
|
||||
{ { $slot "child" } " - the responder to call if a host name prefix is provided." }
|
||||
{ { $slot "param" } " - the name of a request parameter which will store the first host name component of the host name passed to the responder." }
|
||||
{ { $slot "suffix" } " - the domain name suffix which will be chopped off the end of the request's host name in order to produce the parameter." }
|
||||
} } ;
|
||||
|
||||
HELP: <vhost-rewrite>
|
||||
{ $values { "vhost-rewrite" vhost-rewrite } }
|
||||
{ $description "Creates a new " { $link vhost-rewrite } " responder." }
|
||||
{ $examples
|
||||
{ $code
|
||||
"<vhost-rewrite>"
|
||||
" <show-blogs-action> >>default"
|
||||
" <display-blog-action> >>child"
|
||||
" \"blog_id\" >>param"
|
||||
" \"blogs.vegan.net >>suffix"
|
||||
}
|
||||
} ;
|
||||
|
||||
ARTICLE: "http.server.rewrite.overview" "Rewrite responder overview"
|
||||
"Rewrite responders take the file name and turn it into a request parameter named by the " { $slot "param" } " slot before delegating to a child responder. If a file name is provided, it calls the responder in the " { $slot "child" } " slot. If no file name is provided, they call the default responder in the " { $slot "default" } " slot."
|
||||
$nl
|
||||
"For example, suppose you want to have the following website schema:"
|
||||
{ $list
|
||||
{ { $snippet "/posts/" } " - show a list of posts" }
|
||||
{ { $snippet "/posts/factor_language" } " - show thread with ID " { $snippet "factor_language" } }
|
||||
{ { $snippet "/posts/factor_language/1" } " - show first comment in the thread with ID " { $snippet "factor_language" } }
|
||||
{ { $snippet "/animals" } ", ... - a bunch of other actions" } }
|
||||
"One way to achieve this would be to have a nesting of responders as follows:"
|
||||
{ $list
|
||||
{ "A dispatcher at the top level" }
|
||||
{ "A " { $link rewrite } " as a child of the dispatcher under the name " { $snippet "posts" } ". The rewrite has the " { $slot "param" } " slot set to, say, " { $snippet "post_id" } ". The " { $slot "default" } " slot is set to a Furnace action which displays a list of posts." }
|
||||
{ "The child slot is set to a second " { $link rewrite } " instance, with " { $snippet "param" } " set to " { $snippet "comment_id" } ", the " { $slot "default" } " slot set to an action which displays a post identified by the " { $snippet "post_id" } " parameter, and the " { $snippet "child" } " slot set to an action which displays the comment identified by the " { $snippet "comment_id" } " parameter." } }
|
||||
"Note that parameters can be extracted from the request using the " { $link param } " word, but most of the time you want to use " { $vocab-link "furnace.actions" } " instead." ;
|
||||
|
||||
ARTICLE: "http.server.rewrite" "URL rewrite responders"
|
||||
"The " { $vocab-link "http.server.rewrite" } " vocabulary defines two responder types which can help make website URLs more human-friendly."
|
||||
{ $subsection "http.server.rewrite.overview" }
|
||||
"Directory rewrite responders:"
|
||||
{ $subsection rewrite }
|
||||
{ $subsection <rewrite> }
|
||||
"Virtual host rewrite responders -- these chop off the value in the " { $snippet "suffix" } " slot from the tail of the host name, and use the rest as the parameter value:"
|
||||
{ $subsection vhost-rewrite }
|
||||
{ $subsection <vhost-rewrite> } ;
|
||||
|
||||
ABOUT: "http.server.rewrite"
|
|
@ -0,0 +1,48 @@
|
|||
USING: accessors arrays http.server http.server.rewrite kernel
|
||||
namespaces tools.test urls ;
|
||||
IN: http.server.rewrite.tests
|
||||
|
||||
TUPLE: rewrite-test-default ;
|
||||
|
||||
M: rewrite-test-default call-responder*
|
||||
drop "DEFAULT!" 2array ;
|
||||
|
||||
TUPLE: rewrite-test-child ;
|
||||
|
||||
M: rewrite-test-child call-responder*
|
||||
drop "rewritten-param" param 2array ;
|
||||
|
||||
V{ } clone responder-nesting set
|
||||
H{ } clone params set
|
||||
|
||||
<rewrite>
|
||||
rewrite-test-child new >>child
|
||||
rewrite-test-default new >>default
|
||||
"rewritten-param" >>param
|
||||
"rewrite" set
|
||||
|
||||
[ { { } "DEFAULT!" } ] [ { } "rewrite" get call-responder ] unit-test
|
||||
[ { { } "xxx" } ] [ { "xxx" } "rewrite" get call-responder ] unit-test
|
||||
[ { { "blah" } "xxx" } ] [ { "xxx" "blah" } "rewrite" get call-responder ] unit-test
|
||||
|
||||
<vhost-rewrite>
|
||||
rewrite-test-child new >>child
|
||||
rewrite-test-default new >>default
|
||||
"rewritten-param" >>param
|
||||
"blogs.vegan.net" >>suffix
|
||||
"rewrite" set
|
||||
|
||||
[ { { } "DEFAULT!" } ] [
|
||||
URL" http://blogs.vegan.net" url set
|
||||
{ } "rewrite" get call-responder
|
||||
] unit-test
|
||||
|
||||
[ { { } "DEFAULT!" } ] [
|
||||
URL" http://www.blogs.vegan.net" url set
|
||||
{ } "rewrite" get call-responder
|
||||
] unit-test
|
||||
|
||||
[ { { } "erg" } ] [
|
||||
URL" http://erg.blogs.vegan.net" url set
|
||||
{ } "rewrite" get call-responder
|
||||
] unit-test
|
|
@ -0,0 +1,33 @@
|
|||
! Copyright (C) 2009 Slava Pestov.
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
USING: accessors http.server kernel namespaces sequences
|
||||
splitting urls ;
|
||||
IN: http.server.rewrite
|
||||
|
||||
TUPLE: rewrite param child default ;
|
||||
|
||||
: <rewrite> ( -- rewrite )
|
||||
rewrite new ;
|
||||
|
||||
M: rewrite call-responder*
|
||||
over empty? [ default>> ] [
|
||||
[ [ first ] [ param>> ] bi* set-param ]
|
||||
[ [ rest ] [ child>> ] bi* ]
|
||||
2bi
|
||||
] if
|
||||
call-responder* ;
|
||||
|
||||
TUPLE: vhost-rewrite suffix param child default ;
|
||||
|
||||
: <vhost-rewrite> ( -- vhost-rewrite )
|
||||
vhost-rewrite new ;
|
||||
|
||||
: sub-domain? ( vhost-rewrite url -- subdomain ? )
|
||||
swap suffix>> dup [
|
||||
[ host>> canonical-host ] [ "." prepend ] bi* ?tail
|
||||
] [ 2drop f f ] if ;
|
||||
|
||||
M: vhost-rewrite call-responder*
|
||||
dup url get sub-domain?
|
||||
[ over param>> set-param child>> ] [ drop default>> ] if
|
||||
call-responder ;
|
Loading…
Reference in New Issue