diff --git a/CHANGELOG.md b/CHANGELOG.md
index 44e9edb0c03179f7b740df112e10f3f34591d8e9..16efdcb3890a6e2c24b1229b220c36f6c112dba0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
 
 ### Added
 - [DEV] Initial test scaffolding
+- Lua scripting support as a route handler in the `config.yml` file
 
 ## [0.2.0]
 
@@ -34,4 +35,4 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
 - Serve files from the target directory
 - Serve index files from directories
 - Configure number of worker threads
-- Bind to custom address and port
\ No newline at end of file
+- Bind to custom address and port
diff --git a/Cargo.lock b/Cargo.lock
index b084fa9e4b12cfd4b2fc6d40cf3350029df31ddd..d9067357c3e33a6fa83eee0b00826b494ee97ebd 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -14,18 +14,48 @@ dependencies = [
  "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "backtrace"
+version = "0.3.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "backtrace-sys 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-demangle 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "backtrace-sys"
+version = "0.1.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cc 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "base64"
 version = "0.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "base64"
+version = "0.9.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "bitflags"
-version = "1.0.1"
+version = "1.0.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -35,22 +65,35 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "byteorder"
-version = "1.2.2"
+version = "1.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "cc"
+version = "1.0.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "cfg-if"
-version = "0.1.2"
+version = "0.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "chrono"
-version = "0.4.2"
+version = "0.4.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "num-integer 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-integer 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "cloudabi"
+version = "0.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -60,7 +103,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "ring 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -79,9 +122,9 @@ version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -92,7 +135,7 @@ name = "crossbeam-utils"
 version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -100,10 +143,10 @@ name = "docopt"
 version = "0.8.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
  "strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -169,6 +212,25 @@ name = "encoding_index_tests"
 version = "0.1.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
+[[package]]
+name = "failure"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "backtrace 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "failure_derive"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "synstructure 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "formdata"
 version = "0.12.2"
@@ -180,7 +242,7 @@ dependencies = [
  "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "mime_multipart 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "textnonce 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "textnonce 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -188,7 +250,7 @@ name = "fuchsia-zircon"
 version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -218,7 +280,7 @@ dependencies = [
  "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -232,23 +294,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "interpolate_idents"
-version = "0.2.4"
+version = "0.2.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "isatty"
-version = "0.1.7"
+version = "0.1.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -256,15 +317,6 @@ name = "itoa"
 version = "0.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
-[[package]]
-name = "kernel32-sys"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
 [[package]]
 name = "language-tags"
 version = "0.2.2"
@@ -277,12 +329,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "lazy_static"
-version = "1.0.0"
+version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "libc"
-version = "0.2.40"
+version = "0.2.42"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -295,15 +347,15 @@ name = "log"
 version = "0.3.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "log"
-version = "0.4.1"
+version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -311,20 +363,12 @@ name = "matches"
 version = "0.1.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
-[[package]]
-name = "memchr"
-version = "1.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
 [[package]]
 name = "memchr"
 version = "2.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -352,7 +396,7 @@ dependencies = [
  "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "textnonce 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "textnonce 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -362,23 +406,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "num-integer"
-version = "0.1.36"
+version = "0.1.38"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "num-traits"
-version = "0.1.43"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "num-traits"
-version = "0.2.2"
+version = "0.2.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -386,7 +422,7 @@ name = "num_cpus"
 version = "1.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -396,12 +432,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "pear"
-version = "0.0.16"
+version = "0.0.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "pear_codegen"
-version = "0.0.16"
+version = "0.0.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "version_check 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -415,7 +451,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "proc-macro2"
-version = "0.3.6"
+version = "0.4.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -423,10 +459,15 @@ dependencies = [
 
 [[package]]
 name = "quote"
-version = "0.5.1"
+version = "0.3.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "quote"
+version = "0.6.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -435,7 +476,7 @@ version = "0.3.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -445,10 +486,27 @@ version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rand"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "rand_core"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
 [[package]]
 name = "rayon"
 version = "0.7.1"
@@ -463,32 +521,32 @@ version = "1.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "redox_syscall"
-version = "0.1.37"
+version = "0.1.40"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "regex"
-version = "0.2.10"
+version = "0.2.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex-syntax 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "regex-syntax"
-version = "0.5.5"
+version = "0.5.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -496,17 +554,12 @@ dependencies = [
 
 [[package]]
 name = "remove_dir_all"
-version = "0.5.0"
+version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
-[[package]]
-name = "rhai"
-version = "0.7.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
 [[package]]
 name = "ring"
 version = "0.11.0"
@@ -514,29 +567,39 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
  "rayon 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "rlua"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "rocket"
-version = "0.3.8"
+version = "0.3.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "base64 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "cookie 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)",
- "isatty 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "isatty 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "ordermap 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
- "pear 0.0.16 (registry+https://github.com/rust-lang/crates.io-index)",
- "pear_codegen 0.0.16 (registry+https://github.com/rust-lang/crates.io-index)",
- "smallvec 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "state 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pear 0.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pear_codegen 0.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "state 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "version_check 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -545,26 +608,31 @@ dependencies = [
 
 [[package]]
 name = "rocket_codegen"
-version = "0.3.8"
+version = "0.3.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "rocket 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rocket 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "version_check 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "yansi 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "rocket_contrib"
-version = "0.3.8"
+version = "0.3.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "rocket 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rocket 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "rustc-demangle"
+version = "0.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
 [[package]]
 name = "safemem"
 version = "0.2.0"
@@ -577,59 +645,48 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "serde"
-version = "1.0.38"
+version = "1.0.66"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "serde_derive"
-version = "1.0.38"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive_internals 0.23.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "serde_derive_internals"
-version = "0.23.1"
+version = "1.0.66"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.14.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "serde_json"
-version = "1.0.14"
+version = "1.0.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "serde_yaml"
-version = "0.7.3"
+version = "0.7.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
+ "dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
  "yaml-rust 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "smallvec"
-version = "0.4.4"
+version = "0.6.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "state"
-version = "0.4.0"
+version = "0.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -644,47 +701,74 @@ dependencies = [
  "docopt 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "formdata 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)",
- "interpolate_idents 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "interpolate_idents 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)",
- "rhai 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "rocket 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "rocket_codegen 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "rocket_contrib 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_yaml 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rlua 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rocket 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rocket_codegen 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rocket_contrib 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_yaml 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "syn"
+version = "0.11.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "syn"
-version = "0.13.1"
+version = "0.14.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "synom"
+version = "0.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "synstructure"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "tempdir"
 version = "0.3.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "remove_dir_all 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "textnonce"
-version = "0.6.3"
+version = "0.6.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "chrono 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)",
+ "base64 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "chrono 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -692,18 +776,18 @@ name = "thread_local"
 version = "0.3.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "time"
-version = "0.1.39"
+version = "0.1.40"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -711,7 +795,7 @@ name = "toml"
 version = "0.4.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "serde 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -747,7 +831,12 @@ dependencies = [
 
 [[package]]
 name = "unicode-normalization"
-version = "0.1.5"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "unicode-xid"
+version = "0.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -795,23 +884,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "winapi"
-version = "0.2.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "winapi"
-version = "0.3.4"
+version = "0.3.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
-[[package]]
-name = "winapi-build"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
 [[package]]
 name = "winapi-i686-pc-windows-gnu"
 version = "0.4.0"
@@ -838,12 +917,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 [metadata]
 "checksum aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6531d44de723825aa81398a6415283229725a00fa30713812ab9323faa82fc4"
 "checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef"
+"checksum backtrace 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dbdd17cd962b570302f5297aea8648d5923e22e555c2ed2d8b2e34eca646bf6d"
+"checksum backtrace-sys 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)" = "bff67d0c06556c0b8e6b5f090f0eac52d950d9dfd1d35ba04e4ca3543eaf6a7e"
 "checksum base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96434f987501f0ed4eb336a411e0631ecd1afa11574fe148587adc4ff96143c9"
-"checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf"
+"checksum base64 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "85415d2594767338a74a30c1d370b2f3262ec1b4ed2d7bba5b3faf4de40467d9"
+"checksum bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d0c54bb8f454c567f21197eefcdbf5679d0bd99f2ddbe52e84c77061952e6789"
 "checksum buf-read-ext 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9d8de1deea45aacd40d6c4ef975d0ae5550bd7f38594a6f6f734bb75b2ff5c18"
-"checksum byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "73b5bdfe7ee3ad0b99c9801d58807a9dbc9e09196365b0203853b99889ab3c87"
-"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de"
-"checksum chrono 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1cce36c92cb605414e9b824f866f5babe0a0368e39ea07393b9b63cf3844c0e6"
+"checksum byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "74c0b906e9446b0a2e4f760cdb3fa4b2c48cdc6db8766a845c54b6ff063fd2e9"
+"checksum cc 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)" = "49ec142f5768efb5b7622aebc3fdbdbb8950a4b9ba996393cb76ef7466e8747d"
+"checksum cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "405216fd8fe65f718daa7102ea808a946b6ce40c742998fbfd3463645552de18"
+"checksum chrono 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a81892f0d5a53f46fc05ef0b917305a81c13f1f13bb59ac91ff595817f0764b1"
+"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
 "checksum cookie 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "477eb650753e319be2ae77ec368a58c638f9f0c4d941c39bad95e950fb1d1d0d"
 "checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3"
 "checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150"
@@ -857,6 +941,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum encoding-index-singlebyte 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3351d5acffb224af9ca265f435b859c7c01537c0849754d3db3fdf2bfe2ae84a"
 "checksum encoding-index-tradchinese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fd0e20d5688ce3cab59eb3ef3a2083a5c77bf496cb798dc6fcdb75f323890c18"
 "checksum encoding_index_tests 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a246d82be1c9d791c5dfde9a2bd045fc3cbba3fa2b11ad558f27d01712f00569"
+"checksum failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "934799b6c1de475a012a02dab0ace1ace43789ee4b99bcfbf1a2e3e8ced5de82"
+"checksum failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c7cdda555bb90c9bb67a3b670a0f42de8e73f5981524123ad8578aafec8ddb8b"
 "checksum formdata 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f213d4500d262038e97eea11b11242ab2abb4cee30f31a4f3792ce6c5775ecc5"
 "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
 "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
@@ -864,69 +950,73 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum httparse 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2f407128745b78abc95c0ffbe4e5d37427fdc0d45470710cfef8c44522a2e37"
 "checksum hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)" = "368cb56b2740ebf4230520e2b90ebb0461e69034d85d1945febd9b3971426db2"
 "checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d"
-"checksum interpolate_idents 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c038526b1556151b78f71b3e4cb107cf58c4dfc426a64a398c61f76a42a4e08"
-"checksum isatty 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a118a53ba42790ef25c82bb481ecf36e2da892646cccd361e69a6bb881e19398"
+"checksum interpolate_idents 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "99576f81a4b32496245b4fed677ab2cc1efcf0ecbb4eae429861c3c4e00cbf4d"
+"checksum isatty 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6c324313540cd4d7ba008d43dc6606a32a5579f13cc17b2804c13096f0a5c522"
 "checksum itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c069bbec61e1ca5a596166e55dfe4773ff745c3d16b700013bcaff9a6df2c682"
-"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
 "checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a"
 "checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73"
-"checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d"
-"checksum libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)" = "6fd41f331ac7c5b8ac259b8bf82c75c0fb2e469bbf37d2becbba9a6a2221965b"
+"checksum lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e6412c5e2ad9584b0b8e979393122026cdd6d2a80b933f890dcd694ddbe73739"
+"checksum libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)" = "b685088df2b950fccadf07a7187c8ef846a959c142338a48f9dc0b94517eb5f1"
 "checksum linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "70fb39025bc7cdd76305867c4eccf2f2dcf6e9a57f5b21a93e1c2d86cd03ec9e"
 "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
-"checksum log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "89f010e843f2b1a31dbd316b3b8d443758bc634bed37aabade59c686d644e0a2"
+"checksum log 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6fddaa003a65722a7fb9e26b0ce95921fe4ba590542ced664d8ce2fa26f9f3ac"
 "checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376"
-"checksum memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "148fab2e51b4f1cfc66da2a7c32981d1d3c083a803978268bb11fe4b86925e7a"
 "checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d"
 "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3"
 "checksum mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0"
 "checksum mime_multipart 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f2df0bd91963eaf92191e5317f18c839dc3fbec1f1dde0e0c794238e1d6784e2"
 "checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2"
-"checksum num-integer 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f8d26da319fb45674985c78f1d1caf99aa4941f785d384a2ae36d0740bc3e2fe"
-"checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31"
-"checksum num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dee092fcdf725aee04dd7da1d21debff559237d49ef1cb3e69bcb8ece44c7364"
+"checksum num-integer 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)" = "6ac0ea58d64a89d9d6b7688031b3be9358d6c919badcf7fbb0527ccfd891ee45"
+"checksum num-traits 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "775393e285254d2f5004596d69bb8bc1149754570dcc08cf30cabeba67955e28"
 "checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30"
 "checksum ordermap 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "b81cf3b8cb96aa0e73bbedfcdc9708d09fec2854ba8d474be4e6f666d7379e8b"
-"checksum pear 0.0.16 (registry+https://github.com/rust-lang/crates.io-index)" = "b9b645aa07cf1010a67e9f67b4b9b96d6c5fb9315eee678a061d6ab58e9cb77f"
-"checksum pear_codegen 0.0.16 (registry+https://github.com/rust-lang/crates.io-index)" = "ca34109829349aeefe22772916da5404b3f5cd0e63a72c5d91209fc809342265"
+"checksum pear 0.0.17 (registry+https://github.com/rust-lang/crates.io-index)" = "2d0b966f9b387335fedc3546471db37b6e02430c180878015df1eaa3e62da289"
+"checksum pear_codegen 0.0.17 (registry+https://github.com/rust-lang/crates.io-index)" = "3a97c944f71801ef6b36bbf47a98b24167795d74bb8678f013d60d312bfc795c"
 "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
-"checksum proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "49b6a521dc81b643e9a51e0d1cf05df46d5a2f3c0280ea72bcb68276ba64a118"
-"checksum quote 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7b0ff51282f28dc1b53fd154298feaa2e77c5ea0dba68e1fd8b03b72fbe13d2a"
+"checksum proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "effdb53b25cdad54f8f48843d67398f7ef2e14f12c1b4cb4effc549a6462a4d6"
+"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
+"checksum quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e44651a0dc4cdd99f71c83b561e221f714912d11af1a4dff0631f923d53af035"
 "checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1"
 "checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5"
+"checksum rand 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "482c45f965103f2433002a0c4d908599f38d1b8c1375e66e801a24c1c6cadc03"
+"checksum rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "edecf0f94da5551fc9b492093e30b041a891657db7940ee221f9d2f66e82eef2"
 "checksum rayon 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a77c51c07654ddd93f6cb543c7a849863b03abc7e82591afda6dc8ad4ac3ac4a"
 "checksum rayon-core 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d24ad214285a7729b174ed6d3bcfcb80177807f959d95fafd5bfc5c4f201ac8"
-"checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd"
-"checksum regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "aec3f58d903a7d2a9dc2bf0e41a746f4530e0cab6b615494e058f67a3ef947fb"
-"checksum regex-syntax 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "bd90079345f4a4c3409214734ae220fd773c6f2e8a543d07370c6c1c369cfbfb"
-"checksum remove_dir_all 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dfc5b3ce5d5ea144bb04ebd093a9e14e9765bcfec866aecda9b6dec43b3d1e24"
-"checksum rhai 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7d8dd1945cb3f6c777074814bb2856a8fce36af4d6aa6f479c6a3029869e865b"
+"checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1"
+"checksum regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9329abc99e39129fcceabd24cf5d85b4671ef7c29c50e972bc5afe32438ec384"
+"checksum regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d707a4fa2637f2dca2ef9fd02225ec7661fe01a53623c1e6515b6916511f7a7"
+"checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5"
 "checksum ring 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1f2a6dc7fc06a05e6de183c5b97058582e9da2de0c136eafe49609769c507724"
-"checksum rocket 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c000cf7233aa997a19a43f77ddc80db11b58cdbbc12e2c1385bd62cbbace3964"
-"checksum rocket_codegen 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "645dd494d1340a4c16ba8decc4bb94d3e687a7e6b57552e2341dbf436b75ffaa"
-"checksum rocket_contrib 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "2b1f97dc98bf6fa9a861e3c0c71f150f1110350eaaebe56516377d7f4316a51a"
+"checksum rlua 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9f4876476bf0ac0bb596c60153c5ba11ddfc5738df991baa9ec35b303dffb1ff"
+"checksum rocket 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)" = "8c78f181913214426ebfa478806360c4c00200c08b8bd9b176f4d5d868c29752"
+"checksum rocket_codegen 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)" = "a19a861e7aab19c0319cc1ebfb65ef0e59e3e9386f34df66d93b24ec3ab70299"
+"checksum rocket_contrib 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)" = "d14af6aa8061360879f346084609654133c6c62e50a35f4844c4605c61f9987d"
+"checksum rustc-demangle 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "76d7ba1feafada44f2d38eed812bd2489a03c0f5abb975799251518b68848649"
 "checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f"
 "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
-"checksum serde 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)" = "4c36359ac1a823e00db02a243376ced650f088dc1f6259bbf828e4668e3c7399"
-"checksum serde_derive 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)" = "f0477feff739386f5bca8e13fa43d96a4e834904d538f503906c8179f9205f50"
-"checksum serde_derive_internals 0.23.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9d30c4596450fd7bbda79ef15559683f9a79ac0193ea819db90000d7e1cae794"
-"checksum serde_json 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "8f6f1f77b969caa064f347544d703efacaf4854b84831096a5dc206a8aedbc27"
-"checksum serde_yaml 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e0f868d400d9d13d00988da49f7f02aeac6ef00f11901a8c535bd59d777b9e19"
-"checksum smallvec 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ee4f357e8cd37bf8822e1b964e96fd39e2cb5a0424f8aaa284ccaccc2162411c"
-"checksum state 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d5562ac59585fe3d9a1ccf6b4e298ce773f5063db80d59f783776b410c1714c2"
+"checksum serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)" = "e9a2d9a9ac5120e0f768801ca2b58ad6eec929dc9d1d616c162f208869c2ce95"
+"checksum serde_derive 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)" = "0a90213fa7e0f5eac3f7afe2d5ff6b088af515052cc7303bd68c7e3b91a3fb79"
+"checksum serde_json 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)" = "eb40600c756f02d7ea34943626cefa85732fdae5f95b90b31f9797b3c526d1e6"
+"checksum serde_yaml 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ef8099d3df28273c99a1728190c7a9f19d444c941044f64adf986bee7ec53051"
+"checksum smallvec 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "312a7df010092e73d6bbaf141957e868d4f30efd2bfd9bb1028ad91abec58514"
+"checksum state 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7345c971d1ef21ffdbd103a75990a15eb03604fc8b8852ca8cb418ee1a099028"
 "checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694"
-"checksum syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "91b52877572087400e83d24b9178488541e3d535259e04ff17a63df1e5ceff59"
+"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
+"checksum syn 0.14.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c67da57e61ebc7b7b6fff56bb34440ca3a83db037320b0507af4c10368deda7d"
+"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
+"checksum synstructure 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a761d12e6d8dcb4dcf952a7a89b475e3a9d69e4a69307e01a470977642914bd"
 "checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8"
-"checksum textnonce 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1ec1db33aecab90b283d04e845d1fc46a12ea53d98e5ccccdbc520379e2a535f"
+"checksum textnonce 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "df4033262e39249fc34cad20ce07fa03b8181e33e65d854ee1afb229b28974c6"
 "checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963"
-"checksum time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "a15375f1df02096fb3317256ce2cee6a1f42fc84ea5ad5fc8c421cfe40c73098"
+"checksum time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b"
 "checksum toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a0263c6c02c4db6c8f7681f9fd35e90de799ebd4cfdeab77a38f4ff6b3d8c0d9"
 "checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079"
 "checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887"
 "checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d"
 "checksum unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33"
 "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
-"checksum unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "51ccda9ef9efa3f7ef5d91e8f9b83bbe6955f9bf86aec89d5cce2c874625920f"
+"checksum unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6a0180bc61fc5a987082bfa111f4cc95c4caff7f9799f3e46df09163a937aa25"
+"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc"
 "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
 "checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
 "checksum untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f392d7819dbe58833e26872f5f6f0d68b7bbbe90fc3667e98731c4a15ad9a7ae"
@@ -934,9 +1024,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122"
 "checksum version_check 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6b772017e347561807c1aa192438c5fd74242a670a6cffacc40f2defd1dc069d"
 "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
-"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
-"checksum winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3"
-"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
+"checksum winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "773ef9dcc5f24b7d850d0ff101e542ff24c3b090a9768e03ff889fdef41f00fd"
 "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
 "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
 "checksum yaml-rust 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "57ab38ee1a4a266ed033496cf9af1828d8d6e6c1cfa5f643a2809effcae4d628"
diff --git a/Cargo.toml b/Cargo.toml
index f92735d5f80859c70b91584235cf589435caeec0..b59f6f9511aaa1cbcd3b27592d31a349a3f673a8 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -35,8 +35,8 @@ docopt = "0.8"
 formdata = "0.12.2"
 hyper = "0.10"
 rand = "0.3"
-rhai = "0.7"
 serde_yaml = "0.7.3"
+rlua = "0.13.0"
 
 [dev-dependencies]
 interpolate_idents = "0.2.4"
diff --git a/example/.swerve/accounts/handle_widgets.lua b/example/.swerve/accounts/handle_widgets.lua
new file mode 100644
index 0000000000000000000000000000000000000000..776787f46367ee4e4f74304aac62b5731cc7e367
--- /dev/null
+++ b/example/.swerve/accounts/handle_widgets.lua
@@ -0,0 +1,39 @@
+local accountDB = {}
+accountDB['fancy-account'] = {
+    name = "Fancy Account",
+    widgets = { barfoo = "The best widget in town", bipbop = "A really good widget"}
+}
+
+accountDB['less-fancy-account'] = {
+    name = "Not Quite As Fancy Account",
+    widgets = { cooliowidget = "A really good widget that should be respected" }
+}
+
+accountDB['unrelated-account'] = {
+    name = "John Mysterio's Vault of Wonders",
+    widgets = { yes = "You buy widget, yes?", widget = "Widget is good!", flubber = "Green, Ready to Rock" }
+}
+
+account = accountDB[params.account_id]
+
+res = empty_response()
+res:set_header('Content-Type', 'application/json')
+
+print("[WIDGETS] Looking for:", params.account_id, params.widget_id)
+
+if not (account == nil) then
+    print("[WIDGETS] Found", account.name)
+    local widget = account.widgets[params.widget_id]
+    if not (widget == nil) then
+        res:set_status(200)
+        res:set_body(json_encode({ widget = widget }))
+    else
+        res:set_status(404)
+        res:set_body(json_encode({ message = "Could not find widget" }))
+    end
+else
+    res:set_status(404)
+    res:set_body(json_encode({ message = "Could not find account" }))
+end
+
+return res
diff --git a/example/.swerve/config.yml b/example/.swerve/config.yml
index f4bac0706d1e221dcc958508005c809c446048fd..4b11c67a8af11977f72a1c126b66262458a6d821 100644
--- a/example/.swerve/config.yml
+++ b/example/.swerve/config.yml
@@ -2,16 +2,19 @@ field_handling: Log
 file_handling: File
 server:
   port: 9000
-requests:
-  - /users/@user_id : scripts/get_user_by_id.dyon
-  - /users :
+routes:
+  - route: /users/@user_id
+    script: get_user.lua
+  - route: /accounts/@account_id/widgets/@widget_id
+    script: accounts/handle_widgets.lua
+  - route: /users
+    response:
       failure_rate: 5
-      response_headers:
+      headers:
         x-rate-limit: 100
         x-rate-remaining: 96
         x-rate-reset: 10/12/1990
-      response_type: application/json
-      response_body:
+      body:
         count: 2
         data:
           - id: 1
diff --git a/example/.swerve/get_user.lua b/example/.swerve/get_user.lua
new file mode 100644
index 0000000000000000000000000000000000000000..207b0db499edaac725b73d48947684c5b4d38b01
--- /dev/null
+++ b/example/.swerve/get_user.lua
@@ -0,0 +1,22 @@
+print("We're going to the races");
+
+foo = 1 + 1;
+
+r = empty_response();
+r:set_status(200);
+r:set_header("X-Powered-By", "Swerve");
+r:set_header("Content-Type", "text/plain");
+r:set_body("This is my only response");
+
+--return r
+
+print(params.user_id)
+
+r = response(200, "application/json", json_encode({ user_id = params.user_id, path = params.script_path }));
+--
+--r:unset_body();
+--r:set_status(204);
+
+return r
+
+-- return response(200, "application/json", '{ "foo": ' .. foo .. ' }')
diff --git a/example/.swerve/get_user_by_id.rhai b/example/.swerve/get_user_by_id.rhai
deleted file mode 100644
index 0c87298599322e0e807f56e772ff5767444df708..0000000000000000000000000000000000000000
--- a/example/.swerve/get_user_by_id.rhai
+++ /dev/null
@@ -1,4 +0,0 @@
-fn handle(foo: f64) -> {
-	println(foo)
-	{ foo: foo, bar: 123 }
-}
\ No newline at end of file
diff --git a/example/index.html b/example/index.html
index 080c0fc49cfb6a8e4ab7847645034944714928e4..17d3d1e83a8c1ef03047ad1550c73cb1985f44ee 100644
--- a/example/index.html
+++ b/example/index.html
@@ -8,6 +8,7 @@
 	<body>
 		<h1>It's Swervin' Time</h1>
 		<p>This page is part of the swerve example, and includes a stylesheet and stuff.</p>
+		<img src="/files/adorable-puppy.jpg">
 		<script async src="js/say_hello.js"></script>
 	</body>
 </html>
\ No newline at end of file
diff --git a/src/cli/config_file.rs b/src/cli/config_file.rs
index 7723ae5209ec491e3939a6f9b0c46116881003be..8b652b8f071cc865a7dd5c0c5f40077f1ac2a587 100644
--- a/src/cli/config_file.rs
+++ b/src/cli/config_file.rs
@@ -7,6 +7,7 @@ use std::default::Default;
 use serde::{Deserialize, Deserializer, de};
 use std::fmt;
 use serde_yaml as yaml;
+use cli;
 
 #[derive(Debug, Copy, Clone)]
 pub enum HandlerMethod {
@@ -52,6 +53,8 @@ pub struct SwerveConfig {
     pub file_handling: HandlerMethod,
     #[serde(default)]
     pub server: ServerOptions,
+    #[serde(default="get_empty_routes")]
+    pub routes: Vec<cli::RouteHandler>,
 }
 
 #[derive(Deserialize, Debug, Clone)]
@@ -74,12 +77,15 @@ fn get_default_address() -> String { String::from("localhost") }
 fn get_default_quiet_attr() -> bool { false }
 fn get_default_index_attr() -> bool { false }
 
+fn get_empty_routes() -> Vec<cli::RouteHandler> { vec![] }
+
 impl Default for SwerveConfig {
     fn default() -> Self {
         SwerveConfig {
             field_handling: HandlerMethod::Log,
             file_handling: HandlerMethod::Log,
             server: ServerOptions::default(),
+            routes: get_empty_routes(),
         }
     }
 }
diff --git a/src/cli/config_routes.rs b/src/cli/config_routes.rs
new file mode 100644
index 0000000000000000000000000000000000000000..b9396f737b49c21d75aacc8d215d51afab119f4a
--- /dev/null
+++ b/src/cli/config_routes.rs
@@ -0,0 +1,17 @@
+use std::collections::HashMap;
+
+#[derive(Clone, Debug, Deserialize)]
+pub struct RouteHandler {
+    pub route: String,
+    pub response: Option<ResponseHandler>,
+    pub script: Option<String>,
+}
+
+#[derive(Clone, Debug, Deserialize)]
+pub struct ResponseHandler {
+    failure_rate: Option<u32>,
+    #[serde(default="get_default_headers")]
+    headers: HashMap<String, String>,
+}
+
+fn get_default_headers() -> HashMap<String, String> { HashMap::new() }
diff --git a/src/cli/mod.rs b/src/cli/mod.rs
index 4993a2f81a9f290dccf6376a9afbe69b8fad9a1e..2ac3861912c08e89923a472e1838e2dfc83be11f 100644
--- a/src/cli/mod.rs
+++ b/src/cli/mod.rs
@@ -1,7 +1,9 @@
 mod cli;
 mod config_file;
+mod config_routes;
 
 pub mod gpl;
 
 pub use self::cli::{Args, USAGE};
-pub use self::config_file::{HandlerMethod, SwerveConfig};
\ No newline at end of file
+pub use self::config_file::{HandlerMethod, SwerveConfig};
+pub use self::config_routes::RouteHandler;
\ No newline at end of file
diff --git a/src/lib.rs b/src/lib.rs
index d384507b3f4e2159bf5c86a41948d4061d515628..ecabbd9bdfdbda8456485e11b5b668d7c182e50a 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -4,12 +4,12 @@
 extern crate serde;
 #[macro_use] extern crate serde_derive;
 extern crate serde_yaml;
-extern crate rhai;
 extern crate rocket;
 extern crate rocket_contrib;
 extern crate formdata;
 extern crate hyper;
 extern crate rand;
+extern crate rlua;
 
 pub mod cli;
 pub mod routing;
diff --git a/src/main.rs b/src/main.rs
index 832dc7725849cf292ae07853e1bc77283a2d9158..1a211465e60ab241ebbab2df0024337961a62798 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -6,7 +6,6 @@ extern crate alloc_system;
 extern crate rocket;
 extern crate docopt;
 extern crate swerve;
-extern crate rhai;
 
 use std::process;
 use docopt::Docopt;
diff --git a/src/routing/mock_upload.rs b/src/routing/mock_upload.rs
index 9ef566c74884c6d37874b919aaa622e3e74457ac..3f7bcb348b2280d245622f492c7b121447e5a6ec 100644
--- a/src/routing/mock_upload.rs
+++ b/src/routing/mock_upload.rs
@@ -1,15 +1,12 @@
 use rocket::{Data, State};
 use formdata::{read_formdata, FilePart};
 use routing::request::ConvertedHeaders;
-use hyper::header::{Headers, ContentDisposition, DispositionParam};
-use rocket::request::FromRequest;
-use std::io::{Read, Write, copy};
-use std::io::{BufReader, BufWriter};
+use hyper::header::{ContentDisposition, DispositionParam};
+use std::io::{copy};
 use std::fs::{OpenOptions, File, create_dir};
 use cli::{HandlerMethod, SwerveConfig};
-use std::path::{Path, PathBuf};
+use std::path::{PathBuf};
 use std::collections::HashMap;
-use rand::{Rng, StdRng};
 
 #[post(path = "/", data = "<upload>")]
 pub fn to_file(headers: ConvertedHeaders, conf: State<SwerveConfig>, upload: Data) -> Result<String, String> {
@@ -21,7 +18,12 @@ pub fn to_file(headers: ConvertedHeaders, conf: State<SwerveConfig>, upload: Dat
             HandlerMethod::File => println!("{:?}", fields),
         }
 
-        create_dir("uploads");
+        match create_dir("uploads") {
+			Ok(_) => {},
+			Err(err) => {
+				return Err(format!("Could not create uploads directory:\n{}", err));
+			}
+		}
 
         for file in data.files {
             match conf.file_handling {
@@ -49,17 +51,17 @@ type Upload = (String, FilePart);
 fn upload_file(file: Upload) {
     let (name, value) = file;
     let content_disposition = value.headers.get::<ContentDisposition>().unwrap();
-    let file_name = filename_from_disposition(content_disposition);
+    let file_name = filename_from_disposition(content_disposition).unwrap_or(name);
 
     let mut input = File::open(value.path.clone()).unwrap();
     let mut output = OpenOptions::new()
         .write(true)
         .create(true)
-        .open(PathBuf::from("uploads").join(file_name.clone().unwrap_or(String::from("upload_data"))))
+        .open(PathBuf::from("uploads").join(file_name.clone()))
         .unwrap();
 
     copy(&mut input, &mut output).unwrap();
-    println!("File written to {}", file_name.unwrap());
+    println!("File written to {}", file_name);
 }
 
 fn log_file(file: Upload) {
diff --git a/src/routing/mod.rs b/src/routing/mod.rs
index d3fa15ff5030dccc4162756be7c3e0f264472775..8638aa198c483512c2c82bdb8436c8cd8af9c973 100644
--- a/src/routing/mod.rs
+++ b/src/routing/mod.rs
@@ -2,3 +2,7 @@ pub mod mock_upload;
 pub mod request;
 pub mod scripting;
 pub mod core;
+
+mod request_rewriter;
+
+pub use self::request_rewriter::{ScriptMap, RedirectScripts};
diff --git a/src/routing/request.rs b/src/routing/request.rs
index 643abe5ddd56afc24fc01c5970e9bc72b5ea768c..7e210685a4b3e8f89a0a9e8dee04a2a2f5d32369 100644
--- a/src/routing/request.rs
+++ b/src/routing/request.rs
@@ -57,3 +57,75 @@ impl rocket::response::Responder<'static> for TypedFile {
         Ok(response)
     }
 }
+
+pub struct RequestPath(pub String);
+impl <'a, 'req>FromRequest<'a, 'req> for RequestPath {
+    type Error = ();
+
+    fn from_request(request: &'a Request<'req>) -> Outcome<Self, (http::Status, ()), ()> {
+        let uri = request.uri();
+        Outcome::Success(RequestPath(String::from(uri.path())))
+    }
+}
+
+pub mod path {
+    use std::path as std_path;
+    use std::option::Option::*;
+
+	#[derive(PartialEq, Eq, Hash)]
+    pub struct MatchablePath(pub String);
+    pub type PathMatch = (String, String);
+    pub type MatchList = Vec<PathMatch>;
+    pub type MatchResult = Option<MatchList>;
+
+    impl MatchablePath {
+        pub fn from<T>(src: T) -> Self where T: ToString {
+            MatchablePath(src.to_string())
+        }
+
+        fn path_to_vec<T: ToString>(string: T) -> Vec<String> {
+            std_path::PathBuf::from(string.to_string())
+                .components()
+                .filter_map(|c| match c {
+                    std_path::Component::Normal(cmp) => cmp.to_str()
+                        .and_then(|s| Some(String::from(s))),
+                    _ => None,
+                })
+                .collect()
+        }
+
+        pub fn matches<T>(&self, other: T) -> MatchResult where T: ToString {
+            let this_path = MatchablePath::path_to_vec(&self.0);
+            let other_path = MatchablePath::path_to_vec(other);
+
+            if this_path.len() == other_path.len() {
+                let parts_match = this_path.iter()
+                    .zip(other_path.iter())
+                    .fold(true, |acc, (this, other)| {
+                        acc && (this.starts_with("@") || this == other)
+                    });
+
+                if parts_match {
+                    Some(this_path.iter()
+                        .zip(other_path.iter())
+                        .filter_map(|(this, other)| {
+                            if this.starts_with("@") {
+                                Some((
+                                    this.chars().skip(1).collect::<String>(),
+                                    other.clone()
+                                ))
+                            } else {
+                                None
+                            }
+                        })
+                        .collect()
+                    )
+                } else {
+                    None
+                }
+            } else {
+                None
+            }
+        }
+    }
+}
diff --git a/src/routing/request_rewriter.rs b/src/routing/request_rewriter.rs
new file mode 100644
index 0000000000000000000000000000000000000000..d39e6381d8afe2ccabfb70b02756d0eefd75d806
--- /dev/null
+++ b/src/routing/request_rewriter.rs
@@ -0,0 +1,56 @@
+use rocket::fairing::{Fairing, Info, Kind};
+use rocket::{Request, Data, State};
+use cli::SwerveConfig;
+use std::collections::HashMap;
+use routing::request::path::MatchablePath;
+
+pub struct ScriptMap(pub HashMap<MatchablePath, String>);
+impl ScriptMap {
+	pub fn from_config(conf: &SwerveConfig) -> Self {
+		let mut map: HashMap<MatchablePath, String> = HashMap::new();
+
+		for handler in &conf.routes {
+			if let Some(ref script) = handler.script {
+				map.insert(MatchablePath::from(handler.route.clone()), script.clone());
+			}
+		}
+
+		ScriptMap(map)
+	}
+}
+
+pub struct RedirectScripts;
+impl Fairing for RedirectScripts {
+	fn info(&self) -> Info {
+		Info {
+			name: "Redirect Scripts To Handler",
+			kind: Kind::Request,
+		}
+	}
+
+	fn on_request(&self, request: &mut Request, _: &Data) {
+		let script_map_container = request.guard::<State<ScriptMap>>().unwrap();
+		let script_map: &HashMap<MatchablePath, String> = &script_map_container.0;
+		for path in script_map.keys() {
+			let matches = path.matches(request.uri().path());
+			if let Some(values) = matches {
+				let script_name = script_map.get(path).unwrap();
+
+				let mut value_buffer = String::new();
+				value_buffer.push_str("script_path=");
+				value_buffer.push_str(script_name);
+
+				for (ref param, ref val) in values {
+					value_buffer.push_str("&");
+					value_buffer.push_str(param);
+					value_buffer.push_str("=");
+					value_buffer.push_str(val);
+				}
+
+				let path = format!("/__run_script__/?{}", value_buffer);
+				request.set_uri(path);
+				break;
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/src/routing/scripting.rs b/src/routing/scripting.rs
index 165c0070b28c4941538a6bad02dbadfcf75f02cf..8db3b91926ef6d35878ee25afda2b4f87b286f91 100644
--- a/src/routing/scripting.rs
+++ b/src/routing/scripting.rs
@@ -1,8 +1,40 @@
-use scripting::run_script;
-use std::path::PathBuf;
-
-#[get("/__testing__/run-script")]
-pub fn route_script() -> String {
-	let path = PathBuf::from("example/.swerve/get_user_by_id.rhai");
-	run_script(path).unwrap_or(String::from("No script"))
-}
\ No newline at end of file
+use server::LuaRuntime;
+use rlua::{Lua};
+use scripting::{run_script, ScriptResponse};
+
+use rocket::request::{FromForm, FormItems};
+use std::collections::HashMap;
+
+#[derive(Debug)]
+pub struct ScriptParams {
+	pub script_name: String,
+	pub script_params: HashMap<String, String>,
+}
+
+impl <'form> FromForm<'form> for ScriptParams {
+	type Error = ();
+
+	fn from_form(items: &mut FormItems<'form>, _: bool) -> Result<ScriptParams, Self::Error> {
+		let mut script_name: Option<String> = None;
+		let mut script_params: HashMap<String, String> = HashMap::new();
+
+		for (key, value) in items {
+			match key.as_str() {
+				"script_path" if script_name.is_none() => { script_name = Some(String::from(value.as_str())); },
+				_ => { script_params.insert(String::from(key.as_str()), String::from(value.as_str())); },
+			};
+		}
+
+		match script_name {
+			Some(name) => Ok(ScriptParams { script_name: name, script_params }),
+			None => Err(()),
+		}
+	}
+}
+
+
+#[get("/__run_script__?<params>")]
+pub fn route_script(params: ScriptParams, runtime: LuaRuntime) -> ScriptResponse {
+	let lua: Lua = runtime.into();
+	run_script(format!("example/.swerve/{}", params.script_name), &lua, params.script_params).unwrap_or_else(|| ScriptResponse::default())
+}
diff --git a/src/scripting/mod.rs b/src/scripting/mod.rs
index e7d98761b4f3f37a01d3f416fd8b941ec218de42..2d1e71875a98d3c26b96a8a80143ed8544d7f9e6 100644
--- a/src/scripting/mod.rs
+++ b/src/scripting/mod.rs
@@ -1,3 +1,7 @@
+pub mod script_request;
+
 mod run_script;
+mod script_response;
 
-pub use self::run_script::run_script;
\ No newline at end of file
+pub use self::run_script::run_script;
+pub use self::script_response::ScriptResponse;
\ No newline at end of file
diff --git a/src/scripting/run_script.rs b/src/scripting/run_script.rs
index 96d9f57184f7b733964a8d9ffdf6ae96984469cd..53778edd796e3f65d143f1c2c17641d09658d4b9 100644
--- a/src/scripting/run_script.rs
+++ b/src/scripting/run_script.rs
@@ -1,46 +1,42 @@
-//use dyon::{Runtime,Module,load_str,Variable,Dfn,Type};
-//use dyon::ast::convert;
 use std::convert::AsRef;
 use std::path::Path;
 use std::fs::File;
-use std::sync::Arc;
 use std::io::Read;
+use rlua::Lua;
+use scripting::ScriptResponse;
 use std::collections::HashMap;
 
-const SCRIPT_FOOTER: &'static str = "
-fn main() {
-    println(\"Don't directly execute the module, nimrod\")
-}";
+pub fn run_script<P: AsRef<Path>>(path: P, lua: &Lua, params: HashMap<String, String>) -> Option<ScriptResponse> {
+    let mut file = File::open(&path).unwrap();
+    let mut buf = String::new();
 
+    match file.read_to_string(&mut buf) {
+		Ok(_) => {},
+		Err(_) => return None,
+	}
 
-pub fn run_script<P: AsRef<Path>>(path: P) -> Option<String> {
-//    let mut resolution: Option<Variable> = None;
-//    dyon_fn!(fn resolve(val: Variable) {
-//           resolution = Some(val); // if let Ok(val) = runtime.pop() { Some(val) } else { None };
-//    });
-//
-//    println!("{:?}", resolution);
+	let file_name = path.as_ref()
+		.file_name()
+		.and_then(|name| name.to_str());
 
-    let mut file = File::open(&path).unwrap();
-    let mut buf = String::new();
+	let params_table = serialize_table("params", params);
+
+	lua.eval::<ScriptResponse>(&format!("{}\n{}", params_table, buf), file_name)
+		.map_err(|e| println!("{}", e))
+		.ok()
+}
+
+fn serialize_table(name: &'static str, table: HashMap<String, String>) -> String {
+	let mut output = format!("local {} = {{", name);
+
+	let contents = table.iter()
+		.fold(
+			String::new(),
+			|acc, (key, value)| format!("{} {} = \"{}\",", acc, key, value)
+		);
+
+	output.push_str(&contents[0..contents.len() - 1]);
+	output.push_str(" }");
 
-    file.read_to_string(&mut buf);
-    buf.push_str(SCRIPT_FOOTER);
-//    let mut script_module = Module::new();
-//
-//    {
-//        load_str(path.as_ref().to_str().unwrap(), Arc::new(buf), &mut script_module);
-//    }
-    Some(buf)
-//    script_module.add(Arc::new("resolve".into()), resolve, Dfn {
-//        lts: vec![],
-//        tys: vec![Type::Object],
-//        ret: Type::Void,
-//    });
-//
-//    let mut hashmap: HashMap<Arc<String>, Variable> = HashMap::new();
-
-//    runtime.call_str("handle", &[Variable::f64(123f64)], &Arc::new(script_module));
-
-//    None
-}
\ No newline at end of file
+	output
+}
diff --git a/src/scripting/script_request.rs b/src/scripting/script_request.rs
new file mode 100644
index 0000000000000000000000000000000000000000..c001e69673def69cd68772b539aed2a347507995
--- /dev/null
+++ b/src/scripting/script_request.rs
@@ -0,0 +1,29 @@
+use rocket::request::{FromForm, FormItems};
+use std::collections::HashMap;
+
+#[derive(Debug)]
+pub struct ScriptParams {
+	pub script_name: String,
+	pub script_params: HashMap<String, String>,
+}
+
+impl <'form> FromForm<'form> for ScriptParams {
+	type Error = ();
+
+	fn from_form(items: &mut FormItems<'form>, _: bool) -> Result<ScriptParams, Self::Error> {
+		let mut script_name: Option<String> = None;
+		let mut script_params: HashMap<String, String> = HashMap::new();
+
+		for (key, value) in items {
+			match key.as_str() {
+				"script_path" if script_name.is_none() => { script_name = Some(String::from(value.as_str())); },
+				_ => { script_params.insert(String::from(key.as_str()), String::from(value.as_str())); },
+			};
+		}
+
+		match script_name {
+			Some(name) => Ok(ScriptParams { script_name: name, script_params }),
+			None => Err(()),
+		}
+	}
+}
\ No newline at end of file
diff --git a/src/scripting/script_response.rs b/src/scripting/script_response.rs
new file mode 100644
index 0000000000000000000000000000000000000000..7ae702bfb6815e1fcf52e744fec38b67e54cc361
--- /dev/null
+++ b/src/scripting/script_response.rs
@@ -0,0 +1,61 @@
+use rlua::{UserData, UserDataMethods};
+
+use rocket::Request;
+use rocket::http::Status;
+use rocket::response::{Response, Responder};
+
+use std::io::Cursor;
+use std::default::Default;
+use std::collections::HashMap;
+
+#[derive(Debug, Clone)]
+pub struct ScriptResponse {
+	pub status: u16,
+	pub headers: HashMap<String, String>,
+	pub body: Option<String>,
+}
+
+impl Default for ScriptResponse {
+	fn default() -> Self {
+		ScriptResponse {
+			status: 500,
+			headers: HashMap::new(),
+			body: Some("Failed to return response from script".into()),
+		}
+	}
+}
+
+impl UserData for ScriptResponse {
+	fn add_methods(methods: &mut UserDataMethods<Self>) {
+		methods.add_method_mut("set_status", |_, response: &mut ScriptResponse, status: u16| {
+			response.status = status;
+			Ok(())
+		});
+		methods.add_method_mut("set_header", |_, response: &mut ScriptResponse, (header, value): (String, String)| {
+			response.headers.insert(header, value);
+			Ok(())
+		});
+		methods.add_method_mut("set_body", |_, response: &mut ScriptResponse, body: String| {
+			response.body = Some(body);
+			Ok(())
+		});
+		methods.add_method_mut("unset_body", |_, response: &mut ScriptResponse, (): ()| {
+			response.body = None;
+			Ok(())
+		});
+	}
+}
+
+impl <'r>Responder<'r> for ScriptResponse {
+	fn respond_to(self, _: &Request) -> Result<Response<'r>, Status> {
+		let mut r = Response::build();
+		r.status(Status::raw(self.status));
+		for (name, value) in self.headers {
+			r.raw_header(name, value);
+		}
+		if let Some(body) = self.body {
+			r.sized_body(Cursor::new(body));
+		}
+		r.ok()
+	}
+}
diff --git a/src/scripts/json.lua b/src/scripts/json.lua
new file mode 100644
index 0000000000000000000000000000000000000000..617bd18e30c111af59025742d6d34e3bd058d404
--- /dev/null
+++ b/src/scripts/json.lua
@@ -0,0 +1,404 @@
+--
+-- json.lua
+--
+-- Copyright (c) 2018 rxi
+--
+-- Permission is hereby granted, free of charge, to any person obtaining a copy of
+-- this software and associated documentation files (the "Software"), to deal in
+-- the Software without restriction, including without limitation the rights to
+-- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+-- of the Software, and to permit persons to whom the Software is furnished to do
+-- so, subject to the following conditions:
+--
+-- The above copyright notice and this permission notice shall be included in all
+-- copies or substantial portions of the Software.
+--
+-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+-- SOFTWARE.
+--
+
+-- Source: https://github.com/rxi/json.lua
+
+-- Changes:
+-- This library has been modified so that, when loaded into Swerve, it will expose
+-- json_encode and json_decode globals, instead of being imported from a file as a
+-- single 'json' object
+
+local json = { _version = "0.1.1" }
+
+-------------------------------------------------------------------------------
+-- Encode
+-------------------------------------------------------------------------------
+
+local encode
+
+local escape_char_map = {
+  [ "\\" ] = "\\\\",
+  [ "\"" ] = "\\\"",
+  [ "\b" ] = "\\b",
+  [ "\f" ] = "\\f",
+  [ "\n" ] = "\\n",
+  [ "\r" ] = "\\r",
+  [ "\t" ] = "\\t",
+}
+
+local escape_char_map_inv = { [ "\\/" ] = "/" }
+for k, v in pairs(escape_char_map) do
+  escape_char_map_inv[v] = k
+end
+
+
+local function escape_char(c)
+  return escape_char_map[c] or string.format("\\u%04x", c:byte())
+end
+
+
+local function encode_nil(val)
+  return "null"
+end
+
+
+local function encode_table(val, stack)
+  local res = {}
+  stack = stack or {}
+
+  -- Circular reference?
+  if stack[val] then error("circular reference") end
+
+  stack[val] = true
+
+  if val[1] ~= nil or next(val) == nil then
+    -- Treat as array -- check keys are valid and it is not sparse
+    local n = 0
+    for k in pairs(val) do
+      if type(k) ~= "number" then
+        error("invalid table: mixed or invalid key types")
+      end
+      n = n + 1
+    end
+    if n ~= #val then
+      error("invalid table: sparse array")
+    end
+    -- Encode
+    for i, v in ipairs(val) do
+      table.insert(res, encode(v, stack))
+    end
+    stack[val] = nil
+    return "[" .. table.concat(res, ",") .. "]"
+
+  else
+    -- Treat as an object
+    for k, v in pairs(val) do
+      if type(k) ~= "string" then
+        error("invalid table: mixed or invalid key types")
+      end
+      table.insert(res, encode(k, stack) .. ":" .. encode(v, stack))
+    end
+    stack[val] = nil
+    return "{" .. table.concat(res, ",") .. "}"
+  end
+end
+
+
+local function encode_string(val)
+  return '"' .. val:gsub('[%z\1-\31\\"]', escape_char) .. '"'
+end
+
+
+local function encode_number(val)
+  -- Check for NaN, -inf and inf
+  if val ~= val or val <= -math.huge or val >= math.huge then
+    error("unexpected number value '" .. tostring(val) .. "'")
+  end
+  return string.format("%.14g", val)
+end
+
+
+local type_func_map = {
+  [ "nil"     ] = encode_nil,
+  [ "table"   ] = encode_table,
+  [ "string"  ] = encode_string,
+  [ "number"  ] = encode_number,
+  [ "boolean" ] = tostring,
+}
+
+
+encode = function(val, stack)
+  local t = type(val)
+  local f = type_func_map[t]
+  if f then
+    return f(val, stack)
+  end
+  error("unexpected type '" .. t .. "'")
+end
+
+
+function json_encode(val)
+  return ( encode(val) )
+end
+
+
+-------------------------------------------------------------------------------
+-- Decode
+-------------------------------------------------------------------------------
+
+local parse
+
+local function create_set(...)
+  local res = {}
+  for i = 1, select("#", ...) do
+    res[ select(i, ...) ] = true
+  end
+  return res
+end
+
+local space_chars   = create_set(" ", "\t", "\r", "\n")
+local delim_chars   = create_set(" ", "\t", "\r", "\n", "]", "}", ",")
+local escape_chars  = create_set("\\", "/", '"', "b", "f", "n", "r", "t", "u")
+local literals      = create_set("true", "false", "null")
+
+local literal_map = {
+  [ "true"  ] = true,
+  [ "false" ] = false,
+  [ "null"  ] = nil,
+}
+
+
+local function next_char(str, idx, set, negate)
+  for i = idx, #str do
+    if set[str:sub(i, i)] ~= negate then
+      return i
+    end
+  end
+  return #str + 1
+end
+
+
+local function decode_error(str, idx, msg)
+  local line_count = 1
+  local col_count = 1
+  for i = 1, idx - 1 do
+    col_count = col_count + 1
+    if str:sub(i, i) == "\n" then
+      line_count = line_count + 1
+      col_count = 1
+    end
+  end
+  error( string.format("%s at line %d col %d", msg, line_count, col_count) )
+end
+
+
+local function codepoint_to_utf8(n)
+  -- http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=iws-appendixa
+  local f = math.floor
+  if n <= 0x7f then
+    return string.char(n)
+  elseif n <= 0x7ff then
+    return string.char(f(n / 64) + 192, n % 64 + 128)
+  elseif n <= 0xffff then
+    return string.char(f(n / 4096) + 224, f(n % 4096 / 64) + 128, n % 64 + 128)
+  elseif n <= 0x10ffff then
+    return string.char(f(n / 262144) + 240, f(n % 262144 / 4096) + 128,
+                       f(n % 4096 / 64) + 128, n % 64 + 128)
+  end
+  error( string.format("invalid unicode codepoint '%x'", n) )
+end
+
+
+local function parse_unicode_escape(s)
+  local n1 = tonumber( s:sub(3, 6),  16 )
+  local n2 = tonumber( s:sub(9, 12), 16 )
+  -- Surrogate pair?
+  if n2 then
+    return codepoint_to_utf8((n1 - 0xd800) * 0x400 + (n2 - 0xdc00) + 0x10000)
+  else
+    return codepoint_to_utf8(n1)
+  end
+end
+
+
+local function parse_string(str, i)
+  local has_unicode_escape = false
+  local has_surrogate_escape = false
+  local has_escape = false
+  local last
+  for j = i + 1, #str do
+    local x = str:byte(j)
+
+    if x < 32 then
+      decode_error(str, j, "control character in string")
+    end
+
+    if last == 92 then -- "\\" (escape char)
+      if x == 117 then -- "u" (unicode escape sequence)
+        local hex = str:sub(j + 1, j + 5)
+        if not hex:find("%x%x%x%x") then
+          decode_error(str, j, "invalid unicode escape in string")
+        end
+        if hex:find("^[dD][89aAbB]") then
+          has_surrogate_escape = true
+        else
+          has_unicode_escape = true
+        end
+      else
+        local c = string.char(x)
+        if not escape_chars[c] then
+          decode_error(str, j, "invalid escape char '" .. c .. "' in string")
+        end
+        has_escape = true
+      end
+      last = nil
+
+    elseif x == 34 then -- '"' (end of string)
+      local s = str:sub(i + 1, j - 1)
+      if has_surrogate_escape then
+        s = s:gsub("\\u[dD][89aAbB]..\\u....", parse_unicode_escape)
+      end
+      if has_unicode_escape then
+        s = s:gsub("\\u....", parse_unicode_escape)
+      end
+      if has_escape then
+        s = s:gsub("\\.", escape_char_map_inv)
+      end
+      return s, j + 1
+
+    else
+      last = x
+    end
+  end
+  decode_error(str, i, "expected closing quote for string")
+end
+
+
+local function parse_number(str, i)
+  local x = next_char(str, i, delim_chars)
+  local s = str:sub(i, x - 1)
+  local n = tonumber(s)
+  if not n then
+    decode_error(str, i, "invalid number '" .. s .. "'")
+  end
+  return n, x
+end
+
+
+local function parse_literal(str, i)
+  local x = next_char(str, i, delim_chars)
+  local word = str:sub(i, x - 1)
+  if not literals[word] then
+    decode_error(str, i, "invalid literal '" .. word .. "'")
+  end
+  return literal_map[word], x
+end
+
+
+local function parse_array(str, i)
+  local res = {}
+  local n = 1
+  i = i + 1
+  while 1 do
+    local x
+    i = next_char(str, i, space_chars, true)
+    -- Empty / end of array?
+    if str:sub(i, i) == "]" then
+      i = i + 1
+      break
+    end
+    -- Read token
+    x, i = parse(str, i)
+    res[n] = x
+    n = n + 1
+    -- Next token
+    i = next_char(str, i, space_chars, true)
+    local chr = str:sub(i, i)
+    i = i + 1
+    if chr == "]" then break end
+    if chr ~= "," then decode_error(str, i, "expected ']' or ','") end
+  end
+  return res, i
+end
+
+
+local function parse_object(str, i)
+  local res = {}
+  i = i + 1
+  while 1 do
+    local key, val
+    i = next_char(str, i, space_chars, true)
+    -- Empty / end of object?
+    if str:sub(i, i) == "}" then
+      i = i + 1
+      break
+    end
+    -- Read key
+    if str:sub(i, i) ~= '"' then
+      decode_error(str, i, "expected string for key")
+    end
+    key, i = parse(str, i)
+    -- Read ':' delimiter
+    i = next_char(str, i, space_chars, true)
+    if str:sub(i, i) ~= ":" then
+      decode_error(str, i, "expected ':' after key")
+    end
+    i = next_char(str, i + 1, space_chars, true)
+    -- Read value
+    val, i = parse(str, i)
+    -- Set
+    res[key] = val
+    -- Next token
+    i = next_char(str, i, space_chars, true)
+    local chr = str:sub(i, i)
+    i = i + 1
+    if chr == "}" then break end
+    if chr ~= "," then decode_error(str, i, "expected '}' or ','") end
+  end
+  return res, i
+end
+
+
+local char_func_map = {
+  [ '"' ] = parse_string,
+  [ "0" ] = parse_number,
+  [ "1" ] = parse_number,
+  [ "2" ] = parse_number,
+  [ "3" ] = parse_number,
+  [ "4" ] = parse_number,
+  [ "5" ] = parse_number,
+  [ "6" ] = parse_number,
+  [ "7" ] = parse_number,
+  [ "8" ] = parse_number,
+  [ "9" ] = parse_number,
+  [ "-" ] = parse_number,
+  [ "t" ] = parse_literal,
+  [ "f" ] = parse_literal,
+  [ "n" ] = parse_literal,
+  [ "[" ] = parse_array,
+  [ "{" ] = parse_object,
+}
+
+
+parse = function(str, idx)
+  local chr = str:sub(idx, idx)
+  local f = char_func_map[chr]
+  if f then
+    return f(str, idx)
+  end
+  decode_error(str, idx, "unexpected character '" .. chr .. "'")
+end
+
+
+function json_decode(str)
+  if type(str) ~= "string" then
+    error("expected argument of type string, got " .. type(str))
+  end
+  local res, idx = parse(str, next_char(str, 1, space_chars, true))
+  idx = next_char(str, idx, space_chars, true)
+  if idx <= #str then
+    decode_error(str, idx, "trailing garbage")
+  end
+  return res
+end
\ No newline at end of file
diff --git a/src/server/lua.rs b/src/server/lua.rs
new file mode 100644
index 0000000000000000000000000000000000000000..299584af8474b5f806882f770f9da06d2feedb83
--- /dev/null
+++ b/src/server/lua.rs
@@ -0,0 +1,76 @@
+use rlua::{Lua, Result as LuaResult};
+use rocket::{Outcome, http};
+use rocket::request::{FromRequest, Request};
+use std::convert::{Into, AsRef, AsMut};
+use std::collections::HashMap;
+use scripting;
+
+const LIB_JSON_ENCODE: &'static str = include_str!("../scripts/json.lua");
+
+pub struct LuaRuntime(Lua);
+impl Into<Lua> for LuaRuntime {
+    fn into(self) -> Lua {
+        self.0
+    }
+}
+impl AsRef<Lua> for LuaRuntime {
+    fn as_ref(&self) -> &Lua {
+        &self.0
+    }
+}
+impl AsMut<Lua> for LuaRuntime {
+    fn as_mut(&mut self) -> &mut Lua {
+        &mut self.0
+    }
+}
+
+impl <'a, 'req>FromRequest<'a, 'req> for LuaRuntime {
+    type Error = ();
+
+    fn from_request(_request: &'a Request<'req>) -> Outcome<Self, (http::Status, ()), ()> {
+		match create_runtime(false) {
+			Ok(runtime) => Outcome::Success(runtime),
+			_ => Outcome::Failure((http::Status::raw(500), ())),
+		}
+    }
+}
+
+pub fn create_runtime(with_debug: bool) -> LuaResult<LuaRuntime> {
+    let runtime = if with_debug {
+        unsafe { Lua::new_with_debug() }
+    } else {
+        Lua::new()
+    };
+
+	{
+		runtime.eval::<()>(LIB_JSON_ENCODE, Some("json.lua".into()))?
+	}
+
+	{
+		let globals = &runtime.globals();
+		let response_constructor = runtime.create_function(|_, (status, content_type, body): (u16, String, String)| {
+
+			let mut headers = HashMap::new();
+			headers.insert(String::from("Content-Type"), content_type);
+
+			Ok(scripting::ScriptResponse {
+				status,
+				headers,
+				body: Some(body),
+			})
+		})?;
+
+		let empty_response_constructor = runtime.create_function(|_, (): ()| {
+			Ok(scripting::ScriptResponse {
+				status: 204,
+				headers: HashMap::new(),
+				body: None,
+			})
+		})?;
+
+		globals.set("response", response_constructor)?;
+		globals.set("empty_response", empty_response_constructor)?;
+	}
+
+    Ok(LuaRuntime(runtime))
+}
diff --git a/src/server/mod.rs b/src/server/mod.rs
index 1604eface9ba9609f408325378e3fa55eac7927d..21e4c644b65d3427cece43ac3b17f6d003db0769 100644
--- a/src/server/mod.rs
+++ b/src/server/mod.rs
@@ -1,3 +1,5 @@
 mod server;
+mod lua;
 
-pub use self::server::create_server;
\ No newline at end of file
+pub use self::server::create_server;
+pub use self::lua::{LuaRuntime, create_runtime};
\ No newline at end of file
diff --git a/src/server/server.rs b/src/server/server.rs
index 37a1b9453d9ddb28ee397b4b369509eb4c239f63..c2af951ab1a88df486b61e11ae83147bb5979d25 100644
--- a/src/server/server.rs
+++ b/src/server/server.rs
@@ -6,7 +6,10 @@ pub fn create_server(args: Args, config: SwerveConfig) -> Rocket {
 	let server_config = server_config_from_input(args.clone(), config.clone());
 	let mut server = Rocket::custom(server_config, false)
 		.manage(args.clone())
-		.manage(config.clone());
+		.manage(config.clone())
+		.manage(routing::ScriptMap::from_config(&config.clone()))
+
+		.attach(routing::RedirectScripts);
 
 	let quiet = args.flag_quiet;