VirtualBox

source: vbox/trunk/src/libs/curl-7.83.1/lib/headers.c@ 97138

最後變更 在這個檔案從97138是 95312,由 vboxsync 提交於 3 年 前

libs/{curl,libxml2}: OSE export fixes, bugref:8515

  • 屬性 svn:eol-style 設為 native
檔案大小: 8.8 KB
 
1/***************************************************************************
2 * _ _ ____ _
3 * Project ___| | | | _ \| |
4 * / __| | | | |_) | |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
7 *
8 * Copyright (C) 2022, Daniel Stenberg, <[email protected]>, et al.
9 *
10 * This software is licensed as described in the file COPYING, which
11 * you should have received as part of this distribution. The terms
12 * are also available at https://curl.se/docs/copyright.html.
13 *
14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15 * copies of the Software, and permit persons to whom the Software is
16 * furnished to do so, under the terms of the COPYING file.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ***************************************************************************/
22
23#include "curl_setup.h"
24
25#include "urldata.h"
26#include "strdup.h"
27#include "strcase.h"
28#include "headers.h"
29
30/* The last 3 #include files should be in this order */
31#include "curl_printf.h"
32#include "curl_memory.h"
33#include "memdebug.h"
34
35#if !defined(CURL_DISABLE_HTTP) && defined(USE_HEADERS_API)
36
37/* Generate the curl_header struct for the user. This function MUST assign all
38 struct fields in the output struct. */
39static void copy_header_external(struct Curl_easy *data,
40 struct Curl_header_store *hs,
41 size_t index,
42 size_t amount,
43 struct Curl_llist_element *e,
44 struct curl_header **hout)
45{
46 struct curl_header *h = *hout = &data->state.headerout;
47 h->name = hs->name;
48 h->value = hs->value;
49 h->amount = amount;
50 h->index = index;
51 /* this will randomly OR a reserved bit for the sole purpose of making it
52 impossible for applications to do == comparisons, as that would otherwise
53 be very tempting and then lead to the reserved bits not being reserved
54 anymore. */
55 h->origin = hs->type | (1<<27);
56 h->anchor = e;
57}
58
59/* public API */
60CURLHcode curl_easy_header(CURL *easy,
61 const char *name,
62 size_t nameindex,
63 unsigned int type,
64 int request,
65 struct curl_header **hout)
66{
67 struct Curl_llist_element *e;
68 struct Curl_llist_element *e_pick = NULL;
69 struct Curl_easy *data = easy;
70 size_t match = 0;
71 size_t amount = 0;
72 struct Curl_header_store *hs = NULL;
73 struct Curl_header_store *pick = NULL;
74 if(!name || !hout || !data ||
75 (type > (CURLH_HEADER|CURLH_TRAILER|CURLH_CONNECT|CURLH_1XX)) ||
76 !type || (request < -1))
77 return CURLHE_BAD_ARGUMENT;
78 if(!Curl_llist_count(&data->state.httphdrs))
79 return CURLHE_NOHEADERS; /* no headers available */
80 if(request > data->state.requests)
81 return CURLHE_NOREQUEST;
82 if(request == -1)
83 request = data->state.requests;
84
85 /* we need a first round to count amount of this header */
86 for(e = data->state.httphdrs.head; e; e = e->next) {
87 hs = e->ptr;
88 if(strcasecompare(hs->name, name) &&
89 (hs->type & type) &&
90 (hs->request == request)) {
91 amount++;
92 pick = hs;
93 e_pick = e;
94 }
95 }
96 if(!amount)
97 return CURLHE_MISSING;
98 else if(nameindex >= amount)
99 return CURLHE_BADINDEX;
100
101 if(nameindex == amount - 1)
102 /* if the last or only occurrence is what's asked for, then we know it */
103 hs = pick;
104 else {
105 for(e = data->state.httphdrs.head; e; e = e->next) {
106 hs = e->ptr;
107 if(strcasecompare(hs->name, name) &&
108 (hs->type & type) &&
109 (hs->request == request) &&
110 (match++ == nameindex)) {
111 e_pick = e;
112 break;
113 }
114 }
115 if(!e) /* this shouldn't happen */
116 return CURLHE_MISSING;
117 }
118 /* this is the name we want */
119 copy_header_external(data, hs, nameindex, amount, e_pick, hout);
120 return CURLHE_OK;
121}
122
123/* public API */
124struct curl_header *curl_easy_nextheader(CURL *easy,
125 unsigned int type,
126 int request,
127 struct curl_header *prev)
128{
129 struct Curl_easy *data = easy;
130 struct Curl_llist_element *pick;
131 struct Curl_llist_element *e;
132 struct Curl_header_store *hs;
133 struct curl_header *hout;
134 size_t amount = 0;
135 size_t index = 0;
136
137 if(request > data->state.requests)
138 return NULL;
139 if(request == -1)
140 request = data->state.requests;
141
142 if(prev) {
143 pick = prev->anchor;
144 if(!pick)
145 /* something is wrong */
146 return NULL;
147 pick = pick->next;
148 }
149 else
150 pick = data->state.httphdrs.head;
151
152 if(pick) {
153 /* make sure it is the next header of the desired type */
154 do {
155 hs = pick->ptr;
156 if((hs->type & type) && (hs->request == request))
157 break;
158 pick = pick->next;
159 } while(pick);
160 }
161
162 if(!pick)
163 /* no more headers available */
164 return NULL;
165
166 hs = pick->ptr;
167
168 /* count number of occurrences of this name within the mask and figure out
169 the index for the currently selected entry */
170 for(e = data->state.httphdrs.head; e; e = e->next) {
171 struct Curl_header_store *check = e->ptr;
172 if(strcasecompare(hs->name, check->name) &&
173 (check->request == request) &&
174 (check->type & type))
175 amount++;
176 if(e == pick)
177 index = amount - 1;
178 }
179
180 copy_header_external(data, hs, index, amount, pick, &hout);
181 return hout;
182}
183
184static CURLcode namevalue(char *header, size_t hlen, unsigned int type,
185 char **name, char **value)
186{
187 char *end = header + hlen - 1; /* point to the last byte */
188 DEBUGASSERT(hlen);
189 *name = header;
190
191 if(type == CURLH_PSEUDO) {
192 if(*header != ':')
193 return CURLE_BAD_FUNCTION_ARGUMENT;
194 header++;
195 }
196
197 /* Find the end of the header name */
198 while(*header && (*header != ':'))
199 ++header;
200
201 if(*header)
202 /* Skip over colon, null it */
203 *header++ = 0;
204 else
205 return CURLE_BAD_FUNCTION_ARGUMENT;
206
207 /* skip all leading space letters */
208 while(*header && ISSPACE(*header))
209 header++;
210
211 *value = header;
212
213 /* skip all trailing space letters */
214 while((end > header) && ISSPACE(*end))
215 *end-- = 0; /* nul terminate */
216 return CURLE_OK;
217}
218
219/*
220 * Curl_headers_push() gets passed a full HTTP header to store. It gets called
221 * immediately before the header callback. The header is CRLF terminated.
222 */
223CURLcode Curl_headers_push(struct Curl_easy *data, const char *header,
224 unsigned char type)
225{
226 char *value = NULL;
227 char *name = NULL;
228 char *end;
229 size_t hlen; /* length of the incoming header */
230 struct Curl_header_store *hs;
231 CURLcode result = CURLE_OUT_OF_MEMORY;
232
233 if((header[0] == '\r') || (header[0] == '\n'))
234 /* ignore the body separator */
235 return CURLE_OK;
236
237 end = strchr(header, '\r');
238 if(!end) {
239 end = strchr(header, '\n');
240 if(!end)
241 return CURLE_BAD_FUNCTION_ARGUMENT;
242 }
243 hlen = end - header + 1;
244
245 hs = calloc(1, sizeof(*hs) + hlen);
246 if(!hs)
247 return CURLE_OUT_OF_MEMORY;
248 memcpy(hs->buffer, header, hlen);
249 hs->buffer[hlen] = 0; /* nul terminate */
250
251 result = namevalue(hs->buffer, hlen, type, &name, &value);
252 if(result)
253 goto fail;
254
255 hs->name = name;
256 hs->value = value;
257 hs->type = type;
258 hs->request = data->state.requests;
259
260 /* insert this node into the list of headers */
261 Curl_llist_insert_next(&data->state.httphdrs, data->state.httphdrs.tail,
262 hs, &hs->node);
263
264 return CURLE_OK;
265 fail:
266 free(hs);
267 return result;
268}
269
270/*
271 * Curl_headers_init(). Init the headers subsystem.
272 */
273static void headers_init(struct Curl_easy *data)
274{
275 Curl_llist_init(&data->state.httphdrs, NULL);
276}
277
278/*
279 * Curl_headers_cleanup(). Free all stored headers and associated memory.
280 */
281CURLcode Curl_headers_cleanup(struct Curl_easy *data)
282{
283 struct Curl_llist_element *e;
284 struct Curl_llist_element *n;
285
286 for(e = data->state.httphdrs.head; e; e = n) {
287 struct Curl_header_store *hs = e->ptr;
288 n = e->next;
289 free(hs);
290 }
291 headers_init(data);
292 return CURLE_OK;
293}
294
295#else /* HTTP-disabled builds below */
296
297CURLHcode curl_easy_header(CURL *easy,
298 const char *name,
299 size_t index,
300 unsigned int origin,
301 int request,
302 struct curl_header **hout)
303{
304 (void)easy;
305 (void)name;
306 (void)index;
307 (void)origin;
308 (void)request;
309 (void)hout;
310 return CURLHE_NOT_BUILT_IN;
311}
312
313struct curl_header *curl_easy_nextheader(CURL *easy,
314 unsigned int type,
315 int request,
316 struct curl_header *prev)
317{
318 (void)easy;
319 (void)type;
320 (void)request;
321 (void)prev;
322 return NULL;
323}
324#endif
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette