diff --git a/Changelog.md b/Changelog.md
--- a/Changelog.md
+++ b/Changelog.md
@@ -1,3 +1,10 @@
+## 0.5.3
+
+- add macos-aarch64 build
+- add `--hide` option for probe resistance
+- gracefully close stream for HTTP CONNECT
+- `gzip` encoding middleware removed
+
 ## 0.5.2
 
 - add Windows build
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,6 +1,7 @@
 ## hprox
 
 [![CircleCI](https://circleci.com/gh/bjin/hprox.svg?style=shield)](https://circleci.com/gh/bjin/hprox)
+[![CirrusCI](https://api.cirrus-ci.com/github/bjin/hprox.svg)](https://cirrus-ci.com/github/bjin/hprox)
 [![Depends](https://img.shields.io/hackage-deps/v/hprox.svg)](https://packdeps.haskellers.com/feed?needle=hprox)
 [![Release](https://img.shields.io/github/release/bjin/hprox.svg)](https://github.com/bjin/hprox/releases)
 [![Hackage](https://img.shields.io/hackage/v/hprox.svg)](https://hackage.haskell.org/package/hprox)
@@ -76,7 +77,8 @@
 
 * Passwords are currently stored in plain text, please set permission accordingly and
   avoid using existing password.
-* HTTP/3 currently only works on the first domain as specified by `-s/--tls`.
+* HTTP/3 currently only works on the first domain as specified by `-s/--tls`, also SNI
+  validation is unavailable as well.
 
 ### License
 
diff --git a/hprox.cabal b/hprox.cabal
--- a/hprox.cabal
+++ b/hprox.cabal
@@ -1,11 +1,11 @@
 cabal-version: 1.12
 
--- This file has been generated from package.yaml by hpack version 0.35.1.
+-- This file has been generated from package.yaml by hpack version 0.35.2.
 --
 -- see: https://github.com/sol/hpack
 
 name:           hprox
-version:        0.5.2
+version:        0.5.3
 synopsis:       a lightweight HTTP proxy server, and more
 description:    Please see the README on GitHub at <https://github.com/bjin/hprox#readme>
 category:       Web
diff --git a/src/Network/HProx.hs b/src/Network/HProx.hs
--- a/src/Network/HProx.hs
+++ b/src/Network/HProx.hs
@@ -68,6 +68,7 @@
   , _ws       :: Maybe String
   , _rev      :: Maybe String
   , _doh      :: Maybe String
+  , _hide     :: Bool
   , _naive    :: Bool
   , _name     :: BS8.ByteString
   , _log      :: String
@@ -79,7 +80,7 @@
 
 -- | Default value of 'Config', same as running @hprox@ without arguments
 defaultConfig :: Config
-defaultConfig = Config Nothing 3000 [] Nothing Nothing Nothing Nothing False "hprox" "stdout" INFO
+defaultConfig = Config Nothing 3000 [] Nothing Nothing Nothing Nothing False False "hprox" "stdout" INFO
 #ifdef QUIC_ENABLED
     Nothing
 #endif
@@ -116,6 +117,7 @@
                     <*> ws
                     <*> rev
                     <*> doh
+                    <*> hide
                     <*> naive
                     <*> name
                     <*> logging
@@ -165,6 +167,10 @@
        <> metavar "dns-server:port"
        <> help "enable DNS-over-HTTPS(DoH) support (53 will be used if port is not specified)")
 
+    hide = switch
+        ( long "hide"
+       <> help "never send 'proxy authentication required' response (however this might break the use of HTTPS proxy in browser)")
+
     naive = switch
         ( long "naive"
        <> help "add naiveproxy compatible padding (requires TLS)")
@@ -234,8 +240,7 @@
                    setLogger warpLogger $
                    setOnException exceptionHandler $
                    setNoParsePath True $
-                   setServerName _name $
-                   defaultSettings
+                   setServerName _name defaultSettings
 
         exceptionHandler req ex
             | _loglevel > DEBUG                                 = return ()
@@ -251,7 +256,7 @@
             | Just ConnectionClosedByPeer <- fromException ex   = return ()
             | otherwise                                         =
                 logger DEBUG $ "exception: " <> toLogStr (displayException ex) <>
-                    (if (isJust req) then " from: " <> logRequest (fromJust req) else "")
+                    (if isJust req then " from: " <> logRequest (fromJust req) else "")
 
         warpLogger req status _
             | rawPathInfo req == "/.hprox/health" = return ()
@@ -326,12 +331,11 @@
             Just . flip elem . filter (isJust . BS8.elemIndex ':') . BS8.lines <$> BS8.readFile f
     manager <- newTlsManager
 
-    let pset = ProxySettings pauth (Just _name) (BS8.pack <$> _ws) (BS8.pack <$> _rev) (_naive && isSSL) logger
+    let pset = ProxySettings pauth (Just _name) (BS8.pack <$> _ws) (BS8.pack <$> _rev) _hide (_naive && isSSL) logger
         proxy = healthCheckProvider $
                 (if isSSL then forceSSL pset else id) $
                 httpProxy pset manager $
-                reverseProxy pset manager $
-                fallback
+                reverseProxy pset manager fallback
 
     when (isJust _ws) $ logger INFO $ "websocket redirect: " <> toLogStr (fromJust _ws)
     when (isJust _rev) $ logger INFO $ "reverse proxy: " <> toLogStr (fromJust _rev)
diff --git a/src/Network/HProx/Impl.hs b/src/Network/HProx/Impl.hs
--- a/src/Network/HProx/Impl.hs
+++ b/src/Network/HProx/Impl.hs
@@ -15,7 +15,7 @@
   ) where
 
 import Control.Applicative        ((<|>))
-import Control.Concurrent.Async   (concurrently)
+import Control.Concurrent.Async   (cancel, wait, waitEither, withAsync)
 import Control.Exception          (SomeException, try)
 import Control.Monad              (unless, void, when)
 import Control.Monad.IO.Class     (liftIO)
@@ -35,23 +35,24 @@
     wpsUpgradeToRaw)
 import Network.HTTP.Types         qualified as HT
 import Network.HTTP.Types.Header  qualified as HT
+import System.Timeout             (timeout)
 
 import Data.Conduit
 import Data.Maybe
 import Network.Wai
-import Network.Wai.Middleware.Gzip
 import Network.Wai.Middleware.StripHeaders
 
 import Network.HProx.Log
 import Network.HProx.Util
 
 data ProxySettings = ProxySettings
-  { proxyAuth    :: Maybe (BS.ByteString -> Bool)
-  , passPrompt   :: Maybe BS.ByteString
-  , wsRemote     :: Maybe BS.ByteString
-  , revRemote    :: Maybe BS.ByteString
-  , naivePadding :: Bool
-  , logger       :: Logger
+  { proxyAuth     :: Maybe (BS.ByteString -> Bool)
+  , passPrompt    :: Maybe BS.ByteString
+  , wsRemote      :: Maybe BS.ByteString
+  , revRemote     :: Maybe BS.ByteString
+  , hideProxyAuth :: Bool
+  , naivePadding  :: Bool
+  , logger        :: Logger
   }
 
 logRequest :: Request -> LogStr
@@ -102,12 +103,15 @@
 checkAuth ProxySettings{..} req
     | isNothing proxyAuth = True
     | isNothing authRsp   = False
-    | otherwise           = fromJust proxyAuth decodedRsp
+    | otherwise           =
+        pureLogger logger TRACE (authMsg <> " request (credential: " <> toLogStr decodedRsp <> ") from " <> toLogStr (show (remoteHost req))) authorized
   where
     authRsp = lookup HT.hProxyAuthorization (requestHeaders req)
-
     decodedRsp = decodeLenient $ snd $ BS8.spanEnd (/=' ') $ fromJust authRsp
 
+    authorized = fromJust proxyAuth decodedRsp
+    authMsg = if authorized then "authorized" else "unauthorized"
+
 redirectWebsocket :: ProxySettings -> Request -> Bool
 redirectWebsocket ProxySettings{..} req = wpsUpgradeToRaw defaultWaiProxySettings req && isJust wsRemote
 
@@ -174,20 +178,17 @@
                                      ]
 
 httpGetProxy :: ProxySettings -> HC.Manager -> Middleware
-httpGetProxy pset@ProxySettings{..} mgr fallback = appWrapper $ waiProxyToSettings (return.proxyResponseFor) settings mgr
+httpGetProxy pset@ProxySettings{..} mgr fallback = waiProxyToSettings (return.proxyResponseFor) settings mgr
   where
     settings = defaultWaiProxySettings { wpsSetIpHeader = SIHNone }
 
-    appWrapper = ifRequest isGetProxy (gzip def)
-
-    isGetProxy req = case proxyResponseFor req of
-        WPRModifiedRequest _ _ -> True
-        _                      -> False
-
     proxyResponseFor req
         | redirectWebsocket pset req = wsWrapper (ProxyDest wsHost wsPort)
         | not isGETProxy             = WPRApplication fallback
         | checkAuth pset req         = WPRModifiedRequest nreq (ProxyDest host port)
+        | hideProxyAuth              =
+            pureLogger logger WARN ("unauthorized request (hidden without response): " <> logRequest req) $
+            WPRApplication fallback
         | otherwise                  =
             pureLogger logger WARN ("unauthorized request: " <> logRequest req) $
             WPRResponse (proxyAuthRequiredResponse pset)
@@ -224,6 +225,9 @@
 httpConnectProxy pset@ProxySettings{..} fallback req respond
     | not isConnectProxy = fallback req respond
     | checkAuth pset req = respondResponse
+    | hideProxyAuth      = do
+        logger WARN $ "unauthorized request (hidden without response): " <> logRequest req
+        fallback req respond
     | otherwise          = do
         logger WARN $ "unauthorized request: " <> logRequest req
         respond (proxyAuthRequiredResponse pset)
@@ -240,6 +244,17 @@
     tryAndCatchAll :: IO a -> IO (Either SomeException a)
     tryAndCatchAll = try
 
+    runStreams :: Int -> IO () -> IO () -> IO (Either SomeException ())
+    runStreams secs left right = tryAndCatchAll $
+        withAsync left $ \l -> do
+            withAsync right $ \r -> do
+                res1 <- waitEither l r
+                let unfinished = case res1 of
+                        Left _ -> r
+                        _      -> l
+                res2 <- timeout (secs * 1000000) (wait unfinished)
+                when (isNothing res2) $ cancel unfinished
+
     respondResponse
         | HT.httpMajor (httpVersion req) < 2 = respond $ responseRaw (handleConnect True) backup
         | not naivePadding                   = respond $ responseStream HT.status200 [] streaming
@@ -311,6 +326,7 @@
                            | otherwise        = fromServer .| toClient
         in do
             when http1 $ runConduit $ yieldHttp1Response .| toClient
-            void $ tryAndCatchAll $ concurrently
+            -- gracefully close the other stream after 5 seconds if one side of stream is closed.
+            void $ runStreams 5
                 (runConduit clientToServer)
                 (runConduit serverToClient)
