Am I online?

Recently, I was working on an application that needed to know if it was connected to the internet. A common way to do this is to ping DNS servers like 8.8.8.8 (Google) or 1.1.1.1 (Cloudflare). However, this uses the ICMP protocol (which only checks for basic network connectivity), while I wanted to exercise the full stack used by real HTTP clients: DNS, TCP, and HTTP.

Generate 204

After some research, I found this URL that Google itself seems to use in Chrome to check for connectivity:

http://google.com/generate_204
https://google.com/generate_204

The URL returns a 204 No Content HTTP status (a successful response without a body). It's super fast, relies only on the core Google infrastructure (so it's unlikely to fail), and supports both HTTP and HTTPS. So I went with it, and it turned out to be sufficient for my needs.

There are also http://www.gstatic.com/generate_204 and http://clients3.google.com/generate_204. As far as I can tell, they are served by the same backend as the one on google.com.

Other companies provide similar URLs to check for connectivity:

  • http://cp.cloudflare.com/generate_204 (Cloudflare)
  • http://edge-http.microsoft.com/captiveportal/generate_204 (Microsoft)
  • http://connectivity-check.ubuntu.com (Ubuntu)
  • http://connect.rom.miui.com/generate_204 (Xiaomi)

200 OK

Some companies provide 200 OK endpoints instead of 204 No Content:

  • http://spectrum.s3.amazonaws.com/kindle-wifi/wifistub.html (Amazon)
  • http://captive.apple.com/hotspot-detect.html (Apple)
  • http://network-test.debian.org/nm (Debian)
  • http://nmcheck.gnome.org/check_network_status.txt (Gnome)
  • http://www.msftncsi.com/ncsi.txt (Microsoft)
  • http://detectportal.firefox.com/success.txt (Mozilla)

They are all reasonably fast and return compact responses.

Implementation

Finally, here's a simple internet connectivity check implemented in several programming languages. It uses Google's URL, but you can replace it with any of the others listed above.

Python:

import datetime as dt
import http.client

def is_online(timeout: dt.timedelta = dt.timedelta(seconds=1)) -> bool:
    """Checks if there is an internet connection."""
    try:
        conn = http.client.HTTPConnection(
            "google.com",
            timeout=timeout.total_seconds(),
        )
        conn.request("GET", "/generate_204")
        response = conn.getresponse()
        return response.status in (200, 204)
    except Exception:
        return False
    finally:
        conn.close()

JavaScript:

// isOnline checks if there is an internet connection.
async function isOnline(timeoutMs) {
    try {
        const url = "http://google.com/generate_204";
        const response = await fetch(url, {
            signal: AbortSignal.timeout(timeoutMs ?? 1000),
        });
        return response.status === 200 || response.status === 204;
    } catch (error) {
        return false;
    }
}

Shell:

#!/usr/bin/env sh

# Checks if there is an internet connection.
is_online() {
    local url="http://google.com/generate_204"
    local timeout=${1:-1}
    local response=$(
        curl \
        --output /dev/null \
        --write-out "%{http_code}" \
        --max-time "$timeout" \
        --silent \
        "$url"
    )
    if [ "$response" = "200" ] || [ "$response" = "204" ]; then
        return 0
    else
        return 1
    fi
}

Go:

package main

import (
    "context"
    "net/http"
)

// isOnline checks if there is an internet connection.
func isOnline(ctx context.Context) bool {
    const url = "http://google.com/generate_204"

    req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
    if err != nil {
        return false
    }

    resp, err := http.DefaultClient.Do(req)
    if err != nil {
        return false
    }

    defer resp.Body.Close()
    return resp.StatusCode == http.StatusOK || resp.StatusCode == http.StatusNoContent
}

Final thoughts

I'm not a big fan of Google, but I think it's nice of them to provide a publicly available endpoint to check internet connectivity. The same goes for Cloudflare and the other companies mentioned in this post.

Do you know of other similar endpoints? Let me know! @ohmypy (Twitter/X) or @antonz.org (Bluesky)

★ Subscribe to keep up with new posts.