Envoy: Cannot convert GET to POST in a filter

Created on 24 Mar 2017  路  11Comments  路  Source: envoyproxy/envoy

Currently filters can modify HeaderMap / Buffer in decode{Headers,Body,Trailers}, but the end_stream flag cannot be changed.

The use case for this is for REST-gRPC transcoding, when a gRPC method is mapped to HTTP GET, there is no API to convert it to POST (gRPC is always POST) with a request body in a filter.

enhancement

All 11 comments

Hmm. This is going to be quite complicated to fix. Let me think about this and maybe you and I can chat over VC briefly next week.

Sounds good.

@lizan can you clarify a bit more on the flows you need here? I assume that you need basically this:

  • Conversion filter receives decodeHeaders(headers, true) // header only get
  • You want to convert GET to POST, and add a body.
  • You want router/other filters to see:

    • decodeHeaders(headers, false)

    • decodeData(body, true)

Do you need streaming support (ability to have other filters see multiple decodeData() calls)? Continuation support? Or will you always add a body and then continue iteration.

I've been thinking about and I don't think it will be too bad to add this, but would like to clarify exactly what you need.

Yes that is correct.

For REST-gRPC transcoding use case, there is no need of streaming, continuation support. The request body (gRPC frame) for router/other filters will be generated from headers.

OK sounds good. I will work on this in the next week.

I'm very, very excited for this feature. I think it's actually a killer feature for Envoy/gRPC. :)

@lizan what about the response. What will you do with the trailers? Just send them along? Or do we need a way to zero them out and send an empty data frame or something.

Ah yes, I need to clear trailers.

For non-streaming response, current existing implantation is wait until trailers received from upstream and send response to downstream, so grpc-status in trailers can be reflected to HTTP status.

For streaming response, sending an empty data frame should be good.

Yes, this is what happens here: https://github.com/lyft/envoy/blob/master/source/common/grpc/http1_bridge_filter.cc

I think for right now, the trailers could just be emptied and it would probably just work. If we need to actually get rid of the trailers I think I can do it fairly easily in a follow up. I'm fixing the primary issue with request body now.

@mattklein123 I would like to re-open this issue, #633 doesn't work in real case:

  1. router returns StopIteration even it was successful.
    https://github.com/lyft/envoy/blob/master/source/common/router/router.cc#L252

  2. when ConnectionManager get StopIteration it doesn't continue on data.
    https://github.com/lyft/envoy/blob/master/source/common/http/conn_manager_impl.cc#L490

Changing router to return Continue at that line fixed this (and doesn't break tests!), though I am not sure why router is returning StopIteration at the end of decodeHeaders, and if that is a proper way to fix.

@lizan reopening. I will fix.

Was this page helpful?
0 / 5 - 0 ratings