[gRPC-JSON transcoder] Request validation triggers 404 for CORS preflight OPTIONS requests
#17.148 aperta il 25 giu 2021
Metriche repository
- Star
- (27.997 star)
- Metriche merge PR
- (Merge medio 8g) (378 PR mergiate in 30 g)
Descrizione
Title: Request validation triggers 404 for CORS preflight OPTIONS requests
Description:
When a grpc-json transcoder is deployed with CORS enabled preflight (OPTIONS) requests fail if request validation is enabled. This likely happens because the transcoder attempts to validate the HTTP request's method before CORS, triggering an error as OPTIONS is not recognized as a valid "transcodable" method.
Repro steps:
Setup the grpc-json transcoder with request validation enabled and CORS rules and observe that when request_validation_options with reject_unknown_method is set CORS will fail with a 404 error:
cors:
allow_origin_string_match: [{ prefix: "*" }]
allow_methods: GET, PUT, DELETE, POST, PATCH, OPTIONS
allow_headers: authorization, keep-alive, user-agent, cache-control, content-type, content-transfer-encoding, x-accept-content-transfer-encoding, x-accept-response-streaming, x-user-agent, x-grpc-web, referer
expose_headers: grpc-status, grpc-message, x-envoy-upstream-service-time
allow_credentials: true
routes:
- match: { prefix: "/" }
route: { cluster: grpc, timeout: 60s }
request_validation_options:
reject_unknown_method: true
reject_unknown_query_parameters: true
Comment out or remove the request_validation_options block and observe that CORS preflight (OPTIONS) works again correctly:
# request_validation_options:
# reject_unknown_method: true
# reject_unknown_query_parameters: true
Config:
admin:
address:
socket_address: { address: 0.0.0.0, port_value: 9901 }
static_resources:
listeners:
- name: rest-listener
address:
socket_address: { address: 0.0.0.0, port_value: 8080 }
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: grpc_json
codec_type: AUTO
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains: ["*"]
cors:
allow_origin_string_match: [{ prefix: "*" }]
allow_methods: GET, PUT, DELETE, POST, PATCH, OPTIONS
allow_headers: authorization, keep-alive, user-agent, cache-control, content-type, content-transfer-encoding, x-accept-content-transfer-encoding, x-accept-response-streaming, x-user-agent, x-grpc-web, referer
expose_headers: grpc-status, grpc-message, x-envoy-upstream-service-time
allow_credentials: true
routes:
- match: { prefix: "/" }
route: { cluster: grpc, timeout: 60s }
http_filters:
- name: envoy.filters.http.cors
- name: envoy.filters.http.grpc_json_transcoder
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.grpc_json_transcoder.v3.GrpcJsonTranscoder
services:
- animeshon.crossrefs.v1alpha1.Referrer
# - google.iam.v1.IAMPolicy
- google.longrunning.Operations
print_options:
add_whitespace: true
always_print_enums_as_ints: false
always_print_primitive_fields: true
preserve_proto_field_names: false
request_validation_options:
reject_unknown_method: true
reject_unknown_query_parameters: true
convert_grpc_status: true
proto_descriptor: /etc/envoy/proto.bin
- name: envoy.filters.http.router
clusters:
- name: grpc
connect_timeout: 5s
type: LOGICAL_DNS
lb_policy: ROUND_ROBIN
dns_lookup_family: V4_ONLY
typed_extension_protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
"@type": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
explicit_http_config:
http2_protocol_options: {}
load_assignment:
cluster_name: grpc
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: host.docker.internal
port_value: 5000