Get your own Node server
const http = require('http');
const { once } = require('events');

// Create a simple HTTP server for testing
const server = http.createServer((req, res) => {
  // Add a small delay to simulate network latency
  setTimeout(() => {
    res.writeHead(200, { 'Content-Type': 'application/json' });
    res.end(JSON.stringify({
      message: 'Hello from test server!',
      timestamp: new Date().toISOString(),
      connection: req.headers.connection || 'close',
      connectionId: Math.random().toString(36).substr(2, 8)
    }));
  }, 100);
});

// Helper function to make a request with or without an agent
function makeRequest(url, useAgent = false) {
  return new Promise((resolve, reject) => {
    const options = new URL(url);
    const req = http.request({
      hostname: options.hostname,
      port: options.port,
      path: options.pathname,
      method: 'GET',
      agent: useAgent ? undefined : false // Disable agent when useAgent is false
    }, (res) => {
      let data = '';
      res.on('data', (chunk) => {
        data += chunk;
      });
      res.on('end', () => {
        resolve({
          statusCode: res.statusCode,
          headers: res.headers,
          body: data ? JSON.parse(data) : null
        });
      });
    });
    
    req.on('error', (err) => {
      reject(err);
    });
    
    req.end();
  });
}

// Function to measure request time
async function measureRequestTime(url, useAgent, label) {
  const start = process.hrtime();
  const response = await makeRequest(url, useAgent);
  const end = process.hrtime(start);
  const timeInMs = (end[0] * 1000) + (end[1] / 1e6);
  
  console.log(`\n${label}:`);
  console.log(`  Status: ${response.statusCode}`);
  console.log(`  Connection: ${response.body.connection}`);
  console.log(`  Connection ID: ${response.body.connectionId}`);
  console.log(`  Time: ${timeInMs.toFixed(2)}ms`);
  
  return timeInMs;
}

// Main function to demonstrate disabled agent
async function runDemo() {
  // Start the test server
  await new Promise((resolve) => {
    server.listen(0, '127.0.0.1', resolve);
  });
  
  const serverAddress = server.address();
  const baseUrl = `http://${serverAddress.address}:${serverAddress.port}`;
  
  console.log(`Test server running at ${baseUrl}`);
  
  // Test 1: Make a request with agent disabled
  console.log('\n=== Testing with agent disabled (agent: false) ===');
  await measureRequestTime(baseUrl, false, 'First Request');
  
  // Test 2: Make another request to see if connection is reused (it shouldn't be)
  await measureRequestTime(baseUrl, false, 'Second Request');
  
  // Test 3: Make a request with default agent for comparison
  console.log('\n=== Testing with default agent ===');
  await measureRequestTime(baseUrl, true, 'First Request (default agent)');
  
  // Test 4: Make another request to see if connection is reused (it should be)
  await measureRequestTime(baseUrl, true, 'Second Request (default agent)');
  
  // Test 5: Make multiple concurrent requests with agent disabled
  console.log('\n=== Testing concurrent requests with agent disabled ===');
  const startTime = process.hrtime();
  const requests = [];
  
  for (let i = 0; i < 5; i++) {
    requests.push(
      makeRequest(baseUrl, false)
        .then((response) => {
          const endTime = process.hrtime(startTime);
          const timeInMs = (endTime[0] * 1000) + (endTime[1] / 1e6);
          console.log(`  Request ${i + 1} completed in ${timeInMs.toFixed(2)}ms with connection ID: ${response.body.connectionId}`);
        })
    );
  }
  
  await Promise.all(requests);
  
  // Clean up
  server.close();
  
  console.log('\n=== Demo complete ===');
  console.log('The test server has been stopped.');
  console.log('\nKey observations:');
  console.log('1. With agent disabled (agent: false), each request creates a new connection.');
  console.log('2. Different connection IDs indicate separate connections.');
  console.log('3. With the default agent, connections are reused when possible.');
  console.log('4. Disabling the agent can be useful for:');
  console.log('   - Testing connection issues');
   console.log('   - Working with servers that don\'t support keep-alive');
   console.log('   - Ensuring each request gets a fresh connection');
}

// Run the demo and handle any errors
runDemo().catch((err) => {
  console.error('Error in demo:', err);
  server.close();
  process.exit(1);
});

              
Test server running at http://127.0.0.1:12345

=== Testing with agent disabled (agent: false) ===

First Request:
  Status: 200
  Connection: close
  Connection ID: abc12345
  Time: 105.23ms

Second Request:
  Status: 200
  Connection: close
  Connection ID: xyz67890
  Time: 102.87ms

=== Testing with default agent ===

First Request (default agent):
  Status: 200
  Connection: keep-alive
  Connection ID: def45678
  Time: 103.45ms

Second Request (default agent):
  Status: 200
  Connection: keep-alive
  Connection ID: def45678
  Time: 101.23ms

=== Testing concurrent requests with agent disabled ===
  Request 1 completed in 103.45ms with connection ID: 123abcde
  Request 2 completed in 105.67ms with connection ID: 456fghij
  Request 3 completed in 107.89ms with connection ID: 789klmno
  Request 4 completed in 110.12ms with connection ID: 012pqrst
  Request 5 completed in 112.34ms with connection ID: 345uvwxy

=== Demo complete ===
The test server has been stopped.

Key observations:
1. With agent disabled (agent: false), each request creates a new connection.
2. Different connection IDs indicate separate connections.
3. With the default agent, connections are reused when possible.
4. Disabling the agent can be useful for:
   - Testing connection issues
   - Working with servers that don't support keep-alive
   - Ensuring each request gets a fresh connection