spb/internetpressure
Public
TypeScript 36.3%
Python 31.8%
Go 18%
JavaScript 9.8%
Shell 1.9%
SQL 1.4%
CSS 0.5%
1package signer23import (4 "net/http"5 "net/url"6 "strings"7 "testing"8)910// Test vectors — kept in sync with README.md ("How signing works") so the Python server can cross-check.11//12// key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f (32 bytes)13// timestamp = 1789189804 (2026-09-12T05:10:04Z)14// POST /ingest/v1/batch body = {"probe_id":"ca-qc-01","agent_version":"0.1.0","measurements":[]}15// GET /ingest/v1/config body = ""16const (17 vecKey = "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"18 vecTS = int64(1789189804)19 vecBody = `{"probe_id":"ca-qc-01","agent_version":"0.1.0","measurements":[]}`2021 // sha256 of vecBody / of the empty string.22 vecBodyHash = "9fd6962cedcf4a7aedb13c38f7f63137fdbbbf3703b447ebd761234981847c65"23 vecEmptyHash = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"2425 // Expected signatures — computed independently with Python (hmac + hashlib) before this package existed.26 vecPostSig = "111075ee8d4c20723598c8f75d5ad89433f0385ff965f123302d2b9411280723"27 vecGetSig = "3798599e7f1bed2dab170d2aacf5f5288ec7cc591a64bd37285d3ea3c3450a8b"28)2930func TestBodyHash(t *testing.T) {31 if got := BodyHash([]byte(vecBody)); got != vecBodyHash {32 t.Fatalf("body hash = %s, want %s", got, vecBodyHash)33 }34 if got := BodyHash(nil); got != vecEmptyHash {35 t.Fatalf("empty hash = %s, want %s", got, vecEmptyHash)36 }37}3839func TestCanonicalForm(t *testing.T) {40 c := Canonical("GET", "/ingest/v1/config", vecTS, nil)41 want := "GET\n/ingest/v1/config\n1789189804\n" + vecEmptyHash42 if c != want {43 t.Fatalf("canonical mismatch:\n got %q\nwant %q", c, want)44 }45}4647func TestVectors(t *testing.T) {48 s, err := New("ca-qc-01", vecKey)49 if err != nil {50 t.Fatal(err)51 }52 if got := s.Sign("POST", "/ingest/v1/batch", vecTS, []byte(vecBody)); got != vecPostSig {53 t.Errorf("POST signature = %s, want %s", got, vecPostSig)54 }55 if got := s.Sign("GET", "/ingest/v1/config", vecTS, nil); got != vecGetSig {56 t.Errorf("GET signature = %s, want %s", got, vecGetSig)57 }58}5960func TestApplyIgnoresQueryString(t *testing.T) {61 s, _ := New("ca-qc-01", vecKey)62 u, _ := url.Parse("https://www.internetpressure.io/ingest/v1/config?x=1")63 req, _ := http.NewRequest("GET", u.String(), nil)64 s.Apply(req, vecTS, nil)65 if req.Header.Get(HeaderProbe) != "ca-qc-01" || req.Header.Get(HeaderTimestamp) != "1789189804" {66 t.Fatalf("bad headers: %v", req.Header)67 }68 if req.Header.Get(HeaderSignature) != vecGetSig {69 t.Fatalf("signature with query string should equal the path-only signature")70 }71 if !s.Verify("GET", "/ingest/v1/config", vecTS, nil, req.Header.Get(HeaderSignature)) {72 t.Fatal("verify failed")73 }74 if s.Verify("GET", "/ingest/v1/config", vecTS+1, nil, req.Header.Get(HeaderSignature)) {75 t.Fatal("verify should fail with a different timestamp")76 }77}7879func TestNewRejectsBadKeys(t *testing.T) {80 if _, err := New("p", "zz"); err == nil {81 t.Fatal("non-hex key accepted")82 }83 if _, err := New("p", "0011"); err == nil {84 t.Fatal("short key accepted")85 }86 if _, err := New("", vecKey); err == nil {87 t.Fatal("empty probe id accepted")88 }89 if _, err := New("p", strings.Repeat("ab", 32)); err != nil {90 t.Fatal(err)91 }92}93