connectrpc / connect-es

The TypeScript implementation of Connect: Protobuf RPC that works.

Home Page:https://connectrpc.com/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Unix domain socket

jacobwgillespie opened this issue · comments

Is your feature request related to a problem? Please describe.

With other gRPC libraries, I'm able to connect to a gRPC server listening on a unix domain socket (e.g. unix:///path/to/server.sock).

Describe the solution you'd like

I don't think this is possible with createGrpcTransport() at the moment, but it would be awesome if it was.

Describe alternatives you've considered

At the moment, I have to use another gRPC client library - I'd prefer to use @bufbuild/connect instead.

Unfortunately, the Node.js http2 module does not support UDS out of the box. I assume that it's possible to support this, but it's likely not completely trivial.

In general, we aim to not replicate every gRPC feature, and rely on the standard library of the underlying platform. If Node.js were to support UDS in http2.connect, we'd be happy to make any necessary changes (I assume we'll need to treat baseUrl a bit differently).

If someone comes up with a reliable alternative to http2.connect - demonstrated with a code example - we would also be happy to integrate it, or accept contributions.

I may be missing something, but I believe http2 supports UDS. I copied this example from the docs and changed it to bind to a file instead of a port:

import * as http2 from 'node:http2'

const server = http2.createServer()

server.on('stream', (stream, headers) => {
  stream.respond({
    'content-type': 'text/html charset=utf-8',
    ':status': 200,
  })
  stream.end('<h1>Hello World</h1>')
})

// server.listen(8000)
server.listen('./example.sock')
$ curl -v --http2-prior-knowledge --unix-socket ./example.sock http://test
*   Trying ./example.sock:0...
* Connected to test (./example.sock) port 80 (#0)
* h2h3 [:method: GET]
* h2h3 [:path: /]
* h2h3 [:scheme: http]
* h2h3 [:authority: test]
* h2h3 [user-agent: curl/7.88.1]
* h2h3 [accept: */*]
* Using Stream ID: 1 (easy handle 0x13d80a800)
> GET / HTTP/2
> Host: test
> user-agent: curl/7.88.1
> accept: */*
>
< HTTP/2 200
< content-type: text/html; charset=utf-8
< date: Thu, 31 Aug 2023 08:56:53 GMT
<
* Connection #0 to host test left intact
<h1>Hello World</h1>

I'm glad you brought up the example, Jacob - I should have been more precise. Yes, you can listen to an UDS with an http2 server (it's a method inherited from net). There is no equivalent for H2 clients though - http2.connect only accepts URLs with the http or https scheme out of the box, see here.

Ah, fun. So it looks like createConnection exists in http2.ClientSessionOptions, this appears to work:

http2.connect('http://example', {
  createConnection: (authority, option) => {
    return net.connect('./example.sock');
  },
})

It looks like it's also possible to pass that as an option to new Http2SessionManager(..., ..., {createConnection}) - perhaps that would just work?