1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-28 16:20:57 -05:00

feat(flash): add 2nd param to handler to get remote address (#17633)

Closes #17583
This commit is contained in:
Leo Kettmeir 2023-02-15 16:37:41 +01:00 committed by GitHub
parent 4104a674c7
commit c7535950b6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 38 additions and 4 deletions

View file

@ -89,12 +89,14 @@ Deno.test({ permissions: { net: true } }, async function httpServerBasic() {
const listeningPromise = deferred();
const server = Deno.serve({
handler: async (request) => {
handler: async (request, getRemoteAddr) => {
// FIXME(bartlomieju):
// make sure that request can be inspected
console.log(request);
assertEquals(new URL(request.url).href, "http://127.0.0.1:4501/");
assertEquals(await request.text(), "");
const addr = getRemoteAddr();
assertEquals(addr.hostname, "127.0.0.1");
promise.resolve();
return new Response("Hello World", { headers: { "foo": "bar" } });
},

View file

@ -1126,7 +1126,7 @@ declare namespace Deno {
*
* @category HTTP Server
*/
export type ServeHandler = (request: Request) => Response | Promise<Response>;
export type ServeHandler = (request: Request, getRemoteAddr: () => Deno.NetAddr) => Response | Promise<Response>;
/** **UNSTABLE**: New API, yet to be vetted.
*

View file

@ -570,7 +570,16 @@ function createServe(opFn) {
let resp;
try {
resp = handler(req);
resp = handler(req, () => {
const { 0: hostname, 1: port } = core.ops.op_flash_addr(
serverId,
i,
);
return {
hostname,
port,
};
});
if (ObjectPrototypeIsPrototypeOf(PromisePrototype, resp)) {
PromisePrototypeCatch(
PromisePrototypeThen(

View file

@ -665,6 +665,26 @@ fn op_flash_headers(
)
}
#[op]
fn op_flash_addr(
state: Rc<RefCell<OpState>>,
server_id: u32,
token: u32,
) -> Result<(String, u16), AnyError> {
let mut op_state = state.borrow_mut();
let flash_ctx = op_state.borrow_mut::<FlashContext>();
let ctx = flash_ctx
.servers
.get_mut(&server_id)
.ok_or_else(|| type_error("server closed"))?;
let req = &ctx
.requests
.get(&token)
.ok_or_else(|| type_error("request closed"))?;
let socket = req.socket();
Ok((socket.addr.ip().to_string(), socket.addr.port()))
}
// Remember the first packet we read? It probably also has some body data. This op quickly copies it into
// a buffer and sets up channels for streaming the rest.
#[op]
@ -934,7 +954,7 @@ fn run_server(
match token {
Token(0) => loop {
match listener.accept() {
Ok((mut socket, _)) => {
Ok((mut socket, addr)) => {
counter += 1;
let token = Token(counter);
poll
@ -960,6 +980,7 @@ fn run_server(
read_lock: Arc::new(Mutex::new(())),
parse_done: ParseStatus::None,
buffer: UnsafeCell::new(vec![0_u8; 1024]),
addr,
});
trace!("New connection: {}", token.0);
@ -1524,6 +1545,7 @@ pub fn init<P: FlashPermissions + 'static>(unstable: bool) -> Extension {
op_flash_method::decl(),
op_flash_path::decl(),
op_flash_headers::decl(),
op_flash_addr::decl(),
op_flash_next::decl(),
op_flash_next_server::decl(),
op_flash_next_async::decl(),

View file

@ -29,6 +29,7 @@ pub struct Stream {
pub parse_done: ParseStatus,
pub buffer: UnsafeCell<Vec<u8>>,
pub read_lock: Arc<Mutex<()>>,
pub addr: std::net::SocketAddr,
}
impl Stream {