diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,7 +1,65 @@
 # Change Log
 
+## [1.6.0](https://github.com/brendanhay/amazonka/tree/1.6.0)
+Released: **16 May, 2018**, Compare: [1.5.0](https://github.com/brendanhay/amazonka/compare/1.5.0...1.6.0)
+
+### Fixed
+
+- GHC 8.4 compatibility. [\#456](https://github.com/brendanhay/amazonka/pull/456)
+- Conduit `1.3` compatibility. [\#449](https://github.com/brendanhay/amazonka/pull/449)
+- S3 `BucketName` now has a `FromJSON` instance. [\#452](https://github.com/brendanhay/amazonka/pull/452)
+- S3 `ListObjectsV2` is now named correctly. [\#447](https://github.com/brendanhay/amazonka/pull/447)
+- HTTP `Expect` headers are now stripped when presigning URLs. [\#444](https://github.com/brendanhay/amazonka/pull/444)
+- Duplicate generated files no longer exist on case-insensitive file systems. [\#429](https://github.com/brendanhay/amazonka/pull/429)
+- EC2 metadata's instance identity document now has the correct(er) field types. [\#428](https://github.com/brendanhay/amazonka/pull/428)
+- OpsWorks `DescribeApps` and `DescribeStacks` now correctly handle optional attribute values. [\#436](https://github.com/brendanhay/amazonka/pull/436), [\#438](https://github.com/brendanhay/amazonka/pull/438)
+
+### Breaking Changes
+
+- Lambda and other `rest-json` services with binary response payloads now return a raw `ByteString` instead of `HashMap Text Value`,
+  fixing an issue where an empty body could not be deserialized. [\#428](https://github.com/brendanhay/amazonka/pull/394), [\#428](https://github.com/brendanhay/amazonka/pull/407)
+
+### New Libraries
+
+- `amazonka-alexa-business`: Alexa for Business SDK. [Overview](https://aws.amazon.com/alexaforbusiness/)
+- `amazonka-appsync`: Automatically update data in web and mobile applications in real time, and updates data for offline users as soon as they reconnect. [Overview](https://aws.amazon.com/appsync/)
+- `amazonka-autoscaling-plans`: Create instructions to configure dynamic scaling for the scalable resources in your application. [Overview](https://aws.amazon.com/autoscaling/)
+- `amazonka-certificatemanager-pca`: Create a secure private certificate authority (CA). [Overview](https://docs.aws.amazon.com/acm-pca/latest/userguide/PcaWelcome.html)
+- `amazonka-cloud9`: A cloud IDE for writing, running, and debugging code. [Overview](https://aws.amazon.com/cloud9/)
+- `amazonka-comprehend`: Natural language processing (NLP) service that uses machine learning to find insights and relationships in text. [Overview](https://aws.amazon.com/comprehend/)
+- `amazonka-connect`: Simple to use, cloud-based contact center. [Overview](https://aws.amazon.com/connect/)
+- `amazonka-cost-explorer`: Dive deeper into your cost and usage data to identify trends, pinpoint cost drivers, and detect anomalies. [Overview](https://aws.amazon.com/aws-cost-management/aws-cost-explorer/)
+- `amazonka-fms`: Centrally configure and manage firewall rules across accounts and applications. [Overview](https://aws.amazon.com/firewall-manager/)
+- `amazonka-guardduty`: Intelligent threat detection and continuous monitoring to protect your AWS accounts and workloads. [Overview](https://aws.amazon.com/guardduty/)
+- `amazonka-iot-analytics`: Analytics for IoT devices. [Overview](https://aws.amazon.com/iot-analytics/)
+- `amazonka-iot-jobs-dataplane`: Define a set of remote operations that are sent to and executed on one or more devices connected to AWS IoT. [Overview](https://docs.aws.amazon.com/iot/latest/developerguide/iot-jobs.html)
+- `amazonka-kinesis-video`: Capture, process, and store video streams for analytics and machine learning. [Overview](https://aws.amazon.com/kinesis/video-streams/)
+- `amazonka-kinesis-video-media`: Media support for Kinesis Video. [Overview](https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_Operations_Amazon_Kinesis_Video_Streams_Media.html)
+- `amazonka-kinesis-video-archived-media`: Archived media support for Kinesis Video. [Overview](https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_Operations_Amazon_Kinesis_Video_Streams_Archived_Media.html)
+- `amazonka-mediaconvert`: Process video files and clips to prepare on-demand content for distribution or archiving. [Overview](https://aws.amazon.com/mediaconvert/)
+- `amazonka-medialive`: Encode live video for broadcast and streaming to any device. [Overview](https://aws.amazon.com/medialive/)
+- `amazonka-mediapackage`: Easily prepare and protect video for delivery to Internet devices. [Overview](https://aws.amazon.com/mediapackage/)
+- `amazonka-mediastore`: Store and deliver video assets for live streaming media workflows. [Overview](https://aws.amazon.com/mediastore/)
+- `amazonka-mediastore-dataplane`: MediaStore data plane. [Overview](https://docs.aws.amazon.com/mediastore/latest/apireference/API_Operations_AWS_Elemental_MediaStore_Data_Plane.html)
+- `amazonka-mq`: Managed message broker service for Apache ActiveMQ. [Overview](https://aws.amazon.com/amazon-mq/)
+- `amazonka-resourcegroups`: Resource groups make it easier to manage and automate tasks on large numbers of resources at one time. [Overview](https://docs.aws.amazon.com/ARG/latest/userguide/welcome.html)
+- `amazonka-route53-autonaming`: Auto naming makes it easier to provision instances for microservices by automating DNS configuration. [Overview](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/autonaming.html)
+- `amazonka-sagemaker`: Build, train, and deploy machine learning models at scale. [Overview](https://aws.amazon.com/sagemaker/)
+- `amazonka-sagemaker-runtime`: Get inferences from SageMaker models. [Overview](https://docs.aws.amazon.com/sagemaker/latest/dg/API_Operations_Amazon_SageMaker_Runtime.html)
+- `amazonka-secretsmanager`: Easily rotate, manage, and retrieve database credentials, API keys, and other secrets through their lifecycle. [Overview](https://aws.amazon.com/secrets-manager/)
+- `amazonka-serverlessrepo`: Discover, deploy, and publish serverless applications. [Overview](https://aws.amazon.com/serverless/serverlessrepo/)
+- `amazonka-transcribe`: Automatic speech recognition. [Overview](https://aws.amazon.com/transcribe/)
+- `amazonka-translate`: A neural machine translation service that delivers fast, high-quality, and affordable language translation. [Overview](https://aws.amazon.com/translate/)
+- `amazonka-workmail`: Secure, managed business email and calendar service with support for existing desktop and mobile email client applications. [Overview](https://aws.amazon.com/workfmail/)
+
+### Updated Service Definitions
+
+> All service definitions and services have been updated and regenerated.
+Please see each individual library's commits for a list of changes.
+
+
 ## [1.5.0](https://github.com/brendanhay/amazonka/tree/1.5.0)
-fReleased: **15 November, 2017**, Compare: [1.4.5](https://github.com/brendanhay/amazonka/compare/1.4.5...1.5.0)
+Released: **15 November, 2017**, Compare: [1.4.5](https://github.com/brendanhay/amazonka/compare/1.4.5...1.5.0)
 
 ### Fixed
 
diff --git a/amazonka.cabal b/amazonka.cabal
--- a/amazonka.cabal
+++ b/amazonka.cabal
@@ -1,5 +1,5 @@
 name:                  amazonka
-version:               1.5.0
+version:               1.6.0
 synopsis:              Comprehensive Amazon Web Services SDK.
 homepage:              https://github.com/brendanhay/amazonka
 bug-reports:           https://github.com/brendanhay/amazonka/issues
@@ -60,14 +60,16 @@
         , Network.AWS.Internal.Logger
 
     build-depends:
-          amazonka-core       == 1.5.0.*
+          amazonka-core       == 1.6.0.*
         , base                >= 4.7 && < 5
         , bytestring          >= 0.9
         , conduit             >= 1.1
         , conduit-extra       >= 1.1
         , directory           >= 1.2
         , exceptions          >= 0.6
-        , http-conduit        >= 2.2 && < 3
+        , http-client         >= 0.4 && < 0.6
+        , http-conduit        >= 2.1.7 && < 3
+        , http-types          >= 0.8
         , ini                 >= 0.3.5
         , mmorph              >= 1
         , monad-control       >= 1
@@ -79,6 +81,7 @@
         , transformers        >= 0.2
         , transformers-base   >= 0.4
         , transformers-compat >= 0.3
+        , void                >= 0.1
 
 test-suite tests
     type:              exitcode-stdio-1.0
diff --git a/src/Control/Monad/Trans/AWS.hs b/src/Control/Monad/Trans/AWS.hs
--- a/src/Control/Monad/Trans/AWS.hs
+++ b/src/Control/Monad/Trans/AWS.hs
@@ -14,7 +14,7 @@
 
 -- |
 -- Module      : Control.Monad.Trans.AWS
--- Copyright   : (c) 2013-2017 Brendan Hay
+-- Copyright   : (c) 2013-2018 Brendan Hay
 -- License     : Mozilla Public License, v. 2.0.
 -- Maintainer  : Brendan Hay <brendan.g.hay+amazonka@gmail.com>
 -- Stability   : provisional
@@ -262,7 +262,7 @@
 -- | An alias for the constraints required to send requests,
 -- which 'AWST' implicitly fulfils.
 type AWSConstraint r m =
-    ( MonadCatch     m
+    ( MonadThrow     m
     , MonadResource  m
     , MonadReader  r m
     , HasEnv       r
@@ -282,7 +282,7 @@
 -- Throws 'Error'.
 paginate :: (AWSConstraint r m, AWSPager a)
          => a
-         -> Source m (Rs a)
+         -> ConduitM () (Rs a) m ()
 paginate = go
   where
     go !x = do
diff --git a/src/Network/AWS.hs b/src/Network/AWS.hs
--- a/src/Network/AWS.hs
+++ b/src/Network/AWS.hs
@@ -6,7 +6,7 @@
 
 -- |
 -- Module      : Network.AWS
--- Copyright   : (c) 2013-2017 Brendan Hay
+-- Copyright   : (c) 2013-2018 Brendan Hay
 -- License     : Mozilla Public License, v. 2.0.
 -- Maintainer  : Brendan Hay <brendan.g.hay+amazonka@gmail.com>
 -- Stability   : provisional
@@ -154,10 +154,8 @@
     , RsBody
     ) where
 
-import Control.Applicative
 import Control.Monad.Catch          (MonadCatch)
 import Control.Monad.IO.Class       (MonadIO)
-import Control.Monad.Morph          (hoist)
 import Control.Monad.Trans.AWS      (AWST)
 import Control.Monad.Trans.Class    (lift)
 import Control.Monad.Trans.Except   (ExceptT)
@@ -167,8 +165,7 @@
 import Control.Monad.Trans.Reader   (ReaderT)
 import Control.Monad.Trans.Resource
 
-import Data.Conduit (Source)
-import Data.Monoid
+import Data.Conduit (ConduitM, transPipe)
 
 import Network.AWS.Auth
 import Network.AWS.Env             (Env, HasEnv (..), newEnv)
@@ -265,8 +262,8 @@
 
 -- | Repeatedly send a request, automatically setting markers and
 -- paginating over multiple responses while available.
-paginate :: (MonadAWS m, AWSPager a) => a -> Source m (Rs a)
-paginate = hoist liftAWS . AWST.paginate
+paginate :: (MonadAWS m, AWSPager a) => a -> ConduitM () (Rs a) m ()
+paginate x = transPipe liftAWS $ AWST.paginate x
 
 -- | Poll the API with the supplied request until a specific 'Wait' condition
 -- is fulfilled.
diff --git a/src/Network/AWS/Auth.hs b/src/Network/AWS/Auth.hs
--- a/src/Network/AWS/Auth.hs
+++ b/src/Network/AWS/Auth.hs
@@ -4,10 +4,11 @@
 {-# LANGUAGE LambdaCase         #-}
 {-# LANGUAGE OverloadedStrings  #-}
 {-# LANGUAGE TupleSections      #-}
+{-# LANGUAGE CPP      #-}
 
 -- |
 -- Module      : Network.AWS.Auth
--- Copyright   : (c) 2013-2017 Brendan Hay
+-- Copyright   : (c) 2013-2018 Brendan Hay
 -- License     : Mozilla Public License, v. 2.0.
 -- Maintainer  : Brendan Hay <brendan.g.hay+amazonka@gmail.com>
 -- Stability   : provisional
@@ -392,7 +393,7 @@
             -> Maybe Text -- ^ Session token environment variable.
             -> Maybe Text -- ^ Region environment variable.
             -> m (Auth, Maybe Region)
-fromEnvKeys access secret session region =
+fromEnvKeys access secret session region' =
     (,) <$> fmap Auth lookupKeys <*> lookupRegion
   where
     lookupKeys = AuthEnv
@@ -403,8 +404,8 @@
 
     lookupRegion :: (MonadIO m, MonadThrow m) => m (Maybe Region)
     lookupRegion = runMaybeT $ do
-        k <- MaybeT (return region)
-        r <- MaybeT (opt region)
+        k <- MaybeT (return region')
+        r <- MaybeT (opt region')
         case fromText (Text.pack r) of
             Right x -> return x
             Left  e -> throwM . InvalidEnvError $
@@ -566,7 +567,11 @@
         p  <- maybe (throwM . MissingEnvError $ "Unable to read ENV variable: " <> envContainerCredentialsURI)
                     return
                     mp
+#if MIN_VERSION_http_client(0,4,30)
         parseUrlThrow $ "http://169.254.170.2" <> p
+#else
+        parseUrl $ "http://169.254.170.2" <> p
+#endif
 
     renew :: HTTP.Request -> IO AuthEnv
     renew req = do
diff --git a/src/Network/AWS/Data.hs b/src/Network/AWS/Data.hs
--- a/src/Network/AWS/Data.hs
+++ b/src/Network/AWS/Data.hs
@@ -1,6 +1,6 @@
 -- |
 -- Module      : Network.AWS.Data
--- Copyright   : (c) 2013-2017 Brendan Hay
+-- Copyright   : (c) 2013-2018 Brendan Hay
 -- License     : Mozilla Public License, v. 2.0.
 -- Maintainer  : Brendan Hay <brendan.g.hay+amazonka@gmail.com>
 -- Stability   : provisional
diff --git a/src/Network/AWS/EC2/Metadata.hs b/src/Network/AWS/EC2/Metadata.hs
--- a/src/Network/AWS/EC2/Metadata.hs
+++ b/src/Network/AWS/EC2/Metadata.hs
@@ -4,10 +4,11 @@
 {-# LANGUAGE LambdaCase         #-}
 {-# LANGUAGE OverloadedStrings  #-}
 {-# LANGUAGE RecordWildCards    #-}
+{-# LANGUAGE CPP                #-}
 
 -- |
 -- Module      : Network.AWS.EC2.Metadata
--- Copyright   : (c) 2013-2017 Brendan Hay
+-- Copyright   : (c) 2013-2018 Brendan Hay
 -- License     : Mozilla Public License, v. 2.0.
 -- Maintainer  : Brendan Hay <brendan.g.hay+amazonka@gmail.com>
 -- Stability   : provisional
@@ -330,9 +331,15 @@
 userdata m = do
     x <- try $ get m (latest <> "user-data")
     case x of
+#if MIN_VERSION_http_client(0,5,0)
         Left (HttpExceptionRequest _ (StatusCodeException rs _))
             | fromEnum (responseStatus rs) == 404
                 -> return Nothing
+#else
+        Left (StatusCodeException s _ _)
+            | fromEnum s == 404
+                -> return Nothing
+#endif
         Left  e -> throwM e
         Right b -> return (Just b)
 
@@ -342,8 +349,8 @@
 -- will need to be manually parsed using 'fromText' when the relevant types
 -- from a library such as "Network.AWS.EC2" are brought into scope.
 data IdentityDocument = IdentityDocument
-    { _devpayProductCodes :: Maybe Text
-    , _billingProducts    :: Maybe Text
+    { _devpayProductCodes :: Maybe [Text]
+    , _billingProducts    :: Maybe [Text]
     , _version            :: Maybe Text
     , _privateIp          :: Maybe Text
     , _availabilityZone   :: Text
@@ -358,10 +365,10 @@
     , _pendingTime        :: Maybe ISO8601
     } deriving (Eq, Show)
 
-devpayProductCodes :: Lens' IdentityDocument (Maybe Text)
+devpayProductCodes :: Lens' IdentityDocument (Maybe [Text])
 devpayProductCodes = lens _devpayProductCodes (\s a -> s { _devpayProductCodes = a })
 
-billingProducts :: Lens' IdentityDocument (Maybe Text)
+billingProducts :: Lens' IdentityDocument (Maybe [Text])
 billingProducts = lens _billingProducts (\s a -> s { _billingProducts = a })
 
 version :: Lens' IdentityDocument (Maybe Text)
@@ -456,6 +463,10 @@
 
 request :: Manager -> Text -> IO ByteString
 request m url = do
+#if MIN_VERSION_http_client(0,4,30)
     rq <- parseUrlThrow (Text.unpack url)
+#else
+    rq <- parseUrl (Text.unpack url)
+#endif
     rs <- httpLbs rq m
     return . LBS.toStrict $ responseBody rs
diff --git a/src/Network/AWS/Env.hs b/src/Network/AWS/Env.hs
--- a/src/Network/AWS/Env.hs
+++ b/src/Network/AWS/Env.hs
@@ -4,10 +4,11 @@
 {-# LANGUAGE RankNTypes        #-}
 {-# LANGUAGE RecordWildCards   #-}
 {-# LANGUAGE ViewPatterns      #-}
+{-# LANGUAGE CPP               #-}
 
 -- |
 -- Module      : Network.AWS.Env
--- Copyright   : (c) 2013-2017 Brendan Hay
+-- Copyright   : (c) 2013-2018 Brendan Hay
 -- License     : Mozilla Public License, v. 2.0.
 -- Maintainer  : Brendan Hay <brendan.g.hay+amazonka@gmail.com>
 -- Stability   : provisional
@@ -38,7 +39,6 @@
     , retryConnectionFailure
     ) where
 
-import Control.Applicative
 import Control.Monad.Catch
 import Control.Monad.IO.Class
 import Control.Monad.Reader
@@ -192,7 +192,7 @@
        => Credentials -- ^ Credential discovery mechanism.
        -> m Env
 newEnv c =
-    liftIO (newManager conduitManagerSettings)
+    liftIO (newManager tlsManagerSettings)
         >>= newEnvWith c Nothing
 
 -- | /See:/ 'newEnv'
@@ -216,6 +216,7 @@
 -- | Retry the subset of transport specific errors encompassing connection
 -- failure up to the specific number of times.
 retryConnectionFailure :: Int -> Int -> HttpException -> Bool
+#if MIN_VERSION_http_client(0,5,0)
 retryConnectionFailure _     _ InvalidUrlException {}      = False
 retryConnectionFailure limit n (HttpExceptionRequest _ ex)
     | n >= limit = False
@@ -227,3 +228,12 @@
             ConnectionFailure {}   -> True
             InternalException {}   -> True
             _                      -> False
+#else
+retryConnectionFailure limit n = \case
+    _ | n >= limit                -> False
+    NoResponseDataReceived        -> True
+    FailedConnectionException  {} -> True
+    FailedConnectionException2 {} -> True
+    TlsException               {} -> True
+    _                             -> False
+#endif
diff --git a/src/Network/AWS/Internal/Body.hs b/src/Network/AWS/Internal/Body.hs
--- a/src/Network/AWS/Internal/Body.hs
+++ b/src/Network/AWS/Internal/Body.hs
@@ -3,7 +3,7 @@
 
 -- |
 -- Module      : Network.AWS.Internal.Body
--- Copyright   : (c) 2013-2017 Brendan Hay
+-- Copyright   : (c) 2013-2018 Brendan Hay
 -- License     : Mozilla Public License, v. 2.0.
 -- Maintainer  : Brendan Hay <brendan.g.hay+amazonka@gmail.com>
 -- Stability   : provisional
@@ -11,24 +11,23 @@
 --
 module Network.AWS.Internal.Body where
 
-import           Control.Applicative
 import           Control.Monad
 import           Control.Monad.IO.Class
-import           Control.Monad.Morph
 import           Control.Monad.Trans.Resource
 import qualified Data.ByteString              as BS
 import           Data.Conduit
 import qualified Data.Conduit.Binary          as Conduit
 import           Network.AWS.Prelude
 import           System.IO
+import           Data.Void (Void) -- required for < conduit-1.3
 
 -- | Convenience function for obtaining the size of a file.
 getFileSize :: MonadIO m => FilePath -> m Integer
 getFileSize path = liftIO (withBinaryFile path ReadMode hFileSize)
 
 -- | Connect a 'Sink' to a response stream.
-sinkBody :: MonadResource m => RsBody -> Sink ByteString m a -> m a
-sinkBody (RsBody body) sink = hoist liftResourceT body $$+- sink
+sinkBody :: MonadIO m => RsBody -> ConduitM ByteString Void (ResourceT IO) a -> m a
+sinkBody (RsBody body) sink = liftIO $ runConduitRes $ body .| sink
 
 -- | Construct a 'HashedBody' from a 'FilePath', calculating the 'SHA256' hash
 -- and file size.
@@ -43,7 +42,7 @@
            -> m HashedBody
 hashedFile path =
     liftIO $ HashedStream
-        <$> runResourceT (Conduit.sourceFile path $$ sinkSHA256)
+        <$> runResourceT (Conduit.sourceFile path `connect` sinkSHA256)
         <*> getFileSize path
         <*> pure (Conduit.sourceFile path)
 
@@ -59,7 +58,7 @@
                 -> m HashedBody
 hashedFileRange path (Just -> offset) (Just -> len) =
     liftIO $ HashedStream
-        <$> runResourceT (Conduit.sourceFileRange path offset len $$ sinkSHA256)
+        <$> runResourceT (Conduit.sourceFileRange path offset len `connect` sinkSHA256)
         <*> getFileSize path
         <*> pure (Conduit.sourceFileRange path offset len)
 
@@ -70,7 +69,7 @@
 -- /See:/ 'ToHashedBody'.
 hashedBody :: Digest SHA256 -- ^ A SHA256 hash of the file contents.
            -> Integer       -- ^ The size of the stream in bytes.
-           -> Source (ResourceT IO) ByteString
+           -> ConduitM () ByteString (ResourceT IO) ()
            -> HashedBody
 hashedBody = HashedStream
 
@@ -126,14 +125,14 @@
                      -- ^ The idealized size of chunks that will be yielded downstream.
                   -> Integer
                      -- ^ The size of the stream in bytes.
-                  -> Source (ResourceT IO) ByteString
+                  -> ConduitM () ByteString (ResourceT IO) ()
                   -> RqBody
 unsafeChunkedBody chunk size = Chunked . ChunkedBody chunk size
 
 sourceFileChunks :: MonadResource m
                  => ChunkSize
                  -> FilePath
-                 -> Source m ByteString
+                 -> ConduitM () ByteString m ()
 sourceFileChunks (ChunkSize chunk) path =
     bracketP (openBinaryFile path ReadMode) hClose go
   where
@@ -153,7 +152,7 @@
                          -- ^ The byte offset at which to start reading.
                       -> Integer
                          -- ^ The maximum number of bytes to read.
-                      -> Source m ByteString
+                      -> ConduitM () ByteString m ()
 sourceFileRangeChunks (ChunkSize chunk) path offset len =
     bracketP acquire hClose seek
   where
@@ -173,15 +172,15 @@
                 go (remainder - chunk) hd
 
 -- | Incrementally calculate a 'MD5' 'Digest'.
-sinkMD5 :: Monad m => Consumer ByteString m (Digest MD5)
+sinkMD5 :: Monad m => ConduitM ByteString o m (Digest MD5)
 sinkMD5 = sinkHash
 
 -- | Incrementally calculate a 'SHA256' 'Digest'.
-sinkSHA256 :: Monad m => Consumer ByteString m (Digest SHA256)
+sinkSHA256 :: Monad m => ConduitM ByteString o m (Digest SHA256)
 sinkSHA256 = sinkHash
 
 -- | A cryptonite compatible incremental hash sink.
-sinkHash :: (Monad m, HashAlgorithm a) => Consumer ByteString m (Digest a)
+sinkHash :: (Monad m, HashAlgorithm a) => ConduitM ByteString o m (Digest a)
 sinkHash = sink hashInit
   where
     sink ctx = do
diff --git a/src/Network/AWS/Internal/HTTP.hs b/src/Network/AWS/Internal/HTTP.hs
--- a/src/Network/AWS/Internal/HTTP.hs
+++ b/src/Network/AWS/Internal/HTTP.hs
@@ -6,10 +6,11 @@
 {-# LANGUAGE RecordWildCards   #-}
 {-# LANGUAGE TypeFamilies      #-}
 {-# LANGUAGE ViewPatterns      #-}
+{-# LANGUAGE CPP #-} -- b/w compat for http-client < 2.3.0
 
 -- |
 -- Module      : Network.AWS.Internal.HTTP
--- Copyright   : (c) 2013-2017 Brendan Hay
+-- Copyright   : (c) 2013-2018 Brendan Hay
 -- License     : Mozilla Public License, v. 2.0.
 -- Maintainer  : Brendan Hay <brendan.g.hay+amazonka@gmail.com>
 -- Stability   : provisional
@@ -22,10 +23,11 @@
 
 import Control.Arrow                (first)
 import Control.Monad
-import Control.Monad.Catch
+import Control.Monad.Catch (MonadThrow)
 import Control.Monad.Reader
 import Control.Monad.Trans.Resource
 import Control.Retry
+import Control.Exception (Handler(Handler), catches)
 
 import Data.List   (intersperse)
 import Data.Monoid
@@ -39,8 +41,12 @@
 import Network.AWS.Prelude
 import Network.AWS.Waiter
 import Network.HTTP.Conduit        hiding (Proxy, Request, Response)
+#if MIN_VERSION_http_conduit(2, 3, 0)
+#else
+import Data.Conduit (unwrapResumable, addCleanup)
+#endif
 
-retrier :: ( MonadCatch m
+retrier :: ( MonadThrow m
            , MonadResource m
            , MonadReader r m
            , HasEnv r
@@ -76,7 +82,7 @@
           , "attempts."
           ]
 
-waiter :: ( MonadCatch m
+waiter :: ( MonadThrow m
           , MonadResource m
           , MonadReader r m
           , HasEnv r
@@ -116,11 +122,11 @@
           ]
 
 -- | The 'Service' is configured + unwrapped at this point.
-perform :: (MonadCatch m, MonadResource m, AWSRequest a)
+perform :: (MonadThrow m, MonadResource m, AWSRequest a)
         => Env
         -> Request a
         -> m (Either Error (Response a))
-perform Env{..} x = catches go handlers
+perform Env{..} x = liftIO $ catches (runResourceT go) handlers
   where
     go = do
         t           <- liftIO getCurrentTime
@@ -131,8 +137,15 @@
         logTrace _envLogger m  -- trace:Signing:Meta
         logDebug _envLogger rq -- debug:ClientRequest
 
+#if MIN_VERSION_http_conduit(2, 3, 0)
         rs          <- liftResourceT (http rq _envManager)
-
+#else
+        rs'         <- liftResourceT (http rq _envManager)
+        let resSrc   = responseBody rs'
+        (src', fin) <- unwrapResumable resSrc
+        let src = addCleanup (const fin) src'
+        let rs  = src <$ rs'
+#endif
         logDebug _envLogger rs -- debug:ClientResponse
 
         Right <$> response _envLogger (_rqService x) (p x) rs
diff --git a/src/Network/AWS/Internal/Logger.hs b/src/Network/AWS/Internal/Logger.hs
--- a/src/Network/AWS/Internal/Logger.hs
+++ b/src/Network/AWS/Internal/Logger.hs
@@ -2,7 +2,7 @@
 
 -- |
 -- Module      : Network.AWS.Internal.Logger
--- Copyright   : (c) 2013-2017 Brendan Hay
+-- Copyright   : (c) 2013-2018 Brendan Hay
 -- License     : Mozilla Public License, v. 2.0.
 -- Maintainer  : Brendan Hay <brendan.g.hay+amazonka@gmail.com>
 -- Stability   : provisional
@@ -39,7 +39,7 @@
 --
 -- /Note:/ A more sophisticated logging library such as
 -- <http://hackage.haskell.org/package/tinylog tinylog> or
--- <http://hackage.haskell.org/package/FastLogger fast-logger>
+-- <http://hackage.haskell.org/package/fast-logger fast-logger>
 -- should be used in production code.
 newLogger :: MonadIO m => LogLevel -> Handle -> m Logger
 newLogger x hd = liftIO $ do
diff --git a/src/Network/AWS/Presign.hs b/src/Network/AWS/Presign.hs
--- a/src/Network/AWS/Presign.hs
+++ b/src/Network/AWS/Presign.hs
@@ -2,7 +2,7 @@
 
 -- |
 -- Module      : Network.AWS.Presign
--- Copyright   : (c) 2013-2017 Brendan Hay
+-- Copyright   : (c) 2013-2018 Brendan Hay
 -- License     : Mozilla Public License, v. 2.0.
 -- Maintainer  : Brendan Hay <brendan.g.hay+amazonka@gmail.com>
 -- Stability   : provisional
@@ -18,10 +18,12 @@
 import           Control.Monad
 import           Control.Monad.IO.Class
 import           Network.AWS.Data.Time
-import           Network.AWS.Lens       ((%~), (&))
+import           Network.AWS.Lens         ((%~), (&))
 import           Network.AWS.Prelude
-import           Network.AWS.Request    (requestURL)
+import           Network.AWS.Request      (requestURL)
 import           Network.AWS.Types
+import           Network.AWS.Data.Headers (hExpect)
+import           Network.HTTP.Types       (Header)
 
 -- | Presign an URL that is valid from the specified time until the
 -- number of seconds expiry has elapsed.
@@ -39,7 +41,7 @@
 -- | Presign an HTTP request that is valid from the specified time until the
 -- number of seconds expiry has elapsed.
 --
--- /See:/ 'presignWith'
+-- /See:/ 'presignWith', 'presignWithHeaders'
 presign :: (MonadIO m, AWSRequest a)
         => Auth
         -> Region
@@ -51,6 +53,8 @@
 
 -- | A variant of 'presign' that allows modifying the default 'Service'
 -- definition used to configure the request.
+--
+-- /See:/ 'presignWithHeaders'
 presignWith :: (MonadIO m, AWSRequest a)
             => (Service -> Service) -- ^ Modify the default service configuration.
             -> Auth
@@ -59,7 +63,25 @@
             -> Seconds              -- ^ Expiry time.
             -> a                    -- ^ Request to presign.
             -> m ClientRequest
-presignWith f a r ts ex x =
+presignWith = presignWithHeaders defaultHeaders
+
+-- | Modification to the headers that is applied by default (in 'presignWith');
+-- removes the "Expect" header which is added to every 'PutObject'.
+defaultHeaders :: [Header] -> [Header]
+defaultHeaders = filter ((/= hExpect) . fst)
+
+-- | A variant of 'presign' that allows modifying the default 'Headers'
+-- and the default 'Service' definition used to configure the request.
+presignWithHeaders :: (MonadIO m, AWSRequest a)
+            => ([Header] -> [Header]) -- ^ Modify the default headers.
+            -> (Service -> Service) -- ^ Modify the default service configuration.
+            -> Auth
+            -> Region
+            -> UTCTime              -- ^ Signing time.
+            -> Seconds              -- ^ Expiry time.
+            -> a                    -- ^ Request to presign.
+            -> m ClientRequest
+presignWithHeaders f g a r ts ex x =
     withAuth a $ \ae ->
         return $! sgRequest $
-            rqPresign ex (request x & rqService %~ f) ae r ts
+            rqPresign ex (request x & rqHeaders %~ f & rqService %~ g) ae r ts
diff --git a/test/Main.hs b/test/Main.hs
--- a/test/Main.hs
+++ b/test/Main.hs
@@ -1,5 +1,5 @@
 -- Module      : Main
--- Copyright   : (c) 2013-2017 Brendan Hay
+-- Copyright   : (c) 2013-2018 Brendan Hay
 -- License     : Mozilla Public License, v. 2.0.
 -- Maintainer  : Brendan Hay <brendan.g.hay+amazonka@gmail.com>
 -- Stability   : experimental
