Skip to content

Commit 66fdafe

Browse files
committed
Set gRPC response content length
1 parent 1ce6b29 commit 66fdafe

1 file changed

Lines changed: 32 additions & 4 deletions

File tree

ldk-server-grpc/src/grpc.rs

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ pub fn grpc_error_response(status: GrpcStatus) -> http::Response<GrpcBody> {
191191
.status(200)
192192
.header("content-type", "application/grpc+proto")
193193
.header("grpc-accept-encoding", "identity")
194+
.header("content-length", "0")
194195
.header("grpc-status", status.code.to_string());
195196
if !status.message.is_empty() {
196197
let encoded = percent_encode(&status.message);
@@ -203,12 +204,15 @@ pub fn grpc_error_response(status: GrpcStatus) -> http::Response<GrpcBody> {
203204

204205
/// Build an HTTP 200 response with gRPC content-type and the given body.
205206
pub fn grpc_response(body: GrpcBody) -> http::Response<GrpcBody> {
206-
http::Response::builder()
207+
let mut builder = http::Response::builder()
207208
.status(200)
208209
.header("content-type", "application/grpc+proto")
209-
.header("grpc-accept-encoding", "identity")
210-
.body(body)
211-
.unwrap()
210+
.header("grpc-accept-encoding", "identity");
211+
if let GrpcBody::Unary { data, .. } = &body {
212+
let len = data.as_ref().map_or(0, Bytes::len);
213+
builder = builder.header("content-length", len.to_string());
214+
}
215+
builder.body(body).unwrap()
212216
}
213217

214218
/// Validate that the request looks like a gRPC call.
@@ -322,6 +326,30 @@ mod tests {
322326
assert!(decoded.is_empty());
323327
}
324328

329+
#[test]
330+
fn test_grpc_response_sets_unary_content_length() {
331+
let data = encode_grpc_frame(b"hello");
332+
let expected_len = data.len().to_string();
333+
let response = grpc_response(GrpcBody::Unary { data: Some(data), trailers_sent: false });
334+
335+
assert_eq!(response.headers().get("content-length").unwrap(), expected_len.as_str());
336+
}
337+
338+
#[test]
339+
fn test_grpc_response_omits_stream_content_length() {
340+
let (_tx, rx) = tokio::sync::mpsc::channel(1);
341+
let response = grpc_response(GrpcBody::Stream { rx, done: false });
342+
343+
assert!(response.headers().get("content-length").is_none());
344+
}
345+
346+
#[test]
347+
fn test_grpc_error_response_sets_zero_content_length() {
348+
let response = grpc_error_response(GrpcStatus::new(GRPC_STATUS_INVALID_ARGUMENT, "bad"));
349+
350+
assert_eq!(response.headers().get("content-length").unwrap(), "0");
351+
}
352+
325353
#[test]
326354
fn test_decode_too_short() {
327355
assert!(decode_grpc_body(&[0, 0, 0]).is_err());

0 commit comments

Comments
 (0)