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