diff --git a/Web/Scotty.hs b/Web/Scotty.hs
--- a/Web/Scotty.hs
+++ b/Web/Scotty.hs
@@ -15,7 +15,7 @@
       -- * Defining Actions
     , Action
       -- ** Accessing the Request, Captures, and Query Parameters
-    , request, body, param, jsonData
+    , request, reqHeader, body, param, params, jsonData, files
       -- ** Modifying the Response and Redirecting
     , status, header, redirect
       -- ** Setting Response Body
@@ -25,8 +25,10 @@
     , text, html, file, json, source
       -- ** Exceptions
     , raise, rescue, next
+      -- * Parsing Parameters
+    , Param, Parsable(..), readEither
       -- * Types
-    , ScottyM, ActionM, Param, Parsable(..), readEither, RoutePattern
+    , ScottyM, ActionM, RoutePattern, File
     ) where
 
 import Blaze.ByteString.Builder (fromByteString)
diff --git a/Web/Scotty/Action.hs b/Web/Scotty/Action.hs
--- a/Web/Scotty/Action.hs
+++ b/Web/Scotty/Action.hs
@@ -1,6 +1,6 @@
 {-# LANGUAGE OverloadedStrings #-}
 module Web.Scotty.Action
-    ( request, body, param, jsonData
+    ( request, files, reqHeader, body, param, params, jsonData
     , status, header, redirect
     , text, html, file, json, source
     , raise, rescue, next
@@ -95,6 +95,18 @@
 request :: ActionM Request
 request = getReq <$> ask
 
+-- | Get list of uploaded files.
+files :: ActionM [File]
+files = getFiles <$> ask
+
+-- | Get a request header. Header name is case-insensitive.
+reqHeader :: T.Text -> ActionM T.Text
+reqHeader k = do
+    hs <- requestHeaders <$> request
+    maybe (raise (mconcat ["reqHeader: ", k, " not found"]))
+          (return . strictByteStringToLazyText)
+          (lookup (CI.mk (lazyTextToStrictByteString k)) hs)
+
 -- | Get the request body.
 body :: ActionM BL.ByteString
 body = getBody <$> ask
@@ -118,6 +130,10 @@
     case val of
         Nothing -> raise $ mconcat ["Param: ", k, " not found!"]
         Just v  -> either (const next) return $ parseParam v
+
+-- | Get all parameters from capture, form and query (in that order).
+params :: ActionM [Param]
+params = getParams <$> ask
 
 -- | Minimum implemention: 'parseParam'
 class Parsable a where
diff --git a/Web/Scotty/Route.hs b/Web/Scotty/Route.hs
--- a/Web/Scotty/Route.hs
+++ b/Web/Scotty/Route.hs
@@ -12,7 +12,6 @@
 
 import qualified Data.ByteString.Char8 as B
 import qualified Data.ByteString.Lazy.Char8 as BL
-import qualified Data.CaseInsensitive as CI
 import Data.Conduit.Lazy (lazyConsume)
 import Data.Maybe (fromMaybe)
 import Data.Monoid (mconcat)
@@ -21,11 +20,13 @@
 
 import Network.HTTP.Types
 import Network.Wai
+import Network.Wai.Parse (parseRequestBody, lbsBackEnd)
 
 import qualified Text.Regex as Regex
 
 import Web.Scotty.Action
 import Web.Scotty.Types
+import Web.Scotty.Util
 
 -- | get = 'addroute' 'GET'
 get :: (Action action) => RoutePattern -> action -> ScottyM ()
@@ -101,7 +102,7 @@
     if Right method == parseMethod (requestMethod req)
     then case matchRoute pat req of
             Just captures -> do
-                env <- mkEnv method req captures
+                env <- mkEnv req captures
                 res <- lift $ runAction env action
                 maybe tryNext return res
             Nothing -> tryNext
@@ -130,17 +131,17 @@
 path :: Request -> T.Text
 path = T.fromStrict . TS.cons '/' . TS.intercalate "/" . pathInfo
 
-mkEnv :: StdMethod -> Request -> [Param] -> ResourceT IO ActionEnv
-mkEnv method req captures = do
+mkEnv :: Request -> [Param] -> ResourceT IO ActionEnv
+mkEnv req captures = do
     b <- BL.fromChunks <$> lazyConsume (requestBody req)
 
-    let parameters = captures ++ formparams ++ queryparams
-        formparams = case (method, lookup "Content-Type" [(CI.mk k, CI.mk v) | (k,v) <- requestHeaders req]) of
-                        (_, Just "application/x-www-form-urlencoded") -> parseEncodedParams $ mconcat $ BL.toChunks b
-                        _ -> []
+    (formparams, fs) <- parseRequestBody lbsBackEnd req
+
+    let convert (k, v) = (strictByteStringToLazyText k, strictByteStringToLazyText v)
+        parameters = captures ++ map convert formparams ++ queryparams
         queryparams = parseEncodedParams $ rawQueryString req
 
-    return $ Env req parameters b
+    return $ Env req parameters b [ (strictByteStringToLazyText k, fi) | (k,fi) <- fs ]
 
 parseEncodedParams :: B.ByteString -> [Param]
 parseEncodedParams bs = [ (T.fromStrict k, T.fromStrict $ fromMaybe "" v) | (k,v) <- parseQueryText bs ]
diff --git a/Web/Scotty/Types.hs b/Web/Scotty/Types.hs
--- a/Web/Scotty/Types.hs
+++ b/Web/Scotty/Types.hs
@@ -12,6 +12,7 @@
 
 import Network.Wai
 import Network.Wai.Handler.Warp (Settings, defaultSettings)
+import Network.Wai.Parse (FileInfo)
 
 data Options = Options { verbose :: Int -- ^ 0 = silent, 1(def) = startup banner
                        , settings :: Settings -- ^ Warp 'Settings'
@@ -46,7 +47,9 @@
 instance Error ActionError where
     strMsg = ActionError . pack
 
-data ActionEnv = Env { getReq :: Request, getParams :: [Param], getBody :: ByteString }
+type File = (Text, FileInfo ByteString)
+
+data ActionEnv = Env { getReq :: Request, getParams :: [Param], getBody :: ByteString, getFiles :: [File] }
 
 newtype ActionM a = AM { runAM :: ErrorT ActionError (ReaderT ActionEnv (StateT Response IO)) a }
     deriving ( Monad, MonadIO, Functor
diff --git a/Web/Scotty/Util.hs b/Web/Scotty/Util.hs
--- a/Web/Scotty/Util.hs
+++ b/Web/Scotty/Util.hs
@@ -43,7 +43,7 @@
 setContent (ContentSource src) (ResponseFile s h _ _)  = ResponseSource s h src
 setContent (ContentSource src) (ResponseSource s h _)  = ResponseSource s h src
 
-setHeader :: (CI Ascii, Ascii) -> Response -> Response
+setHeader :: (CI B.ByteString, B.ByteString) -> Response -> Response
 setHeader (k,v) (ResponseBuilder s h b) = ResponseBuilder s (update h k v) b
 setHeader (k,v) (ResponseFile s h f fp) = ResponseFile s (update h k v) f fp
 setHeader (k,v) (ResponseSource s h cs) = ResponseSource s (update h k v) cs
diff --git a/examples/basic.hs b/examples/basic.hs
--- a/examples/basic.hs
+++ b/examples/basic.hs
@@ -88,6 +88,10 @@
     get "/lambda/:foo/:bar/:baz" $ \ foo bar baz -> do
         text $ mconcat [foo, bar, baz]
 
+    get "/reqHeader" $ do
+        agent <- reqHeader "User-Agent"
+        text agent
+
 {- If you don't want to use Warp as your webserver,
    you can use any WAI handler.
 
diff --git a/scotty.cabal b/scotty.cabal
--- a/scotty.cabal
+++ b/scotty.cabal
@@ -1,5 +1,5 @@
 Name:                scotty
-Version:             0.4.4
+Version:             0.4.5
 Synopsis:            Haskell web framework inspired by Ruby's Sinatra, using WAI and Warp
 Homepage:            https://github.com/xich/scotty
 Bug-reports:         https://github.com/xich/scotty/issues
@@ -74,15 +74,16 @@
                        blaze-builder    >= 0.3,
                        bytestring       >= 0.9.1,
                        case-insensitive >= 0.4,
-                       conduit          >= 0.4.0.1 && < 0.5,
+                       conduit          >= 0.4.0.1 && < 0.6,
                        data-default     >= 0.3,
-                       http-types       >= 0.6.8 && < 0.7,
+                       http-types       >= 0.6.8 && < 0.8,
                        mtl              >= 2.0.1,
                        resourcet        >= 0.3.2 && < 0.4,
                        text             >= 0.11.1,
                        wai              >= 1.0.0,
                        warp             >= 1.0.0,
-                       regex-compat     >= 0.95.1
+                       regex-compat     >= 0.95.1,
+                       wai-extra        >= 1.2
 
   GHC-options: -Wall -fno-warn-orphans
 
