1 # Final application response safety; transport alone owns framing and suppression. 2 import Base 3 4 def token.extra(c: U32) -> Bool: 5 match c: 6 case 33: True{} 7 case 35: True{} 8 case 36: True{} 9 case 37: True{} 10 case 38: True{} 11 case 39: True{} 12 case 42: True{} 13 case 43: True{} 14 case 45: True{} 15 case 46: True{} 16 case 94: True{} 17 case 95: True{} 18 case 96: True{} 19 case 124: True{} 20 case 126: True{} 21 case _: False{} 22 23 def token(char: Char) -> Bool: 24 Chr{+c} = char 25 (U32.is_ge(c, 97) && U32.is_le(c, 122)) || (U32.is_ge(c, 48) && U32.is_le(c, 57)) || token.extra(c) 26 27 def name.tail(s: String) -> Bool: 28 match s: 29 case SNil{}: 30 True{} 31 case SCon{c, rest}: 32 token(c) && name.tail(rest) 33 34 def name(s: String) -> Bool: 35 match s: 36 case SNil{}: 37 False{} 38 case SCon{c, rest}: 39 token(c) && name.tail(rest) 40 41 def value(s: String) -> Bool: 42 match s: 43 case SNil{}: 44 True{} 45 case SCon{Chr{+c}, rest}: 46 (U32.is_eq(c, 9) || (U32.is_ge(c, 32) && U32.is_le(c, 255) && U32.is_ne(c, 127))) && value(rest) 47 48 def values(xs: List<&2, String>) -> Bool: 49 match xs: 50 case Nil{}: 51 True{} 52 case item <> rest: 53 value(item) && values(rest) 54 55 def connection(xs: List<&2, String>) -> Bool: 56 match xs: 57 case Nil{}: 58 True{} 59 case item <> rest: 60 String.eq(item, "close") && connection(rest) 61 62 def kind(key: String, items: List<&2, String>) -> Bool: 63 match key: 64 case "content-length": False{} 65 case "transfer-encoding": False{} 66 case "keep-alive": False{} 67 case "upgrade": False{} 68 case "te": False{} 69 case "trailer": False{} 70 case "proxy-connection": False{} 71 case "connection": connection(items) 72 case _: True{} 73 74 def headers(h: Map<&2, List<&2, String>>) -> Bool: 75 match h: 76 case MTip{}: 77 True{} 78 case MLeaf{+key, +items}: 79 name(key) && kind(key, items) && values(items) 80 case MNode{position, lo, hi}: 81 headers(lo) && headers(hi) 82 83 def valid(+status: U32, h: Map<&2, List<&2, String>>) -> Bool: 84 U32.is_ge(status, 200) && U32.is_le(status, 599) && headers(h)