/** * Mock HTTP server for testing the HTTP client * Replaces external dependency on httpbin.org with a local server */ export class MockServer { private server: ReturnType | null = null; private port: number = 0; /** * Start the mock server on a random port */ async start(): Promise { this.server = Bun.serve({ port: 1, // Use any available port fetch: this.handleRequest.bind(this), error: this.handleError.bind(this), }); this.port = this.server.port || 1; console.log(`Mock server started on port ${this.port}`); } /** * Stop the mock server */ async stop(): Promise { if (this.server) { this.server.stop(true); this.server = null; this.port = 0; console.log('Mock server stopped'); } } /** * Get the base URL of the mock server */ getBaseUrl(): string { if (!this.server) { throw new Error('Server not started'); } return `http://localhost:${this.port}`; } /** * Handle incoming requests */ private async handleRequest(req: Request): Promise { const url = new URL(req.url); const path = url.pathname; console.log(`Mock server handling request: ${req.method} ${path}`); // Status endpoints if (path.startsWith('/status/')) { const status = parseInt(path.replace('/status/', ''), 10); console.log(`Returning status: ${status}`); return new Response(null, { status }); } // Headers endpoint if (path === '/headers') { const headers = Object.fromEntries([...req.headers.entries()]); console.log('Headers endpoint called, received headers:', headers); return Response.json({ headers }); } // Basic auth endpoint if (path.startsWith('/basic-auth/')) { const parts = path.split('/').filter(Boolean); const expectedUsername = parts[1]; const expectedPassword = parts[2]; console.log( `Basic auth endpoint called: expected user=${expectedUsername}, pass=${expectedPassword}` ); const authHeader = req.headers.get('authorization'); if (!authHeader || !authHeader.startsWith('Basic ')) { console.log('Missing or invalid Authorization header'); return new Response('Unauthorized', { status: 401 }); } const base64Credentials = authHeader.split(' ')[1]; const credentials = atob(base64Credentials); const [username, password] = credentials.split(':'); if (username === expectedUsername && password === expectedPassword) { return Response.json({ authenticated: true, user: username, }); } return new Response('Unauthorized', { status: 401 }); } // Echo request body if (path === '/post' && req.method === 'POST') { const data = await req.json(); return Response.json({ data, headers: Object.fromEntries([...req.headers.entries()]), method: req.method, }); } // Default response return Response.json({ url: req.url, method: req.method, headers: Object.fromEntries([...req.headers.entries()]), }); } /** * Handle errors */ private handleError(error: Error): Response { return new Response('Server error', { status: 500 }); } }