diff --git a/Network/Wai/Middleware/Gzip.hs b/Network/Wai/Middleware/Gzip.hs
--- a/Network/Wai/Middleware/Gzip.hs
+++ b/Network/Wai/Middleware/Gzip.hs
@@ -25,7 +25,7 @@
     ) where
 
 import Network.Wai
-import Data.Maybe (fromMaybe)
+import Data.Maybe (fromMaybe, isJust)
 import qualified Data.ByteString.Char8 as S8
 import qualified Data.ByteString as S
 import Data.Default
@@ -76,7 +76,7 @@
     res <- app env
     case res of
         ResponseFile{} | gzipFiles set == GzipIgnore -> return res
-        _ -> if "gzip" `elem` enc && not isMSIE6
+        _ -> if "gzip" `elem` enc && not isMSIE6 && not (isEncoded res)
                 then
                     case (res, gzipFiles set) of
                         (ResponseFile s hs file Nothing, GzipCacheFolder cache) ->
@@ -91,6 +91,11 @@
                     `fmap` lookup "Accept-Encoding" (requestHeaders env)
     ua = fromMaybe "" $ lookup "user-agent" $ requestHeaders env
     isMSIE6 = "MSIE 6" `S.isInfixOf` ua
+    responseHeaders res = case res of
+                            ResponseFile _ h _ _  -> h
+                            ResponseBuilder _ h _ -> h
+                            ResponseSource _ h _  -> h
+    isEncoded res = isJust $ lookup "Content-Encoding" $ responseHeaders res
 
 compressFile :: Status -> [Header] -> FilePath -> FilePath -> IO Response
 compressFile s hs file cache = do
diff --git a/test/WaiExtraTest.hs b/test/WaiExtraTest.hs
--- a/test/WaiExtraTest.hs
+++ b/test/WaiExtraTest.hs
@@ -63,6 +63,7 @@
     it "jsonp" caseJsonp
     it "gzip" caseGzip
     it "gzip not for MSIE" caseGzipMSIE
+    it "gzip bypass when precompressed" caseGzipBypassPre
     it "defaultCheckMime" caseDefaultCheckMime
     it "vhost" caseVhost
     it "autohead" caseAutohead
@@ -318,6 +319,14 @@
     [("Content-Type", "text/plain")]
     "test"
 
+-- Lie a little and don't compress the body.  This way we test
+-- that the compression is skipped based on the presence of
+-- the Content-Encoding header.
+gzipPrecompressedApp :: Application
+gzipPrecompressedApp = gzip def $ const $ return $ responseLBS status200
+    [("Content-Type", "text/plain"), ("Content-Encoding", "gzip")]
+    "test"
+
 caseGzip :: Assertion
 caseGzip = flip runSession gzipApp $ do
     sres1 <- request defaultRequest
@@ -352,6 +361,14 @@
                 }
     assertNoHeader "Content-Encoding" sres1
     liftIO $ simpleBody sres1 @?= "test"
+
+caseGzipBypassPre :: Assertion
+caseGzipBypassPre = flip runSession gzipPrecompressedApp $ do
+    sres1 <- request defaultRequest
+                { requestHeaders = [("Accept-Encoding", "gzip")]
+                }
+    assertHeader "Content-Encoding" "gzip" sres1
+    assertBody "test" sres1 -- the body is not actually compressed
 
 vhostApp1, vhostApp2, vhostApp :: Application
 vhostApp1 = const $ return $ responseLBS status200 [] "app1"
diff --git a/wai-extra.cabal b/wai-extra.cabal
--- a/wai-extra.cabal
+++ b/wai-extra.cabal
@@ -1,5 +1,5 @@
 Name:                wai-extra
-Version:             1.3.4.3
+Version:             1.3.4.4
 Synopsis:            Provides some basic WAI handlers and middleware.
 Description:         The goal here is to provide common features without many dependencies.
 License:             MIT
