Packages
unleash_fresha
3.0.1
5.1.4
5.1.3
5.1.2
5.1.1
5.1.0
5.0.0
4.0.0
4.0.0-git-bda3
3.0.1
3.0.0
2.1.0
2.0.1
2.0.0-git-75d8
2.0.0-git-67b2
2.0.0-git-4b61
2.0.0-git-49f4
1.16.0
1.15.0
1.14.1-git-e754
1.14.0
1.14.0-git-71e9
1.13.0
1.13.0-git-4ba6
1.12.0
1.11.0
1.11.0-git-1b62
1.10.2
1.10.2-git-b835
1.10.1
1.10.0
1.9.3-alpha0
1.9.2
1.9.1
1.9.0
An Unleash Feature Flag client for Elixir, forked from [unleash](https://gitlab.com/afontaine/unleash_ex)
Current section
Files
Jump to
Current section
Files
lib/propagation/grpc/context_server_interceptor.ex
defmodule Unleash.Propagation.GRPC.ContextServerInterceptor do
@moduledoc """
A GRPC Server Interceptor to extract unleash context and overrides
from incoming GRPC request headers and store them for feature flag checks
and further propagation downstream (e.g. via `Unleash.Propagation.GRPC.ContextClientInterceptor`).
See `Unleash.Propagation` for more details on the propagation mechanism.
Note that, contrarily to the ContextClientInterceptor, this interceptor does not raise
in case of invalid context or overrides in the gRPC request headers.
The difference is due to the nature of the data: in here, it's dynamic input data,
beyond our control. Invalid data is expected and we should handle it gracefully.
"""
@behaviour GRPC.ServerInterceptor
alias Unleash.Propagation
alias Unleash.Propagation.Serialization
require Logger
@context_header_name "x-unleash-context"
@overrides_header_name "x-unleash-overrides"
@impl true
def init(_), do: nil
@impl true
def call(req, stream, next, _opts) do
headers = GRPC.Stream.get_headers(stream)
parse_and_store_context(Map.get(headers, @context_header_name))
parse_and_store_overrides(Map.get(headers, @overrides_header_name))
next.(req, stream)
end
@spec parse_and_store_context(binary() | nil) :: :ok
defp parse_and_store_context(header_value)
defp parse_and_store_context(nil), do: :ok
defp parse_and_store_context(header_value) when is_binary(header_value) do
header_value
|> Serialization.deserialize_context()
|> case do
{:ok, context} ->
Propagation.put_context(context)
{:error, err} ->
Logger.error(
"Unleash gRPC server interceptor: failed to decode" <>
" incoming context: #{Exception.format(:error, err)}"
)
end
end
@spec parse_and_store_overrides(binary() | nil) :: :ok
defp parse_and_store_overrides(header_value)
defp parse_and_store_overrides(nil), do: :ok
defp parse_and_store_overrides(header_value) when is_binary(header_value) do
header_value
|> Serialization.deserialize_overrides()
|> case do
{:ok, overrides} ->
Propagation.put_overrides(overrides)
{:error, err} ->
Logger.error(
"Unleash gRPC server interceptor: failed to decode" <>
" incoming overrides: #{Exception.format(:error, err)}"
)
end
end
end