@@ -1041,14 +1041,33 @@ pub const Transfer = struct {
10411041 try req .done_callback (req .ctx );
10421042 }
10431043
1044+ // This function should be called during the dataCallback. Calling it after
1045+ // such as in the doneCallback is guaranteed to return null.
10441046 pub fn getContentLength (self : * const Transfer ) ? u32 {
1045- // It's possible for this to be null even with correct code, due to
1046- // request fulfillment. If transfer.fulfill is called, we won't have
1047- // a handle.
1048- const handle = self ._handle orelse return null ;
1047+ const cl = self .getContentLengthRawValue () orelse return null ;
1048+ return std .fmt .parseInt (u32 , cl , 10 ) catch null ;
1049+ }
1050+
1051+ fn getContentLengthRawValue (self : * const Transfer ) ? []const u8 {
1052+ if (self ._handle ) | handle | {
1053+ // If we have a handle, than this is a normal request. We can get the
1054+ // header value from the easy handle.
1055+ const cl = getResponseHeader (handle .conn .easy , "content-length" , 0 ) orelse return null ;
1056+ return cl .value ;
1057+ }
1058+
1059+ // If we have no handle, then maybe this is being called after the
1060+ // doneCallback. OR, maybe this is a "fulfilled" request. Let's check
1061+ // the injected headers (if we have any).
10491062
1050- const cl = getResponseHeader (handle .conn .easy , "content-length" , 0 ) orelse return null ;
1051- return std .fmt .parseInt (u32 , cl .value , 10 ) catch null ;
1063+ const rh = self .response_header orelse return null ;
1064+ for (rh ._injected_headers ) | hdr | {
1065+ if (std .ascii .eqlIgnoreCase (hdr .name , "content-length" )) {
1066+ return hdr .value ;
1067+ }
1068+ }
1069+
1070+ return null ;
10521071 }
10531072};
10541073
0 commit comments