@@ -5,7 +5,7 @@ use magnus::{value::{qnil, ReprValue}, RString, Value};
55use bytes:: Bytes ;
66use hyper:: Request as HyperRequest ;
77
8- use rb_sys:: { rb_str_cat , rb_str_resize , RSTRING_PTR , VALUE } ;
8+ use rb_sys:: { rb_str_set_len , rb_str_modify , rb_str_modify_expand , rb_str_capacity , RSTRING_PTR , VALUE } ;
99
1010// Type passed to ruby giving access to the request properties.
1111#[ magnus:: wrap( class = "HyperRuby::Request" ) ]
@@ -44,21 +44,32 @@ impl Request {
4444 buffer
4545 }
4646
47- pub fn fill_body ( & self , buffer : RString ) -> usize {
47+ pub fn fill_body ( & self , buffer : RString ) -> i64 {
4848 let body = self . request . body ( ) ;
49- let body_len = body. len ( ) ;
49+ let body_len: i64 = body. len ( ) . try_into ( ) . unwrap ( ) ;
5050
5151 // Access the ruby string VALUE directly, and resize to 0 (keeping the capacity),
5252 // then copy our buffer into it.
5353 unsafe {
5454 let rb_value = buffer. as_value ( ) ;
5555 let inner: VALUE = std:: ptr:: read ( & rb_value as * const _ as * const VALUE ) ;
56- rb_str_resize ( inner, body_len. try_into ( ) . unwrap ( ) ) ;
56+ let existing_capacity = rb_str_capacity ( inner) as i64 ;
57+
58+ // If the buffer is too small, expand it.
59+ if existing_capacity < body_len. try_into ( ) . unwrap ( ) {
60+ rb_str_modify_expand ( inner, body_len) ;
61+ }
62+ else {
63+ rb_str_modify ( inner) ;
64+ }
65+
5766 if body_len > 0 {
5867 let body_ptr = body. as_ptr ( ) as * const c_char ;
5968 let rb_string_ptr = RSTRING_PTR ( inner) as * mut c_char ;
60- std:: ptr:: copy ( body_ptr, rb_string_ptr, body_len) ;
69+ std:: ptr:: copy ( body_ptr, rb_string_ptr, body_len as usize ) ;
6170 }
71+
72+ rb_str_set_len ( inner, body_len) ;
6273 }
6374
6475 body_len
0 commit comments