1*6236dae4SAndroid Build Coastguard Worker /***************************************************************************
2*6236dae4SAndroid Build Coastguard Worker * _ _ ____ _
3*6236dae4SAndroid Build Coastguard Worker * Project ___| | | | _ \| |
4*6236dae4SAndroid Build Coastguard Worker * / __| | | | |_) | |
5*6236dae4SAndroid Build Coastguard Worker * | (__| |_| | _ <| |___
6*6236dae4SAndroid Build Coastguard Worker * \___|\___/|_| \_\_____|
7*6236dae4SAndroid Build Coastguard Worker *
8*6236dae4SAndroid Build Coastguard Worker * Copyright (C) Daniel Stenberg, <[email protected]>, et al.
9*6236dae4SAndroid Build Coastguard Worker *
10*6236dae4SAndroid Build Coastguard Worker * This software is licensed as described in the file COPYING, which
11*6236dae4SAndroid Build Coastguard Worker * you should have received as part of this distribution. The terms
12*6236dae4SAndroid Build Coastguard Worker * are also available at https://curl.se/docs/copyright.html.
13*6236dae4SAndroid Build Coastguard Worker *
14*6236dae4SAndroid Build Coastguard Worker * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15*6236dae4SAndroid Build Coastguard Worker * copies of the Software, and permit persons to whom the Software is
16*6236dae4SAndroid Build Coastguard Worker * furnished to do so, under the terms of the COPYING file.
17*6236dae4SAndroid Build Coastguard Worker *
18*6236dae4SAndroid Build Coastguard Worker * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19*6236dae4SAndroid Build Coastguard Worker * KIND, either express or implied.
20*6236dae4SAndroid Build Coastguard Worker *
21*6236dae4SAndroid Build Coastguard Worker * SPDX-License-Identifier: curl
22*6236dae4SAndroid Build Coastguard Worker *
23*6236dae4SAndroid Build Coastguard Worker ***************************************************************************/
24*6236dae4SAndroid Build Coastguard Worker
25*6236dae4SAndroid Build Coastguard Worker #include "curl_setup.h"
26*6236dae4SAndroid Build Coastguard Worker #include "dynhds.h"
27*6236dae4SAndroid Build Coastguard Worker #include "strcase.h"
28*6236dae4SAndroid Build Coastguard Worker
29*6236dae4SAndroid Build Coastguard Worker /* The last 3 #include files should be in this order */
30*6236dae4SAndroid Build Coastguard Worker #ifdef USE_NGHTTP2
31*6236dae4SAndroid Build Coastguard Worker #include <stdint.h>
32*6236dae4SAndroid Build Coastguard Worker #include <nghttp2/nghttp2.h>
33*6236dae4SAndroid Build Coastguard Worker #endif /* USE_NGHTTP2 */
34*6236dae4SAndroid Build Coastguard Worker #include "curl_printf.h"
35*6236dae4SAndroid Build Coastguard Worker #include "curl_memory.h"
36*6236dae4SAndroid Build Coastguard Worker #include "memdebug.h"
37*6236dae4SAndroid Build Coastguard Worker
38*6236dae4SAndroid Build Coastguard Worker
39*6236dae4SAndroid Build Coastguard Worker static struct dynhds_entry *
entry_new(const char * name,size_t namelen,const char * value,size_t valuelen,int opts)40*6236dae4SAndroid Build Coastguard Worker entry_new(const char *name, size_t namelen,
41*6236dae4SAndroid Build Coastguard Worker const char *value, size_t valuelen, int opts)
42*6236dae4SAndroid Build Coastguard Worker {
43*6236dae4SAndroid Build Coastguard Worker struct dynhds_entry *e;
44*6236dae4SAndroid Build Coastguard Worker char *p;
45*6236dae4SAndroid Build Coastguard Worker
46*6236dae4SAndroid Build Coastguard Worker DEBUGASSERT(name);
47*6236dae4SAndroid Build Coastguard Worker DEBUGASSERT(value);
48*6236dae4SAndroid Build Coastguard Worker e = calloc(1, sizeof(*e) + namelen + valuelen + 2);
49*6236dae4SAndroid Build Coastguard Worker if(!e)
50*6236dae4SAndroid Build Coastguard Worker return NULL;
51*6236dae4SAndroid Build Coastguard Worker e->name = p = ((char *)e) + sizeof(*e);
52*6236dae4SAndroid Build Coastguard Worker memcpy(p, name, namelen);
53*6236dae4SAndroid Build Coastguard Worker e->namelen = namelen;
54*6236dae4SAndroid Build Coastguard Worker e->value = p += namelen + 1; /* leave a \0 at the end of name */
55*6236dae4SAndroid Build Coastguard Worker memcpy(p, value, valuelen);
56*6236dae4SAndroid Build Coastguard Worker e->valuelen = valuelen;
57*6236dae4SAndroid Build Coastguard Worker if(opts & DYNHDS_OPT_LOWERCASE)
58*6236dae4SAndroid Build Coastguard Worker Curl_strntolower(e->name, e->name, e->namelen);
59*6236dae4SAndroid Build Coastguard Worker return e;
60*6236dae4SAndroid Build Coastguard Worker }
61*6236dae4SAndroid Build Coastguard Worker
62*6236dae4SAndroid Build Coastguard Worker static struct dynhds_entry *
entry_append(struct dynhds_entry * e,const char * value,size_t valuelen)63*6236dae4SAndroid Build Coastguard Worker entry_append(struct dynhds_entry *e,
64*6236dae4SAndroid Build Coastguard Worker const char *value, size_t valuelen)
65*6236dae4SAndroid Build Coastguard Worker {
66*6236dae4SAndroid Build Coastguard Worker struct dynhds_entry *e2;
67*6236dae4SAndroid Build Coastguard Worker size_t valuelen2 = e->valuelen + 1 + valuelen;
68*6236dae4SAndroid Build Coastguard Worker char *p;
69*6236dae4SAndroid Build Coastguard Worker
70*6236dae4SAndroid Build Coastguard Worker DEBUGASSERT(value);
71*6236dae4SAndroid Build Coastguard Worker e2 = calloc(1, sizeof(*e) + e->namelen + valuelen2 + 2);
72*6236dae4SAndroid Build Coastguard Worker if(!e2)
73*6236dae4SAndroid Build Coastguard Worker return NULL;
74*6236dae4SAndroid Build Coastguard Worker e2->name = p = ((char *)e2) + sizeof(*e2);
75*6236dae4SAndroid Build Coastguard Worker memcpy(p, e->name, e->namelen);
76*6236dae4SAndroid Build Coastguard Worker e2->namelen = e->namelen;
77*6236dae4SAndroid Build Coastguard Worker e2->value = p += e->namelen + 1; /* leave a \0 at the end of name */
78*6236dae4SAndroid Build Coastguard Worker memcpy(p, e->value, e->valuelen);
79*6236dae4SAndroid Build Coastguard Worker p += e->valuelen;
80*6236dae4SAndroid Build Coastguard Worker p[0] = ' ';
81*6236dae4SAndroid Build Coastguard Worker memcpy(p + 1, value, valuelen);
82*6236dae4SAndroid Build Coastguard Worker e2->valuelen = valuelen2;
83*6236dae4SAndroid Build Coastguard Worker return e2;
84*6236dae4SAndroid Build Coastguard Worker }
85*6236dae4SAndroid Build Coastguard Worker
entry_free(struct dynhds_entry * e)86*6236dae4SAndroid Build Coastguard Worker static void entry_free(struct dynhds_entry *e)
87*6236dae4SAndroid Build Coastguard Worker {
88*6236dae4SAndroid Build Coastguard Worker free(e);
89*6236dae4SAndroid Build Coastguard Worker }
90*6236dae4SAndroid Build Coastguard Worker
Curl_dynhds_init(struct dynhds * dynhds,size_t max_entries,size_t max_strs_size)91*6236dae4SAndroid Build Coastguard Worker void Curl_dynhds_init(struct dynhds *dynhds, size_t max_entries,
92*6236dae4SAndroid Build Coastguard Worker size_t max_strs_size)
93*6236dae4SAndroid Build Coastguard Worker {
94*6236dae4SAndroid Build Coastguard Worker DEBUGASSERT(dynhds);
95*6236dae4SAndroid Build Coastguard Worker DEBUGASSERT(max_strs_size);
96*6236dae4SAndroid Build Coastguard Worker dynhds->hds = NULL;
97*6236dae4SAndroid Build Coastguard Worker dynhds->hds_len = dynhds->hds_allc = dynhds->strs_len = 0;
98*6236dae4SAndroid Build Coastguard Worker dynhds->max_entries = max_entries;
99*6236dae4SAndroid Build Coastguard Worker dynhds->max_strs_size = max_strs_size;
100*6236dae4SAndroid Build Coastguard Worker dynhds->opts = 0;
101*6236dae4SAndroid Build Coastguard Worker }
102*6236dae4SAndroid Build Coastguard Worker
Curl_dynhds_free(struct dynhds * dynhds)103*6236dae4SAndroid Build Coastguard Worker void Curl_dynhds_free(struct dynhds *dynhds)
104*6236dae4SAndroid Build Coastguard Worker {
105*6236dae4SAndroid Build Coastguard Worker DEBUGASSERT(dynhds);
106*6236dae4SAndroid Build Coastguard Worker if(dynhds->hds && dynhds->hds_len) {
107*6236dae4SAndroid Build Coastguard Worker size_t i;
108*6236dae4SAndroid Build Coastguard Worker DEBUGASSERT(dynhds->hds);
109*6236dae4SAndroid Build Coastguard Worker for(i = 0; i < dynhds->hds_len; ++i) {
110*6236dae4SAndroid Build Coastguard Worker entry_free(dynhds->hds[i]);
111*6236dae4SAndroid Build Coastguard Worker }
112*6236dae4SAndroid Build Coastguard Worker }
113*6236dae4SAndroid Build Coastguard Worker Curl_safefree(dynhds->hds);
114*6236dae4SAndroid Build Coastguard Worker dynhds->hds_len = dynhds->hds_allc = dynhds->strs_len = 0;
115*6236dae4SAndroid Build Coastguard Worker }
116*6236dae4SAndroid Build Coastguard Worker
Curl_dynhds_reset(struct dynhds * dynhds)117*6236dae4SAndroid Build Coastguard Worker void Curl_dynhds_reset(struct dynhds *dynhds)
118*6236dae4SAndroid Build Coastguard Worker {
119*6236dae4SAndroid Build Coastguard Worker DEBUGASSERT(dynhds);
120*6236dae4SAndroid Build Coastguard Worker if(dynhds->hds_len) {
121*6236dae4SAndroid Build Coastguard Worker size_t i;
122*6236dae4SAndroid Build Coastguard Worker DEBUGASSERT(dynhds->hds);
123*6236dae4SAndroid Build Coastguard Worker for(i = 0; i < dynhds->hds_len; ++i) {
124*6236dae4SAndroid Build Coastguard Worker entry_free(dynhds->hds[i]);
125*6236dae4SAndroid Build Coastguard Worker dynhds->hds[i] = NULL;
126*6236dae4SAndroid Build Coastguard Worker }
127*6236dae4SAndroid Build Coastguard Worker }
128*6236dae4SAndroid Build Coastguard Worker dynhds->hds_len = dynhds->strs_len = 0;
129*6236dae4SAndroid Build Coastguard Worker }
130*6236dae4SAndroid Build Coastguard Worker
Curl_dynhds_count(struct dynhds * dynhds)131*6236dae4SAndroid Build Coastguard Worker size_t Curl_dynhds_count(struct dynhds *dynhds)
132*6236dae4SAndroid Build Coastguard Worker {
133*6236dae4SAndroid Build Coastguard Worker return dynhds->hds_len;
134*6236dae4SAndroid Build Coastguard Worker }
135*6236dae4SAndroid Build Coastguard Worker
Curl_dynhds_set_opts(struct dynhds * dynhds,int opts)136*6236dae4SAndroid Build Coastguard Worker void Curl_dynhds_set_opts(struct dynhds *dynhds, int opts)
137*6236dae4SAndroid Build Coastguard Worker {
138*6236dae4SAndroid Build Coastguard Worker dynhds->opts = opts;
139*6236dae4SAndroid Build Coastguard Worker }
140*6236dae4SAndroid Build Coastguard Worker
Curl_dynhds_getn(struct dynhds * dynhds,size_t n)141*6236dae4SAndroid Build Coastguard Worker struct dynhds_entry *Curl_dynhds_getn(struct dynhds *dynhds, size_t n)
142*6236dae4SAndroid Build Coastguard Worker {
143*6236dae4SAndroid Build Coastguard Worker DEBUGASSERT(dynhds);
144*6236dae4SAndroid Build Coastguard Worker return (n < dynhds->hds_len) ? dynhds->hds[n] : NULL;
145*6236dae4SAndroid Build Coastguard Worker }
146*6236dae4SAndroid Build Coastguard Worker
Curl_dynhds_get(struct dynhds * dynhds,const char * name,size_t namelen)147*6236dae4SAndroid Build Coastguard Worker struct dynhds_entry *Curl_dynhds_get(struct dynhds *dynhds, const char *name,
148*6236dae4SAndroid Build Coastguard Worker size_t namelen)
149*6236dae4SAndroid Build Coastguard Worker {
150*6236dae4SAndroid Build Coastguard Worker size_t i;
151*6236dae4SAndroid Build Coastguard Worker for(i = 0; i < dynhds->hds_len; ++i) {
152*6236dae4SAndroid Build Coastguard Worker if(dynhds->hds[i]->namelen == namelen &&
153*6236dae4SAndroid Build Coastguard Worker strncasecompare(dynhds->hds[i]->name, name, namelen)) {
154*6236dae4SAndroid Build Coastguard Worker return dynhds->hds[i];
155*6236dae4SAndroid Build Coastguard Worker }
156*6236dae4SAndroid Build Coastguard Worker }
157*6236dae4SAndroid Build Coastguard Worker return NULL;
158*6236dae4SAndroid Build Coastguard Worker }
159*6236dae4SAndroid Build Coastguard Worker
Curl_dynhds_cget(struct dynhds * dynhds,const char * name)160*6236dae4SAndroid Build Coastguard Worker struct dynhds_entry *Curl_dynhds_cget(struct dynhds *dynhds, const char *name)
161*6236dae4SAndroid Build Coastguard Worker {
162*6236dae4SAndroid Build Coastguard Worker return Curl_dynhds_get(dynhds, name, strlen(name));
163*6236dae4SAndroid Build Coastguard Worker }
164*6236dae4SAndroid Build Coastguard Worker
Curl_dynhds_add(struct dynhds * dynhds,const char * name,size_t namelen,const char * value,size_t valuelen)165*6236dae4SAndroid Build Coastguard Worker CURLcode Curl_dynhds_add(struct dynhds *dynhds,
166*6236dae4SAndroid Build Coastguard Worker const char *name, size_t namelen,
167*6236dae4SAndroid Build Coastguard Worker const char *value, size_t valuelen)
168*6236dae4SAndroid Build Coastguard Worker {
169*6236dae4SAndroid Build Coastguard Worker struct dynhds_entry *entry = NULL;
170*6236dae4SAndroid Build Coastguard Worker CURLcode result = CURLE_OUT_OF_MEMORY;
171*6236dae4SAndroid Build Coastguard Worker
172*6236dae4SAndroid Build Coastguard Worker DEBUGASSERT(dynhds);
173*6236dae4SAndroid Build Coastguard Worker if(dynhds->max_entries && dynhds->hds_len >= dynhds->max_entries)
174*6236dae4SAndroid Build Coastguard Worker return CURLE_OUT_OF_MEMORY;
175*6236dae4SAndroid Build Coastguard Worker if(dynhds->strs_len + namelen + valuelen > dynhds->max_strs_size)
176*6236dae4SAndroid Build Coastguard Worker return CURLE_OUT_OF_MEMORY;
177*6236dae4SAndroid Build Coastguard Worker
178*6236dae4SAndroid Build Coastguard Worker entry = entry_new(name, namelen, value, valuelen, dynhds->opts);
179*6236dae4SAndroid Build Coastguard Worker if(!entry)
180*6236dae4SAndroid Build Coastguard Worker goto out;
181*6236dae4SAndroid Build Coastguard Worker
182*6236dae4SAndroid Build Coastguard Worker if(dynhds->hds_len + 1 >= dynhds->hds_allc) {
183*6236dae4SAndroid Build Coastguard Worker size_t nallc = dynhds->hds_len + 16;
184*6236dae4SAndroid Build Coastguard Worker struct dynhds_entry **nhds;
185*6236dae4SAndroid Build Coastguard Worker
186*6236dae4SAndroid Build Coastguard Worker if(dynhds->max_entries && nallc > dynhds->max_entries)
187*6236dae4SAndroid Build Coastguard Worker nallc = dynhds->max_entries;
188*6236dae4SAndroid Build Coastguard Worker
189*6236dae4SAndroid Build Coastguard Worker nhds = calloc(nallc, sizeof(struct dynhds_entry *));
190*6236dae4SAndroid Build Coastguard Worker if(!nhds)
191*6236dae4SAndroid Build Coastguard Worker goto out;
192*6236dae4SAndroid Build Coastguard Worker if(dynhds->hds) {
193*6236dae4SAndroid Build Coastguard Worker memcpy(nhds, dynhds->hds,
194*6236dae4SAndroid Build Coastguard Worker dynhds->hds_len * sizeof(struct dynhds_entry *));
195*6236dae4SAndroid Build Coastguard Worker Curl_safefree(dynhds->hds);
196*6236dae4SAndroid Build Coastguard Worker }
197*6236dae4SAndroid Build Coastguard Worker dynhds->hds = nhds;
198*6236dae4SAndroid Build Coastguard Worker dynhds->hds_allc = nallc;
199*6236dae4SAndroid Build Coastguard Worker }
200*6236dae4SAndroid Build Coastguard Worker dynhds->hds[dynhds->hds_len++] = entry;
201*6236dae4SAndroid Build Coastguard Worker entry = NULL;
202*6236dae4SAndroid Build Coastguard Worker dynhds->strs_len += namelen + valuelen;
203*6236dae4SAndroid Build Coastguard Worker result = CURLE_OK;
204*6236dae4SAndroid Build Coastguard Worker
205*6236dae4SAndroid Build Coastguard Worker out:
206*6236dae4SAndroid Build Coastguard Worker if(entry)
207*6236dae4SAndroid Build Coastguard Worker entry_free(entry);
208*6236dae4SAndroid Build Coastguard Worker return result;
209*6236dae4SAndroid Build Coastguard Worker }
210*6236dae4SAndroid Build Coastguard Worker
Curl_dynhds_cadd(struct dynhds * dynhds,const char * name,const char * value)211*6236dae4SAndroid Build Coastguard Worker CURLcode Curl_dynhds_cadd(struct dynhds *dynhds,
212*6236dae4SAndroid Build Coastguard Worker const char *name, const char *value)
213*6236dae4SAndroid Build Coastguard Worker {
214*6236dae4SAndroid Build Coastguard Worker return Curl_dynhds_add(dynhds, name, strlen(name), value, strlen(value));
215*6236dae4SAndroid Build Coastguard Worker }
216*6236dae4SAndroid Build Coastguard Worker
Curl_dynhds_h1_add_line(struct dynhds * dynhds,const char * line,size_t line_len)217*6236dae4SAndroid Build Coastguard Worker CURLcode Curl_dynhds_h1_add_line(struct dynhds *dynhds,
218*6236dae4SAndroid Build Coastguard Worker const char *line, size_t line_len)
219*6236dae4SAndroid Build Coastguard Worker {
220*6236dae4SAndroid Build Coastguard Worker const char *p;
221*6236dae4SAndroid Build Coastguard Worker const char *name;
222*6236dae4SAndroid Build Coastguard Worker size_t namelen;
223*6236dae4SAndroid Build Coastguard Worker const char *value;
224*6236dae4SAndroid Build Coastguard Worker size_t valuelen, i;
225*6236dae4SAndroid Build Coastguard Worker
226*6236dae4SAndroid Build Coastguard Worker if(!line || !line_len)
227*6236dae4SAndroid Build Coastguard Worker return CURLE_OK;
228*6236dae4SAndroid Build Coastguard Worker
229*6236dae4SAndroid Build Coastguard Worker if((line[0] == ' ') || (line[0] == '\t')) {
230*6236dae4SAndroid Build Coastguard Worker struct dynhds_entry *e, *e2;
231*6236dae4SAndroid Build Coastguard Worker /* header continuation, yikes! */
232*6236dae4SAndroid Build Coastguard Worker if(!dynhds->hds_len)
233*6236dae4SAndroid Build Coastguard Worker return CURLE_BAD_FUNCTION_ARGUMENT;
234*6236dae4SAndroid Build Coastguard Worker
235*6236dae4SAndroid Build Coastguard Worker while(line_len && ISBLANK(line[0])) {
236*6236dae4SAndroid Build Coastguard Worker ++line;
237*6236dae4SAndroid Build Coastguard Worker --line_len;
238*6236dae4SAndroid Build Coastguard Worker }
239*6236dae4SAndroid Build Coastguard Worker if(!line_len)
240*6236dae4SAndroid Build Coastguard Worker return CURLE_BAD_FUNCTION_ARGUMENT;
241*6236dae4SAndroid Build Coastguard Worker e = dynhds->hds[dynhds->hds_len-1];
242*6236dae4SAndroid Build Coastguard Worker e2 = entry_append(e, line, line_len);
243*6236dae4SAndroid Build Coastguard Worker if(!e2)
244*6236dae4SAndroid Build Coastguard Worker return CURLE_OUT_OF_MEMORY;
245*6236dae4SAndroid Build Coastguard Worker dynhds->hds[dynhds->hds_len-1] = e2;
246*6236dae4SAndroid Build Coastguard Worker entry_free(e);
247*6236dae4SAndroid Build Coastguard Worker return CURLE_OK;
248*6236dae4SAndroid Build Coastguard Worker }
249*6236dae4SAndroid Build Coastguard Worker else {
250*6236dae4SAndroid Build Coastguard Worker p = memchr(line, ':', line_len);
251*6236dae4SAndroid Build Coastguard Worker if(!p)
252*6236dae4SAndroid Build Coastguard Worker return CURLE_BAD_FUNCTION_ARGUMENT;
253*6236dae4SAndroid Build Coastguard Worker name = line;
254*6236dae4SAndroid Build Coastguard Worker namelen = p - line;
255*6236dae4SAndroid Build Coastguard Worker p++; /* move past the colon */
256*6236dae4SAndroid Build Coastguard Worker for(i = namelen + 1; i < line_len; ++i, ++p) {
257*6236dae4SAndroid Build Coastguard Worker if(!ISBLANK(*p))
258*6236dae4SAndroid Build Coastguard Worker break;
259*6236dae4SAndroid Build Coastguard Worker }
260*6236dae4SAndroid Build Coastguard Worker value = p;
261*6236dae4SAndroid Build Coastguard Worker valuelen = line_len - i;
262*6236dae4SAndroid Build Coastguard Worker
263*6236dae4SAndroid Build Coastguard Worker p = memchr(value, '\r', valuelen);
264*6236dae4SAndroid Build Coastguard Worker if(!p)
265*6236dae4SAndroid Build Coastguard Worker p = memchr(value, '\n', valuelen);
266*6236dae4SAndroid Build Coastguard Worker if(p)
267*6236dae4SAndroid Build Coastguard Worker valuelen = (size_t)(p - value);
268*6236dae4SAndroid Build Coastguard Worker
269*6236dae4SAndroid Build Coastguard Worker return Curl_dynhds_add(dynhds, name, namelen, value, valuelen);
270*6236dae4SAndroid Build Coastguard Worker }
271*6236dae4SAndroid Build Coastguard Worker }
272*6236dae4SAndroid Build Coastguard Worker
Curl_dynhds_h1_cadd_line(struct dynhds * dynhds,const char * line)273*6236dae4SAndroid Build Coastguard Worker CURLcode Curl_dynhds_h1_cadd_line(struct dynhds *dynhds, const char *line)
274*6236dae4SAndroid Build Coastguard Worker {
275*6236dae4SAndroid Build Coastguard Worker return Curl_dynhds_h1_add_line(dynhds, line, line ? strlen(line) : 0);
276*6236dae4SAndroid Build Coastguard Worker }
277*6236dae4SAndroid Build Coastguard Worker
278*6236dae4SAndroid Build Coastguard Worker #ifdef UNITTESTS
279*6236dae4SAndroid Build Coastguard Worker /* used by unit2602.c */
280*6236dae4SAndroid Build Coastguard Worker
Curl_dynhds_contains(struct dynhds * dynhds,const char * name,size_t namelen)281*6236dae4SAndroid Build Coastguard Worker bool Curl_dynhds_contains(struct dynhds *dynhds,
282*6236dae4SAndroid Build Coastguard Worker const char *name, size_t namelen)
283*6236dae4SAndroid Build Coastguard Worker {
284*6236dae4SAndroid Build Coastguard Worker return !!Curl_dynhds_get(dynhds, name, namelen);
285*6236dae4SAndroid Build Coastguard Worker }
286*6236dae4SAndroid Build Coastguard Worker
Curl_dynhds_ccontains(struct dynhds * dynhds,const char * name)287*6236dae4SAndroid Build Coastguard Worker bool Curl_dynhds_ccontains(struct dynhds *dynhds, const char *name)
288*6236dae4SAndroid Build Coastguard Worker {
289*6236dae4SAndroid Build Coastguard Worker return Curl_dynhds_contains(dynhds, name, strlen(name));
290*6236dae4SAndroid Build Coastguard Worker }
291*6236dae4SAndroid Build Coastguard Worker
Curl_dynhds_count_name(struct dynhds * dynhds,const char * name,size_t namelen)292*6236dae4SAndroid Build Coastguard Worker size_t Curl_dynhds_count_name(struct dynhds *dynhds,
293*6236dae4SAndroid Build Coastguard Worker const char *name, size_t namelen)
294*6236dae4SAndroid Build Coastguard Worker {
295*6236dae4SAndroid Build Coastguard Worker size_t n = 0;
296*6236dae4SAndroid Build Coastguard Worker if(dynhds->hds_len) {
297*6236dae4SAndroid Build Coastguard Worker size_t i;
298*6236dae4SAndroid Build Coastguard Worker for(i = 0; i < dynhds->hds_len; ++i) {
299*6236dae4SAndroid Build Coastguard Worker if((namelen == dynhds->hds[i]->namelen) &&
300*6236dae4SAndroid Build Coastguard Worker strncasecompare(name, dynhds->hds[i]->name, namelen))
301*6236dae4SAndroid Build Coastguard Worker ++n;
302*6236dae4SAndroid Build Coastguard Worker }
303*6236dae4SAndroid Build Coastguard Worker }
304*6236dae4SAndroid Build Coastguard Worker return n;
305*6236dae4SAndroid Build Coastguard Worker }
306*6236dae4SAndroid Build Coastguard Worker
Curl_dynhds_ccount_name(struct dynhds * dynhds,const char * name)307*6236dae4SAndroid Build Coastguard Worker size_t Curl_dynhds_ccount_name(struct dynhds *dynhds, const char *name)
308*6236dae4SAndroid Build Coastguard Worker {
309*6236dae4SAndroid Build Coastguard Worker return Curl_dynhds_count_name(dynhds, name, strlen(name));
310*6236dae4SAndroid Build Coastguard Worker }
311*6236dae4SAndroid Build Coastguard Worker
Curl_dynhds_set(struct dynhds * dynhds,const char * name,size_t namelen,const char * value,size_t valuelen)312*6236dae4SAndroid Build Coastguard Worker CURLcode Curl_dynhds_set(struct dynhds *dynhds,
313*6236dae4SAndroid Build Coastguard Worker const char *name, size_t namelen,
314*6236dae4SAndroid Build Coastguard Worker const char *value, size_t valuelen)
315*6236dae4SAndroid Build Coastguard Worker {
316*6236dae4SAndroid Build Coastguard Worker Curl_dynhds_remove(dynhds, name, namelen);
317*6236dae4SAndroid Build Coastguard Worker return Curl_dynhds_add(dynhds, name, namelen, value, valuelen);
318*6236dae4SAndroid Build Coastguard Worker }
319*6236dae4SAndroid Build Coastguard Worker
Curl_dynhds_remove(struct dynhds * dynhds,const char * name,size_t namelen)320*6236dae4SAndroid Build Coastguard Worker size_t Curl_dynhds_remove(struct dynhds *dynhds,
321*6236dae4SAndroid Build Coastguard Worker const char *name, size_t namelen)
322*6236dae4SAndroid Build Coastguard Worker {
323*6236dae4SAndroid Build Coastguard Worker size_t n = 0;
324*6236dae4SAndroid Build Coastguard Worker if(dynhds->hds_len) {
325*6236dae4SAndroid Build Coastguard Worker size_t i, len;
326*6236dae4SAndroid Build Coastguard Worker for(i = 0; i < dynhds->hds_len; ++i) {
327*6236dae4SAndroid Build Coastguard Worker if((namelen == dynhds->hds[i]->namelen) &&
328*6236dae4SAndroid Build Coastguard Worker strncasecompare(name, dynhds->hds[i]->name, namelen)) {
329*6236dae4SAndroid Build Coastguard Worker ++n;
330*6236dae4SAndroid Build Coastguard Worker --dynhds->hds_len;
331*6236dae4SAndroid Build Coastguard Worker dynhds->strs_len -= (dynhds->hds[i]->namelen +
332*6236dae4SAndroid Build Coastguard Worker dynhds->hds[i]->valuelen);
333*6236dae4SAndroid Build Coastguard Worker entry_free(dynhds->hds[i]);
334*6236dae4SAndroid Build Coastguard Worker len = dynhds->hds_len - i; /* remaining entries */
335*6236dae4SAndroid Build Coastguard Worker if(len) {
336*6236dae4SAndroid Build Coastguard Worker memmove(&dynhds->hds[i], &dynhds->hds[i + 1],
337*6236dae4SAndroid Build Coastguard Worker len * sizeof(dynhds->hds[i]));
338*6236dae4SAndroid Build Coastguard Worker }
339*6236dae4SAndroid Build Coastguard Worker --i; /* do this index again */
340*6236dae4SAndroid Build Coastguard Worker }
341*6236dae4SAndroid Build Coastguard Worker }
342*6236dae4SAndroid Build Coastguard Worker }
343*6236dae4SAndroid Build Coastguard Worker return n;
344*6236dae4SAndroid Build Coastguard Worker }
345*6236dae4SAndroid Build Coastguard Worker
Curl_dynhds_cremove(struct dynhds * dynhds,const char * name)346*6236dae4SAndroid Build Coastguard Worker size_t Curl_dynhds_cremove(struct dynhds *dynhds, const char *name)
347*6236dae4SAndroid Build Coastguard Worker {
348*6236dae4SAndroid Build Coastguard Worker return Curl_dynhds_remove(dynhds, name, strlen(name));
349*6236dae4SAndroid Build Coastguard Worker }
350*6236dae4SAndroid Build Coastguard Worker
351*6236dae4SAndroid Build Coastguard Worker #endif
352*6236dae4SAndroid Build Coastguard Worker
Curl_dynhds_h1_dprint(struct dynhds * dynhds,struct dynbuf * dbuf)353*6236dae4SAndroid Build Coastguard Worker CURLcode Curl_dynhds_h1_dprint(struct dynhds *dynhds, struct dynbuf *dbuf)
354*6236dae4SAndroid Build Coastguard Worker {
355*6236dae4SAndroid Build Coastguard Worker CURLcode result = CURLE_OK;
356*6236dae4SAndroid Build Coastguard Worker size_t i;
357*6236dae4SAndroid Build Coastguard Worker
358*6236dae4SAndroid Build Coastguard Worker if(!dynhds->hds_len)
359*6236dae4SAndroid Build Coastguard Worker return result;
360*6236dae4SAndroid Build Coastguard Worker
361*6236dae4SAndroid Build Coastguard Worker for(i = 0; i < dynhds->hds_len; ++i) {
362*6236dae4SAndroid Build Coastguard Worker result = Curl_dyn_addf(dbuf, "%.*s: %.*s\r\n",
363*6236dae4SAndroid Build Coastguard Worker (int)dynhds->hds[i]->namelen, dynhds->hds[i]->name,
364*6236dae4SAndroid Build Coastguard Worker (int)dynhds->hds[i]->valuelen, dynhds->hds[i]->value);
365*6236dae4SAndroid Build Coastguard Worker if(result)
366*6236dae4SAndroid Build Coastguard Worker break;
367*6236dae4SAndroid Build Coastguard Worker }
368*6236dae4SAndroid Build Coastguard Worker
369*6236dae4SAndroid Build Coastguard Worker return result;
370*6236dae4SAndroid Build Coastguard Worker }
371*6236dae4SAndroid Build Coastguard Worker
372*6236dae4SAndroid Build Coastguard Worker #ifdef USE_NGHTTP2
373*6236dae4SAndroid Build Coastguard Worker
Curl_dynhds_to_nva(struct dynhds * dynhds,size_t * pcount)374*6236dae4SAndroid Build Coastguard Worker nghttp2_nv *Curl_dynhds_to_nva(struct dynhds *dynhds, size_t *pcount)
375*6236dae4SAndroid Build Coastguard Worker {
376*6236dae4SAndroid Build Coastguard Worker nghttp2_nv *nva = calloc(1, sizeof(nghttp2_nv) * dynhds->hds_len);
377*6236dae4SAndroid Build Coastguard Worker size_t i;
378*6236dae4SAndroid Build Coastguard Worker
379*6236dae4SAndroid Build Coastguard Worker *pcount = 0;
380*6236dae4SAndroid Build Coastguard Worker if(!nva)
381*6236dae4SAndroid Build Coastguard Worker return NULL;
382*6236dae4SAndroid Build Coastguard Worker
383*6236dae4SAndroid Build Coastguard Worker for(i = 0; i < dynhds->hds_len; ++i) {
384*6236dae4SAndroid Build Coastguard Worker struct dynhds_entry *e = dynhds->hds[i];
385*6236dae4SAndroid Build Coastguard Worker DEBUGASSERT(e);
386*6236dae4SAndroid Build Coastguard Worker nva[i].name = (unsigned char *)e->name;
387*6236dae4SAndroid Build Coastguard Worker nva[i].namelen = e->namelen;
388*6236dae4SAndroid Build Coastguard Worker nva[i].value = (unsigned char *)e->value;
389*6236dae4SAndroid Build Coastguard Worker nva[i].valuelen = e->valuelen;
390*6236dae4SAndroid Build Coastguard Worker nva[i].flags = NGHTTP2_NV_FLAG_NONE;
391*6236dae4SAndroid Build Coastguard Worker }
392*6236dae4SAndroid Build Coastguard Worker *pcount = dynhds->hds_len;
393*6236dae4SAndroid Build Coastguard Worker return nva;
394*6236dae4SAndroid Build Coastguard Worker }
395*6236dae4SAndroid Build Coastguard Worker
396*6236dae4SAndroid Build Coastguard Worker #endif /* USE_NGHTTP2 */
397