3

I'm having a bit of a struggle with using the External Processing filter for Envoy (described HERE. I'm currently using a similar setup to THIS EXAMPLE , where I want to do some processing on both the request and response bodies being sent to an upstream service using a GRPC server in Go.

The issue I'm facing is that when I try to make changes to the request body, meaning using a BodyMutation to send a new body (basically the same JSON but with one field altered as an example) the Content-Length header is missing when the request is forwarded to the upstream service, which causes an error. Yet if I don't alter the body (so no BodyMutation) the header is there as it should be.

Basically, if I try to set the processing response for the request body like so:

bytesToSend := b.RequestBody.Body
resp = &pb.ProcessingResponse{
                    Response: &pb.ProcessingResponse_RequestBody{
                        RequestBody: &pb.BodyResponse{
                            Response: &pb.CommonResponse{
                                HeaderMutation: &pb.HeaderMutation{
                                    SetHeaders: []*core.HeaderValueOption{
                                        {
                                            Header: &core.HeaderValue{
                                                Key:   "Content-Length",
                                                Value: strconv.Itoa(len(bytesToSend)),
                                            },
                                        },
                                    },
                                },
                                BodyMutation: &pb.BodyMutation{
                                    Mutation: &pb.BodyMutation_Body{
                                        Body: bytesToSend,
                                    },
                                },
                            },
                        },
                    },
                    ModeOverride: &v3.ProcessingMode{
                        ResponseHeaderMode: v3.ProcessingMode_SEND,
                        ResponseBodyMode:   v3.ProcessingMode_NONE,
                    },
                }

The Content-Length is removed completely. But if I don't set the BodyMutation, like so:

bytesToSend := b.RequestBody.Body
                resp = &pb.ProcessingResponse{
                    Response: &pb.ProcessingResponse_RequestBody{
                        RequestBody: &pb.BodyResponse{
                            Response: &pb.CommonResponse{
                                HeaderMutation: &pb.HeaderMutation{
                                    SetHeaders: []*core.HeaderValueOption{
                                        {
                                            Header: &core.HeaderValue{
                                                Key:   "Content-Length",
                                                Value: strconv.Itoa(len(bytesToSend)),
                                            },
                                        },
                                    },
                                },
                            },
                        },
                    },
                    ModeOverride: &v3.ProcessingMode{
                        ResponseHeaderMode: v3.ProcessingMode_SEND,
                        ResponseBodyMode:   v3.ProcessingMode_NONE,
                    },
                }

Then the Content-Length is present, and the HeaderMutation does set it to whatever I set it to (in the example it's just the length of the body again).

I'm not entirely clear on the behaviour here. Is there something in particular I should be looking out for, either in this code or Envoy's configuration?

Any pointers would be greatly appreciated.

EDIT: Seems like the behaviour here is: when the body is mutated, it switches to chunked transfer encoding, therefore removing the content length. Makes sense, but then if the upstream service requires a content length it causes issues. The Header Mutation is ignored, so computing the content length manually and sending it doesn't seem to work.

0 Answers0