             }
         }
 
+    private static func extractBody(from request: URLRequest) -> Data?
+        {
+        if let data = request.httpBody
+            { return data }
+        if let stream = request.httpBodyStream
+            {
+            // adapted from https://forums.swift.org/t/pitch-make-inputstream-and-outputstream-methods-safe-and-swifty/23726
+            var buffer = [UInt8](repeating: 0, count: 65536)
+
+            stream.open()
+            defer { stream.close() }
+
+            let bytesRead = stream.read(&buffer, maxLength: buffer.count)
+            if bytesRead < 0
+                { fatalError("Unable to ready HTTP body stream: \(stream.streamError?.localizedDescription ?? "unknown error")") }
+            return Data(buffer.prefix(bytesRead))
+            }
+        return nil
+        }
+
     override func startLoading()
         {
         let stub = URLProtocol.property(forKey: stubPropertyKey, in: request) as! RequestStub

            defer
                { Self.requestInitialization.decrement() }

            let stubs = Self.stubs
            guard let stub = stubs.first(where: { $0.matcher.matches(request) }) else
                {
                fatalError(
                    """
                    Unstubbed network request:
                        \(request.httpMethod ?? "<nil method>") \(request.url?.absoluteString ?? "<nil URL>")
                        headers: \(request.allHTTPHeaderFields ?? [:])
                        body: \(request.httpBody?.description ?? "nil")

                    Available stubs:
                        \(stubs.map { $0.description }.joined(separator: "\n    "))

                key, value in
                request.allHTTPHeaderFields?[key] == value
                }
            && body?.httpData == requestBody
        }
    }

