Debugging HTTPBody
Question
I'm trying to do what I do in most of my apps: add a button that, when tapped, copies request url, request headers, request body, response headers, response body, etc to the clipboard so that it can be shared with developers for further debugging. This is used when a user has issues with failing url requests on a device the developer might not have access to.
Typically I use https://github.com/pmusolino/Wormholy or https://github.com/kean/Pulse for this as they take care of all this for me. But when used with swift-openapi-urlsession, results are mixed: while the requests are listed, and contain most information such as headers and parameters, the tools have troubles picking up request data, and sometimes even response data. Taking a look at the code of swift-openapi-urlsession, I assume this is because swift-openapi-urlsession does fancy bi-directional stream sending and receiving instead of the basic way that is more commonly used?
So I set myself a breakpoint at func bidirectionalStreamingRequest to po requestBody - but this doesn't provide any useful debug representation. I then thought of using po String(collecting: requestBody!, upTo: 1024) but that fails too because collecting is an async function, so doesn't play well with lldb (or at least I can't figure out how to quickly do so).
Could something be done to make it easier to debug HTTPBody - for example a non async function that spits out the HTTPBody to be used for debugging only?
Would a PR for swift-openapi-urlsession that optionally just uses the basic non streaming versions of sending/receiving data be a welcome addition, so that tools such as wormholy or pulse would work? I'm not sure how feasible it is to add bi-directional streaming support to wormholy or pulse... Or is the issue somewhere else and do I have it all wrong? :)
Hi @hactar,
if the existing tools don't support full end-to-end streaming, which the URLSession transport is built on, you should be able to build what you need using a middleware.
Since HTTPBody is an async sequence of byte chunks, you first need to buffer it, then you can stash the copy of the bytes where you need, and finally you need to return the bytes in a new HTTPBody from the middleware.
Something like this: https://github.com/apple/swift-openapi-generator/blob/755c0ec69bd667aa4e8ba50c8b710585d302879e/Examples/logging-middleware-swift-log-example/Sources/LoggingMiddleware/LoggingMiddleware.swift#L150
Thanks! I noticed that its already technically possible to use buffered mode, but that the choice was not public. I have created a PR to expose this and so make swift-openapi-urlsession compatible if a developer needs that.
My second question still would remain however: when debugging via lldb, is there a way a developer can see the String contents of the data during debugging?
My second question still would remain however: when debugging via lldb, is there a way a developer can see the String contents of the data during debugging?
Depends on whether the response is truly streaming all the way, or if it's a content type that requires buffering before processing, like JSON. If this is for JSON/Codable, you can put a breakpoint here and print the buffered bytes before they're handed to JSONDecoder: https://github.com/apple/swift-openapi-runtime/blob/e1c9d542d82ca6546dcbb44a3402e425cfae0c66/Sources/OpenAPIRuntime/Conversion/CurrencyExtensions.swift#L137
To answer your more general question - no it's not possible to print the String contents of HTTPBody, because it's an async sequence (the bytes might not have been delivered yet). Similar how for an async sequence of arbitrary elements can't be easily printed until you've e.g. collected all the elements in an array.
@czechboy0 Thanks!