diff --git a/changelog b/changelog
--- a/changelog
+++ b/changelog
@@ -1,3 +1,7 @@
+0.2.2.6:
+
+    * Extract parser runner. `invokeWS` now is a mere default pipeline.
+
 0.2.2.5:
 
     * Drop upper bounds entirely.
diff --git a/soap.cabal b/soap.cabal
--- a/soap.cabal
+++ b/soap.cabal
@@ -1,5 +1,5 @@
 name:                soap
-version:             0.2.2.5
+version:             0.2.2.6
 synopsis:            SOAP client tools
 description:
   Tools to build SOAP clients using xml-conduit.
diff --git a/src/Network/SOAP.hs b/src/Network/SOAP.hs
--- a/src/Network/SOAP.hs
+++ b/src/Network/SOAP.hs
@@ -1,6 +1,6 @@
 -- | A heart of the package, 'invokeWS' assembles and executes requests.
 
-{-# LANGUAGE CPP, OverloadedStrings, Rank2Types, FlexibleContexts #-}
+{-# LANGUAGE BangPatterns, CPP, OverloadedStrings, Rank2Types, FlexibleContexts #-}
 module Network.SOAP
     (
     -- * Requests
@@ -48,13 +48,28 @@
          -> b                -- ^ SOAP Body element.
          -> ResponseParser a -- ^ Parser to use on a request reply.
          -> IO a
-invokeWS transport soapAction header body parser = do
-    lbs <- transport soapAction $! soap header body
+invokeWS transport soapAction header body parser =
+    transport soapAction doc >>= runResponseParser parser
+  where
+    !doc = soap header body
+
+runResponseParser :: ResponseParser a -> LBS.ByteString -> IO a
+runResponseParser parser lbs =
     case parser of
-        StreamParser sink -> runResourceT $ XSP.parseLBS def lbs $$ unwrapEnvelopeSink sink
-        CursorParser func -> checkFault func . unwrapEnvelopeCursor . XML.fromDocument $ XML.parseLBS_ def lbs
-        DocumentParser func -> return . func $ XML.parseLBS_ def lbs
-        RawParser func    -> return . func $ lbs
+        StreamParser sink ->
+            runResourceT $
+                XSP.parseLBS def lbs $$ unwrapEnvelopeSink sink
+
+        CursorParser func ->
+            checkFault func . unwrapEnvelopeCursor
+                            . XML.fromDocument
+                            $ XML.parseLBS_ def lbs
+
+        DocumentParser func ->
+            return . func $ XML.parseLBS_ def lbs
+
+        RawParser func ->
+            return . func $ lbs
 
 unwrapEnvelopeSink :: Parser a -> Parser a
 unwrapEnvelopeSink sink = XSP.force "No SOAP Envelope" $ XSP.tagNoAttr "{http://schemas.xmlsoap.org/soap/envelope/}Envelope"
