Skip to content

for debugging purposes, we should offer an option to switch on plain text .pcap recording #239

Open
@weissi

Description

@weissi

for debugging purposes, we should offer an option to switch on plain text .pcap recording.

It should be very clear that it's for debugging because NIOWritePCAPHandler.SynchronisedFileSink blocks the event loop (we could write an async file sink ofc)...

A pretty terrible patch that can serve as example (but not the final impl ofc) is here:

diff --git a/Package.swift b/Package.swift
index bce6b69..0575c2d 100644
--- a/Package.swift
+++ b/Package.swift
@@ -31,7 +31,7 @@ let package = Package(
         .target(
             name: "AsyncHTTPClient",
             dependencies: ["NIO", "NIOHTTP1", "NIOSSL", "NIOConcurrencyHelpers", "NIOHTTPCompression",
-                           "NIOFoundationCompat", "NIOTransportServices", "Logging"]
+                           "NIOFoundationCompat", "NIOTransportServices", "Logging", "NIOExtras"]
         ),
         .testTarget(
             name: "AsyncHTTPClientTests",
diff --git a/Sources/AsyncHTTPClient/ConnectionPool.swift b/Sources/AsyncHTTPClient/ConnectionPool.swift
index 46e0b61..03abfc3 100644
--- a/Sources/AsyncHTTPClient/ConnectionPool.swift
+++ b/Sources/AsyncHTTPClient/ConnectionPool.swift
@@ -20,6 +20,7 @@ import NIOHTTP1
 import NIOHTTPCompression
 import NIOTLS
 import NIOTransportServices
+import NIOExtras
 
 /// A connection pool that manages and creates new connections to hosts respecting the specified preferences
 ///
@@ -257,6 +258,10 @@ struct ConnectionKey: Hashable {
     }
 }
 
+let fileSink = try? NIOWritePCAPHandler.SynchronizedFileSink.fileSinkWritingToFile(path: "/tmp/ahc-\(getpid()).pcap") { error in
+    print("AHC ERROR: something went wrong creating the file sink: \(error)")
+}
+
 /// A connection provider of `HTTP/1.1` connections with a given `Key` (host, scheme, port)
 ///
 /// On top of enabling connection reuse this provider it also facilitates the creation
@@ -529,9 +534,22 @@ class HTTP1ConnectionProvider {
             let requiresSSLHandler = self.configuration.proxy != nil && self.key.scheme.requiresTLS
             let handshakePromise = channel.eventLoop.makePromise(of: Void.self)
 
+
             channel.pipeline.addSSLHandlerIfNeeded(for: self.key, tlsConfiguration: self.configuration.tlsConfiguration, addSSLClient: requiresSSLHandler, handshakePromise: handshakePromise)
 
+            func addWritePCAP() -> EventLoopFuture<Void> {
+                if let fileSink = fileSink {
+                    return channel.pipeline.addHandler(NIOWritePCAPHandler(mode: .client, fileSink: fileSink.write(buffer:)),
+                                                position: .last)
+                } else {
+                    return channel.eventLoop.makeSucceededFuture(())
+                }
+
+            }
+
             return handshakePromise.futureResult.flatMap {
+                addWritePCAP()
+            }.flatMap {
                 channel.pipeline.addHTTPClientHandlers(leftOverBytesStrategy: .forwardBytes)
             }.flatMap {
                 #if canImport(Network)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions