GET /oauth-token
/oauth-tokenReturns a well-formed RFC 6749 §5.1 token response: `expires_in` as integer, `scope` space-delimited, `token_type` as "Bearer", `refresh_token` present. Cache-Control: no-store. Counterpart to the chaos /oauth-token endpoint.
expect: 200 OK with Cache-Control: no-store. All fields correctly typed per RFC 6749 §5.1. Build OAuth clients against this, then flip hostname to chaos.catastrophic.io to test adversity.
curl -si 'https://not.catastrophic.io/oauth-token' | grep -E '^(HTTP|cache-control|content-type|x-chaos)'
import urllib.request, json
resp = urllib.request.urlopen("https://not.catastrophic.io/oauth-token")
print("X-Chaos-Oauth-Token-Mode:", resp.headers.get("X-Chaos-Oauth-Token-Mode"))
body = json.loads(resp.read())
print("expires_in type:", type(body.get("expires_in")).__name__)
print("scope:", body.get("scope"))
print("token_type:", body.get("token_type"))
print("note:", body.get("note"))
const res = await fetch("https://not.catastrophic.io/oauth-token");
const body = await res.json();
console.log("X-Chaos-Oauth-Token-Mode:", res.headers.get("x-chaos-oauth-token-mode"));
console.log("expires_in type:", typeof body.expires_in);
console.log("scope:", body.scope);
console.log("token_type:", body.token_type);
console.log("note:", body.note);
// Attempt expiry arithmetic
const expiresAt = Date.now() + body.expires_in * 1000;
console.log("expiry calculation valid:", !isNaN(expiresAt));
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
)
func main() {
resp, _ := http.Get("https://not.catastrophic.io/oauth-token")
defer resp.Body.Close()
raw, _ := io.ReadAll(resp.Body)
var body map[string]any
json.Unmarshal(raw, &body)
fmt.Println("X-Chaos-Oauth-Token-Mode:", resp.Header.Get("X-Chaos-Oauth-Token-Mode"))
fmt.Printf("expires_in type: %T\n", body["expires_in"])
fmt.Println("scope:", body["scope"])
fmt.Println("token_type:", body["token_type"])
}
// Cargo.toml: reqwest = { version = "0.12", features = ["blocking", "json"] }
fn main() -> Result<(), Box> {
let resp = reqwest::blocking::get("https://not.catastrophic.io/oauth-token")?;
println!("X-Chaos-Oauth-Token-Mode: {:?}", resp.headers().get("x-chaos-oauth-token-mode"));
let body: serde_json::Value = resp.json()?;
println!("expires_in: {:?}", body.get("expires_in"));
println!("scope: {:?}", body.get("scope"));
println!("token_type: {:?}", body.get("token_type"));
Ok(())
}
import java.net.URI;
import java.net.http.*;
public class OauthTokenChaos {
public static void main(String[] args) throws Exception {
var client = HttpClient.newHttpClient();
var req = HttpRequest.newBuilder(URI.create("https://not.catastrophic.io/oauth-token")).build();
var resp = client.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println("X-Chaos-Oauth-Token-Mode: " +
resp.headers().firstValue("X-Chaos-Oauth-Token-Mode").orElse(""));
System.out.println("Body: " + resp.body());
}
}
using var client = new HttpClient();
var resp = await client.GetAsync("https://not.catastrophic.io/oauth-token");
Console.WriteLine($"X-Chaos-Oauth-Token-Mode: " +
$"{resp.Headers.GetValues("X-Chaos-Oauth-Token-Mode").FirstOrDefault()}");
var body = await resp.Content.ReadAsStringAsync();
Console.WriteLine($"Body: {body}");
require "net/http"
require "json"
uri = URI("https://not.catastrophic.io/oauth-token")
Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
res = http.get(uri.request_uri)
puts "X-Chaos-Oauth-Token-Mode: #{res['X-Chaos-Oauth-Token-Mode']}"
body = JSON.parse(res.body)
puts "expires_in type: #{body['expires_in'].class}"
puts "scope: #{body['scope']}"
puts "token_type: #{body['token_type']}"
end
$r = Invoke-RestMethod -Uri 'https://not.catastrophic.io/oauth-token' -ResponseHeadersVariable h
"X-Chaos-Oauth-Token-Mode: $($h['X-Chaos-Oauth-Token-Mode'])"
"expires_in type: $($r.expires_in.GetType().Name)"
"scope: $($r.scope)"
"token_type: $($r.token_type)"
headers
body