Envoy: route.HeaderMatcher present_match is invalid

Created on 18 Feb 2020  路  4Comments  路  Source: envoyproxy/envoy

Title: route.HeaderMatcher present_match is invalid

Description:

I tried to use HeaderMatch in the routing configuration, the request header name is x-ams-namespace. Whether I set present_match true or false, it only filters requests that have x-ams-namespace. If there is no x-ams-namespace in the header, the envoy log shows no match cluster

Repro steps:

the environment

Config:

here is my route config

route_config:
    name: local_route
    virtual_hosts:
      - name: local_service
        domains: ["*"]
        routes:
          - match:
              prefix: "/ams.demo.HelloWorldService"
              grpc: {}
              headers:
                - name: "x-ams-namespace"
                  present_match: false
            route:
              cluster: default-service

Logs:

this is the log containing the x-ams-namespace request header

[2020-02-18 02:20:54.192][12][debug][http] [source/common/http/conn_manager_impl.cc:731] [C0][S9768922037303758833] request headers complete (end_stream=false):
':path', '/ams.demo.HelloWorldService/SayHello'
':method', 'POST'
':scheme', 'https'
'content-type', 'application/grpc'
'te', 'trailers'
'user-agent', 'grpc-java-netty/1.27.0'
'x-ams-namespace', 't2est'
'grpc-accept-encoding', 'gzip'
'grpc-timeout', '999706u'

[2020-02-18 02:20:54.192][12][debug][router] [source/common/router/router.cc:474] [C0][S9768922037303758833] cluster 'default-service' match for URL '/ams.demo.HelloWorldService/SayHello'
[2020-02-18 02:20:54.192][12][debug][router] [source/common/router/router.cc:614] [C0][S9768922037303758833] router decoding headers:

this is the log that does not contain the x-ams-namespace request header

[2020-02-18 02:20:57.938][12][debug][http] [source/common/http/conn_manager_impl.cc:731] [C1][S2265561003369121236] request headers complete (end_stream=false):
':path', '/ams.demo.HelloWorldService/SayHello'
':method', 'POST'
':scheme', 'https'
'content-type', 'application/grpc'
'te', 'trailers'
'user-agent', 'grpc-java-netty/1.27.0'
'grpc-accept-encoding', 'gzip'
'grpc-timeout', '999638u'

[2020-02-18 02:20:57.938][12][debug][router] [source/common/router/router.cc:412] [C1][S2265561003369121236] no cluster match for URL '/ams.demo.HelloWorldService/SayHello'
[2020-02-18 02:20:57.938][12][debug][http] [source/common/http/conn_manager_impl.cc:1417] [C1][S2265561003369121236] Sending local reply with details route_not_found
question

Most helpful comment

@wcmolin because the configuration language protobuf doesn't differentiate whether a bool is not set or false, so present_match: false is a no-op. As documented in https://www.envoyproxy.io/docs/envoy/latest/api-v2/api/v2/route/route_components.proto#route-headermatcher, by default the header matcher will be performed as present_match, because no other match are set.

All 4 comments

Is invert_match what you want? try:

route_config:
    name: local_route
    virtual_hosts:
      - name: local_service
        domains: ["*"]
        routes:
          - match:
              prefix: "/ams.demo.HelloWorldService"
              grpc: {}
              headers:
                - name: "x-ams-namespace"
                  present_match: true
                  invert_match: true
            route:
              cluster: default-service

@lizan
forgive my poor english.

your suggestion is useful, but I don't want to use invert_match, just present_match.

I tried to set present_match to true, and then a request with a header 'x-ams-namespace'matched to the cluster. Next, I changed present_match to false, restarted the envoy, and again sent a request with the same header, but it still matched to the cluster. Why did present_match set to true and false give the same result

@wcmolin because the configuration language protobuf doesn't differentiate whether a bool is not set or false, so present_match: false is a no-op. As documented in https://www.envoyproxy.io/docs/envoy/latest/api-v2/api/v2/route/route_components.proto#route-headermatcher, by default the header matcher will be performed as present_match, because no other match are set.

ok, thanks

Was this page helpful?
0 / 5 - 0 ratings