mirror of
https://github.com/Myzel394/amiopen.now.git
synced 2025-06-18 15:35:27 +02:00
fix: Properly handle timeouts
This commit is contained in:
parent
1390ef247c
commit
c60913b796
@ -5,7 +5,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"hono": "^4.6.9",
|
||||
"id": "^0.0.0",
|
||||
"ip": "^2.0.1",
|
||||
"zod": "^3.23.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
18
src/index.ts
18
src/index.ts
@ -1,19 +1,11 @@
|
||||
import { Hono } from 'hono'
|
||||
import {getConnInfo} from "hono/bun"
|
||||
import connectToAddress from './utils/connect-to-address'
|
||||
import { portRoute } from './routes/port'
|
||||
|
||||
const app = new Hono()
|
||||
|
||||
app.get('/:port', async context => {
|
||||
const port = Number(context.req.param("port"))
|
||||
const info = getConnInfo(context)
|
||||
const ipAddress = info.remote.address!
|
||||
|
||||
const result = await connectToAddress(ipAddress, port)
|
||||
|
||||
return context.json({
|
||||
isOpen: result.isOpen
|
||||
})
|
||||
})
|
||||
app.route(
|
||||
"/",
|
||||
portRoute,
|
||||
)
|
||||
|
||||
export default app
|
||||
|
@ -7,8 +7,8 @@ import * as IP from "ip"
|
||||
export const portRoute = new Hono();
|
||||
|
||||
const schema = z.object({
|
||||
ip: z.string().refine(ip => !IP.isPublic(ip), "This IP address is not valid"),
|
||||
port: z.coerce.number().min(1).max(2**16 - 1),
|
||||
ip: z.string().refine(ip => IP.isPublic(ip), "This IP address is not valid"),
|
||||
port: z.string().transform(Number).pipe(z.number().min(1).max(2**16 - 1)),
|
||||
});
|
||||
|
||||
portRoute.get("/:port", async context => {
|
||||
@ -31,3 +31,23 @@ portRoute.get("/:port", async context => {
|
||||
isOpen: result.isOpen
|
||||
})
|
||||
});
|
||||
|
||||
portRoute.get("/:ip/:port", async context => {
|
||||
const rawData = {
|
||||
ip: context.req.param("ip"),
|
||||
port: context.req.param("port"),
|
||||
};
|
||||
const parsedData = schema.safeParse(rawData);
|
||||
|
||||
if (!parsedData.success) {
|
||||
return context.json({ error: parsedData.error }, 401);
|
||||
}
|
||||
|
||||
const { ip, port } = parsedData.data;
|
||||
|
||||
const result = await connectToAddress(ip, port)
|
||||
|
||||
return context.json({
|
||||
isOpen: result.isOpen
|
||||
})
|
||||
})
|
||||
|
@ -1,43 +1,54 @@
|
||||
import * as net from "net"
|
||||
|
||||
export interface ConnectionResult {
|
||||
isOpen: boolean
|
||||
}
|
||||
|
||||
const TIMEOUT = 5
|
||||
const TIMEOUT = 5_000
|
||||
|
||||
export default function connectToAddress(address: string, port: number): Promise<ConnectionResult> {
|
||||
return new Promise<ConnectionResult>(async (resolve) => {
|
||||
const socket = await Bun.connect({
|
||||
hostname: address,
|
||||
port: port,
|
||||
|
||||
socket: {
|
||||
open(socket) {
|
||||
const onIsOpen = () => {
|
||||
if (!socket.destroyed) {
|
||||
socket.end()
|
||||
socket.destroy()
|
||||
}
|
||||
|
||||
resolve({
|
||||
isOpen: true
|
||||
})
|
||||
},
|
||||
data() {
|
||||
},
|
||||
connectError() {
|
||||
resolve({
|
||||
isOpen: false
|
||||
})
|
||||
},
|
||||
error(socket) {
|
||||
socket.end()
|
||||
resolve({
|
||||
isOpen: false
|
||||
})
|
||||
},
|
||||
timeout() {
|
||||
resolve({
|
||||
isOpen: false
|
||||
})
|
||||
},
|
||||
}
|
||||
})
|
||||
const onIsClosed = () => {
|
||||
if (!socket.destroyed) {
|
||||
socket.end()
|
||||
socket.destroy()
|
||||
}
|
||||
|
||||
socket.timeout(TIMEOUT)
|
||||
resolve({
|
||||
isOpen: false
|
||||
})
|
||||
}
|
||||
|
||||
const socket = new net.Socket()
|
||||
|
||||
// The `setTimeout` function from a socket does not work when connecting,
|
||||
// so we need to use a custom timeout function ourselves.
|
||||
setTimeout(() => {
|
||||
if (!socket.destroyed) {
|
||||
socket.end()
|
||||
socket.destroy()
|
||||
}
|
||||
|
||||
resolve({
|
||||
isOpen: false
|
||||
})
|
||||
}, TIMEOUT)
|
||||
|
||||
socket.on("ready", onIsOpen)
|
||||
socket.on("close", onIsClosed)
|
||||
socket.on("error", onIsClosed)
|
||||
socket.on("timeout", onIsClosed)
|
||||
|
||||
socket.connect(port, address)
|
||||
})
|
||||
}
|
||||
|
4
src/utils/timeout.ts
Normal file
4
src/utils/timeout.ts
Normal file
@ -0,0 +1,4 @@
|
||||
export default function timeout(ms: number): Promise<void> {
|
||||
return new Promise(resolve => setTimeout(resolve, ms))
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user