@@ -191,6 +191,8 @@ async fn build_http_request(
191191 } else if let Some ( ref body_val) = input. body {
192192 request = request. header ( "Content-Type" , "application/json" ) ;
193193 request = request. json ( body_val) ;
194+ } else if matches ! ( method. http_method. as_str( ) , "POST" | "PUT" | "PATCH" ) {
195+ request = request. header ( "Content-Length" , "0" ) ;
194196 }
195197 }
196198
@@ -1817,3 +1819,84 @@ fn test_get_value_type_helper() {
18171819 assert_eq ! ( get_value_type( & json!( [ 1 , 2 ] ) ) , "array" ) ;
18181820 assert_eq ! ( get_value_type( & json!( { "a" : 1 } ) ) , "object" ) ;
18191821}
1822+
1823+ #[ tokio:: test]
1824+ async fn test_post_without_body_sets_content_length_zero ( ) {
1825+ let client = reqwest:: Client :: new ( ) ;
1826+ let method = RestMethod {
1827+ http_method : "POST" . to_string ( ) ,
1828+ path : "messages/trash" . to_string ( ) ,
1829+ ..Default :: default ( )
1830+ } ;
1831+ let input = ExecutionInput {
1832+ full_url : "https://example.com/messages/trash" . to_string ( ) ,
1833+ body : None ,
1834+ params : Map :: new ( ) ,
1835+ query_params : HashMap :: new ( ) ,
1836+ is_upload : false ,
1837+ } ;
1838+
1839+ let request = build_http_request ( & client, & method, & input, None , & AuthMethod :: None , None , 0 , None )
1840+ . await
1841+ . unwrap ( ) ;
1842+
1843+ let built = request. build ( ) . unwrap ( ) ;
1844+ assert_eq ! (
1845+ built. headers( ) . get( "Content-Length" ) . map( |v| v. to_str( ) . unwrap( ) ) ,
1846+ Some ( "0" ) ,
1847+ "POST with no body must include Content-Length: 0"
1848+ ) ;
1849+ }
1850+
1851+ #[ tokio:: test]
1852+ async fn test_post_with_body_does_not_add_content_length_zero ( ) {
1853+ let client = reqwest:: Client :: new ( ) ;
1854+ let method = RestMethod {
1855+ http_method : "POST" . to_string ( ) ,
1856+ path : "files" . to_string ( ) ,
1857+ ..Default :: default ( )
1858+ } ;
1859+ let input = ExecutionInput {
1860+ full_url : "https://example.com/files" . to_string ( ) ,
1861+ body : Some ( json ! ( { "name" : "test" } ) ) ,
1862+ params : Map :: new ( ) ,
1863+ query_params : HashMap :: new ( ) ,
1864+ is_upload : false ,
1865+ } ;
1866+
1867+ let request = build_http_request ( & client, & method, & input, None , & AuthMethod :: None , None , 0 , None )
1868+ . await
1869+ . unwrap ( ) ;
1870+
1871+ let built = request. build ( ) . unwrap ( ) ;
1872+ // When body is present, Content-Length should NOT be "0"
1873+ let cl = built. headers ( ) . get ( "Content-Length" ) . map ( |v| v. to_str ( ) . unwrap ( ) . to_string ( ) ) ;
1874+ assert ! ( cl. is_none( ) || cl. as_deref( ) != Some ( "0" ) ) ;
1875+ }
1876+
1877+ #[ tokio:: test]
1878+ async fn test_get_does_not_set_content_length_zero ( ) {
1879+ let client = reqwest:: Client :: new ( ) ;
1880+ let method = RestMethod {
1881+ http_method : "GET" . to_string ( ) ,
1882+ path : "files" . to_string ( ) ,
1883+ ..Default :: default ( )
1884+ } ;
1885+ let input = ExecutionInput {
1886+ full_url : "https://example.com/files" . to_string ( ) ,
1887+ body : None ,
1888+ params : Map :: new ( ) ,
1889+ query_params : HashMap :: new ( ) ,
1890+ is_upload : false ,
1891+ } ;
1892+
1893+ let request = build_http_request ( & client, & method, & input, None , & AuthMethod :: None , None , 0 , None )
1894+ . await
1895+ . unwrap ( ) ;
1896+
1897+ let built = request. build ( ) . unwrap ( ) ;
1898+ assert ! (
1899+ built. headers( ) . get( "Content-Length" ) . is_none( ) ,
1900+ "GET with no body should not have Content-Length header"
1901+ ) ;
1902+ }
0 commit comments