Skip to content

Commit 381ae3c

Browse files
committed
fix(realtime): noindex the socket server's 404 responses
The sockets.* hostnames are served by this server and return a plain JSON 404, which Google Search Console reports as crawl errors. Mark unmatched routes noindex so crawlers drop the hostnames instead of retrying them.
1 parent c0b19da commit 381ae3c

2 files changed

Lines changed: 48 additions & 1 deletion

File tree

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import type { IncomingMessage, ServerResponse } from 'http'
2+
import { describe, expect, it, vi } from 'vitest'
3+
import type { IRoomManager } from '@/rooms'
4+
import { createHttpHandler } from '@/routes/http'
5+
6+
function createMocks(req: Partial<IncomingMessage>) {
7+
const writeHead = vi.fn()
8+
const end = vi.fn()
9+
const logger = { info: vi.fn(), error: vi.fn(), debug: vi.fn(), warn: vi.fn() }
10+
const roomManager = {
11+
getTotalActiveConnections: vi.fn().mockResolvedValue(0),
12+
isReady: vi.fn().mockReturnValue(true),
13+
} as unknown as IRoomManager
14+
15+
return {
16+
handler: createHttpHandler(roomManager, logger),
17+
req: { headers: {}, ...req } as IncomingMessage,
18+
res: { writeHead, end } as unknown as ServerResponse,
19+
writeHead,
20+
end,
21+
}
22+
}
23+
24+
describe('createHttpHandler', () => {
25+
it('marks unmatched routes noindex so crawlers drop the socket hostnames', async () => {
26+
const { handler, req, res, writeHead, end } = createMocks({ method: 'GET', url: '/' })
27+
28+
await handler(req, res)
29+
30+
expect(writeHead).toHaveBeenCalledWith(404, {
31+
'Content-Type': 'application/json',
32+
'X-Robots-Tag': 'noindex, nofollow',
33+
})
34+
expect(end).toHaveBeenCalledWith(JSON.stringify({ error: 'Not found' }))
35+
})
36+
37+
it('does not mark the health check noindex', async () => {
38+
const { handler, req, res, writeHead } = createMocks({ method: 'GET', url: '/health' })
39+
40+
await handler(req, res)
41+
42+
expect(writeHead).toHaveBeenCalledWith(200, { 'Content-Type': 'application/json' })
43+
})
44+
})

apps/realtime/src/routes/http.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,10 @@ export function createHttpHandler(roomManager: IRoomManager, logger: Logger) {
150150
return
151151
}
152152

153-
res.writeHead(404, { 'Content-Type': 'application/json' })
153+
res.writeHead(404, {
154+
'Content-Type': 'application/json',
155+
'X-Robots-Tag': 'noindex, nofollow',
156+
})
154157
res.end(JSON.stringify({ error: 'Not found' }))
155158
}
156159
}

0 commit comments

Comments
 (0)