GET /partial-stream
Sends a Content-Type: application/json header and an opening fragment of a JSON object, then closes the stream cleanly after N bytes. No Content-Length, so there's no size mismatch to detect — the stream just ends before the body is complete. The result will fail JSON.parse() but doesn't look like a network error.
bytes
How many bytes of the JSON fragment to send before closing. Range: 1–16384. Default: 128.
control Compare against the well-formed counterpart: not.catastrophic.io/partial-stream side-by-side
build a request:
expect: Content-Type: application/json with an opening JSON fragment that ends before the body is valid. No Content-Length — looks like a clean stream close at the HTTP layer.
curl -i 'https://chaos.catastrophic.io/partial-stream?bytes=128'
# See what JSON.parse would do with this:
curl -s 'https://chaos.catastrophic.io/partial-stream?bytes=128' | python -c "import sys, json; json.loads(sys.stdin.read())"
import json, urllib.request
raw = urllib.request.urlopen("https://chaos.catastrophic.io/partial-stream?bytes=128").read()
print(f"Got {len(raw)} bytes (HTTP layer is fine)")
try:
json.loads(raw)
except json.JSONDecodeError as e:
print(f"JSON parse failed (expected): {e.msg}")
const res = await fetch("https://chaos.catastrophic.io/partial-stream?bytes=128");
const text = await res.text();
console.log(`HTTP ${res.status}, ${text.length} bytes`);
try {
JSON.parse(text);
} catch (e) {
console.error("JSON parse failed (expected):", e.message);
}
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
)
func main() {
resp, _ := http.Get("https://chaos.catastrophic.io/partial-stream?bytes=128")
defer resp.Body.Close()
raw, _ := io.ReadAll(resp.Body)
fmt.Printf("HTTP %d, %d bytes\n", resp.StatusCode, len(raw))
var data any
if err := json.Unmarshal(raw, &data); err != nil {
fmt.Println("JSON parse failed (expected):", err)
}
}
// Cargo.toml: reqwest = { version = "0.12", features = ["blocking"] }
// serde_json = "1"
fn main() -> Result<(), Box> {
let resp = reqwest::blocking::get("https://chaos.catastrophic.io/partial-stream?bytes=128")?;
let status = resp.status();
let raw = resp.text()?;
println!("HTTP {status}, {} bytes", raw.len());
if let Err(e) = serde_json::from_str::(&raw) {
eprintln!("JSON parse failed (expected): {e}");
}
Ok(())
}
// Requires Jackson
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.http.*;
public class PartialStream {
public static void main(String[] args) throws Exception {
var client = HttpClient.newHttpClient();
var req = HttpRequest.newBuilder(URI.create("https://chaos.catastrophic.io/partial-stream?bytes=128")).build();
var resp = client.send(req, HttpResponse.BodyHandlers.ofString());
System.out.printf("HTTP %d, %d bytes%n", resp.statusCode(), resp.body().length());
try {
new ObjectMapper().readTree(resp.body());
} catch (Exception e) {
System.err.println("JSON parse failed (expected): " + e.getMessage());
}
}
}
using System.Text.Json;
using var client = new HttpClient();
var resp = await client.GetAsync("https://chaos.catastrophic.io/partial-stream?bytes=128");
var raw = await resp.Content.ReadAsStringAsync();
Console.WriteLine($"HTTP {(int)resp.StatusCode}, {raw.Length} bytes");
try {
JsonDocument.Parse(raw);
} catch (JsonException e) {
Console.Error.WriteLine($"JSON parse failed (expected): {e.Message}");
}
require "net/http"
require "json"
res = Net::HTTP.get_response(URI("https://chaos.catastrophic.io/partial-stream?bytes=128"))
puts "HTTP #{res.code}, #{res.body.bytesize} bytes"
begin
JSON.parse(res.body)
rescue JSON::ParserError => e
puts "JSON parse failed (expected): #{e.message}"
end
$r = Invoke-WebRequest -Uri 'https://chaos.catastrophic.io/partial-stream?bytes=128'
$r.StatusCode # 200 — the HTTP layer is fine
try {
$r.Content | ConvertFrom-Json # this is where it breaks
} catch {
'JSON parse failed (expected)'
}
headers
body