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