diff --git a/hack2-contrib-extra.cabal b/hack2-contrib-extra.cabal
--- a/hack2-contrib-extra.cabal
+++ b/hack2-contrib-extra.cabal
@@ -1,5 +1,5 @@
 Name:                 hack2-contrib-extra
-Version:              2013.6.22
+Version:              2014.12.20
 Build-type:           Simple
 Synopsis:             Hack2 contrib extra
 Description:          Extra middlewares and utilities for Hack2
@@ -16,7 +16,7 @@
 
 library
 
-  build-depends: 
+  build-depends:
                     base >=4 && < 100
                   , cgi
                   , network
@@ -32,17 +32,11 @@
                   , air-extra
                   , hack2
                   , hack2-contrib
-                  
+
   hs-source-dirs: src/
-  
-  exposed-modules:  
-                    
+
+  exposed-modules:
+
                     Hack2.Contrib.RequestExtra
                     Hack2.Contrib.Middleware.RegexpRouter
                     Hack2.Contrib.Middleware.UTF8Body
-
-
-
-
-
-
diff --git a/src/Hack2/Contrib/RequestExtra.hs b/src/Hack2/Contrib/RequestExtra.hs
--- a/src/Hack2/Contrib/RequestExtra.hs
+++ b/src/Hack2/Contrib/RequestExtra.hs
@@ -11,6 +11,7 @@
 import Hack2.Contrib.Request
 import Hack2.Contrib.Utils
 import qualified Data.ByteString.Char8 as B
+import Network.CGI.Protocol (decodeInput, inputValue, inputFilename)
 
 
 media_type :: Env -> ByteString
@@ -23,7 +24,7 @@
 media_type_params :: Env -> [(ByteString, ByteString)]
 media_type_params env
   | env.content_type.B.unpack.empty = []
-  | otherwise = 
+  | otherwise =
       env
         .content_type
         .B.unpack
@@ -38,3 +39,24 @@
 
 content_charset :: Env -> ByteString
 content_charset env = env.media_type_params.lookup "charset" .fromMaybe ""
+
+inputs :: Env -> IO [(ByteString, ByteString)]
+inputs env = do
+  _body <- env.input_bytestring
+  return -
+    env
+      .httpHeaders
+      .map_fst (B.unpack > upper > map (\x -> if x == '-' then '_' else x)) -- cgi env use all cap letters
+      .map_snd B.unpack
+      .(("REQUEST_METHOD", env.request_method.show) : ) -- for cgi request
+      .flip decodeInput (_body.s2l)
+      .fst
+      .concatMap to_headers
+
+  where
+    to_headers (k, input) = case input.inputFilename of
+      Nothing -> [(k.B.pack, input.inputValue.l2s)]
+      Just name ->
+        [  (k.B.pack, input.inputValue.l2s)
+        ,  ("hack2_input_file_name_" + k.B.pack, name.B.pack)
+        ]
