1/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc.  See LICENSE. */
2/* Various HTTP-related functions. */
3
4#include <stddef.h>
5#include <stdlib.h>
6#ifdef WIN32
7#include <vc_compat.h>
8#endif
9
10#include "ls-sfparser.h"
11#include "lsquic.h"
12#include "lsquic_hq.h"
13
14
15struct parse_pfv_ctx
16{
17    enum ppc_flags                  ppc_flags;
18    struct lsquic_ext_http_prio    *ppc_ehp;
19};
20
21
22static int
23parse_pfv (void *user_data, enum ls_sf_dt type, char *str, size_t len, int off)
24{
25    struct parse_pfv_ctx *const pfv_ctx = user_data;
26    unsigned urgency;
27
28    if (type == LS_SF_DT_NAME)
29    {
30        if (1 == len)
31            switch (str[0])
32            {
33                case 'u': pfv_ctx->ppc_flags |= PPC_URG_NAME; return 0;
34                case 'i': pfv_ctx->ppc_flags |= PPC_INC_NAME; return 0;
35            }
36    }
37    else if (pfv_ctx->ppc_flags & PPC_URG_NAME)
38    {
39        if (type == LS_SF_DT_INTEGER)
40        {
41            urgency = atoi(str);
42            if (urgency <= LSQUIC_MAX_HTTP_URGENCY)
43            {
44                pfv_ctx->ppc_ehp->urgency = urgency;
45                pfv_ctx->ppc_flags |= PPC_URG_SET;
46            }
47        }
48    }
49    else if (pfv_ctx->ppc_flags & PPC_INC_NAME)
50    {
51        if (type == LS_SF_DT_BOOLEAN)
52        {
53            pfv_ctx->ppc_ehp->incremental = str[0] - '0';
54            pfv_ctx->ppc_flags |= PPC_INC_SET;
55        }
56    }
57    pfv_ctx->ppc_flags &= ~(PPC_INC_NAME|PPC_URG_NAME);
58
59    return 0;
60}
61
62
63int
64lsquic_http_parse_pfv (const char *pfv, size_t pfv_sz,
65        enum ppc_flags *flags, struct lsquic_ext_http_prio *ehp,
66        char *scratch_buf, size_t scratch_sz)
67{
68    int ret;
69    struct parse_pfv_ctx pfv_ctx = { .ppc_flags = flags ? *flags : 0,
70                                     .ppc_ehp   = ehp, };
71
72    ret = ls_sf_parse(LS_SF_TLT_DICTIONARY, pfv, pfv_sz, parse_pfv, &pfv_ctx,
73                                                    scratch_buf, scratch_sz);
74    if (flags)
75        *flags = pfv_ctx.ppc_flags;
76    return ret;
77}
78