diff --git a/http-pony.cabal b/http-pony.cabal
--- a/http-pony.cabal
+++ b/http-pony.cabal
@@ -1,15 +1,10 @@
--- Initial http-pony.cabal generated by cabal init.  For further 
--- documentation, see http://haskell.org/cabal/users-guide/
-
 name:                http-pony
-version:             0.1.0.3
+version:             0.1.0.4
 synopsis:            A type unsafe http library
--- description:         
 license:             BSD3
 license-file:        LICENSE
 author:              Jinjing Wang
 maintainer:          nfjinjing@gmail.com
--- copyright:           
 category:            Network
 build-type:          Simple
 extra-source-files:  ChangeLog.md README.md
@@ -20,18 +15,18 @@
 library
   exposed-modules:     Network.HTTP.Pony.Type
                      , Network.HTTP.Pony.Serve
+                     , Network.HTTP.Pony.ServeSafe
                      , Network.HTTP.Pony.Helper
-  -- other-modules:       
-  -- other-extensions:    OverloadedStrings
   build-depends:       
 
-                         base >=4.9 && <4.10
+                         base >=4.8 && < 5
                        , bytestring >=0.10
                        , network >=2.6
                        , pipes >=4.1
                        , pipes-network >=0.6
                        , pipes-safe >=2.2
-                       , transformers >=0.5
+                       , transformers >=0.4
+                       , exceptions >= 0.8.3
 
 
                        -- , case-insensitive >= 1.2.0.7
diff --git a/src/Network/HTTP/Pony/Serve.hs b/src/Network/HTTP/Pony/Serve.hs
--- a/src/Network/HTTP/Pony/Serve.hs
+++ b/src/Network/HTTP/Pony/Serve.hs
@@ -1,13 +1,14 @@
--- | Serve
-
 {-# LANGUAGE OverloadedStrings #-}
 
 module Network.HTTP.Pony.Serve where
 
 import           Control.Monad.IO.Class (MonadIO(..))
+import Control.Monad.Catch (MonadMask)
 import           Data.ByteString.Char8 (ByteString)
+import qualified Data.ByteString.Char8 as B
 import qualified Network.Socket as NS
-import           Pipes (Effect, Producer, Consumer, runEffect, (>->))
+import qualified Network.Socket.ByteString as NSB
+import           Pipes (Effect, Producer, Consumer, runEffect, (>->), await)
 import           Pipes.Network.TCP.Safe (HostPreference())
 import           Pipes.Network.TCP.Safe (fromSocket, toSocket, connect, connectSock
                                         , closeSock)
@@ -15,42 +16,53 @@
 import           Pipes.Safe (MonadSafe(), runSafeT, SafeT)
 
 import           Network.HTTP.Pony.Helper ((-), shutdownSend, shutdownReceive)
+import           Network.HTTP.Pony.ServeSafe (serveWithPipe)
 import           Prelude hiding ((-), log)
 
-serveWithPipe :: (Monad m)  => Producer ByteString m a
-                            -> Consumer ByteString m b
-                            -> (Producer ByteString m a -> m (Producer ByteString m b))
-                            -> m ()
-serveWithPipe pull push pipe = do
-  r <- pipe pull
-  runEffect - r >-> push
 
-  pure ()
-
 serveWithSocket :: (MonadIO m)  => (NS.Socket, NS.SockAddr)
                                 -> (Producer ByteString m () -> m (Producer ByteString m ()))
                                 -> m ()
 serveWithSocket (s,_) =
   let
-    pull = fromSocket s 4096 >> shutdownReceive s
-    push = toSocket s >> shutdownSend s
+    pull = fromSocket s 4096
+    push = do
+      x <- await
+      -- liftIO (putStrLn ( "pony chunk: " ++ show (B.length x) ++ " - " ++ B.unpack x ))
+
+      if B.null x
+        then do
+          -- liftIO (putStrLn "pony shutdone send")
+          shutdownSend s
+          () <$ await
+        else do
+          liftIO (NSB.send s x)
+          push
   in
 
   serveWithPipe pull push
 
-serve :: (MonadSafe m)  => HostPreference
+serveT :: (MonadSafe m, MonadMask n, MonadIO n)
+               => (n () -> IO ())
+               -> HostPreference
+               -> NS.ServiceName
+               -> (Producer ByteString (SafeT n) ()
+                   -> (SafeT n) (Producer ByteString (SafeT n) ()))
+               -> m ()
+serveT exit host service app =
+  PipesNetwork.serve host service - \socket -> do
+    -- no-delay is specifically encouraged in HTTP/2
+    -- https://http2.github.io/faq/#will-i-need-tcpnodelay-for-my-http2-connections
+    liftIO - NS.setSocketOption (fst socket) NS.NoDelay 1
+
+    exit - runSafeT (serveWithSocket socket app)
+
+
+serve, run :: (MonadSafe m)  => HostPreference
                         -> NS.ServiceName
                         -> (Producer ByteString (SafeT IO) ()
                             -> (SafeT IO) (Producer ByteString (SafeT IO) ()))
                         -> m ()
-
-serve host service app =
-  PipesNetwork.serve host service - \socket -> runSafeT (serveWithSocket socket app)
-
-run :: (MonadSafe m) => HostPreference
-                     -> NS.ServiceName
-                     -> (Producer ByteString (SafeT IO) ()
-                         -> (SafeT IO) (Producer ByteString (SafeT IO) ()))
-                     -> m ()
+serve = serveT id
 run = serve
 
diff --git a/src/Network/HTTP/Pony/ServeSafe.hs b/src/Network/HTTP/Pony/ServeSafe.hs
new file mode 100644
--- /dev/null
+++ b/src/Network/HTTP/Pony/ServeSafe.hs
@@ -0,0 +1,16 @@
+{-# LANGUAGE Safe #-}
+
+module Network.HTTP.Pony.ServeSafe where
+
+import Data.ByteString (ByteString)
+import Pipes (Effect, Producer, Consumer, runEffect, (>->))
+
+serveWithPipe :: (Monad m)  => Producer ByteString m a
+                            -> Consumer ByteString m b
+                            -> (Producer ByteString m a -> m (Producer ByteString m b))
+                            -> m ()
+serveWithPipe pull push pipe = do
+  r <- pipe pull
+  runEffect (r >-> push)
+
+  pure ()
diff --git a/src/Network/HTTP/Pony/Type.hs b/src/Network/HTTP/Pony/Type.hs
--- a/src/Network/HTTP/Pony/Type.hs
+++ b/src/Network/HTTP/Pony/Type.hs
@@ -1,3 +1,5 @@
+{-# LANGUAGE Safe #-}
+
 module Network.HTTP.Pony.Type where
 
 import Data.ByteString (ByteString)
