1*76404edcSAsim Jamshed #include "server.h"
2*76404edcSAsim Jamshed #include "keyvalue.h"
3*76404edcSAsim Jamshed #include "log.h"
4*76404edcSAsim Jamshed
5*76404edcSAsim Jamshed #include <stdlib.h>
6*76404edcSAsim Jamshed #include <string.h>
7*76404edcSAsim Jamshed #include <stdio.h>
8*76404edcSAsim Jamshed
9*76404edcSAsim Jamshed static const keyvalue http_versions[] = {
10*76404edcSAsim Jamshed { HTTP_VERSION_1_1, "HTTP/1.1" },
11*76404edcSAsim Jamshed { HTTP_VERSION_1_0, "HTTP/1.0" },
12*76404edcSAsim Jamshed { HTTP_VERSION_UNSET, NULL }
13*76404edcSAsim Jamshed };
14*76404edcSAsim Jamshed
15*76404edcSAsim Jamshed static const keyvalue http_methods[] = {
16*76404edcSAsim Jamshed { HTTP_METHOD_GET, "GET" },
17*76404edcSAsim Jamshed { HTTP_METHOD_POST, "POST" },
18*76404edcSAsim Jamshed { HTTP_METHOD_HEAD, "HEAD" },
19*76404edcSAsim Jamshed { HTTP_METHOD_PROPFIND, "PROPFIND" },
20*76404edcSAsim Jamshed { HTTP_METHOD_PROPPATCH, "PROPPATCH" },
21*76404edcSAsim Jamshed { HTTP_METHOD_REPORT, "REPORT" },
22*76404edcSAsim Jamshed { HTTP_METHOD_OPTIONS, "OPTIONS" },
23*76404edcSAsim Jamshed { HTTP_METHOD_MKCOL, "MKCOL" },
24*76404edcSAsim Jamshed { HTTP_METHOD_PUT, "PUT" },
25*76404edcSAsim Jamshed { HTTP_METHOD_PATCH, "PATCH" },
26*76404edcSAsim Jamshed { HTTP_METHOD_DELETE, "DELETE" },
27*76404edcSAsim Jamshed { HTTP_METHOD_COPY, "COPY" },
28*76404edcSAsim Jamshed { HTTP_METHOD_MOVE, "MOVE" },
29*76404edcSAsim Jamshed { HTTP_METHOD_LABEL, "LABEL" },
30*76404edcSAsim Jamshed { HTTP_METHOD_CHECKOUT, "CHECKOUT" },
31*76404edcSAsim Jamshed { HTTP_METHOD_CHECKIN, "CHECKIN" },
32*76404edcSAsim Jamshed { HTTP_METHOD_MERGE, "MERGE" },
33*76404edcSAsim Jamshed { HTTP_METHOD_LOCK, "LOCK" },
34*76404edcSAsim Jamshed { HTTP_METHOD_UNLOCK, "UNLOCK" },
35*76404edcSAsim Jamshed { HTTP_METHOD_MKACTIVITY, "MKACTIVITY" },
36*76404edcSAsim Jamshed { HTTP_METHOD_UNCHECKOUT, "UNCHECKOUT" },
37*76404edcSAsim Jamshed { HTTP_METHOD_VERSION_CONTROL, "VERSION-CONTROL" },
38*76404edcSAsim Jamshed { HTTP_METHOD_CONNECT, "CONNECT" },
39*76404edcSAsim Jamshed
40*76404edcSAsim Jamshed { HTTP_METHOD_UNSET, NULL }
41*76404edcSAsim Jamshed };
42*76404edcSAsim Jamshed
43*76404edcSAsim Jamshed static const keyvalue http_status[] = {
44*76404edcSAsim Jamshed { 100, "Continue" },
45*76404edcSAsim Jamshed { 101, "Switching Protocols" },
46*76404edcSAsim Jamshed { 102, "Processing" }, /* WebDAV */
47*76404edcSAsim Jamshed { 200, "OK" },
48*76404edcSAsim Jamshed { 201, "Created" },
49*76404edcSAsim Jamshed { 202, "Accepted" },
50*76404edcSAsim Jamshed { 203, "Non-Authoritative Information" },
51*76404edcSAsim Jamshed { 204, "No Content" },
52*76404edcSAsim Jamshed { 205, "Reset Content" },
53*76404edcSAsim Jamshed { 206, "Partial Content" },
54*76404edcSAsim Jamshed { 207, "Multi-status" }, /* WebDAV */
55*76404edcSAsim Jamshed { 300, "Multiple Choices" },
56*76404edcSAsim Jamshed { 301, "Moved Permanently" },
57*76404edcSAsim Jamshed { 302, "Found" },
58*76404edcSAsim Jamshed { 303, "See Other" },
59*76404edcSAsim Jamshed { 304, "Not Modified" },
60*76404edcSAsim Jamshed { 305, "Use Proxy" },
61*76404edcSAsim Jamshed { 306, "(Unused)" },
62*76404edcSAsim Jamshed { 307, "Temporary Redirect" },
63*76404edcSAsim Jamshed { 400, "Bad Request" },
64*76404edcSAsim Jamshed { 401, "Unauthorized" },
65*76404edcSAsim Jamshed { 402, "Payment Required" },
66*76404edcSAsim Jamshed { 403, "Forbidden" },
67*76404edcSAsim Jamshed { 404, "Not Found At All" },
68*76404edcSAsim Jamshed { 405, "Method Not Allowed" },
69*76404edcSAsim Jamshed { 406, "Not Acceptable" },
70*76404edcSAsim Jamshed { 407, "Proxy Authentication Required" },
71*76404edcSAsim Jamshed { 408, "Request Timeout" },
72*76404edcSAsim Jamshed { 409, "Conflict" },
73*76404edcSAsim Jamshed { 410, "Gone" },
74*76404edcSAsim Jamshed { 411, "Length Required" },
75*76404edcSAsim Jamshed { 412, "Precondition Failed" },
76*76404edcSAsim Jamshed { 413, "Request Entity Too Large" },
77*76404edcSAsim Jamshed { 414, "Request-URI Too Long" },
78*76404edcSAsim Jamshed { 415, "Unsupported Media Type" },
79*76404edcSAsim Jamshed { 416, "Requested Range Not Satisfiable" },
80*76404edcSAsim Jamshed { 417, "Expectation Failed" },
81*76404edcSAsim Jamshed { 422, "Unprocessable Entity" }, /* WebDAV */
82*76404edcSAsim Jamshed { 423, "Locked" }, /* WebDAV */
83*76404edcSAsim Jamshed { 424, "Failed Dependency" }, /* WebDAV */
84*76404edcSAsim Jamshed { 426, "Upgrade Required" }, /* TLS */
85*76404edcSAsim Jamshed { 500, "Internal Server Error" },
86*76404edcSAsim Jamshed { 501, "Not Implemented" },
87*76404edcSAsim Jamshed { 502, "Bad Gateway" },
88*76404edcSAsim Jamshed { 503, "Service Not Available" },
89*76404edcSAsim Jamshed { 504, "Gateway Timeout" },
90*76404edcSAsim Jamshed { 505, "HTTP Version Not Supported" },
91*76404edcSAsim Jamshed { 507, "Insufficient Storage" }, /* WebDAV */
92*76404edcSAsim Jamshed
93*76404edcSAsim Jamshed { -1, NULL }
94*76404edcSAsim Jamshed };
95*76404edcSAsim Jamshed
96*76404edcSAsim Jamshed static const keyvalue http_status_body[] = {
97*76404edcSAsim Jamshed { 400, "400.html" },
98*76404edcSAsim Jamshed { 401, "401.html" },
99*76404edcSAsim Jamshed { 403, "403.html" },
100*76404edcSAsim Jamshed { 404, "404.html" },
101*76404edcSAsim Jamshed { 411, "411.html" },
102*76404edcSAsim Jamshed { 416, "416.html" },
103*76404edcSAsim Jamshed { 500, "500.html" },
104*76404edcSAsim Jamshed { 501, "501.html" },
105*76404edcSAsim Jamshed { 503, "503.html" },
106*76404edcSAsim Jamshed { 505, "505.html" },
107*76404edcSAsim Jamshed
108*76404edcSAsim Jamshed { -1, NULL }
109*76404edcSAsim Jamshed };
110*76404edcSAsim Jamshed
111*76404edcSAsim Jamshed
keyvalue_get_value(const keyvalue * kv,int k)112*76404edcSAsim Jamshed const char *keyvalue_get_value(const keyvalue *kv, int k) {
113*76404edcSAsim Jamshed int i;
114*76404edcSAsim Jamshed for (i = 0; kv[i].value; i++) {
115*76404edcSAsim Jamshed if (kv[i].key == k) return kv[i].value;
116*76404edcSAsim Jamshed }
117*76404edcSAsim Jamshed return NULL;
118*76404edcSAsim Jamshed }
119*76404edcSAsim Jamshed
keyvalue_get_key(const keyvalue * kv,const char * s)120*76404edcSAsim Jamshed int keyvalue_get_key(const keyvalue *kv, const char *s) {
121*76404edcSAsim Jamshed int i;
122*76404edcSAsim Jamshed for (i = 0; kv[i].value; i++) {
123*76404edcSAsim Jamshed if (0 == strcmp(kv[i].value, s)) return kv[i].key;
124*76404edcSAsim Jamshed }
125*76404edcSAsim Jamshed return -1;
126*76404edcSAsim Jamshed }
127*76404edcSAsim Jamshed
keyvalue_buffer_init(void)128*76404edcSAsim Jamshed keyvalue_buffer *keyvalue_buffer_init(void) {
129*76404edcSAsim Jamshed keyvalue_buffer *kvb;
130*76404edcSAsim Jamshed
131*76404edcSAsim Jamshed kvb = calloc(1, sizeof(*kvb));
132*76404edcSAsim Jamshed
133*76404edcSAsim Jamshed return kvb;
134*76404edcSAsim Jamshed }
135*76404edcSAsim Jamshed
keyvalue_buffer_append(keyvalue_buffer * kvb,int key,const char * value)136*76404edcSAsim Jamshed int keyvalue_buffer_append(keyvalue_buffer *kvb, int key, const char *value) {
137*76404edcSAsim Jamshed size_t i;
138*76404edcSAsim Jamshed if (kvb->size == 0) {
139*76404edcSAsim Jamshed kvb->size = 4;
140*76404edcSAsim Jamshed
141*76404edcSAsim Jamshed kvb->kv = malloc(kvb->size * sizeof(*kvb->kv));
142*76404edcSAsim Jamshed
143*76404edcSAsim Jamshed for(i = 0; i < kvb->size; i++) {
144*76404edcSAsim Jamshed kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
145*76404edcSAsim Jamshed }
146*76404edcSAsim Jamshed } else if (kvb->used == kvb->size) {
147*76404edcSAsim Jamshed kvb->size += 4;
148*76404edcSAsim Jamshed
149*76404edcSAsim Jamshed kvb->kv = realloc(kvb->kv, kvb->size * sizeof(*kvb->kv));
150*76404edcSAsim Jamshed
151*76404edcSAsim Jamshed for(i = kvb->used; i < kvb->size; i++) {
152*76404edcSAsim Jamshed kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
153*76404edcSAsim Jamshed }
154*76404edcSAsim Jamshed }
155*76404edcSAsim Jamshed
156*76404edcSAsim Jamshed kvb->kv[kvb->used]->key = key;
157*76404edcSAsim Jamshed kvb->kv[kvb->used]->value = strdup(value);
158*76404edcSAsim Jamshed
159*76404edcSAsim Jamshed kvb->used++;
160*76404edcSAsim Jamshed
161*76404edcSAsim Jamshed return 0;
162*76404edcSAsim Jamshed }
163*76404edcSAsim Jamshed
keyvalue_buffer_free(keyvalue_buffer * kvb)164*76404edcSAsim Jamshed void keyvalue_buffer_free(keyvalue_buffer *kvb) {
165*76404edcSAsim Jamshed size_t i;
166*76404edcSAsim Jamshed
167*76404edcSAsim Jamshed for (i = 0; i < kvb->size; i++) {
168*76404edcSAsim Jamshed if (kvb->kv[i]->value) free(kvb->kv[i]->value);
169*76404edcSAsim Jamshed free(kvb->kv[i]);
170*76404edcSAsim Jamshed }
171*76404edcSAsim Jamshed
172*76404edcSAsim Jamshed if (kvb->kv) free(kvb->kv);
173*76404edcSAsim Jamshed
174*76404edcSAsim Jamshed free(kvb);
175*76404edcSAsim Jamshed }
176*76404edcSAsim Jamshed
177*76404edcSAsim Jamshed
s_keyvalue_buffer_init(void)178*76404edcSAsim Jamshed s_keyvalue_buffer *s_keyvalue_buffer_init(void) {
179*76404edcSAsim Jamshed s_keyvalue_buffer *kvb;
180*76404edcSAsim Jamshed
181*76404edcSAsim Jamshed kvb = calloc(1, sizeof(*kvb));
182*76404edcSAsim Jamshed
183*76404edcSAsim Jamshed return kvb;
184*76404edcSAsim Jamshed }
185*76404edcSAsim Jamshed
s_keyvalue_buffer_append(s_keyvalue_buffer * kvb,const char * key,const char * value)186*76404edcSAsim Jamshed int s_keyvalue_buffer_append(s_keyvalue_buffer *kvb, const char *key, const char *value) {
187*76404edcSAsim Jamshed size_t i;
188*76404edcSAsim Jamshed if (kvb->size == 0) {
189*76404edcSAsim Jamshed kvb->size = 4;
190*76404edcSAsim Jamshed kvb->used = 0;
191*76404edcSAsim Jamshed
192*76404edcSAsim Jamshed kvb->kv = malloc(kvb->size * sizeof(*kvb->kv));
193*76404edcSAsim Jamshed
194*76404edcSAsim Jamshed for(i = 0; i < kvb->size; i++) {
195*76404edcSAsim Jamshed kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
196*76404edcSAsim Jamshed }
197*76404edcSAsim Jamshed } else if (kvb->used == kvb->size) {
198*76404edcSAsim Jamshed kvb->size += 4;
199*76404edcSAsim Jamshed
200*76404edcSAsim Jamshed kvb->kv = realloc(kvb->kv, kvb->size * sizeof(*kvb->kv));
201*76404edcSAsim Jamshed
202*76404edcSAsim Jamshed for(i = kvb->used; i < kvb->size; i++) {
203*76404edcSAsim Jamshed kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
204*76404edcSAsim Jamshed }
205*76404edcSAsim Jamshed }
206*76404edcSAsim Jamshed
207*76404edcSAsim Jamshed kvb->kv[kvb->used]->key = key ? strdup(key) : NULL;
208*76404edcSAsim Jamshed kvb->kv[kvb->used]->value = strdup(value);
209*76404edcSAsim Jamshed
210*76404edcSAsim Jamshed kvb->used++;
211*76404edcSAsim Jamshed
212*76404edcSAsim Jamshed return 0;
213*76404edcSAsim Jamshed }
214*76404edcSAsim Jamshed
s_keyvalue_buffer_free(s_keyvalue_buffer * kvb)215*76404edcSAsim Jamshed void s_keyvalue_buffer_free(s_keyvalue_buffer *kvb) {
216*76404edcSAsim Jamshed size_t i;
217*76404edcSAsim Jamshed
218*76404edcSAsim Jamshed for (i = 0; i < kvb->size; i++) {
219*76404edcSAsim Jamshed if (kvb->kv[i]->key) free(kvb->kv[i]->key);
220*76404edcSAsim Jamshed if (kvb->kv[i]->value) free(kvb->kv[i]->value);
221*76404edcSAsim Jamshed free(kvb->kv[i]);
222*76404edcSAsim Jamshed }
223*76404edcSAsim Jamshed
224*76404edcSAsim Jamshed if (kvb->kv) free(kvb->kv);
225*76404edcSAsim Jamshed
226*76404edcSAsim Jamshed free(kvb);
227*76404edcSAsim Jamshed }
228*76404edcSAsim Jamshed
229*76404edcSAsim Jamshed
httpauth_keyvalue_buffer_init(void)230*76404edcSAsim Jamshed httpauth_keyvalue_buffer *httpauth_keyvalue_buffer_init(void) {
231*76404edcSAsim Jamshed httpauth_keyvalue_buffer *kvb;
232*76404edcSAsim Jamshed
233*76404edcSAsim Jamshed kvb = calloc(1, sizeof(*kvb));
234*76404edcSAsim Jamshed
235*76404edcSAsim Jamshed return kvb;
236*76404edcSAsim Jamshed }
237*76404edcSAsim Jamshed
httpauth_keyvalue_buffer_append(httpauth_keyvalue_buffer * kvb,const char * key,const char * realm,httpauth_type type)238*76404edcSAsim Jamshed int httpauth_keyvalue_buffer_append(httpauth_keyvalue_buffer *kvb, const char *key, const char *realm, httpauth_type type) {
239*76404edcSAsim Jamshed size_t i;
240*76404edcSAsim Jamshed if (kvb->size == 0) {
241*76404edcSAsim Jamshed kvb->size = 4;
242*76404edcSAsim Jamshed
243*76404edcSAsim Jamshed kvb->kv = malloc(kvb->size * sizeof(*kvb->kv));
244*76404edcSAsim Jamshed
245*76404edcSAsim Jamshed for(i = 0; i < kvb->size; i++) {
246*76404edcSAsim Jamshed kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
247*76404edcSAsim Jamshed }
248*76404edcSAsim Jamshed } else if (kvb->used == kvb->size) {
249*76404edcSAsim Jamshed kvb->size += 4;
250*76404edcSAsim Jamshed
251*76404edcSAsim Jamshed kvb->kv = realloc(kvb->kv, kvb->size * sizeof(*kvb->kv));
252*76404edcSAsim Jamshed
253*76404edcSAsim Jamshed for(i = kvb->used; i < kvb->size; i++) {
254*76404edcSAsim Jamshed kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
255*76404edcSAsim Jamshed }
256*76404edcSAsim Jamshed }
257*76404edcSAsim Jamshed
258*76404edcSAsim Jamshed kvb->kv[kvb->used]->key = strdup(key);
259*76404edcSAsim Jamshed kvb->kv[kvb->used]->realm = strdup(realm);
260*76404edcSAsim Jamshed kvb->kv[kvb->used]->type = type;
261*76404edcSAsim Jamshed
262*76404edcSAsim Jamshed kvb->used++;
263*76404edcSAsim Jamshed
264*76404edcSAsim Jamshed return 0;
265*76404edcSAsim Jamshed }
266*76404edcSAsim Jamshed
httpauth_keyvalue_buffer_free(httpauth_keyvalue_buffer * kvb)267*76404edcSAsim Jamshed void httpauth_keyvalue_buffer_free(httpauth_keyvalue_buffer *kvb) {
268*76404edcSAsim Jamshed size_t i;
269*76404edcSAsim Jamshed
270*76404edcSAsim Jamshed for (i = 0; i < kvb->size; i++) {
271*76404edcSAsim Jamshed if (kvb->kv[i]->key) free(kvb->kv[i]->key);
272*76404edcSAsim Jamshed if (kvb->kv[i]->realm) free(kvb->kv[i]->realm);
273*76404edcSAsim Jamshed free(kvb->kv[i]);
274*76404edcSAsim Jamshed }
275*76404edcSAsim Jamshed
276*76404edcSAsim Jamshed if (kvb->kv) free(kvb->kv);
277*76404edcSAsim Jamshed
278*76404edcSAsim Jamshed free(kvb);
279*76404edcSAsim Jamshed }
280*76404edcSAsim Jamshed
281*76404edcSAsim Jamshed
get_http_version_name(int i)282*76404edcSAsim Jamshed const char *get_http_version_name(int i) {
283*76404edcSAsim Jamshed return keyvalue_get_value(http_versions, i);
284*76404edcSAsim Jamshed }
285*76404edcSAsim Jamshed
get_http_status_name(int i)286*76404edcSAsim Jamshed const char *get_http_status_name(int i) {
287*76404edcSAsim Jamshed return keyvalue_get_value(http_status, i);
288*76404edcSAsim Jamshed }
289*76404edcSAsim Jamshed
get_http_method_name(http_method_t i)290*76404edcSAsim Jamshed const char *get_http_method_name(http_method_t i) {
291*76404edcSAsim Jamshed return keyvalue_get_value(http_methods, i);
292*76404edcSAsim Jamshed }
293*76404edcSAsim Jamshed
get_http_status_body_name(int i)294*76404edcSAsim Jamshed const char *get_http_status_body_name(int i) {
295*76404edcSAsim Jamshed return keyvalue_get_value(http_status_body, i);
296*76404edcSAsim Jamshed }
297*76404edcSAsim Jamshed
get_http_version_key(const char * s)298*76404edcSAsim Jamshed int get_http_version_key(const char *s) {
299*76404edcSAsim Jamshed return keyvalue_get_key(http_versions, s);
300*76404edcSAsim Jamshed }
301*76404edcSAsim Jamshed
get_http_method_key(const char * s)302*76404edcSAsim Jamshed http_method_t get_http_method_key(const char *s) {
303*76404edcSAsim Jamshed return (http_method_t)keyvalue_get_key(http_methods, s);
304*76404edcSAsim Jamshed }
305*76404edcSAsim Jamshed
306*76404edcSAsim Jamshed
307*76404edcSAsim Jamshed
308*76404edcSAsim Jamshed
pcre_keyvalue_buffer_init(void)309*76404edcSAsim Jamshed pcre_keyvalue_buffer *pcre_keyvalue_buffer_init(void) {
310*76404edcSAsim Jamshed pcre_keyvalue_buffer *kvb;
311*76404edcSAsim Jamshed
312*76404edcSAsim Jamshed kvb = calloc(1, sizeof(*kvb));
313*76404edcSAsim Jamshed
314*76404edcSAsim Jamshed return kvb;
315*76404edcSAsim Jamshed }
316*76404edcSAsim Jamshed
pcre_keyvalue_buffer_append(server * srv,pcre_keyvalue_buffer * kvb,const char * key,const char * value)317*76404edcSAsim Jamshed int pcre_keyvalue_buffer_append(server *srv, pcre_keyvalue_buffer *kvb, const char *key, const char *value) {
318*76404edcSAsim Jamshed #ifdef HAVE_PCRE_H
319*76404edcSAsim Jamshed size_t i;
320*76404edcSAsim Jamshed const char *errptr;
321*76404edcSAsim Jamshed int erroff;
322*76404edcSAsim Jamshed pcre_keyvalue *kv;
323*76404edcSAsim Jamshed #endif
324*76404edcSAsim Jamshed
325*76404edcSAsim Jamshed if (!key) return -1;
326*76404edcSAsim Jamshed
327*76404edcSAsim Jamshed #ifdef HAVE_PCRE_H
328*76404edcSAsim Jamshed if (kvb->size == 0) {
329*76404edcSAsim Jamshed kvb->size = 4;
330*76404edcSAsim Jamshed kvb->used = 0;
331*76404edcSAsim Jamshed
332*76404edcSAsim Jamshed kvb->kv = malloc(kvb->size * sizeof(*kvb->kv));
333*76404edcSAsim Jamshed
334*76404edcSAsim Jamshed for(i = 0; i < kvb->size; i++) {
335*76404edcSAsim Jamshed kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
336*76404edcSAsim Jamshed }
337*76404edcSAsim Jamshed } else if (kvb->used == kvb->size) {
338*76404edcSAsim Jamshed kvb->size += 4;
339*76404edcSAsim Jamshed
340*76404edcSAsim Jamshed kvb->kv = realloc(kvb->kv, kvb->size * sizeof(*kvb->kv));
341*76404edcSAsim Jamshed
342*76404edcSAsim Jamshed for(i = kvb->used; i < kvb->size; i++) {
343*76404edcSAsim Jamshed kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
344*76404edcSAsim Jamshed }
345*76404edcSAsim Jamshed }
346*76404edcSAsim Jamshed
347*76404edcSAsim Jamshed kv = kvb->kv[kvb->used];
348*76404edcSAsim Jamshed if (NULL == (kv->key = pcre_compile(key,
349*76404edcSAsim Jamshed 0, &errptr, &erroff, NULL))) {
350*76404edcSAsim Jamshed
351*76404edcSAsim Jamshed log_error_write(srv, __FILE__, __LINE__, "SS",
352*76404edcSAsim Jamshed "rexexp compilation error at ", errptr);
353*76404edcSAsim Jamshed return -1;
354*76404edcSAsim Jamshed }
355*76404edcSAsim Jamshed
356*76404edcSAsim Jamshed if (NULL == (kv->key_extra = pcre_study(kv->key, 0, &errptr)) &&
357*76404edcSAsim Jamshed errptr != NULL) {
358*76404edcSAsim Jamshed return -1;
359*76404edcSAsim Jamshed }
360*76404edcSAsim Jamshed
361*76404edcSAsim Jamshed kv->value = buffer_init_string(value);
362*76404edcSAsim Jamshed
363*76404edcSAsim Jamshed kvb->used++;
364*76404edcSAsim Jamshed
365*76404edcSAsim Jamshed return 0;
366*76404edcSAsim Jamshed #else
367*76404edcSAsim Jamshed UNUSED(kvb);
368*76404edcSAsim Jamshed UNUSED(value);
369*76404edcSAsim Jamshed
370*76404edcSAsim Jamshed return -1;
371*76404edcSAsim Jamshed #endif
372*76404edcSAsim Jamshed }
373*76404edcSAsim Jamshed
pcre_keyvalue_buffer_free(pcre_keyvalue_buffer * kvb)374*76404edcSAsim Jamshed void pcre_keyvalue_buffer_free(pcre_keyvalue_buffer *kvb) {
375*76404edcSAsim Jamshed #ifdef HAVE_PCRE_H
376*76404edcSAsim Jamshed size_t i;
377*76404edcSAsim Jamshed pcre_keyvalue *kv;
378*76404edcSAsim Jamshed
379*76404edcSAsim Jamshed for (i = 0; i < kvb->size; i++) {
380*76404edcSAsim Jamshed kv = kvb->kv[i];
381*76404edcSAsim Jamshed if (kv->key) pcre_free(kv->key);
382*76404edcSAsim Jamshed if (kv->key_extra) pcre_free(kv->key_extra);
383*76404edcSAsim Jamshed if (kv->value) buffer_free(kv->value);
384*76404edcSAsim Jamshed free(kv);
385*76404edcSAsim Jamshed }
386*76404edcSAsim Jamshed
387*76404edcSAsim Jamshed if (kvb->kv) free(kvb->kv);
388*76404edcSAsim Jamshed #endif
389*76404edcSAsim Jamshed
390*76404edcSAsim Jamshed free(kvb);
391*76404edcSAsim Jamshed }
392