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.
@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)
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.
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 https://github.com/AleksandarFilipov/grpc-elixir/compare/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:
The one thing that might need to change (I'm not that familiar with the code base yet) is that this only works if
intercept
s are called beforestream_reply
.I'm almost sure that
intercepts
are only called after the reply, though. If so, we'll need to introduce something likereply_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 theserver_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 https://github.com/elixir-grpc/grpc/issues/206#issuecomment-1186731225