Skip to content

grpc-web allow custom setting custom cors headers #237

@AleksandarFilipov

Description

@AleksandarFilipov

With the introduction of grpc-web, web browsers can access the services. Given the CORS nature of web clients, they will likely be blocked if the accessing web-client is hosted separately.

Issue braked out as suggested by @polvalente see linked issue below, which also suggests a temporary workaround shown here AleksandarFilipov/grpc-elixir@feature/grpc-web-cors...grpc-web-cors-custom.

@AleksandarFilipov I think we could use the interceptors in a similar way to how Tesla modifies the current response given the result of next.(stream, req)

https://github.com/elixir-tesla/tesla/blob/master/lib/tesla/middleware/compression.ex

In this example, they decide if the resp body needs to be decompressed based on the result tuple tag. We can provide a custom interceptor that injects response headers based on a predicate MFA tuple (that receives the stream and returns true if the headers should be injected). Something like:

defmodule MyServer do
  use GRPC.Endpoint

  intercept GRPC.Interceptors.ResponseHeaders, should_inject: {__MODULE__, :"add_cors?", 1}, headers: [{"Access-Control-Allow-Origin", "*"}, {"Access-Control-Allow-Headers", "Content-Type, x-grpc-web, x-user-agent"}]

  def add_cors?(...), do: ...
end

The one thing that might need to change (I'm not that familiar with the code base yet) is that this only works if intercepts are called before stream_reply.

I'm almost sure that intercepts are only called after the reply, though. If so, we'll need to introduce something like reply_intercept that will be called right before the reply, but the overall idea remains the same.
This idea would allow us to remove the Codec from the server_headers match as well, while still allowing us to modify the headers (the whole connection, really), as we see fit.

Shall we move this into a new issue?

Originally posted by @polvalente in #206 (comment)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions