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

GET /atom

GET /atom

Returns Atom 1.0 feeds (RFC 4287) with spec violations. Default omits the required entry id element. Use ?mode= to isolate other violations: wrong date format, missing author, or incorrect rel=self link.

mode Which violation to send. One of: entry-id-missing (default; entry <id> absent, breaking aggregator deduplication), updated-wrong-format (<updated> uses RFC 822 instead of required RFC 3339), author-missing (no <author> on entry or feed level), link-rel-self-wrong (<link rel="self"> href points to a different host).
build a request:

expect: An Atom 1.0 document served as application/atom+xml with one of four spec violations. X-Chaos-Atom-Note explains what is wrong.

bash
curl -si 'https://chaos.catastrophic.io/atom?mode=entry-id-missing' | grep -E '^(HTTP|content-type|x-chaos-atom)'
# Default mode (entry-id-missing) drops the  from each .
# RFC 4287 §4.1.2 requires it. Aggregators that key off id for
# deduplication or "mark as read" state see undefined.
import urllib.request
from xml.etree import ElementTree as ET

resp = urllib.request.urlopen("https://chaos.catastrophic.io/atom?mode=entry-id-missing")
print("Content-Type:", resp.headers.get("Content-Type"))
print("X-Chaos-Atom-Mode:", resp.headers.get("X-Chaos-Atom-Mode"))
root = ET.fromstring(resp.read())
ns = {"atom": "http://www.w3.org/2005/Atom"}
entries = root.findall("atom:entry", ns)
print(f"entries: {len(entries)}")
for e in entries:
    eid = e.find("atom:id", ns)
    print(f"  entry id present: {eid is not None}")
// DOMParser handles Atom; check entry/id presence.
const res = await fetch("https://chaos.catastrophic.io/atom?mode=entry-id-missing");
console.log("Mode:", res.headers.get("X-Chaos-Atom-Mode"));
const raw = await res.text();
const doc = new DOMParser().parseFromString(raw, "application/xml");
const entries = doc.getElementsByTagNameNS("http://www.w3.org/2005/Atom", "entry");
console.log("entries:", entries.length);
for (const e of entries) {
  const id = e.getElementsByTagNameNS("http://www.w3.org/2005/Atom", "id");
  console.log("  entry id present:", id.length > 0);
}
package main

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

type Feed struct {
    Entries []struct {
        ID string `xml:"id"`
    } `xml:"entry"`
}

func main() {
    resp, _ := http.Get("https://chaos.catastrophic.io/atom?mode=entry-id-missing")
    defer resp.Body.Close()
    raw, _ := io.ReadAll(resp.Body)
    fmt.Println("Mode:", resp.Header.Get("X-Chaos-Atom-Mode"))
    var feed Feed
    xml.Unmarshal(raw, &feed)
    fmt.Println("entries:", len(feed.Entries))
    for _, e := range feed.Entries {
        fmt.Println("  entry id present:", e.ID != "")
    }
}
// Cargo.toml: reqwest = { version = "0.12", features = ["blocking"] }
//            quick-xml = "0.36"
fn main() -> Result<(), Box> {
    let resp = reqwest::blocking::get("https://chaos.catastrophic.io/atom?mode=entry-id-missing")?;
    println!("Mode: {:?}", resp.headers().get("x-chaos-atom-mode"));
    let body = resp.text()?;
    // Count  blocks and check for  inside each.
    let entries = body.matches("").count();
    let ids = body.matches("").count() - 1;  // subtract 1 for feed-level 
    println!("entries: {}  entry  elements: {}", entries, ids);
    Ok(())
}
import java.net.URI;
import java.net.http.*;

public class AtomChaos {
    public static void main(String[] args) throws Exception {
        var client = HttpClient.newHttpClient();
        var req = HttpRequest.newBuilder(URI.create("https://chaos.catastrophic.io/atom?mode=entry-id-missing")).build();
        var resp = client.send(req, HttpResponse.BodyHandlers.ofString());
        System.out.println("Content-Type: " + resp.headers().firstValue("Content-Type").orElse(""));
        System.out.println("X-Chaos-Atom-Mode: " + resp.headers().firstValue("X-Chaos-Atom-Mode").orElse(""));
        System.out.println("Body: " + resp.body());
    }
}
using var client = new HttpClient();
var resp = await client.GetAsync("https://chaos.catastrophic.io/atom?mode=entry-id-missing");
Console.WriteLine($"Content-Type: {resp.Content.Headers.ContentType}");
Console.WriteLine($"X-Chaos-Atom-Mode: {resp.Headers.GetValues("X-Chaos-Atom-Mode").FirstOrDefault()}");
var body = await resp.Content.ReadAsStringAsync();
Console.WriteLine($"Body: {body}");
require "net/http"
require "rexml/document"
uri = URI("https://chaos.catastrophic.io/atom?mode=entry-id-missing")
Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
    res = http.get(uri.request_uri)
    puts "Content-Type: #{res['Content-Type']}"
    puts "X-Chaos-Atom-Mode: #{res['X-Chaos-Atom-Mode']}"
    doc = REXML::Document.new(res.body)
    entries = doc.elements.to_a("//entry")
    puts "entries: #{entries.length}"
    entries.each_with_index do |e, i|
        id = e.elements["id"]
        puts "  entry[#{i}] id present: #{!id.nil?}"
    end
end
$r = Invoke-WebRequest -Uri 'https://chaos.catastrophic.io/atom?mode=entry-id-missing'
"Content-Type: $($r.Headers['Content-Type'])"
"X-Chaos-Atom-Mode: $($r.Headers['X-Chaos-Atom-Mode'])"
$xml = [xml]$r.Content
$ns = New-Object System.Xml.XmlNamespaceManager $xml.NameTable
$ns.AddNamespace('a', 'http://www.w3.org/2005/Atom')
$entries = $xml.SelectNodes('//a:entry', $ns)
"entries: $($entries.Count)"
foreach ($e in $entries) {
    $id = $e.SelectSingleNode('a:id', $ns)
    "  entry id present: $($null -ne $id)"
}