gRPC HTTP/1.1 reverse bridge

This is a filter that enables converting an incoming gRPC request into a HTTP/1.1 request to allow a server that does not understand HTTP/2 or HTTP/3 or gRPC semantics to handle the request.

The filter works by:

  • Checking the content type of the incoming request. If it’s a gRPC request, the filter is enabled.

  • The content type is modified to a configurable value. This can be a noop by configuring application/grpc.

  • The gRPC frame header is optionally stripped from the request body. The content length header will be adjusted if so.

  • On receiving a response, the content type of the response is validated and the status code is mapped to a grpc-status which is inserted into the response trailers.

  • The response body is optionally prefixed by the gRPC frame header, again adjusting the content length header if necessary.

Due to being mapped to HTTP/1.1, this filter will only work with unary gRPC calls.

gRPC frame header management

By setting the withhold_grpc_frame option, the filter will assume that the upstream does not understand any gRPC semantics and will convert the request body into a simple binary encoding of the request body and perform the reverse conversion on the response body. This ends up simplifying the server side handling of these requests, as they no longer need to be concerned with parsing and generating gRPC formatted data.

This works by stripping the gRPC frame header from the request body, while injecting a gRPC frame header in the response.

If this feature is not used, the upstream must be ready to receive HTTP/1.1 requests prefixed with the gRPC frame header and respond with gRPC formatted responses.

How to disable HTTP/1.1 reverse bridge filter per route

  1. admin:
  2. address:
  3. socket_address:
  4. address: 0.0.0.0
  5. port_value: 9901
  6. static_resources:
  7. listeners:
  8. - name: listener_0
  9. address:
  10. socket_address:
  11. address: 0.0.0.0
  12. port_value: 80
  13. filter_chains:
  14. - filters:
  15. - name: envoy.filters.network.http_connection_manager
  16. typed_config:
  17. "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
  18. access_log:
  19. - name: envoy.access_loggers.stdout
  20. typed_config:
  21. "@type": type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog
  22. stat_prefix: ingress_http
  23. route_config:
  24. name: local_route
  25. virtual_hosts:
  26. - name: local_service
  27. domains: ["*"]
  28. routes:
  29. - match:
  30. prefix: "/route-with-filter-disabled"
  31. route:
  32. host_rewrite_literal: localhost
  33. cluster: grpc
  34. timeout: 5.00s
  35. # per_filter_config disables the filter for this route
  36. typed_per_filter_config:
  37. envoy.filters.http.grpc_http1_reverse_bridge:
  38. "@type": type.googleapis.com/envoy.extensions.filters.http.grpc_http1_reverse_bridge.v3.FilterConfigPerRoute
  39. disabled: true
  40. - match:
  41. prefix: "/route-with-filter-enabled"
  42. route:
  43. host_rewrite_literal: localhost
  44. cluster: other
  45. timeout: 5.00s
  46. http_filters:
  47. - name: envoy.filters.http.grpc_http1_reverse_bridge
  48. typed_config:
  49. "@type": type.googleapis.com/envoy.extensions.filters.http.grpc_http1_reverse_bridge.v3.FilterConfig
  50. content_type: application/grpc+proto
  51. withhold_grpc_frames: true
  52. - name: envoy.filters.http.router
  53. clusters:
  54. - name: other
  55. type: LOGICAL_DNS
  56. dns_lookup_family: V4_ONLY
  57. lb_policy: ROUND_ROBIN
  58. load_assignment:
  59. cluster_name: some_service
  60. endpoints:
  61. - lb_endpoints:
  62. - endpoint:
  63. address:
  64. socket_address:
  65. address: localhost
  66. port_value: 4630
  67. - name: grpc
  68. type: STRICT_DNS
  69. lb_policy: ROUND_ROBIN
  70. typed_extension_protocol_options:
  71. envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
  72. "@type": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
  73. explicit_http_config:
  74. http2_protocol_options: {}
  75. load_assignment:
  76. cluster_name: grpc
  77. endpoints:
  78. - lb_endpoints:
  79. - endpoint:
  80. address:
  81. socket_address:
  82. address: localhost
  83. port_value: 10005