---
name: verify-site-availability-using-nodejs
category: devops
description: Check if a website is reachable and returns expected content using Node.js when standard tools like curl or wget are unavailable.
---

This skill provides a reusable way to verify site availability using only Node.js (which is commonly present in many environments). It is useful when you cannot rely on external utilities like curl, wget, or netcat.

## When to use
- You need to confirm a site is up and responding with HTTP 200.
- Standard HTTP checking tools are not installed or blocked.
- You have Node.js available (version >=10 recommended for built-in `https` module).
- You want a lightweight, dependency-free check.

## Steps

### 1. Create a verification script
Save the following as `check-site.js` (or any name):

```js
const https = require('https');
const http = require('http');

function fetchSite(url, options = {}) {
  return new Promise((resolve, reject) => {
    const lib = url.startsWith('https') ? https : http;
    const req = lib.get(url, (res) => {
      let data = '';
      res.on('data', chunk => data += chunk);
      res.on('end', () => {
        resolve({
          statusCode: res.statusCode,
          headers: res.headers,
          body: data
        });
      });
    });
    req.on('error', (err) => {
      reject(err);
    });
    // optional timeout
    if (options.timeout) {
      req.setTimeout(options.timeout, () => {
        req.destroy();
        reject(new Error(`Request timeout after ${options.timeout} ms`));
      });
    }
  });
}

// Usage example:
(async () => {
  const target = process.argv[2] || 'https://sailor.bar';
  const timeoutMs = parseInt(process.argv[3]) || 5000;

  try {
    const result = await fetchSite(target, { timeout: timeoutMs });
    console.log(`Status: ${result.statusCode}`);
    console.log(`Headers:`, JSON.stringify(result.headers, null, 2));
    console.log(`Body length: ${result.body.length}`);
    // Optionally check for expected string
    if (options.expect && !result.body.includes(options.expect)) {
      console.warn(`Warning: expected string "${options.expect}" not found in body`);
    }
    process.exit(result.statusCode === 200 ? 0 : 1);
  } catch (err) {
    console.error(`Error fetching ${target}:`, err.message);
    process.exit(1);
  }
})();
```

### 2. Run the script
```bash
node check-site.js https://sailor.bar 5000
```
- First argument: URL to check (default can be hardcoded).
- Second argument: timeout in milliseconds (optional).

### 3. Interpret the result
- Exit code `0` means success (status 200, or whatever you define as success).
- Non‑zero exit code indicates failure (network error, timeout, non‑200 status, etc.).
- The script prints status, headers, and body length to stdout for quick inspection.

## Adaptations
- **Custom success condition**: Change `process.exit` line to accept other status codes (e.g., 301 redirect).
- **Body validation**: Add a fourth argument for a string that must appear in the response.
- **Output format**: Modify to output JSON only for machine consumption.
- **Authentication**: Add headers (e.g., Authorization) by setting `req.setHeader` before `req.end()` (need to use `request` method instead of `get`).

## Notes
- Uses only Node.js core modules, no npm dependencies.
- Follows redirects automatically (the underlying http/https modules do not follow redirects; if you need redirect handling, implement checking of status codes 301/302 and manually follow the `location` header, or use a lightweight dependency like `follow-redirects` if allowed).
- In environments where even Node.js is missing, consider installing it via the official binary or using a container—outside the scope of this skill.

---
*Skill created: $(date +%Y-%m-%d)*