Skip to content

Commit d7e7f1b

Browse files
author
Dmitri Tikhonov
committed
Add h3prio example: parse HTTP/3 Priority Parameters
1 parent 0cbe373 commit d7e7f1b

File tree

2 files changed

+115
-2
lines changed

2 files changed

+115
-2
lines changed

Makefile

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
CFLAGS=-Wall
22

3-
all: test-sfp
3+
all: test-sfp h3prio
44

55
fuzz: fuzz-sfp
66

77
test-sfp: test-sfp.c ls-sfparser.c ls-sfparser.h
88
cc ${CFLAGS} -o test-sfp test-sfp.c ls-sfparser.c
99

10+
h3prio: h3prio.c ls-sfparser.c ls-sfparser.h
11+
cc ${CFLAGS} -o h3prio h3prio.c ls-sfparser.c
12+
1013
fuzz-sfp: fuzz-sfp.c ls-sfparser.c ls-sfparser.h
1114
afl-gcc -O3 -o fuzz-sfp fuzz-sfp.c ls-sfparser.c
1215
#cc -g3 -o fuzz-sfp fuzz-sfp.c ls-sfparser.c
@@ -17,4 +20,4 @@ ls-sfparser.c: ls-sfparser.l
1720
flex -o ls-sfparser.c ls-sfparser.l
1821

1922
clean:
20-
rm -vf test-sfp fuzz-sfp
23+
rm -vf test-sfp fuzz-sfp h3prio

h3prio.c

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
/* Parse HTTP/3 Priority Parameters
2+
*
3+
* See
4+
* https://tools.ietf.org/html/draft-ietf-httpbis-priority-01
5+
*/
6+
7+
#include <stdbool.h>
8+
#include <stdio.h>
9+
#include <stdlib.h>
10+
#include <string.h>
11+
12+
#include "ls-sfparser.h"
13+
14+
15+
struct prio {
16+
enum {
17+
URG_SET = 1 << 0, /* True if `urgency' is set */
18+
INC_SET = 1 << 1, /* True if `incremental' is set */
19+
URG_NAME = 1 << 2, /* True if previous element dictionary name "u" */
20+
INC_NAME = 1 << 3, /* True if previous element dictionary name "i" */
21+
} flags;
22+
unsigned urgency;
23+
bool incremental;
24+
};
25+
26+
27+
static int
28+
callback (void *user_data, enum ls_sf_dt type, char *str, size_t len, int off)
29+
{
30+
struct prio *const prio = user_data;
31+
32+
if (type == LS_SF_DT_NAME)
33+
{
34+
if (1 == len)
35+
switch (str[0])
36+
{
37+
case 'u': prio->flags |= URG_NAME; return 0;
38+
case 'i': prio->flags |= INC_NAME; return 0;
39+
}
40+
}
41+
else if (prio->flags & URG_NAME)
42+
{
43+
if (type == LS_SF_DT_INTEGER)
44+
{
45+
prio->urgency = atoi(str);
46+
if (prio->urgency <= 7)
47+
prio->flags |= URG_SET;
48+
else
49+
{
50+
printf("invalid value of urgency: %.*s\n", (int) len, str);
51+
return -1;
52+
}
53+
}
54+
else
55+
{
56+
printf("invalid type of urgency: %s\n", ls_sf_dt2str[type]);
57+
return -1;
58+
}
59+
}
60+
else if (prio->flags & INC_NAME)
61+
{
62+
if (type == LS_SF_DT_BOOLEAN)
63+
{
64+
prio->flags |= INC_SET;
65+
prio->incremental = str[0] - '0';
66+
}
67+
else
68+
{
69+
printf("invalid type of incremental: %s\n", ls_sf_dt2str[type]);
70+
return -1;
71+
}
72+
}
73+
prio->flags &= ~(INC_NAME|URG_NAME);
74+
75+
return 0;
76+
}
77+
78+
79+
int
80+
main (int argc, char **argv)
81+
{
82+
struct prio prio;
83+
int ret;
84+
85+
if (argc != 2)
86+
{
87+
printf("Usage: %s 'HTTP/3 priority parameters'\n", argv[0]);
88+
return 1;
89+
}
90+
91+
memset(&prio, 0, sizeof(prio));
92+
ret = ls_sf_parse(LS_SF_TLT_DICTIONARY, argv[1], strlen(argv[1]), callback,
93+
&prio, NULL, 0);
94+
if (ret == 0)
95+
{
96+
printf("parsing successful\n");
97+
if (prio.flags & URG_SET)
98+
printf("urgency: %u\n", prio.urgency);
99+
else
100+
printf("urgency: <not set>\n");
101+
if (prio.flags & INC_SET)
102+
printf("incremental: %i\n", (int) prio.incremental);
103+
else
104+
printf("incremental: <not set>\n");
105+
}
106+
else
107+
printf("parsing failed\n");
108+
109+
return ret ? -1 : 0;
110+
}

0 commit comments

Comments
 (0)