120 lines
3.2 KiB
TypeScript
120 lines
3.2 KiB
TypeScript
import { tap, expect } from '@git.zone/tstest/tapbundle';
|
|
import * as net from 'net';
|
|
|
|
/**
|
|
* Simple test to verify HTTP parsing works for ACME challenges
|
|
*/
|
|
tap.test('should parse HTTP requests correctly', async (tools) => {
|
|
tools.timeout(15000);
|
|
|
|
let receivedRequest = '';
|
|
|
|
// Create a simple HTTP server to test the parsing
|
|
const server = net.createServer((socket) => {
|
|
socket.on('data', (data) => {
|
|
receivedRequest = data.toString();
|
|
|
|
// Send response
|
|
const response = [
|
|
'HTTP/1.1 200 OK',
|
|
'Content-Type: text/plain',
|
|
'Content-Length: 2',
|
|
'',
|
|
'OK'
|
|
].join('\r\n');
|
|
|
|
socket.write(response);
|
|
socket.end();
|
|
});
|
|
});
|
|
|
|
await new Promise<void>((resolve) => {
|
|
server.listen(18091, () => {
|
|
console.log('Test server listening on port 18091');
|
|
resolve();
|
|
});
|
|
});
|
|
|
|
// Connect and send request
|
|
const client = net.connect(18091, 'localhost');
|
|
|
|
await new Promise<void>((resolve, reject) => {
|
|
client.on('connect', () => {
|
|
const request = [
|
|
'GET /.well-known/acme-challenge/test-token HTTP/1.1',
|
|
'Host: localhost:18091',
|
|
'User-Agent: test-client',
|
|
'',
|
|
''
|
|
].join('\r\n');
|
|
|
|
client.write(request);
|
|
});
|
|
|
|
client.on('data', (data) => {
|
|
const response = data.toString();
|
|
expect(response).toContain('200 OK');
|
|
client.end();
|
|
});
|
|
|
|
client.on('end', () => {
|
|
resolve();
|
|
});
|
|
|
|
client.on('error', reject);
|
|
});
|
|
|
|
// Verify we received the request
|
|
expect(receivedRequest).toContain('GET /.well-known/acme-challenge/test-token');
|
|
expect(receivedRequest).toContain('Host: localhost:18091');
|
|
|
|
server.close();
|
|
});
|
|
|
|
/**
|
|
* Test to verify ACME route configuration
|
|
*/
|
|
tap.test('should configure ACME challenge route', async () => {
|
|
// Simple test to verify the route configuration structure
|
|
const challengeRoute = {
|
|
name: 'acme-challenge',
|
|
priority: 1000,
|
|
match: {
|
|
ports: 80,
|
|
path: '/.well-known/acme-challenge/*'
|
|
},
|
|
action: {
|
|
type: 'socket-handler',
|
|
socketHandler: (socket: any, context: any) => {
|
|
socket.once('data', (data: Buffer) => {
|
|
const request = data.toString();
|
|
const lines = request.split('\r\n');
|
|
const [method, path] = lines[0].split(' ');
|
|
const token = path?.split('/').pop() || '';
|
|
|
|
const response = [
|
|
'HTTP/1.1 200 OK',
|
|
'Content-Type: text/plain',
|
|
`Content-Length: ${('challenge-response-' + token).length}`,
|
|
'Connection: close',
|
|
'',
|
|
`challenge-response-${token}`
|
|
].join('\r\n');
|
|
|
|
socket.write(response);
|
|
socket.end();
|
|
});
|
|
}
|
|
}
|
|
};
|
|
|
|
expect(challengeRoute.name).toEqual('acme-challenge');
|
|
expect(challengeRoute.match.path).toEqual('/.well-known/acme-challenge/*');
|
|
expect(challengeRoute.match.ports).toEqual(80);
|
|
expect(challengeRoute.priority).toEqual(1000);
|
|
|
|
// Socket handlers are tested differently - they handle raw sockets
|
|
expect(challengeRoute.action.socketHandler).toBeDefined();
|
|
});
|
|
|
|
tap.start(); |