URLSession "data(for request: URLRequest, delegate:) async throws -> (Data, URLResponse)" function migration?

Preface: I've been developing a Vapor Server in Swift 5.7 on my iMac, running the latest development binary (July 5th) on a linux machine (using AUR (en) - swift-bin-development).

The method "data(for request: URLRequest, delegate:) async throws -> (Data, URLResponse)" no longer exists in the URLSession, and I am writing here to figure out how to achieve the same thing without this function, or locate where it went in the new FoundationNetworking module (from GitHub - apple/swift-corelibs-foundation: The Foundation Project, providing core utilities, internationalization, and OS independence). I tried looking at the source code and other branches that support async-await for anything that can help me figure this out, but couldn't find a fix or workaround without reverting back to completion handlers (my project is deeply coded in async-await).

This is the final error I need to fix before production, and any help relating to this is greatly appreciated!

Edit:
I found some helpful links relating to this issue

2 Likes

That is tracked by SR-15187.
The (partial?) implementation by @David_Smith is #3036 which seems to be pending.
I'm not sure what we can do.

1 Like

As an aside you probably don't want to be using URLSession in a Vapor app. URLSession works well for a client with one user but it doesn't integrate with EventLoops, you don't get to take advantage of connection pooling and a host of other issues. You should use AsyncHTTPClient and Vapor provides that via req.client and app.client. It also has functions for decoding Content etc, using the same HTTPHeaders so I recommend just using that.

There's more info on the docs

3 Likes

I use the AsyncHTTPClient and AsyncResponseEncodable for client stuff along side actors for caching, but use URLSession for server stuff (web scraping, third-party API requests). I'll have to downgrade to 5.6 for now.

PS: thank you for you work on Vapor, I love and support the project (Leaf as-well) <3

Downgrading won't work - those APIs have never existed on Linux. You should not use URLSession at all in a server app (some exceptions apply). Use the client for third party API calls and scraping etc

2 Likes

I understand now; just converted to Vapor's Client, and everything builds and works as intended, except TLS. NIOSSL can't find my certificate files. I tried some hard-coded fixes, config changes, a server reboot, and even generated a new certificate, but nothing fixed it. The files were generated from Certbot (Let's Encrypt) as sudo, as required. I attached the stacktrace of the error + my new certificate paths.

Another Linux thing I guess?

How are you loading the certificates?

let liveKeysPath:String = Settings.Https.Certbot.getLiveKeysPath(), folder:String = Settings.Https.Certbot.getFolderPath() + liveKeysPath + "/"
        let certificatePath:String = folder + "cert.pem", privatekeyPath:String = folder + "privkey.pem"
        let chain:[NIOSSLCertificateSource] = try NIOSSLCertificate.fromPEMFile(certificatePath).map({ NIOSSLCertificateSource.certificate($0) })
        app.http.server.configuration.tlsConfiguration = .makeServerConfiguration(certificateChain: chain, privateKey: .file(privatekeyPath))

I got it to work by allowing read and executable access via chmod.

Thanks for your help! <3

I agree not for a server app but just for a normal commandline app that you would also like to test on linux it might be usefull that they are ported no?

1 Like

I agree. It would be nice to be able to write portable command lines apps in Swift that use URLSession.

1 Like