diff options
author | Ryan Dahl <ry@tinyclouds.org> | 2021-04-15 18:48:56 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-04-15 18:48:56 -0400 |
commit | fe9cee620a4c0d8923bdf99882f95275b69abcb4 (patch) | |
tree | 9b9e68fc3a837f05f4933195590cbcc1cb90462d /runtime/ops/http.rs | |
parent | ad7f6d4510afc71ed40da1aa1ad649d59d3aef12 (diff) |
fix(#10182): hang during http server response (#10197)
Diffstat (limited to 'runtime/ops/http.rs')
-rw-r--r-- | runtime/ops/http.rs | 34 |
1 files changed, 23 insertions, 11 deletions
diff --git a/runtime/ops/http.rs b/runtime/ops/http.rs index f209662c4..57df19d84 100644 --- a/runtime/ops/http.rs +++ b/runtime/ops/http.rs @@ -48,7 +48,7 @@ pub fn init(rt: &mut deno_core::JsRuntime) { super::reg_async(rt, "op_http_request_next", op_http_request_next); super::reg_async(rt, "op_http_request_read", op_http_request_read); - super::reg_sync(rt, "op_http_response", op_http_response); + super::reg_async(rt, "op_http_response", op_http_response); super::reg_async(rt, "op_http_response_write", op_http_response_write); super::reg_async(rt, "op_http_response_close", op_http_response_close); } @@ -312,16 +312,15 @@ struct RespondArgs( Vec<String>, ); -fn op_http_response( - state: &mut OpState, +async fn op_http_response( + state: Rc<RefCell<OpState>>, args: RespondArgs, data: Option<ZeroCopyBuf>, ) -> Result<Option<ResourceId>, AnyError> { - let rid = args.0; - let status = args.1; - let headers = args.2; + let RespondArgs(rid, status, headers) = args; let response_sender = state + .borrow_mut() .resource_table .take::<ResponseSenderResource>(rid) .ok_or_else(bad_resource_id)?; @@ -329,6 +328,12 @@ fn op_http_response( .ok() .expect("multiple op_http_respond ongoing"); + let conn_resource = state + .borrow() + .resource_table + .get::<ConnResource>(response_sender.conn_rid) + .ok_or_else(bad_resource_id)?; + let mut builder = Response::builder().status(status); debug_assert_eq!(headers.len() % 2, 0); @@ -348,11 +353,12 @@ fn op_http_response( let (sender, body) = Body::channel(); res = builder.body(body)?; - let response_body_rid = state.resource_table.add(ResponseBodyResource { - body: AsyncRefCell::new(sender), - cancel: CancelHandle::default(), - conn_rid: response_sender.conn_rid, - }); + let response_body_rid = + state.borrow_mut().resource_table.add(ResponseBodyResource { + body: AsyncRefCell::new(sender), + cancel: CancelHandle::default(), + conn_rid: response_sender.conn_rid, + }); Some(response_body_rid) }; @@ -364,6 +370,12 @@ fn op_http_response( return Err(type_error("internal communication error")); } + poll_fn(|cx| match conn_resource.poll(cx) { + Poll::Ready(x) => Poll::Ready(x), + Poll::Pending => Poll::Ready(Ok(())), + }) + .await?; + Ok(maybe_response_body_rid) } |