@@ -42,50 +42,54 @@ namespace HttpClient
4242 {
4343 std::vector<char > buf;
4444 buf.reserve (4096 );
45+ buf.resize (Http2::FRAME_HEADER_SIZE + sizeof (uint8_t ) );
4546
4647 headers.emplace (headers.begin (), " :status" , std::to_string (static_cast <int >(status) ) );
4748
4849 HPack::pack (buf, headers, this ->stream ->dynamic_table );
4950
50- uint32_t data_size = buf.size ();
51+ uint32_t data_size = buf.size () - Http2::FRAME_HEADER_SIZE - sizeof ( uint8_t ) ;
5152
5253 const uint8_t padding = getPaddingSize (data_size);
5354 const uint16_t padding_size = padding + sizeof (uint8_t );
5455
55- if (padding_size)
56+ if (data_size + padding_size > this -> stream -> settings . max_frame_size )
5657 {
57- if (data_size + padding_size > this ->stream ->settings .max_frame_size )
58- {
59- data_size = this ->stream ->settings .max_frame_size - padding_size;
60- }
58+ data_size = this ->stream ->settings .max_frame_size - padding_size;
6159 }
6260
6361 const size_t frame_size = data_size + padding_size;
6462
63+ buf.resize (frame_size + Http2::FRAME_HEADER_SIZE);
64+
6565 Http2::FrameFlag flags = Http2::FrameFlag::END_HEADERS;
6666
6767 if (endStream)
6868 {
6969 flags |= Http2::FrameFlag::END_STREAM;
7070 }
7171
72- if (padding_size)
73- {
74- flags |= Http2::FrameFlag::PADDED;
72+ flags |= Http2::FrameFlag::PADDED;
7573
76- buf. insert (buf. begin (), sizeof ( uint8_t ), padding) ;
74+ buf[Http2::FRAME_HEADER_SIZE] = padding;
7775
78- if (padding)
79- {
80- buf.insert (buf.end (), padding, 0 );
81- }
76+ if (padding)
77+ {
78+ std::fill (buf.end () - padding, buf.end (), 0 );
8279 }
8380
84- buf.insert (buf.begin (), Http2::FRAME_HEADER_SIZE, 0 );
85-
8681 this ->stream ->setHttp2FrameHeader (reinterpret_cast <uint8_t *>(buf.data () ), frame_size, Http2::FrameType::HEADERS, flags);
8782
88- return this ->sock ->nonblock_send (buf.data (), buf.size (), timeout) > 0 ;
83+ this ->stream ->lock ();
84+
85+ auto const is_sended = this ->sock ->nonblock_send (buf.data (), buf.size (), timeout) > 0 ;
86+
87+ if (endStream || false == is_sended)
88+ {
89+ this ->stream ->unlock ();
90+ }
91+
92+ return is_sended;
8993 }
9094
9195 void ClientHttp2::sendWindowUpdate (const uint32_t size, const std::chrono::milliseconds &timeout) const
@@ -111,23 +115,20 @@ namespace HttpClient
111115
112116 while (total < size)
113117 {
114- buf.resize (0 );
115-
116118 size_t data_size = (size - total < this ->stream ->settings .max_frame_size ) ? size - total : this ->stream ->settings .max_frame_size ;
117119
118120 const uint8_t padding = getPaddingSize (data_size);
119121 const uint16_t padding_size = padding + sizeof (uint8_t );
120122
121- if (padding_size)
123+ if (data_size + padding_size > this -> stream -> settings . max_frame_size )
122124 {
123- if (data_size + padding_size > this ->stream ->settings .max_frame_size )
124- {
125- data_size = this ->stream ->settings .max_frame_size - padding_size;
126- }
125+ data_size = this ->stream ->settings .max_frame_size - padding_size;
127126 }
128127
129128 const size_t frame_size = data_size + padding_size;
130129
130+ buf.resize (frame_size + Http2::FRAME_HEADER_SIZE);
131+
131132 if (static_cast <int32_t >(this ->stream ->window_size_out - this ->stream ->settings .max_frame_size ) <= 0 )
132133 {
133134 size_t update_size = this ->stream ->settings .initial_window_size + (size - total) - this ->stream ->window_size_out ;
@@ -149,30 +150,33 @@ namespace HttpClient
149150 flags |= Http2::FrameFlag::END_STREAM;
150151 }
151152
153+ size_t cur = Http2::FRAME_HEADER_SIZE;
154+
152155 if (padding_size)
153156 {
154157 flags |= Http2::FrameFlag::PADDED;
155158
156- buf.insert (buf.begin (), sizeof (uint8_t ), padding);
157- }
159+ buf[cur] = padding;
158160
159- buf.insert (buf.begin (), Http2::FRAME_HEADER_SIZE, 0 );
161+ ++cur;
162+ }
160163
161164 const Http2::FrameType frame_type = Http2::FrameType::DATA;
162165
163166 this ->stream ->setHttp2FrameHeader (buf.data (), frame_size, frame_type, flags);
164167
165- std::copy (data, data + data_size, std::back_inserter ( buf) );
168+ std::copy (data, data + data_size, buf. begin () + cur );
166169
167170 if (padding)
168171 {
169- buf. insert (buf.end (), padding, 0 );
172+ std::fill (buf.end () - padding, buf. end () , 0 );
170173 }
171174
172175 long sended = this ->sock ->nonblock_send (buf.data (), buf.size (), timeout);
173176
174177 if (sended <= 0 )
175178 {
179+ total = 0 ;
176180 break ;
177181 }
178182
@@ -182,6 +186,11 @@ namespace HttpClient
182186 total += data_size;
183187 }
184188
185- return total;
189+ if (total == 0 || endStream)
190+ {
191+ this ->stream ->unlock ();
192+ }
193+
194+ return static_cast <long >(total);
186195 }
187196};
0 commit comments