Skip to content

Commit 77c54db

Browse files
committed
Fixed stuck threads and interruption of data reception over HTTPS
1 parent 5289618 commit 77c54db

File tree

9 files changed

+187
-377
lines changed

9 files changed

+187
-377
lines changed

src/server/Server.cpp

Lines changed: 100 additions & 213 deletions
Large diffs are not rendered by default.

src/server/protocol/ServerHttp2.cpp

Lines changed: 44 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@ namespace HttpServer
1313

1414
}
1515

16-
void ServerHttp2::close()
17-
{
16+
void ServerHttp2::close() {
1817
this->sock.close();
1918
}
2019

@@ -32,8 +31,7 @@ namespace HttpServer
3231
{
3332
auto it = streams.find(streamId);
3433

35-
if (streams.end() != it)
36-
{
34+
if (streams.end() != it) {
3735
return it->second;
3836
}
3937

@@ -56,18 +54,15 @@ namespace HttpServer
5654

5755
static Http2::ErrorCode parseHttp2Data(Http2::FrameMeta &meta, Http2::IncStream &stream, const uint8_t *src, const uint8_t *end)
5856
{
59-
if (0 == meta.stream_id)
60-
{
57+
if (0 == meta.stream_id) {
6158
return Http2::ErrorCode::PROTOCOL_ERROR;
6259
}
6360

64-
if (Http2::StreamState::OPEN != stream.state)
65-
{
61+
if (Http2::StreamState::OPEN != stream.state) {
6662
return Http2::ErrorCode::STREAM_CLOSED;
6763
}
6864

69-
if (stream.window_size_inc <= 0)
70-
{
65+
if (stream.window_size_inc <= 0) {
7166
return Http2::ErrorCode::FLOW_CONTROL_ERROR;
7267
}
7368

@@ -77,8 +72,7 @@ namespace HttpServer
7772
{
7873
padding = *src;
7974

80-
if (padding >= meta.length)
81-
{
75+
if (padding >= meta.length) {
8276
return Http2::ErrorCode::PROTOCOL_ERROR;
8377
}
8478

@@ -134,8 +128,7 @@ namespace HttpServer
134128
{
135129
padding = *src;
136130

137-
if (padding >= meta.length)
138-
{
131+
if (padding >= meta.length) {
139132
return Http2::ErrorCode::PROTOCOL_ERROR;
140133
}
141134

@@ -155,8 +148,7 @@ namespace HttpServer
155148
src += sizeof(uint8_t);
156149
}
157150

158-
if (false == HPack::unpack(src, end - src - padding, stream) )
159-
{
151+
if (HPack::unpack(src, end - src - padding, stream) == false) {
160152
return Http2::ErrorCode::COMPRESSION_ERROR;
161153
}
162154

@@ -165,27 +157,23 @@ namespace HttpServer
165157

166158
static Http2::ErrorCode parseHttp2rstStream(Http2::FrameMeta &meta, Http2::IncStream &stream, const uint8_t *src, const uint8_t *end)
167159
{
168-
if (Http2::StreamState::IDLE == stream.state)
169-
{
160+
if (Http2::StreamState::IDLE == stream.state) {
170161
return Http2::ErrorCode::PROTOCOL_ERROR;
171162
}
172163

173164
stream.state = Http2::StreamState::CLOSED;
174165

175-
if (0 == meta.stream_id)
176-
{
166+
if (0 == meta.stream_id) {
177167
return Http2::ErrorCode::PROTOCOL_ERROR;
178168
}
179169

180-
if (sizeof(uint32_t) != meta.length)
181-
{
170+
if (sizeof(uint32_t) != meta.length) {
182171
return Http2::ErrorCode::FRAME_SIZE_ERROR;
183172
}
184173

185174
const Http2::ErrorCode error_code = static_cast<const Http2::ErrorCode>(::ntohl(*reinterpret_cast<const uint32_t *>(src) ) );
186175

187-
if (Http2::ErrorCode::NO_ERROR != error_code)
188-
{
176+
if (Http2::ErrorCode::NO_ERROR != error_code) {
189177
// DEBUG
190178
}
191179

@@ -194,18 +182,15 @@ namespace HttpServer
194182

195183
static Http2::ErrorCode parseHttp2Settings(Http2::FrameMeta &meta, Http2::IncStream &stream, const uint8_t *src, const uint8_t *end)
196184
{
197-
if (0 != meta.stream_id)
198-
{
185+
if (0 != meta.stream_id) {
199186
return Http2::ErrorCode::PROTOCOL_ERROR;
200187
}
201188

202-
if (meta.length % (sizeof(uint16_t) + sizeof(uint32_t) ) )
203-
{
189+
if (meta.length % (sizeof(uint16_t) + sizeof(uint32_t) ) ) {
204190
return Http2::ErrorCode::FRAME_SIZE_ERROR;
205191
}
206192

207-
if (Http2::StreamState::OPEN != stream.state)
208-
{
193+
if (Http2::StreamState::OPEN != stream.state) {
209194
stream.state = Http2::StreamState::OPEN;
210195
}
211196

@@ -229,8 +214,7 @@ namespace HttpServer
229214

230215
case Http2::ConnectionSetting::SETTINGS_ENABLE_PUSH:
231216
{
232-
if (value > 1)
233-
{
217+
if (value > 1) {
234218
return Http2::ErrorCode::PROTOCOL_ERROR;
235219
}
236220

@@ -245,8 +229,7 @@ namespace HttpServer
245229

246230
case Http2::ConnectionSetting::SETTINGS_INITIAL_WINDOW_SIZE:
247231
{
248-
if (value >= uint32_t(1 << 31) )
249-
{
232+
if (value >= uint32_t(1 << 31) ) {
250233
return Http2::ErrorCode::FLOW_CONTROL_ERROR;
251234
}
252235

@@ -257,8 +240,7 @@ namespace HttpServer
257240

258241
case Http2::ConnectionSetting::SETTINGS_MAX_FRAME_SIZE:
259242
{
260-
if (value < (1 << 14) || value >= (1 << 24) )
261-
{
243+
if (value < (1 << 14) || value >= (1 << 24) ) {
262244
return Http2::ErrorCode::PROTOCOL_ERROR;
263245
}
264246

@@ -281,26 +263,23 @@ namespace HttpServer
281263

282264
static Http2::ErrorCode parseHttp2GoAway(Http2::FrameMeta &meta, Http2::IncStream &stream, const uint8_t *src, const uint8_t *end)
283265
{
284-
if (0 != meta.stream_id)
285-
{
266+
if (0 != meta.stream_id) {
286267
return Http2::ErrorCode::PROTOCOL_ERROR;
287268
}
288269

289270
stream.state = Http2::StreamState::CLOSED;
290271

291272
const uint32_t last_stream_id = ::ntohl(*reinterpret_cast<const uint32_t *>(src) );
292273

293-
if (last_stream_id > 0)
294-
{
274+
if (last_stream_id > 0) {
295275

296276
}
297277

298278
src += sizeof(uint32_t);
299279

300280
const Http2::ErrorCode error_code = static_cast<Http2::ErrorCode>(::ntohl(*reinterpret_cast<const uint32_t *>(src) ) );
301281

302-
if (Http2::ErrorCode::NO_ERROR != error_code)
303-
{
282+
if (Http2::ErrorCode::NO_ERROR != error_code) {
304283

305284
}
306285

@@ -327,13 +306,11 @@ namespace HttpServer
327306

328307
static Http2::ErrorCode parseHttp2Ping(Http2::FrameMeta &meta)
329308
{
330-
if (0 != meta.stream_id)
331-
{
309+
if (0 != meta.stream_id) {
332310
return Http2::ErrorCode::PROTOCOL_ERROR;
333311
}
334312

335-
if (sizeof(uint64_t) != meta.length)
336-
{
313+
if (sizeof(uint64_t) != meta.length) {
337314
return Http2::ErrorCode::FRAME_SIZE_ERROR;
338315
}
339316

@@ -342,38 +319,30 @@ namespace HttpServer
342319

343320
static Http2::ErrorCode parseHttp2WindowUpdate(Http2::FrameMeta &meta, Http2::IncStream &stream, const uint8_t *src, const uint8_t *end)
344321
{
345-
if (Http2::StreamState::RESERVED == stream.state)
346-
{
322+
if (Http2::StreamState::RESERVED == stream.state) {
347323
return Http2::ErrorCode::PROTOCOL_ERROR;
348324
}
349-
else if (Http2::StreamState::OPEN != stream.state)
350-
{
325+
else if (Http2::StreamState::OPEN != stream.state) {
351326
return Http2::ErrorCode::NO_ERROR;
352327
}
353328

354-
if (sizeof(uint32_t) != meta.length)
355-
{
329+
if (sizeof(uint32_t) != meta.length) {
356330
return Http2::ErrorCode::FRAME_SIZE_ERROR;
357331
}
358332

359333
const uint32_t window_size_increment = ::ntohl(*reinterpret_cast<const uint32_t *>(src) );
360334

361-
if (0 == window_size_increment)
362-
{
335+
if (0 == window_size_increment) {
363336
return Http2::ErrorCode::PROTOCOL_ERROR;
364337
}
365-
else if (window_size_increment >= uint32_t(1 << 31) )
366-
{
338+
else if (window_size_increment >= uint32_t(1 << 31) ) {
367339
return Http2::ErrorCode::FLOW_CONTROL_ERROR;
368340
}
369341

370-
if (0 == meta.stream_id)
371-
{
342+
if (0 == meta.stream_id) {
372343
// TODO: update all streams
373344
stream.window_size_out += window_size_increment;
374-
}
375-
else
376-
{
345+
} else {
377346
stream.window_size_out += window_size_increment;
378347
}
379348

@@ -439,8 +408,7 @@ namespace HttpServer
439408

440409
const long read_size = sock.nonblock_recv(buf.data(), buf.size(), timeout);
441410

442-
if (read_size != buf.size() )
443-
{
411+
if (read_size != buf.size() ) {
444412
return false;
445413
}
446414

@@ -478,15 +446,13 @@ namespace HttpServer
478446
{
479447
if (read_size <= static_cast<long>(meta.length + Http2::FRAME_HEADER_SIZE) )
480448
{
481-
if (read_size == static_cast<long>(meta.length + Http2::FRAME_HEADER_SIZE) )
482-
{
449+
if (read_size == static_cast<long>(meta.length + Http2::FRAME_HEADER_SIZE) ) {
483450
read_size = 0;
484451
}
485452

486453
read_size = sock.nonblock_recv(buf.data() + read_size, buf.size() - read_size, timeout);
487454

488-
if (read_size < static_cast<long>(Http2::FRAME_HEADER_SIZE) )
489-
{
455+
if (read_size < static_cast<long>(Http2::FRAME_HEADER_SIZE) ) {
490456
return false;
491457
}
492458
}
@@ -517,12 +483,9 @@ namespace HttpServer
517483

518484
sendEmptySettings(this->sock, req.timeout, conn, Http2::FrameFlag::EMPTY);
519485

520-
if (false == getClientPreface(this->sock, req.timeout) )
521-
{
486+
if (getClientPreface(this->sock, req.timeout) == false) {
522487
constexpr uint32_t last_stream_id = 0;
523-
524488
goAway(this->sock, req.timeout, conn, last_stream_id, Http2::ErrorCode::PROTOCOL_ERROR);
525-
526489
return this;
527490
}
528491

@@ -544,32 +507,26 @@ namespace HttpServer
544507
Http2::FrameMeta meta {};
545508
long read_size = 0;
546509

547-
do
548-
{
549-
if (false == getNextHttp2FrameMeta(this->sock, req.timeout, buf, meta, read_size) )
550-
{
510+
do {
511+
if (getNextHttp2FrameMeta(this->sock, req.timeout, buf, meta, read_size) == false) {
551512
break;
552513
}
553514

554515
const uint8_t *addr = reinterpret_cast<const uint8_t *>(buf.data() ) + Http2::FRAME_HEADER_SIZE;
555516
const uint8_t *end = addr + meta.length;
556517

557-
if (meta.stream_id > last_stream_id)
558-
{
518+
if (meta.stream_id > last_stream_id) {
559519
last_stream_id = meta.stream_id;
560520
}
561521

562522
Http2::IncStream &stream = getStreamData(streams, meta.stream_id, conn);
563523

564-
if (Http2::StreamState::CLOSED == stream.state)
565-
{
524+
if (Http2::StreamState::CLOSED == stream.state) {
566525
rstStream(this->sock, req.timeout, stream, Http2::ErrorCode::STREAM_CLOSED);
567-
568526
continue;
569527
}
570528

571-
if (meta.type != Http2::FrameType::CONTINUATION)
572-
{
529+
if (meta.type != Http2::FrameType::CONTINUATION) {
573530
stream.frame_type = meta.type;
574531
}
575532

@@ -591,8 +548,7 @@ namespace HttpServer
591548
{
592549
size_t update_size = conn.server_settings.initial_window_size + (dr->full_size - dr->recv_total) - stream.window_size_inc;
593550

594-
if (update_size > Http2::MAX_WINDOW_UPDATE)
595-
{
551+
if (update_size > Http2::MAX_WINDOW_UPDATE) {
596552
update_size = Http2::MAX_WINDOW_UPDATE;
597553
}
598554

@@ -616,10 +572,8 @@ namespace HttpServer
616572

617573
stream.reserved = createDataReceiver(rd, this->settings.variants);
618574

619-
if (stream.reserved)
620-
{
575+
if (stream.reserved) {
621576
DataVariant::DataReceiver *dr = reinterpret_cast<DataVariant::DataReceiver *>(stream.reserved);
622-
623577
dr->reserved = new std::string();
624578
}
625579
}
@@ -661,7 +615,6 @@ namespace HttpServer
661615
if (Http2::ErrorCode::NO_ERROR == result && false == (meta.flags & Http2::FrameFlag::ACK) )
662616
{
663617
const uint64_t ping_data = *reinterpret_cast<const uint64_t *>(addr);
664-
665618
ping(this->sock, req.timeout, conn, ping_data);
666619
}
667620

@@ -711,18 +664,16 @@ namespace HttpServer
711664
}
712665
while (Http2::StreamState::CLOSED != primary.state);
713666

714-
while (conn.sync.completed.load() < streams_process_count)
715-
{
667+
while (conn.sync.completed.load() < streams_process_count) {
716668
conn.sync.event.wait();
717669
}
718670

719671
goAway(this->sock, req.timeout, conn, last_stream_id, Http2::ErrorCode::NO_ERROR);
720672

721-
for (auto &pair : streams)
722-
{
673+
for (auto &pair : streams) {
723674
destroyDataReceiver(pair.second.reserved);
724675
}
725676

726677
return this;
727678
}
728-
};
679+
}

src/server/protocol/ServerHttp2.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,4 @@ namespace HttpServer
1818
virtual ServerProtocol *process() override;
1919
virtual void close() override;
2020
};
21-
};
21+
}

0 commit comments

Comments
 (0)