Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unix domain socket #756

Open
jacobwgillespie opened this issue Aug 14, 2023 · 5 comments
Open

Unix domain socket #756

jacobwgillespie opened this issue Aug 14, 2023 · 5 comments
Labels
enhancement New feature or request

Comments

@jacobwgillespie
Copy link

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.

@jacobwgillespie jacobwgillespie added the enhancement New feature or request label Aug 14, 2023
@timostamm
Copy link
Member

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.

@jacobwgillespie
Copy link
Author

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>

@timostamm
Copy link
Member

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.

@jacobwgillespie
Copy link
Author

jacobwgillespie commented Aug 31, 2023

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?

@caleblloyd
Copy link

Yup, I can confirm that this works on Linux. Using @connectrpc/connect-node version 2.0.0-alpha1

import { createGrpcTransport } from "@connectrpc/connect-node";
import { connect as nodeConnect } from "node:net";

const socket = "/path/to/socket"
const transport = createGrpcTransport({
  httpVersion: "2",
  baseUrl: "http://socket.localhost", // not a real URL, socket is in nodeOptions.createConnection
  nodeOptions: {
    createConnection: () => {
      return nodeConnect(socket)
    },
  },
})

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants