code wiki / _hdl_build / nx_adnet_creative.nx

nx_adnet_creative.nx source

↩ module page · 116 lines · 4787 B

1// nx_adnet_creative.nx -- LIB: advertiser CREATIVE INTAKE for the sovereign ad network (debt 1785512202). 2// THE CHICKEN-AND-EGG IT CLOSES: nx_adnet_selfserve accepts an inventory row whose img field must already 3// be a FIRST-PARTY url -- but nothing ever let an advertiser produce one, so no client could onboard at all. 4// 5// CONTENT-ADDRESSED BY CONSTRUCTION. The stored name is derived from the BYTES, so: 6// * replacing artwork MINTS A NEW URL -- the cache-busting problem solves itself and the creative can 7// finally be served cacheable (today every page view re-pulls it under a blanket no-cache). 8// * the same bytes always land on the same name -- re-upload is idempotent, never a duplicate. 9// The digest is FNV-1a, a NON-CRYPTOGRAPHIC content hash. It is named that here on purpose: it is a 10// cache key, NOT an integrity or authenticity claim, and must never be cited as one. 11// 12// THE SIZE CEILING IS A REFUSAL, NOT A GUIDELINE. The four house banners are 196,733 bytes each of 13// UNCOMPRESSED png -- a 728x90 banner roughly ten times heavier than it should be, re-fetched on every 14// page view. A platform that merely hopes clients upload small files will host that class forever, so an 15// oversize creative is REFUSED at intake with a named reason. Weight is an advertiser-facing quality 16// problem: a banner that slows the host page reflects on the client who paid for it. 17// license_tier: ORIGINAL 18import "nx_syscalls.nx" 19import "_hdl_build/nx_adnet_slot.nx" 20 21const ACR_W: i64 = 728 22const ACR_H: i64 = 90 23const ACR_MAX_BYTES: i64 = 65536 24const ACR_MIN_BYTES: i64 = 68 25 26// big-endian u32 at off 27func acr_be32(b: *u8, off: i64) -> i64 { 28 return ((b[off] as i64) * 16777216) + ((b[off + 1] as i64) * 65536) + ((b[off + 2] as i64) * 256) + (b[off + 3] as i64) 29} 30 31// PNG signature check: 89 50 4E 47 0D 0A 1A 0A 32func acr_is_png(b: *u8, n: i64) -> i64 { 33 if n < ACR_MIN_BYTES { return 0 } 34 if b[0] != (137 as u8) { return 0 } 35 if b[1] != (80 as u8) { return 0 } 36 if b[2] != (78 as u8) { return 0 } 37 if b[3] != (71 as u8) { return 0 } 38 if b[4] != (13 as u8) { return 0 } 39 if b[5] != (10 as u8) { return 0 } 40 if b[6] != (26 as u8) { return 0 } 41 if b[7] != (10 as u8) { return 0 } 42 if b[12] != (73 as u8) { return 0 } 43 if b[13] != (72 as u8) { return 0 } 44 if b[14] != (68 as u8) { return 0 } 45 if b[15] != (82 as u8) { return 0 } 46 return 1 47} 48 49func acr_width(b: *u8, n: i64) -> i64 { if acr_is_png(b, n) == 0 { return 0 - 1 } return acr_be32(b, 16) } 50func acr_height(b: *u8, n: i64) -> i64 { if acr_is_png(b, n) == 0 { return 0 - 1 } return acr_be32(b, 20) } 51 52// Verdicts -- a sealed enum so a caller cannot confuse WHY a creative was refused. 53const ACR_OK: i64 = 1 54const ACR_NOT_PNG: i64 = 2 55const ACR_BAD_DIMS: i64 = 3 56const ACR_TOO_HEAVY: i64 = 4 57 58func acr_validate(b: *u8, n: i64) -> i64 { 59 if acr_is_png(b, n) == 0 { return ACR_NOT_PNG } 60 if n > ACR_MAX_BYTES { return ACR_TOO_HEAVY } 61 if acr_width(b, n) != ACR_W { return ACR_BAD_DIMS } 62 if acr_height(b, n) != ACR_H { return ACR_BAD_DIMS } 63 return ACR_OK 64} 65 66func acr_reason(v: i64, out: *u8) -> i64 { 67 var o: i64 = 0 68 if v == ACR_OK { o = ad_cat(out, o, "accepted" as *u8) } 69 if v == ACR_NOT_PNG { o = ad_cat(out, o, "refused=not-a-png" as *u8) } 70 if v == ACR_BAD_DIMS { o = ad_cat(out, o, "refused=wrong-dimensions-must-be-728x90" as *u8) } 71 if v == ACR_TOO_HEAVY { o = ad_cat(out, o, "refused=over-64KB-recompress-the-png" as *u8) } 72 out[o] = 0 as u8 73 return o 74} 75 76// FNV-1a 64-bit over the creative bytes. CACHE KEY ONLY -- not an integrity claim. 77func acr_digest(b: *u8, n: i64) -> i64 { 78 var h: i64 = 0x00000100000001B3 79 var i: i64 = 0 80 while i < n { 81 h = h ^ (b[i] as i64) 82 h = h * 0x100000001B3 83 i = i + 1 84 } 85 if h < 0 { h = 0 - h } 86 return h 87} 88 89// content-addressed basename: adnet_<16 lowercase hex>.png 90func acr_name(b: *u8, n: i64, out: *u8, cap: i64) -> i64 { 91 if cap < 32 { return 0 } 92 if acr_validate(b, n) != ACR_OK { return 0 } 93 let h: i64 = acr_digest(b, n) 94 var o: i64 = ad_cat(out, 0, "adnet_" as *u8) 95 var shift: i64 = 60 96 while shift >= 0 { 97 let nib: i64 = (h / (1 << shift)) & 15 98 if nib < 10 { out[o] = (48 + nib) as u8 } else { out[o] = (87 + nib) as u8 } 99 o = o + 1 100 shift = shift - 4 101 } 102 o = ad_cat(out, o, ".png" as *u8) 103 out[o] = 0 as u8 104 return o 105} 106 107// the first-party url the advertiser puts in their inventory row's img field 108func acr_url(b: *u8, n: i64, out: *u8, cap: i64) -> i64 { 109 if cap < 48 { return 0 } 110 let nm: *u8 = sys_mmap(64) 111 if acr_name(b, n, nm, 64) == 0 { return 0 } 112 var o: i64 = ad_cat(out, 0, "/synth/" as *u8) 113 o = ad_cat(out, o, nm) 114 out[o] = 0 as u8 115 return o 116}