rew_extensions/ext/http/
mod.rs1use super::ExtensionTrait;
2use deno_core::{Extension, extension};
3
4use std::rc::Rc;
7
8use ::deno_http::http_create_conn_resource;
9use deno_core::OpState;
10use deno_core::ResourceId;
11use deno_core::error::ResourceError;
12use deno_core::op2;
13use deno_net::io::TcpStreamResource;
14
15
16pub const UNSTABLE_FEATURE_NAME: &str = "http";
17
18#[derive(Debug, thiserror::Error, deno_error::JsError)]
19pub enum HttpStartError {
20 #[class("Busy")]
21 #[error("TCP stream is currently in use")]
22 TcpStreamInUse,
23 #[class("Busy")]
24 #[error("TLS stream is currently in use")]
25 TlsStreamInUse,
26 #[class("Busy")]
27 #[error("Unix socket is currently in use")]
28 UnixSocketInUse,
29 #[class(generic)]
30 #[error(transparent)]
31 ReuniteTcp(#[from] tokio::net::tcp::ReuniteError),
32 #[cfg(unix)]
33 #[class(generic)]
34 #[error(transparent)]
35 ReuniteUnix(#[from] tokio::net::unix::ReuniteError),
36 #[class(inherit)]
37 #[error("{0}")]
38 Io(
39 #[from]
40 #[inherit]
41 std::io::Error,
42 ),
43 #[class(inherit)]
44 #[error(transparent)]
45 Resource(#[inherit] ResourceError),
46}
47
48#[op2(fast)]
49#[smi]
50fn op_http_start(
51 state: &mut OpState,
52 #[smi] tcp_stream_rid: ResourceId,
53) -> Result<ResourceId, HttpStartError> {
54 if let Ok(resource_rc) = state
55 .resource_table
56 .take::<TcpStreamResource>(tcp_stream_rid)
57 {
58 let resource = Rc::try_unwrap(resource_rc).map_err(|_| HttpStartError::TcpStreamInUse)?;
62 let (read_half, write_half) = resource.into_inner();
63 let tcp_stream = read_half.reunite(write_half)?;
64 let addr = tcp_stream.local_addr()?;
65 return Ok(http_create_conn_resource(state, tcp_stream, addr, "http"));
66 }
67
68 #[cfg(unix)]
83 if let Ok(resource_rc) = state
84 .resource_table
85 .take::<deno_net::io::UnixStreamResource>(tcp_stream_rid)
86 {
87 let resource = Rc::try_unwrap(resource_rc).map_err(|_| HttpStartError::UnixSocketInUse)?;
91 let (read_half, write_half) = resource.into_inner();
92 let unix_stream = read_half.reunite(write_half)?;
93 let addr = unix_stream.local_addr()?;
94 return Ok(http_create_conn_resource(
95 state,
96 unix_stream,
97 addr,
98 "http+unix",
99 ));
100 }
101
102 Err(HttpStartError::Resource(ResourceError::BadResourceId))
103}
104
105extension!(
106 deno_http,
107 ops = [op_http_start],
108 esm = [ dir "src/ext/http", "00_serve.ts", "01_http.js", "02_websocket.ts" ],
109);
110impl ExtensionTrait<()> for deno_http {
111 fn init((): ()) -> Extension {
112 deno_http::init()
113 }
114}
115extension!(
116 http,
117 esm_entry_point = "ext:http/init_http.js",
118 esm = [ dir "src/ext/http", "init_http.js" ],
119);
120impl ExtensionTrait<()> for http {
121 fn init((): ()) -> Extension {
122 http::init()
123 }
124}
125
126impl ExtensionTrait<()> for ::deno_http::deno_http {
127 fn init((): ()) -> Extension {
128 ::deno_http::deno_http::init(::deno_http::Options::default())
129 }
130}
131
132pub fn extensions(is_snapshot: bool) -> Vec<Extension> {
133 vec![
134 deno_http::build((), is_snapshot),
135 ::deno_http::deno_http::build((), true),
136 http::build((), is_snapshot),
137 ]
138}