Skip to content

Attempting to request from local unix socket with Swift 6.0 snapshot results in a "no such file or directory" error #767

@xtremekforever

Description

@xtremekforever

Consider the following sample code:

import AsyncHTTPClient
import Foundation

let client = HTTPClient()
defer {
    _ = client.shutdown()
}

let request = try HTTPClient.Request(
    url: URL(httpURLWithSocketPath: "/var/run/docker.sock", uri: "/_ping")!,
    method: .GET,
    headers: [
        "Host": "localhost"
    ]
)
print("Sending request: \(request)")
let response = try await client.execute(request: request).get()
print("Got response: \(response)")

When I run this with the latest Swift 6.0 snapshot (2024-08-22), it throws an error about "no such file or directory:

Sending request: Request(method: NIOHTTP1.HTTPMethod.GET, url: http+unix://%2Fvar%2Frun%2Fdocker.sock/_ping, headers: [("Host", "localhost")], body: nil, tlsConfiguration: nil, deconstructedURL: AsyncHTTPClient.DeconstructedURL(scheme: AsyncHTTPClient.Scheme.httpUnix, connectionTarget: AsyncHTTPClient.ConnectionTarget.unixSocket(path: "%2Fvar%2Frun%2Fdocker.sock"), uri: "/_ping"))
Swift/ErrorType.swift:253: Fatal error: Error raised at top level: connect(descriptor:addr:size:): No such file or directory (errno: 2)

This seems to be unique to Swift 6.0, because when I try to run the same code with a 5.10.1 toolchain, I get a successful result:

Sending request: Request(method: NIOHTTP1.HTTPMethod.GET, url: http+unix://%2Fvar%2Frun%2Fdocker.sock/_ping, headers: [("Host", "localhost")], body: nil, tlsConfiguration: nil, deconstructedURL: AsyncHTTPClient.DeconstructedURL(scheme: AsyncHTTPClient.Scheme.httpUnix, connectionTarget: AsyncHTTPClient.ConnectionTarget.unixSocket(path: "/var/run/docker.sock"), uri: "/_ping"))
Got response: Response(host: "", status: 200 OK, version: HTTP/1.1, headers: [("Api-Version", "1.47"), ("Builder-Version", "2"), ("Cache-Control", "no-cache, no-store, must-revalidate"), ("Docker-Experimental", "false"), ("Ostype", "linux"), ("Pragma", "no-cache"), ("Server", "Docker/27.2.0 (linux)"), ("Swarm", "inactive"), ("Date", "Fri, 30 Aug 2024 13:05:07 GMT"), ("Content-Length", "2"), ("Content-Type", "text/plain; charset=utf-8")], body: Optional(ByteBuffer { readerIndex: 0, writerIndex: 2, readableBytes: 2, capacity: 2, storageCapacity: 2048, slice: _ByteBufferSlice { 316..<318 }, storage: 0x00007fffec00f900 (2048 bytes) }
readable bytes (max 1k): [ 4f 4b ]))

What could possibly be causing this issue? Could it be the new Foundation that works differently with URL? I notice that the unixSocket path looks different in both instances in the log output:

6.0: AsyncHTTPClient.ConnectionTarget.unixSocket(path: "%2Fvar%2Frun%2Fdocker.sock")
5.10.1: AsyncHTTPClient.ConnectionTarget.unixSocket(path: "/var/run/docker.sock")

Activity

changed the title [-]Attempting to requests from local unix socket with Swift 6.0 snapshot results in a "no such file or directory" error[/-] [+]Attempting to request from local unix socket with Swift 6.0 snapshot results in a "no such file or directory" error[/+] on Aug 30, 2024
xtremekforever

xtremekforever commented on Aug 30, 2024

@xtremekforever
Author

Update: I found that if I change the .httpUnix/.httpsUnix deconstruction in Sources/AsyncHTTPClient/DeconstructedURL.swift to not use percent encoding it works:

        case .httpUnix, .httpsUnix:
            guard let socketPath = url.host(percentEncoded: false), !socketPath.isEmpty else {
                throw HTTPClientError.missingSocketPath
            }
            ...

So I'm going to venture that this has to do with some new default behavior in the new swift-foundation. Maybe it's an easy fix.

FranzBusch

FranzBusch commented on Sep 2, 2024

@FranzBusch
Collaborator

This is potentially a dupe of swiftlang/swift-foundation#863. @xtremekforever Do you mind checking if you can reproduce this with latest top of tree of swift-foundation? cc @jrflat

xtremekforever

xtremekforever commented on Sep 2, 2024

@xtremekforever
Author

This is potentially a dupe of swiftlang/swift-foundation#863. @xtremekforever Do you mind checking if you can reproduce this with latest top of tree of swift-foundation? cc @jrflat

Looks like this is exactly the issue. I can try to see if I can get the latest foundation- is it as simple as including swift-foundation as a dependency in Package.swift?

FranzBusch

FranzBusch commented on Sep 2, 2024

@FranzBusch
Collaborator

Looks like this is exactly the issue. I can try to see if I can get the latest foundation- is it as simple as including swift-foundation as a dependency in Package.swift?

Not sure if that works. I was thinking to just checkout swift-foundation and write a quick test for URL that mimics what you are doing here.

xtremekforever

xtremekforever commented on Sep 2, 2024

@xtremekforever
Author

Looks like including it in Package.swift worked. I used the following dependencies:

    dependencies: [
        .package(url: "https://github.com/swift-server/async-http-client.git", from: "1.9.0"),
        .package(url: "https://github.com/apple/swift-foundation.git", branch: "main"),
    ],

And now my example works exactly as it should without the behavior seen in this issue. Do you think this fix that's on main will be included in 6.0 eventually? It is slated for the next snapshot for example?

FranzBusch

FranzBusch commented on Sep 3, 2024

@FranzBusch
Collaborator

@xtremekforever As far as I know yes that change should be included in the Swift 6.0 release. Thanks for confirming. Going to close this issue for now.

jrflat

jrflat commented on Sep 5, 2024

@jrflat

@xtremekforever Thanks for bringing this to our attention! I'm requesting this be cherry-picked to 6.0 in swiftlang/swift-foundation#903

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @xtremekforever@FranzBusch@jrflat

        Issue actions

          Attempting to request from local unix socket with Swift 6.0 snapshot results in a "no such file or directory" error · Issue #767 · swift-server/async-http-client