1#!/usr/bin/env python3 2 3HEADERS = [ 4 (':authority', 0), 5 (':method', 1), 6 (':method', 2), 7 (':path', 3), 8 (':path', 4), 9 (':scheme', 5), 10 (':scheme', 6), 11 (':status', 7), 12 (':status', 8), 13 (':status', 9), 14 (':status', 10), 15 (':status', 11), 16 (':status', 12), 17 (':status', 13), 18 ('accept-charset', 14), 19 ('accept-encoding', 15), 20 ('accept-language', 16), 21 ('accept-ranges', 17), 22 ('accept', 18), 23 ('access-control-allow-origin', 19), 24 ('age', 20), 25 ('allow', 21), 26 ('authorization', 22), 27 ('cache-control', 23), 28 ('content-disposition', 24), 29 ('content-encoding', 25), 30 ('content-language', 26), 31 ('content-length', 27), 32 ('content-location', 28), 33 ('content-range', 29), 34 ('content-type', 30), 35 ('cookie', 31), 36 ('date', 32), 37 ('etag', 33), 38 ('expect', 34), 39 ('expires', 35), 40 ('from', 36), 41 ('host', 37), 42 ('if-match', 38), 43 ('if-modified-since', 39), 44 ('if-none-match', 40), 45 ('if-range', 41), 46 ('if-unmodified-since', 42), 47 ('last-modified', 43), 48 ('link', 44), 49 ('location', 45), 50 ('max-forwards', 46), 51 ('proxy-authenticate', 47), 52 ('proxy-authorization', 48), 53 ('range', 49), 54 ('referer', 50), 55 ('refresh', 51), 56 ('retry-after', 52), 57 ('server', 53), 58 ('set-cookie', 54), 59 ('strict-transport-security', 55), 60 ('transfer-encoding', 56), 61 ('user-agent', 57), 62 ('vary', 58), 63 ('via', 59), 64 ('www-authenticate', 60), 65 ('te', None), 66 ('connection', None), 67 ('keep-alive',None), 68 ('proxy-connection', None), 69 ('upgrade', None), 70 (':protocol', None), 71 ('priority', None), 72] 73 74def to_enum_hd(k): 75 res = 'NGHTTP2_TOKEN_' 76 for c in k.upper(): 77 if c == ':' or c == '-': 78 res += '_' 79 continue 80 res += c 81 return res 82 83def build_header(headers): 84 res = {} 85 for k, _ in headers: 86 size = len(k) 87 if size not in res: 88 res[size] = {} 89 ent = res[size] 90 c = k[-1] 91 if c not in ent: 92 ent[c] = [] 93 if k not in ent[c]: 94 ent[c].append(k) 95 96 return res 97 98def gen_enum(): 99 name = '' 100 print('typedef enum {') 101 for k, token in HEADERS: 102 if token is None: 103 print(' {},'.format(to_enum_hd(k))) 104 else: 105 if name != k: 106 name = k 107 print(' {} = {},'.format(to_enum_hd(k), token)) 108 print('} nghttp2_token;') 109 110def gen_index_header(): 111 print('''\ 112static int32_t lookup_token(const uint8_t *name, size_t namelen) { 113 switch (namelen) {''') 114 b = build_header(HEADERS) 115 for size in sorted(b.keys()): 116 ents = b[size] 117 print('''\ 118 case {}:'''.format(size)) 119 print('''\ 120 switch (name[{}]) {{'''.format(size - 1)) 121 for c in sorted(ents.keys()): 122 headers = sorted(ents[c]) 123 print('''\ 124 case '{}':'''.format(c)) 125 for k in headers: 126 print('''\ 127 if (memeq("{}", name, {})) {{ 128 return {}; 129 }}'''.format(k[:-1], size - 1, to_enum_hd(k))) 130 print('''\ 131 break;''') 132 print('''\ 133 } 134 break;''') 135 print('''\ 136 } 137 return -1; 138}''') 139 140if __name__ == '__main__': 141 gen_enum() 142 print() 143 gen_index_header() 144