@@ -5,7 +5,7 @@ use magnus::{value::{qnil, ReprValue}, RString, Value};
5
5
use bytes:: Bytes ;
6
6
use hyper:: Request as HyperRequest ;
7
7
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 } ;
9
9
10
10
// Type passed to ruby giving access to the request properties.
11
11
#[ magnus:: wrap( class = "HyperRuby::Request" ) ]
@@ -44,21 +44,32 @@ impl Request {
44
44
buffer
45
45
}
46
46
47
- pub fn fill_body ( & self , buffer : RString ) -> usize {
47
+ pub fn fill_body ( & self , buffer : RString ) -> i64 {
48
48
let body = self . request . body ( ) ;
49
- let body_len = body. len ( ) ;
49
+ let body_len: i64 = body. len ( ) . try_into ( ) . unwrap ( ) ;
50
50
51
51
// Access the ruby string VALUE directly, and resize to 0 (keeping the capacity),
52
52
// then copy our buffer into it.
53
53
unsafe {
54
54
let rb_value = buffer. as_value ( ) ;
55
55
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
+
57
66
if body_len > 0 {
58
67
let body_ptr = body. as_ptr ( ) as * const c_char ;
59
68
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 ) ;
61
70
}
71
+
72
+ rb_str_set_len ( inner, body_len) ;
62
73
}
63
74
64
75
body_len
0 commit comments