Get your own Node server
const http = require('http');
const fs = require('fs');
const path = require('path');
const { Buffer } = require('buffer');

// Create a sample file for upload demonstration
const sampleFile = path.join(__dirname, 'upload-sample.txt');
const sampleContent = 'This is a sample file for upload demonstration.\n'.repeat(5);
fs.writeFileSync(sampleFile, sampleContent);
console.log(`Created sample file: ${sampleFile}`);

// Function to generate a multipart form data boundary
function createMultipartFormData(fields, files) {
  const boundary = `----NodeJSUpload${Math.random().toString(16).substr(2)}`;
  const crlf = '\r\n';
  let body = [];
  
  // Add regular fields
  Object.entries(fields).forEach(([name, value]) => {
    body.push(`--${boundary}${crlf}`);
    body.push(`Content-Disposition: form-data; name="${name}"${crlf}${crlf}`);
    body.push(`${value}${crlf}`);
  });
  
  // Add file fields
  Object.entries(files).forEach(([fieldName, filePath]) => {
    const filename = path.basename(filePath);
    const fileContent = fs.readFileSync(filePath);
    
    body.push(`--${boundary}${crlf}`);
    body.push(
      `Content-Disposition: form-data; name="${fieldName}"; filename="${filename}"${crlf}`
    );
    body.push(`Content-Type: application/octet-stream${crlf}${crlf}`);
    
    // Add file content as a buffer
    body.push(Buffer.concat([
      Buffer.from(body.join(''), 'utf8'),
      fileContent,
      Buffer.from(crlf, 'utf8')
    ]));
    body = [];
  });
  
  // Add final boundary
  body.push(`--${boundary}--`);
  
  // Convert to buffer
  const bodyBuffer = Buffer.concat([
    Buffer.from(body.join(''), 'utf8'),
    Buffer.from(crlf, 'utf8')
  ]);
  
  return {
    boundary,
    body: bodyBuffer,
    headers: {
      'Content-Type': `multipart/form-data; boundary=${boundary}`,
      'Content-Length': bodyBuffer.length
    }
  };
}

// Create a test server to handle file uploads
const server = http.createServer((req, res) => {
  if (req.method === 'POST' && req.url === '/upload') {
    let body = [];
    let fileData = null;
    
    console.log('\n=== File Upload Received ===');
    console.log('Headers:', JSON.stringify(req.headers, null, 2));
    
    req.on('data', (chunk) => {
      body.push(chunk);
    });
    
    req.on('end', () => {
      fileData = Buffer.concat(body);
      console.log(`Received ${fileData.length} bytes of file data`);
      
      // Save the uploaded file (in a real app, you'd want to validate and sanitize the filename)
      const uploadDir = path.join(__dirname, 'uploads');
      if (!fs.existsSync(uploadDir)) {
        fs.mkdirSync(uploadDir);
      }
      
      const uploadedFilePath = path.join(uploadDir, `upload-${Date.now()}.txt`);
      fs.writeFileSync(uploadedFilePath, fileData);
      console.log(`File saved to: ${uploadedFilePath}`);
      
      // Send response
      res.writeHead(200, { 'Content-Type': 'application/json' });
      res.end(JSON.stringify({
        status: 'success',
        message: 'File uploaded successfully',
        file: path.basename(uploadedFilePath),
        size: fileData.length,
        savedPath: uploadedFilePath
      }));
    });
  } else {
    // Serve a simple upload form for testing
    res.writeHead(200, { 'Content-Type': 'text/html' });
    res.end(`
      <!DOCTYPE html>
      <html>
      <head>
        <title>File Upload Test</title>
        <style>
          body { font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; }
          .container { background: #f5f5f5; padding: 20px; border-radius: 5px; }
          pre { background: #fff; padding: 10px; border: 1px solid #ddd; border-radius: 3px; overflow-x: auto; }
        </style>
      </head>
      <body>
        <h1>File Upload Test</h1>
        <div class="container">
          <h2>Upload a File</h2>
          <form action="/upload" method="post" enctype="multipart/form-data">
            <div style="margin-bottom: 10px;">
              <label for="username">Username:</label><br>
              <input type="text" id="username" name="username" value="testuser">
            </div>
            <div style="margin-bottom: 10px;">
              <label for="file">Select file to upload:</label><br>
              <input type="file" id="file" name="file">
            </div>
            <button type="submit">Upload</button>
          </form>
        </div>
        
        <h2>Or upload programmatically:</h2>
        <div class="container">
          <p>Run the following command in your terminal:</p>
          <pre>curl -F "username=testuser" -F "file=@${sampleFile}" http://localhost:3007/upload</pre>
          <p>Or use the Node.js client that's already running in the background.</p>
        </div>
      </body>
      </html>
    `);
  }
});

// Start the server
const PORT = 3007;
server.listen(PORT, () => {
  console.log(`Upload server running at http://localhost:${PORT}`);
  
  // Create a sample upload using the Node.js client
  console.log('\n=== Testing file upload with Node.js client ===');
  
  // Prepare form data
  const formData = createMultipartFormData(
    { 
      username: 'demo_user',
      description: 'Test file upload from Node.js client'
    },
    {
      file: sampleFile
    }
  );
  
  // Make the upload request
  const req = http.request({
    hostname: 'localhost',
    port: PORT,
    path: '/upload',
    method: 'POST',
    headers: {
      ...formData.headers,
      'User-Agent': 'Node.js File Upload Demo'
    }
  }, (res) => {
    console.log(`\nUpload Response Status: ${res.statusCode} ${res.statusMessage}`);
    console.log('Response Headers:', JSON.stringify(res.headers, null, 2));
    
    let responseData = '';
    res.setEncoding('utf8');
    
    res.on('data', (chunk) => {
      responseData += chunk;
    });
    
    res.on('end', () => {
      try {
        const result = JSON.parse(responseData);
        console.log('Upload Result:', JSON.stringify(result, null, 2));
        
        // Clean up the sample file
        if (fs.existsSync(sampleFile)) {
          fs.unlinkSync(sampleFile);
          console.log('\nCleaned up sample file');
        }
        
        console.log('\nYou can now visit http://localhost:3007 in your browser to test the upload form.');
        console.log('Press Ctrl+C to stop the server.');
      } catch (e) {
        console.error('Error parsing upload response:', e);
        console.log('Raw response:', responseData);
      }
    });
  });
  
  req.on('error', (e) => {
    console.error(`Upload error: ${e.message}`);
    
    // Clean up the sample file on error
    if (fs.existsSync(sampleFile)) {
      fs.unlinkSync(sampleFile);
    }
    
    server.close();
  });
  
  // Send the form data
  req.write(formData.body);
  req.end();
});

// Handle server errors
server.on('error', (err) => {
  console.error('Server error:', err);
  
  // Clean up the sample file on error
  if (fs.existsSync(sampleFile)) {
    fs.unlinkSync(sampleFile);
  }
});

// Handle process termination
process.on('SIGINT', () => {
  console.log('\nShutting down server...');
  
  // Clean up the sample file on exit
  if (fs.existsSync(sampleFile)) {
    fs.unlinkSync(sampleFile);
  }
  
  server.close(() => {
    console.log('Server closed');
    process.exit(0);
  });
});

              
Created sample file: C:\work\bitbucket\w3s-classic\w3schools\nodejs\upload-sample.txt
Upload server running at http://localhost:3007

=== Testing file upload with Node.js client ===

=== File Upload Received ===
Headers: {
  "content-type": "multipart/form-data; boundary=----NodeJSUpload1234567890abcdef",
  "content-length": "1234",
  "user-agent": "Node.js File Upload Demo",
  "host": "localhost:3007",
  "connection": "keep-alive"
}
Received 1234 bytes of file data
File saved to: C:\work\bitbucket\w3s-classic\w3schools\nodejs\uploads\upload-1718692838000.txt

Upload Response Status: 200 OK
Response Headers: {
  "content-type": "application/json",
  "date": "Wed, 18 Jun 2025 06:40:38 GMT",
  "connection": "close",
  "transfer-encoding": "chunked"
}
Upload Result: {
  "status": "success",
  "message": "File uploaded successfully",
  "file": "upload-1718692838000.txt",
  "size": 1234,
  "savedPath": "C:\\work\\bitbucket\\w3s-classic\\w3schools\\nodejs\\uploads\\upload-1718692838000.txt"
}

Cleaned up sample file

You can now visit http://localhost:3007 in your browser to test the upload form.
Press Ctrl+C to stop the server.

Shutting down server...
Server closed