online / endpoints 59 / categories 14 / rate 60/min/ip /

GET /etag

GET /etag

Returns ETag and Last-Modified headers that break HTTP conditional-request semantics. Tests caches, CDNs, and clients that rely on validators.

mode random-etag (default; different ETag every call for identical content), stable-etag-mutated-body (same ETag, body changes), weak-strong-conflict (both strong and weak ETag headers), unquoted (ETag without required quotes), future-last-modified (Last-Modified in 2099).
build a request:

expect: 200 OK with a Content-Type of application/json and an ETag (and sometimes Last-Modified) header that violates RFC 9110 in the chosen way. X-Chaos-Etag-Mode reflects the selection; click try-it twice to see how the mode behaves across calls.

bash
# Two calls — observe how the ETag and body change across them
curl -is 'https://chaos.catastrophic.io/etag?mode=random-etag' | grep -iE '^(etag|last-modified|x-chaos-etag-mode):'
curl -is 'https://chaos.catastrophic.io/etag?mode=random-etag' | grep -iE '^(etag|last-modified|x-chaos-etag-mode):'
import urllib.request
for i in range(2):
    resp = urllib.request.urlopen("https://chaos.catastrophic.io/etag?mode=random-etag")
    etag = resp.headers["ETag"]
    lm = resp.headers["Last-Modified"]
    print(f"call {i+1}: ETag={etag!r} Last-Modified={lm!r}")
    print("  body:", resp.read().decode()[:120])
for (let i = 0; i < 2; i++) {
    const res = await fetch("https://chaos.catastrophic.io/etag?mode=random-etag");
    console.log(`call ${i+1}:`, res.headers.get("etag"), res.headers.get("last-modified"));
    console.log("  body:", (await res.text()).slice(0, 120));
}
package main

import (
    "fmt"
    "io"
    "net/http"
)

func main() {
    for i := 1; i <= 2; i++ {
        resp, _ := http.Get("https://chaos.catastrophic.io/etag?mode=random-etag")
        body, _ := io.ReadAll(resp.Body)
        resp.Body.Close()
        fmt.Printf("call %d: ETag=%q Last-Modified=%q\n",
            i, resp.Header.Get("ETag"), resp.Header.Get("Last-Modified"))
        fmt.Printf("  body: %s\n", string(body)[:min(120, len(body))])
    }
}

func min(a, b int) int { if a < b { return a }; return b }
// Cargo.toml: reqwest = { version = "0.12", features = ["blocking"] }
fn main() -> Result<(), Box> {
    let client = reqwest::blocking::Client::new();
    for i in 1..=2 {
        let resp = client.get("https://chaos.catastrophic.io/etag?mode=random-etag").send()?;
        println!("call {i}: ETag={:?} Last-Modified={:?}",
            resp.headers().get("etag"), resp.headers().get("last-modified"));
        println!("  body: {}", &resp.text()?[..120.min(usize::MAX)]);
    }
    Ok(())
}
import java.net.URI;
import java.net.http.*;

public class EtagChaos {
    public static void main(String[] args) throws Exception {
        var client = HttpClient.newHttpClient();
        var req = HttpRequest.newBuilder(URI.create("https://chaos.catastrophic.io/etag?mode=random-etag")).build();
        for (int i = 1; i <= 2; i++) {
            var resp = client.send(req, HttpResponse.BodyHandlers.ofString());
            System.out.printf("call %d: ETag=%s Last-Modified=%s%n",
                i,
                resp.headers().firstValue("ETag").orElse(""),
                resp.headers().firstValue("Last-Modified").orElse(""));
        }
    }
}
using var client = new HttpClient();
for (int i = 1; i <= 2; i++)
{
    var resp = await client.GetAsync("https://chaos.catastrophic.io/etag?mode=random-etag");
    var etag = resp.Headers.ETag?.Tag ?? "";
    var lm = resp.Content.Headers.LastModified?.ToString("R") ?? "";
    Console.WriteLine($"call {i}: ETag={etag} Last-Modified={lm}");
}
require "net/http"
uri = URI("https://chaos.catastrophic.io/etag?mode=random-etag")
2.times do |i|
    res = Net::HTTP.get_response(uri)
    puts "call #{i+1}: ETag=#{res['ETag'].inspect} Last-Modified=#{res['Last-Modified'].inspect}"
end
1..2 | ForEach-Object {
    $r = Invoke-WebRequest -Uri 'https://chaos.catastrophic.io/etag?mode=random-etag'
    "call $($_): ETag=$($r.Headers['ETag']) Last-Modified=$($r.Headers['Last-Modified'])"
}