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.