summary refs log tree commit diff
diff options
context:
space:
mode:
authorfranck cuny <franck@lumberjaph.net>2010-03-18 18:41:31 +0100
committerfranck cuny <franck@lumberjaph.net>2010-03-18 18:41:31 +0100
commit5540780e9011d2385a0226f4e22fe73c0bc92798 (patch)
tree2cf808350607f3be2b8e10d4ad942f6fc4db6aa4
downloaddancer-rest-5540780e9011d2385a0226f4e22fe73c0bc92798.tar.gz
initial import
-rw-r--r--app.psgi13
-rw-r--r--config.yml3
-rwxr-xr-xdancerREST.pl4
-rw-r--r--dancerREST.pm95
-rw-r--r--environments/development.yml5
-rw-r--r--environments/production.yml6
-rw-r--r--logs/development.log565
-rw-r--r--public/404.html17
-rw-r--r--public/500.html17
-rw-r--r--public/css/error.css70
-rw-r--r--public/css/style.css34
-rwxr-xr-xpublic/dispatch.cgi3
-rwxr-xr-xpublic/dispatch.fcgi6
-rw-r--r--public/favicon.icobin0 -> 1406 bytes
-rw-r--r--views/index.tt5
-rw-r--r--views/layouts/main.tt17
-rw-r--r--views/user.tt5
17 files changed, 865 insertions, 0 deletions
diff --git a/app.psgi b/app.psgi
new file mode 100644
index 0000000..c4ed02b
--- /dev/null
+++ b/app.psgi
@@ -0,0 +1,13 @@
+# PSGI application bootstraper for Dancer
+use lib '/home/franck/tmp/dancerREST';
+use dancerREST;
+
+use Dancer::Config 'setting';
+setting apphandler  => 'PSGI';
+Dancer::Config->load;
+
+my $handler = sub {
+    my $env = shift;
+    my $request = Dancer::Request->new($env);
+    Dancer->dance($request);
+};
diff --git a/config.yml b/config.yml
new file mode 100644
index 0000000..e2fc722
--- /dev/null
+++ b/config.yml
@@ -0,0 +1,3 @@
+layout: "main"
+logger: "file"
+serializer: "JSON"
diff --git a/dancerREST.pl b/dancerREST.pl
new file mode 100755
index 0000000..02b2cf2
--- /dev/null
+++ b/dancerREST.pl
@@ -0,0 +1,4 @@
+#!/home/franck/local/bin/perl
+use Dancer;
+use dancerREST;
+dance;
diff --git a/dancerREST.pm b/dancerREST.pm
new file mode 100644
index 0000000..7b0ed0f
--- /dev/null
+++ b/dancerREST.pm
@@ -0,0 +1,95 @@
+package dancerREST;
+use Dancer;
+use Dancer::SharedData;
+
+my %users = ();
+
+get '/' => sub {
+    template "index.tt";
+};
+
+# return a list of users
+# curl -H "Content-Type: application/json" http://localhost:5000/api/user/
+# => [{"name":"foo","id":"1"}]
+get '/api/user/' => sub {
+    my @users;
+    push @users, { name => $users{$_}->{name}, id => $_ } foreach keys %users;
+    return \@users;
+};
+
+# return a specific user
+# curl -H "Content-Type: application/json" http://localhost:5000/api/user/1
+# => {"name":"foo"}
+get '/api/user/:id' => sub {
+    my $params = Dancer::SharedData->request->params;
+    if ( exists $users{ $params->{id} } ) {
+        return $users{$params->{id}};
+    }
+    else {
+        return { error => "unknown user" };
+    }
+};
+
+# create a new user
+# curl -H "Content-Type: application/json" -X POST http://localhost:5000/api/user/ -d '{"name":"foo","id":1}'
+# => {"name":"foo","id":"1"}
+post '/api/user/' => sub {
+    my $params = Dancer::SharedData->request->params;
+    if ( $params->{name} && $params->{id} ) {
+        if ( exists $users{ $params->{id} } ) {
+            return { error => "user already exists" };
+        }
+        $users{$params->{id}} = {name => $params->{name}};
+        return { id => $params->{id}, name => $params->{name} };
+    }
+    else {
+        return { error => "name is missing" };
+    }
+};
+
+# delete a user
+# curl -H "Content-Type: application/json" -X DELETE http://localhost:5000/api/user/1 
+# {"deleted":1}
+del '/api/user/:id' => sub {
+    my $params = Dancer::SharedData->request->params;
+    if ( $params->{id} ) {
+        if ( exists $users{ $params->{id} } ) {
+            delete $users{ $params->{id} };
+            return { deleted => 1 };
+        }
+        else {
+            return { error => "unknown user" };
+        }
+    }
+    else {
+        return { error => "user id is missing" };
+    }
+};
+
+# curl http://localhost:5000/user/1
+# or
+# curl -H "X-Requested-With: XMLHttpRequest" http://localhost:5000/user/1
+get '/user/:id' => sub {
+    my $params = Dancer::SharedData->request->params;
+    my $user    = $users{ $params->{id} };
+    my $result;
+    if ( !$user ) {
+        _render_user( { error => "unknown user" } );
+    }
+    else {
+        _render_user($user);
+    }
+};
+
+sub _render_user {
+    my $result  = shift;
+    my $request = Dancer::SharedData->request;
+    if ( $request->is_ajax ) {
+        return Dancer::Serializer->engine->serialize($result);
+    }
+    else {
+        template 'user.tt', $result;
+    }
+}
+
+true;
diff --git a/environments/development.yml b/environments/development.yml
new file mode 100644
index 0000000..7b8406f
--- /dev/null
+++ b/environments/development.yml
@@ -0,0 +1,5 @@
+log: "debug"
+warnings: 1
+show_errors: 1
+auto_reload: 1
+
diff --git a/environments/production.yml b/environments/production.yml
new file mode 100644
index 0000000..1a69035
--- /dev/null
+++ b/environments/production.yml
@@ -0,0 +1,6 @@
+log: "warning"
+warnings: 0
+show_errors: 0
+route_cache: 1
+auto_reload: 0
+
diff --git a/logs/development.log b/logs/development.log
new file mode 100644
index 0000000..755311b
--- /dev/null
+++ b/logs/development.log
@@ -0,0 +1,565 @@
+Thu Mar 18 14:48:10 2010 [7870] (warning) --- !!perl/hash:Dancer::Request 
+_body_params: &1 {}
+
+_chunk_size: 4096
+_http_body: !!perl/hash:HTTP::Body::UrlEncoded 
+  body: ~
+  buffer: ''
+  chunk_buffer: ''
+  chunked: ''
+  cleanup: 0
+  content_length: 9
+  content_type: application/x-www-form-urlencoded
+  length: 9
+  param: *1
+  state: done
+  tmpdir: /tmp
+  upload: {}
+
+_query_params: {}
+
+_read_position: 9
+_route_params: {}
+
+accept: "*/*"
+accept_charset: ~
+accept_encoding: ~
+accept_language: ~
+body: "{'foo':1}"
+connection: ~
+content_length: 9
+content_type: application/x-www-form-urlencoded
+env: 
+  CONTENT_LENGTH: 9
+  CONTENT_TYPE: application/x-www-form-urlencoded
+  HTTP_ACCEPT: "*/*"
+  HTTP_HOST: localhost:5000
+  HTTP_USER_AGENT: curl/7.20.0 (x86_64-pc-linux-gnu) libcurl/7.20.0 OpenSSL/0.9.8m zlib/1.2.3.4 libidn/1.18 libssh2/1.2.2
+  PATH_INFO: /
+  QUERY_STRING: ''
+  REMOTE_ADDR: 127.0.0.1
+  REQUEST_METHOD: POST
+  REQUEST_URI: /
+  SCRIPT_NAME: ''
+  SERVER_NAME: 0
+  SERVER_PORT: 5000
+  SERVER_PROTOCOL: HTTP/1.1
+  psgi.errors: "*main::STDERR"
+  psgi.input: !!perl/glob:FileHandle 
+    =: "*Plack::TempBuffer::PerlIO::$io"
+  psgi.multiprocess: ~
+  psgi.multithread: ''
+  psgi.nonblocking: ''
+  psgi.run_once: ''
+  psgi.streaming: 1
+  psgi.url_scheme: http
+  psgi.version: 
+    - 1
+    - 1
+  psgix.input.buffered: 1
+host: localhost:5000
+keep_alive: ~
+method: POST
+params: {}
+
+path: /
+path_info: /
+referer: ~
+user_agent: curl/7.20.0 (x86_64-pc-linux-gnu) libcurl/7.20.0 OpenSSL/0.9.8m zlib/1.2.3.4 libidn/1.18 libssh2/1.2.2
+x_requested_with: ~ in /home/franck/code/projects/perl5/dancer/lib/Dancer/Route.pm l. 188
+Thu Mar 18 14:49:25 2010 [7870] (warning) --- !!perl/hash:Dancer::Request 
+_body_params: &1 {}
+
+_chunk_size: 4096
+_http_body: !!perl/hash:HTTP::Body::OctetStream 
+  body: !!perl/glob:File::Temp 
+    =: "*File::Temp::$fh"
+  buffer: ''
+  chunk_buffer: ''
+  chunked: ''
+  cleanup: 0
+  content_length: 9
+  content_type: application/json
+  length: 9
+  param: *1
+  state: done
+  tmpdir: /tmp
+  upload: {}
+
+_query_params: {}
+
+_read_position: 9
+_route_params: {}
+
+accept: "*/*"
+accept_charset: ~
+accept_encoding: ~
+accept_language: ~
+body: "{'foo':1}"
+connection: ~
+content_length: 9
+content_type: application/json
+env: 
+  CONTENT_LENGTH: 9
+  CONTENT_TYPE: application/json
+  HTTP_ACCEPT: "*/*"
+  HTTP_HOST: localhost:5000
+  HTTP_USER_AGENT: curl/7.20.0 (x86_64-pc-linux-gnu) libcurl/7.20.0 OpenSSL/0.9.8m zlib/1.2.3.4 libidn/1.18 libssh2/1.2.2
+  PATH_INFO: /
+  QUERY_STRING: ''
+  REMOTE_ADDR: 127.0.0.1
+  REQUEST_METHOD: POST
+  REQUEST_URI: /
+  SCRIPT_NAME: ''
+  SERVER_NAME: 0
+  SERVER_PORT: 5000
+  SERVER_PROTOCOL: HTTP/1.1
+  psgi.errors: "*main::STDERR"
+  psgi.input: !!perl/glob:FileHandle 
+    =: "*Plack::TempBuffer::PerlIO::$io"
+  psgi.multiprocess: ~
+  psgi.multithread: ''
+  psgi.nonblocking: ''
+  psgi.run_once: ''
+  psgi.streaming: 1
+  psgi.url_scheme: http
+  psgi.version: 
+    - 1
+    - 1
+  psgix.input.buffered: 1
+host: localhost:5000
+keep_alive: ~
+method: POST
+params: {}
+
+path: /
+path_info: /
+referer: ~
+user_agent: curl/7.20.0 (x86_64-pc-linux-gnu) libcurl/7.20.0 OpenSSL/0.9.8m zlib/1.2.3.4 libidn/1.18 libssh2/1.2.2
+x_requested_with: ~ in /home/franck/code/projects/perl5/dancer/lib/Dancer/Route.pm l. 188
+Thu Mar 18 14:49:41 2010 [7870] (warning) --- !!perl/hash:Dancer::Request 
+_body_params: 
+  foo: 1
+_chunk_size: 4096
+_http_body: !!perl/hash:HTTP::Body::OctetStream 
+  body: !!perl/glob:File::Temp 
+    =: "*File::Temp::$fh"
+  buffer: ''
+  chunk_buffer: ''
+  chunked: ''
+  cleanup: 0
+  content_length: 9
+  content_type: application/json
+  length: 9
+  param: {}
+
+  state: done
+  tmpdir: /tmp
+  upload: {}
+
+_query_params: {}
+
+_read_position: 9
+_route_params: {}
+
+accept: "*/*"
+accept_charset: ~
+accept_encoding: ~
+accept_language: ~
+body: "{\"foo\":1}"
+connection: ~
+content_length: 9
+content_type: application/json
+env: 
+  CONTENT_LENGTH: 9
+  CONTENT_TYPE: application/json
+  HTTP_ACCEPT: "*/*"
+  HTTP_HOST: localhost:5000
+  HTTP_USER_AGENT: curl/7.20.0 (x86_64-pc-linux-gnu) libcurl/7.20.0 OpenSSL/0.9.8m zlib/1.2.3.4 libidn/1.18 libssh2/1.2.2
+  PATH_INFO: /
+  QUERY_STRING: ''
+  REMOTE_ADDR: 127.0.0.1
+  REQUEST_METHOD: POST
+  REQUEST_URI: /
+  SCRIPT_NAME: ''
+  SERVER_NAME: 0
+  SERVER_PORT: 5000
+  SERVER_PROTOCOL: HTTP/1.1
+  psgi.errors: "*main::STDERR"
+  psgi.input: !!perl/glob:FileHandle 
+    =: "*Plack::TempBuffer::PerlIO::$io"
+  psgi.multiprocess: ~
+  psgi.multithread: ''
+  psgi.nonblocking: ''
+  psgi.run_once: ''
+  psgi.streaming: 1
+  psgi.url_scheme: http
+  psgi.version: 
+    - 1
+    - 1
+  psgix.input.buffered: 1
+host: localhost:5000
+keep_alive: ~
+method: POST
+params: 
+  foo: 1
+path: /
+path_info: /
+referer: ~
+user_agent: curl/7.20.0 (x86_64-pc-linux-gnu) libcurl/7.20.0 OpenSSL/0.9.8m zlib/1.2.3.4 libidn/1.18 libssh2/1.2.2
+x_requested_with: ~ in /home/franck/code/projects/perl5/dancer/lib/Dancer/Route.pm l. 188
+Thu Mar 18 14:50:01 2010 [7870] (warning) --- !!perl/hash:Dancer::Request 
+_body_params: 
+  foo: 1
+_chunk_size: 4096
+_http_body: !!perl/hash:HTTP::Body::OctetStream 
+  body: !!perl/glob:File::Temp 
+    =: "*File::Temp::$fh"
+  buffer: ''
+  chunk_buffer: ''
+  chunked: ''
+  cleanup: 0
+  content_length: 9
+  content_type: application/json
+  length: 9
+  param: {}
+
+  state: done
+  tmpdir: /tmp
+  upload: {}
+
+_query_params: {}
+
+_read_position: 9
+_route_params: {}
+
+accept: "*/*"
+accept_charset: ~
+accept_encoding: ~
+accept_language: ~
+body: "{\"foo\":1}"
+connection: ~
+content_length: 9
+content_type: application/json
+env: 
+  CONTENT_LENGTH: 9
+  CONTENT_TYPE: application/json
+  HTTP_ACCEPT: "*/*"
+  HTTP_HOST: localhost:5000
+  HTTP_USER_AGENT: curl/7.20.0 (x86_64-pc-linux-gnu) libcurl/7.20.0 OpenSSL/0.9.8m zlib/1.2.3.4 libidn/1.18 libssh2/1.2.2
+  PATH_INFO: /
+  QUERY_STRING: ''
+  REMOTE_ADDR: 127.0.0.1
+  REQUEST_METHOD: POST
+  REQUEST_URI: /
+  SCRIPT_NAME: ''
+  SERVER_NAME: 0
+  SERVER_PORT: 5000
+  SERVER_PROTOCOL: HTTP/1.1
+  psgi.errors: "*main::STDERR"
+  psgi.input: !!perl/glob:FileHandle 
+    =: "*Plack::TempBuffer::PerlIO::$io"
+  psgi.multiprocess: ~
+  psgi.multithread: ''
+  psgi.nonblocking: ''
+  psgi.run_once: ''
+  psgi.streaming: 1
+  psgi.url_scheme: http
+  psgi.version: 
+    - 1
+    - 1
+  psgix.input.buffered: 1
+host: localhost:5000
+keep_alive: ~
+method: POST
+params: 
+  foo: 1
+path: /
+path_info: /
+referer: ~
+user_agent: curl/7.20.0 (x86_64-pc-linux-gnu) libcurl/7.20.0 OpenSSL/0.9.8m zlib/1.2.3.4 libidn/1.18 libssh2/1.2.2
+x_requested_with: ~ in /home/franck/code/projects/perl5/dancer/lib/Dancer/Route.pm l. 188
+Thu Mar 18 14:51:16 2010 [7870] (warning) --- !!perl/hash:Dancer::Request 
+_body_params: 
+  foo: 1
+_chunk_size: 4096
+_http_body: !!perl/hash:HTTP::Body::OctetStream 
+  body: !!perl/glob:File::Temp 
+    =: "*File::Temp::$fh"
+  buffer: ''
+  chunk_buffer: ''
+  chunked: ''
+  cleanup: 0
+  content_length: 9
+  content_type: application/json
+  length: 9
+  param: {}
+
+  state: done
+  tmpdir: /tmp
+  upload: {}
+
+_query_params: {}
+
+_read_position: 9
+_route_params: {}
+
+accept: "*/*"
+accept_charset: ~
+accept_encoding: ~
+accept_language: ~
+body: "{\"foo\":1}"
+connection: ~
+content_length: 9
+content_type: application/json
+env: 
+  CONTENT_LENGTH: 9
+  CONTENT_TYPE: application/json
+  HTTP_ACCEPT: "*/*"
+  HTTP_HOST: localhost:5000
+  HTTP_USER_AGENT: curl/7.20.0 (x86_64-pc-linux-gnu) libcurl/7.20.0 OpenSSL/0.9.8m zlib/1.2.3.4 libidn/1.18 libssh2/1.2.2
+  PATH_INFO: /
+  QUERY_STRING: ''
+  REMOTE_ADDR: 127.0.0.1
+  REQUEST_METHOD: POST
+  REQUEST_URI: /
+  SCRIPT_NAME: ''
+  SERVER_NAME: 0
+  SERVER_PORT: 5000
+  SERVER_PROTOCOL: HTTP/1.1
+  psgi.errors: "*main::STDERR"
+  psgi.input: !!perl/glob:FileHandle 
+    =: "*Plack::TempBuffer::PerlIO::$io"
+  psgi.multiprocess: ~
+  psgi.multithread: ''
+  psgi.nonblocking: ''
+  psgi.run_once: ''
+  psgi.streaming: 1
+  psgi.url_scheme: http
+  psgi.version: 
+    - 1
+    - 1
+  psgix.input.buffered: 1
+host: localhost:5000
+keep_alive: ~
+method: POST
+params: 
+  foo: 1
+path: /
+path_info: /
+referer: ~
+user_agent: curl/7.20.0 (x86_64-pc-linux-gnu) libcurl/7.20.0 OpenSSL/0.9.8m zlib/1.2.3.4 libidn/1.18 libssh2/1.2.2
+x_requested_with: ~ in /home/franck/code/projects/perl5/dancer/lib/Dancer/Route.pm l. 188
+Thu Mar 18 14:51:22 2010 [8135] (warning) --- !!perl/hash:Dancer::Request 
+_body_params: 
+  foo: 1
+_chunk_size: 4096
+_http_body: !!perl/hash:HTTP::Body::OctetStream 
+  body: !!perl/glob:File::Temp 
+    =: "*File::Temp::$fh"
+  buffer: ''
+  chunk_buffer: ''
+  chunked: ''
+  cleanup: 0
+  content_length: 9
+  content_type: application/json
+  length: 9
+  param: {}
+
+  state: done
+  tmpdir: /tmp
+  upload: {}
+
+_query_params: {}
+
+_read_position: 9
+_route_params: {}
+
+accept: "*/*"
+accept_charset: ~
+accept_encoding: ~
+accept_language: ~
+body: "{\"foo\":1}"
+connection: ~
+content_length: 9
+content_type: application/json
+env: 
+  CONTENT_LENGTH: 9
+  CONTENT_TYPE: application/json
+  HTTP_ACCEPT: "*/*"
+  HTTP_HOST: localhost:5000
+  HTTP_USER_AGENT: curl/7.20.0 (x86_64-pc-linux-gnu) libcurl/7.20.0 OpenSSL/0.9.8m zlib/1.2.3.4 libidn/1.18 libssh2/1.2.2
+  PATH_INFO: /
+  QUERY_STRING: ''
+  REMOTE_ADDR: 127.0.0.1
+  REQUEST_METHOD: POST
+  REQUEST_URI: /
+  SCRIPT_NAME: ''
+  SERVER_NAME: 0
+  SERVER_PORT: 5000
+  SERVER_PROTOCOL: HTTP/1.1
+  psgi.errors: "*main::STDERR"
+  psgi.input: !!perl/glob:FileHandle 
+    =: "*Plack::TempBuffer::PerlIO::$io"
+  psgi.multiprocess: ~
+  psgi.multithread: ''
+  psgi.nonblocking: ''
+  psgi.run_once: ''
+  psgi.streaming: 1
+  psgi.url_scheme: http
+  psgi.version: 
+    - 1
+    - 1
+  psgix.input.buffered: 1
+host: localhost:5000
+keep_alive: ~
+method: POST
+params: 
+  foo: 1
+path: /
+path_info: /
+referer: ~
+user_agent: curl/7.20.0 (x86_64-pc-linux-gnu) libcurl/7.20.0 OpenSSL/0.9.8m zlib/1.2.3.4 libidn/1.18 libssh2/1.2.2
+x_requested_with: ~ in /home/franck/code/projects/perl5/dancer/lib/Dancer/Route.pm l. 188
+Thu Mar 18 14:52:38 2010 [8338] (warning) --- 
+foo: 1 in /home/franck/code/projects/perl5/dancer/lib/Dancer/Route.pm l. 188
+Thu Mar 18 16:22:10 2010 [11104] (warning) --- !!perl/hash:Dancer::Request 
+_body_params: &1 {}
+
+_chunk_size: 4096
+_http_body: !!perl/hash:HTTP::Body::OctetStream 
+  body: ~
+  buffer: ''
+  chunk_buffer: ''
+  chunked: ''
+  cleanup: 0
+  content_length: 0
+  content_type: ''
+  length: 0
+  param: *1
+  state: buffering
+  tmpdir: /tmp
+  upload: {}
+
+_query_params: {}
+
+_read_position: 0
+_route_params: 
+  id: 5
+accept: "*/*"
+accept_charset: ~
+accept_encoding: ~
+accept_language: ~
+body: ''
+connection: ~
+content_length: 0
+content_type: ''
+env: 
+  HTTP_ACCEPT: "*/*"
+  HTTP_HOST: localhost:5000
+  HTTP_USER_AGENT: curl/7.20.0 (x86_64-pc-linux-gnu) libcurl/7.20.0 OpenSSL/0.9.8m zlib/1.2.3.4 libidn/1.18 libssh2/1.2.2
+  HTTP_X_REQUESTED_WITH: XMLHttpRequest
+  PATH_INFO: /user/5
+  QUERY_STRING: ''
+  REMOTE_ADDR: 127.0.0.1
+  REQUEST_METHOD: GET
+  REQUEST_URI: /user/5
+  SCRIPT_NAME: ''
+  SERVER_NAME: 0
+  SERVER_PORT: 5000
+  SERVER_PROTOCOL: HTTP/1.1
+  psgi.errors: "*main::STDERR"
+  psgi.input: !!perl/ref 
+    =: "*HTTP::Server::PSGI::$input"
+  psgi.multiprocess: ~
+  psgi.multithread: ''
+  psgi.nonblocking: ''
+  psgi.run_once: ''
+  psgi.streaming: 1
+  psgi.url_scheme: http
+  psgi.version: 
+    - 1
+    - 1
+  psgix.input.buffered: 1
+host: localhost:5000
+keep_alive: ~
+method: GET
+params: 
+  id: 5
+path: /user/5
+path_info: /user/5
+referer: ~
+user_agent: curl/7.20.0 (x86_64-pc-linux-gnu) libcurl/7.20.0 OpenSSL/0.9.8m zlib/1.2.3.4 libidn/1.18 libssh2/1.2.2
+x_requested_with: ~ in /home/franck/code/projects/perl5/dancer/lib/Dancer/Route.pm l. 188
+Thu Mar 18 16:25:53 2010 [11414] (warning) --- !!perl/hash:Dancer::Request 
+_body_params: &1 {}
+
+_chunk_size: 4096
+_http_body: !!perl/hash:HTTP::Body::OctetStream 
+  body: ~
+  buffer: ''
+  chunk_buffer: ''
+  chunked: ''
+  cleanup: 0
+  content_length: 0
+  content_type: ''
+  length: 0
+  param: *1
+  state: buffering
+  tmpdir: /tmp
+  upload: {}
+
+_query_params: {}
+
+_read_position: 0
+_route_params: 
+  id: 5
+accept: "*/*"
+accept_charset: ~
+accept_encoding: ~
+accept_language: ~
+body: ''
+connection: ~
+content_length: 0
+content_type: ''
+env: 
+  HTTP_ACCEPT: "*/*"
+  HTTP_HOST: localhost:5000
+  HTTP_USER_AGENT: curl/7.20.0 (x86_64-pc-linux-gnu) libcurl/7.20.0 OpenSSL/0.9.8m zlib/1.2.3.4 libidn/1.18 libssh2/1.2.2
+  HTTP_X_REQUESTED_WITH: XMLHttpRequest
+  PATH_INFO: /user/5
+  QUERY_STRING: ''
+  REMOTE_ADDR: 127.0.0.1
+  REQUEST_METHOD: GET
+  REQUEST_URI: /user/5
+  SCRIPT_NAME: ''
+  SERVER_NAME: 0
+  SERVER_PORT: 5000
+  SERVER_PROTOCOL: HTTP/1.1
+  psgi.errors: "*main::STDERR"
+  psgi.input: !!perl/ref 
+    =: "*HTTP::Server::PSGI::$input"
+  psgi.multiprocess: ~
+  psgi.multithread: ''
+  psgi.nonblocking: ''
+  psgi.run_once: ''
+  psgi.streaming: 1
+  psgi.url_scheme: http
+  psgi.version: 
+    - 1
+    - 1
+  psgix.input.buffered: 1
+host: localhost:5000
+keep_alive: ~
+method: GET
+params: 
+  id: 5
+path: /user/5
+path_info: /user/5
+referer: ~
+user_agent: curl/7.20.0 (x86_64-pc-linux-gnu) libcurl/7.20.0 OpenSSL/0.9.8m zlib/1.2.3.4 libidn/1.18 libssh2/1.2.2
+x_requested_with: XMLHttpRequest in /home/franck/code/projects/perl5/dancer/lib/Dancer/Route.pm l. 188
+Thu Mar 18 17:50:02 2010 [14535] (warning) --- {}
+ in /home/franck/code/projects/perl5/dancer/lib/Dancer/Route.pm l. 188
+Thu Mar 18 18:40:06 2010 [17243] (warning) --- 
+name: foo in /home/franck/code/projects/perl5/dancer/lib/Dancer/Route.pm l. 188
diff --git a/public/404.html b/public/404.html
new file mode 100644
index 0000000..56a7b9d
--- /dev/null
+++ b/public/404.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US" xml:lang="en-US">
+<head>
+<title>Error 404</title>
+<link rel="stylesheet" type="text/css" href="/css/error.css" />
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+</head>
+<body>
+<h1>Error 404</h1>
+<div id="content">
+<p><h2>Page Not Found</h2><p>Sorry, this is the void.</p></p>
+</div>
+<div id="footer">
+Powered by <a href="http://dancer.sukria.net">Dancer</a> 
+</div>
+</body>
+</html>
\ No newline at end of file
diff --git a/public/500.html b/public/500.html
new file mode 100644
index 0000000..f726607
--- /dev/null
+++ b/public/500.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US" xml:lang="en-US">
+<head>
+<title>Error 500</title>
+<link rel="stylesheet" type="text/css" href="/css/error.css" />
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+</head>
+<body>
+<h1>Error 500</h1>
+<div id="content">
+<p><h2>Internal Server Error</h2><p>Wooops, something went wrong</p></p>
+</div>
+<div id="footer">
+Powered by <a href="http://dancer.sukria.net">Dancer</a> 
+</div>
+</body>
+</html>
\ No newline at end of file
diff --git a/public/css/error.css b/public/css/error.css
new file mode 100644
index 0000000..c65d027
--- /dev/null
+++ b/public/css/error.css
@@ -0,0 +1,70 @@
+body {
+    font-family: Lucida,sans-serif;
+}
+
+h1 {
+    color: #AA0000;
+    border-bottom: 1px solid #444;
+}
+
+h2 { color: #444; }
+
+pre {
+    font-family: "lucida console","monaco","andale mono","bitstream vera sans mono","consolas",monospace;
+    font-size: 12px;
+    border-left: 2px solid #777;
+    padding-left: 1em;
+}
+
+#footer {
+    font-size: 10px;
+}
+
+span.key { 
+    color: #449;
+    font-weight: bold;
+    width: 120px;
+    display: inline;
+}
+
+span.value {
+    color: #494;
+}
+
+/* these are for the message boxes */
+
+pre.content {
+    background-color: #eee;
+    color: #000;
+    padding: 1em;
+    margin: 0;
+    border: 1px solid #aaa;
+    border-top: 0;
+    margin-bottom: 1em;
+}
+
+div.title {
+    font-family: "lucida console","monaco","andale mono","bitstream vera sans mono","consolas",monospace;
+    font-size: 12px;
+    background-color: #aaa;
+    color: #444;
+    font-weight: bold;
+    padding: 3px;
+    padding-left: 10px;
+}
+
+pre.content span.nu {
+    color: #889;
+    margin-right: 10px;
+}
+
+pre.error {
+    background: #334;
+    color: #ccd;
+    padding: 1em;
+    border-top: 1px solid #000;
+    border-left: 1px solid #000;
+    border-right: 1px solid #eee;
+    border-bottom: 1px solid #eee;
+}
+
diff --git a/public/css/style.css b/public/css/style.css
new file mode 100644
index 0000000..4a7f59e
--- /dev/null
+++ b/public/css/style.css
@@ -0,0 +1,34 @@
+body {
+    font-family: Lucida,sans-serif;   
+    color: #eee;
+    background-color: #1f1b1a;
+}
+
+#content {
+    color: #000;
+    background-color: #eee;
+    padding: 1em;
+    margin: 1em;
+    padding-top: 0.5em;
+}
+
+a { 
+    color: #a5ec02;
+}
+
+h1 { 
+    color: #a5ec02;
+}
+
+#footer {
+    border-top: 1px solid #aba29c;
+    margin-top: 2em;
+    padding-top: 1em;
+    font-size: 10px;
+    color: #ddd;
+}
+
+pre {
+    font-family: \"lucida console\",\"monaco\",\"andale mono\",\"bitstream vera sans mono\",\"consolas\",monospace;
+}
+
diff --git a/public/dispatch.cgi b/public/dispatch.cgi
new file mode 100755
index 0000000..85eb1db
--- /dev/null
+++ b/public/dispatch.cgi
@@ -0,0 +1,3 @@
+#!/home/franck/local/bin/perl
+use Plack::Runner;
+Plack::Runner->run('/home/franck/tmp/dancerREST/app.psgi');
diff --git a/public/dispatch.fcgi b/public/dispatch.fcgi
new file mode 100755
index 0000000..559f2b7
--- /dev/null
+++ b/public/dispatch.fcgi
@@ -0,0 +1,6 @@
+#!/home/franck/local/bin/perl
+use Plack::Handler::FCGI;
+
+my $app = do('/home/franck/tmp/dancerREST/app.psgi');
+my $server = Plack::Handler::FCGI->new(nproc  => 5, detach => 1);
+$server->run($app);
diff --git a/public/favicon.ico b/public/favicon.ico
new file mode 100644
index 0000000..957f4b4
--- /dev/null
+++ b/public/favicon.ico
Binary files differdiff --git a/views/index.tt b/views/index.tt
new file mode 100644
index 0000000..3d6b342
--- /dev/null
+++ b/views/index.tt
@@ -0,0 +1,5 @@
+<h2>It Works!</h2>
+
+<p>
+I'm in <code>/home/franck/tmp/dancerREST/views/index.tt</code>
+</p>
diff --git a/views/layouts/main.tt b/views/layouts/main.tt
new file mode 100644
index 0000000..514bac0
--- /dev/null
+++ b/views/layouts/main.tt
@@ -0,0 +1,17 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US" xml:lang="en-US">
+<head>
+<title>dancerREST</title>
+<link rel="stylesheet" type="text/css" href="/css/style.css" />
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+</head>
+<body>
+<h1>dancerREST</h1>
+<div id="content">
+<p><% content %></p>
+</div>
+<div id="footer">
+Powered by <a href="http://dancer.sukria.net">Dancer</a> 
+</div>
+</body>
+</html>
\ No newline at end of file
diff --git a/views/user.tt b/views/user.tt
new file mode 100644
index 0000000..a36ad2b
--- /dev/null
+++ b/views/user.tt
@@ -0,0 +1,5 @@
+<h2>It Works!</h2>
+
+<p>
+hello <% name %>
+</p>