question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Allow passing of metadata to websocket transport upgrade request

See original GitHub issue

Version

0.12.0

What happened

URL with the query string at the end got the protobuf package/service/method appended at the end

wss://localhost:7778/ws?access_token=XXXXXXX/hello.HelloService/SayHello

Expected

URL would be constructed correctly, e.g:

wss://localhost:7778/ws/hello.HelloService/SayHello?access_token=XXXXXXX

How to reproduce it (as minimally and precisely as possible):

       grpc.invoke(HelloService.SayHello, {
        request :helloRequest,
        host : "https://localhost:7778/ws?access_token=XXXXXXX",

What I was trying to do: I was exploring the possibilities of passing the OAuth2 token as query parameter, to be consumed by the API Gateway fronting the grpcwebproxy.

I believe that client.ts does somewhat optimistic URL building:

    const url = `${this.props.host}/${this.methodDefinition.service.serviceName}/${this.methodDefinition.methodName}`;

I understand that “host” is normally expected to be the host, but, in fact, everywhere in the code and the documentation it looks like a URL, e.g. schema://host:port at least.

Thus, I believe, it won’t hurt if instead of simple concatenation, the value of this.props.host is first parsed as URL, then the path it modified, then the final URL is serialized.

Issue Analytics

  • State:open
  • Created 4 years ago
  • Comments:15

github_iconTop GitHub Comments

1reaction
ngrigorievcommented, Feb 20, 2020

I disagree. Metadata works fine for anything BUT websocket protocol. In case of websocket, as far as I understand, the gRPC metadata is passes after the connection upgrade. You are ignoring the fact that the typical deployment pattern is to use an API Gateway (any one) and usually it is the API Gateway that takes care of the cross-service tasks, including authorization. As long as there is a way to pass the bearer token in the original HTTP request handled by the API Gateway, I would be happy. By Websocket API does not leave too many options.

API Gateway would strip these values and grpcwebproxy would receive the request it expects.

The specification you are pointing to does not explicitely forbid, I think, using of the query strings. It should ignore them, of course. Just like it ignores, for example, the headers it does not understand. Just like it ignores the host name.

I still suggest to fix this code and at least make it correct from common practice point of view, URLs are not constructed by concatenating the strings.

There is a difference between the Websocket endpoint on the client side (URL that the browser connects to) and the API exposed by grpcwebproxy. They do not have to be absolutely the same, as long as the RFC compliance is preserved.

By the way, even today I can use a prefix (like “/ws”) on my API Gateway to have a separate endpoint for Websocket access. With different rules etc. And the gateway strips off the prefix when forwarding this request to the upstream (grpcwebproxy).

1reaction
johanbrandhorstcommented, Feb 20, 2020

Hi Nikolai,

Thanks for your bug report. I think we should take a step back and find a different solution to this than your proposed one. There is already a well defined method for passing arbitrary data down from the client to the server, and that is with grpc metadata. See https://github.com/improbable-eng/grpc-web/blob/master/client/grpc-web-react-example/ts/_proto/examplecom/library/book_service_pb_service.d.ts#L65 for an example of how to pass this information to the server. I do not think we want to make query parameters globally configurable like this. Please consult the grpc-web spec for more information: https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-WEB.md.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Subscriptions in Apollo Server - Apollo GraphQL Docs
Enabling subscriptions ; 1. // Creating the WebSocket server ; 2. const wsServer = new WebSocketServer({ ; 3. // This is the `httpServer`...
Read more >
RFC 6455: The WebSocket Protocol
To this end, the WebSocket client's handshake is an HTTP Upgrade request: GET /chat HTTP/1.1 Host: server.example.com Upgrade: websocket Connection: Upgrade ...
Read more >
Browser APIs and Protocols: WebSocket
WebSocket is the only transport that allows bidirectional communication over the same TCP connection (Figure 17-2): the client and server can exchange messages ......
Read more >
The WebSocket protocol - IETF Datatracker
The "Request-URI" of the GET method [RFC2616] is used to identify the endpoint of the WebSocket connection, both to allow multiple domains to...
Read more >
WebSockets - A Conceptual Deep Dive - Ably Realtime
HTTP/1.1 101 Web Socket Protocol Handshake Upgrade: WebSocket Connection: Upgrade Sec-WebSocket-Accept: m9raz0Lr21hfqAitCxWigVwhppA=.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found