Skip to content

Commit 37bdaab

Browse files
committed
chore: fix HTTP server's error handling code path for unparsable HTTP requests
1 parent 6a0d048 commit 37bdaab

File tree

2 files changed

+27
-40
lines changed

2 files changed

+27
-40
lines changed

stackslib/src/net/rpc.rs

Lines changed: 23 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,6 @@ pub struct ConversationHttp {
115115
pending_request: Option<ReplyHandleHttp>,
116116
/// outstanding response
117117
pending_response: Option<StacksHttpResponse>,
118-
/// whether or not there's an error response pending
119-
pending_error_response: bool,
120118
/// how much data to buffer (i.e. the socket's send buffer size)
121119
socket_send_buffer_size: u32,
122120
}
@@ -166,7 +164,6 @@ impl ConversationHttp {
166164
canonical_stacks_tip_height: None,
167165
pending_request: None,
168166
pending_response: None,
169-
pending_error_response: false,
170167
keep_alive: true,
171168
total_request_count: 0,
172169
total_reply_count: 0,
@@ -228,15 +225,6 @@ impl ConversationHttp {
228225
);
229226
return Err(net_error::InProgress);
230227
}
231-
if self.pending_error_response {
232-
test_debug!(
233-
"{:?},id={}: Error response is inflight",
234-
&self.peer_host,
235-
self.conn_id
236-
);
237-
return Err(net_error::InProgress);
238-
}
239-
240228
let handle = self.start_request(req)?;
241229

242230
self.pending_request = Some(handle);
@@ -255,12 +243,12 @@ impl ConversationHttp {
255243
);
256244
return Err(net_error::InProgress);
257245
}
258-
if self.pending_error_response {
259-
// error already in-flight
260-
return Ok(());
261-
}
246+
let (mut preamble, body_contents) = res.try_into_contents()?;
247+
preamble.content_length = body_contents.content_length();
248+
preamble.keep_alive = false;
262249

263-
let (preamble, body_contents) = res.try_into_contents()?;
250+
// account for the request
251+
self.total_request_count += 1;
264252

265253
// make the relay handle. There may not have been a valid request in the first place, so
266254
// we'll use a relay handle (not a reply handle) to push out the error.
@@ -269,7 +257,6 @@ impl ConversationHttp {
269257
// queue up the HTTP headers, and then stream back the body.
270258
preamble.consensus_serialize(&mut reply)?;
271259
self.reply_streams.push_back((reply, body_contents, false));
272-
self.pending_error_response = true;
273260
Ok(())
274261
}
275262

@@ -388,11 +375,12 @@ impl ConversationHttp {
388375
if broken || (drained_handle && drained_stream) {
389376
// done with this stream
390377
test_debug!(
391-
"{:?}: done with stream (broken={}, drained_handle={}, drained_stream={})",
378+
"{:?}: done with stream (broken={}, drained_handle={}, drained_stream={}, do_keep_alive={})",
392379
&self,
393380
broken,
394381
drained_handle,
395-
drained_stream
382+
drained_stream,
383+
do_keep_alive,
396384
);
397385
self.total_reply_count += 1;
398386
self.reply_streams.pop_front();
@@ -482,6 +470,14 @@ impl ConversationHttp {
482470

483471
/// Is the connection idle?
484472
pub fn is_idle(&self) -> bool {
473+
test_debug!(
474+
"{:?} is_idle? {},{},{},{}",
475+
self,
476+
self.pending_response.is_none(),
477+
self.connection.inbox_len(),
478+
self.connection.outbox_len(),
479+
self.reply_streams.len()
480+
);
485481
self.pending_response.is_none()
486482
&& self.connection.inbox_len() == 0
487483
&& self.connection.outbox_len() == 0
@@ -491,9 +487,13 @@ impl ConversationHttp {
491487
/// Is the conversation out of pending data?
492488
/// Don't consider it drained if we haven't received anything yet
493489
pub fn is_drained(&self) -> bool {
494-
((self.total_request_count > 0 && self.total_reply_count > 0)
495-
|| self.pending_error_response)
496-
&& self.is_idle()
490+
test_debug!(
491+
"{:?} is_drained? {},{}",
492+
self,
493+
self.total_request_count,
494+
self.total_reply_count
495+
);
496+
self.total_request_count > 0 && self.total_reply_count > 0 && self.is_idle()
497497
}
498498

499499
/// Should the connection be kept alive even if drained?
@@ -523,11 +523,6 @@ impl ConversationHttp {
523523
&mut self,
524524
node: &mut StacksNodeState,
525525
) -> Result<Vec<StacksMessageType>, net_error> {
526-
// if we have an in-flight error, then don't take any more requests.
527-
if self.pending_error_response {
528-
return Ok(vec![]);
529-
}
530-
531526
// handle in-bound HTTP request(s)
532527
let num_inbound = self.connection.inbox_len();
533528
let mut ret = vec![];
@@ -568,7 +563,6 @@ impl ConversationHttp {
568563
}
569564
StacksHttpMessage::Error(path, resp) => {
570565
// new request, but resulted in an error when parsing it
571-
self.total_request_count += 1;
572566
self.last_request_timestamp = get_epoch_time_secs();
573567
let start_time = Instant::now();
574568
self.reply_error(resp)?;

stackslib/src/net/server.rs

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,7 @@ impl HttpPeer {
288288
/// Deregister a socket/event pair
289289
#[cfg_attr(test, mutants::skip)]
290290
pub fn deregister_http(&mut self, network_state: &mut NetworkState, event_id: usize) -> () {
291+
test_debug!("Remove HTTP event {}", event_id);
291292
self.peers.remove(&event_id);
292293

293294
match self.sockets.remove(&event_id) {
@@ -456,7 +457,7 @@ impl HttpPeer {
456457
"Failed to flush HTTP 400 to socket {:?}: {:?}",
457458
&client_sock, &e
458459
);
459-
convo_dead = true;
460+
// convo_dead = true;
460461
}
461462
}
462463
Err(e) => {
@@ -559,19 +560,11 @@ impl HttpPeer {
559560
let mut to_remove = vec![];
560561
let mut msgs = vec![];
561562
for event_id in &poll_state.ready {
562-
if !self.sockets.contains_key(&event_id) {
563+
let Some(client_sock) = self.sockets.get_mut(&event_id) else {
563564
debug!("Rogue socket event {}", event_id);
564565
to_remove.push(*event_id);
565566
continue;
566-
}
567-
568-
let client_sock_opt = self.sockets.get_mut(&event_id);
569-
if client_sock_opt.is_none() {
570-
debug!("No such socket event {}", event_id);
571-
to_remove.push(*event_id);
572-
continue;
573-
}
574-
let client_sock = client_sock_opt.unwrap();
567+
};
575568

576569
match self.peers.get_mut(event_id) {
577570
Some(ref mut convo) => {

0 commit comments

Comments
 (0)