agoo 2.4.0 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of agoo might be problematic. Click here for more details.

@@ -21,6 +21,7 @@ typedef struct _Rec {
21
21
  static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
22
22
  static Rec recs = NULL;
23
23
 
24
+ atomic_int mem_bind = 0;
24
25
  atomic_int mem_cb = 0;
25
26
  atomic_int mem_con = 0;
26
27
  atomic_int mem_cslot = 0;
@@ -89,6 +90,7 @@ print_stats() {
89
90
  printf("********************************************************************************\n");
90
91
  #if 0
91
92
  printf("memory statistics\n");
93
+ printf(" mem_bind: %d\n", mem_bind);
92
94
  printf(" mem_cb: %d\n", mem_cb);
93
95
  printf(" mem_con: %d\n", mem_con);
94
96
  printf(" mem_cslot: %d\n", mem_cslot);
@@ -15,6 +15,7 @@
15
15
  #define DEBUG_FREE(var, ptr) { }
16
16
  #endif
17
17
 
18
+ extern atomic_int mem_bind;
18
19
  extern atomic_int mem_cb;
19
20
  extern atomic_int mem_con;
20
21
  extern atomic_int mem_cslot;
@@ -2,6 +2,7 @@
2
2
 
3
3
  #include "error_stream.h"
4
4
  #include "debug.h"
5
+ #include "log.h"
5
6
  #include "text.h"
6
7
 
7
8
  static VALUE es_class = Qundef;
@@ -7,29 +7,39 @@
7
7
  #include "hook.h"
8
8
 
9
9
  Hook
10
- hook_create(Method method, const char *pattern, void *handler, HookType type) {
10
+ hook_create(Method method, const char *pattern, void *handler, HookType type, Queue q) {
11
11
  Hook hook = (Hook)malloc(sizeof(struct _Hook));
12
12
 
13
13
  if (NULL != hook) {
14
- DEBUG_ALLOC(mem_hook, hook)
14
+ char *pat = NULL;
15
+
16
+ DEBUG_ALLOC(mem_hook, hook);
15
17
  if (NULL == pattern) {
16
- pattern = "";
18
+ if (NONE != method) {
19
+ pat = strdup("");
20
+ }
21
+ } else {
22
+ pat = strdup(pattern);
17
23
  }
24
+ hook->pattern = pat;
25
+
18
26
  hook->next = NULL;
19
- hook->pattern = strdup(pattern);
20
27
  DEBUG_ALLOC(mem_hook_pattern, hook->pattern)
21
28
  hook->method = method;
22
29
  hook->handler = handler;
23
30
  hook->type = type;
31
+ hook->queue = q;
24
32
  }
25
33
  return hook;
26
34
  }
27
35
 
28
36
  void
29
37
  hook_destroy(Hook hook) {
30
- DEBUG_FREE(mem_hook_pattern, hook->pattern);
38
+ if (NULL != hook->pattern) {
39
+ DEBUG_FREE(mem_hook_pattern, hook->pattern);
40
+ free(hook->pattern);
41
+ }
31
42
  DEBUG_FREE(mem_hook, hook)
32
- free(hook->pattern);
33
43
  free(hook);
34
44
  }
35
45
 
@@ -6,6 +6,7 @@
6
6
  #include <stdbool.h>
7
7
 
8
8
  #include "method.h"
9
+ #include "queue.h"
9
10
  #include "seg.h"
10
11
 
11
12
  typedef enum {
@@ -31,9 +32,10 @@ typedef struct _Hook {
31
32
  char *pattern;
32
33
  HookType type;
33
34
  void* handler;
35
+ Queue queue;
34
36
  } *Hook;
35
37
 
36
- extern Hook hook_create(Method method, const char *pattern, void *handler, HookType type);
38
+ extern Hook hook_create(Method method, const char *pattern, void *handler, HookType type, Queue q);
37
39
  extern void hook_destroy(Hook hook);
38
40
 
39
41
  extern bool hook_match(Hook hook, Method method, const Seg seg);
@@ -4,8 +4,6 @@
4
4
  #include <stdlib.h>
5
5
  #include <string.h>
6
6
 
7
- #include <ruby.h>
8
-
9
7
  #include "debug.h"
10
8
  #include "http.h"
11
9
 
@@ -507,8 +505,8 @@ http_cleanup() {
507
505
  }
508
506
  }
509
507
 
510
- void
511
- http_header_ok(const char *key, int klen, const char *value, int vlen) {
508
+ int
509
+ http_header_ok(Err err, const char *key, int klen, const char *value, int vlen) {
512
510
  int len = klen;
513
511
  int64_t h = calc_hash(key, &len);
514
512
  Slot *bucket = get_bucketp(h);
@@ -530,21 +528,23 @@ http_header_ok(const char *key, int klen, const char *value, int vlen) {
530
528
  }
531
529
  strncpy(buf, key, klen);
532
530
  buf[klen] = '\0';
533
- rb_raise(rb_eArgError, "%s is not a valid HTTP header key.", buf);
531
+
532
+ return err_set(err, ERR_ARG, "%s is not a valid HTTP header key.", buf);
534
533
  }
535
534
  // Now check the value.
536
535
  found = false; // reuse as indicator for in a quoted string
537
536
  for (; 0 < vlen; vlen--, value++) {
538
537
  if ('o' != header_value_chars[(uint8_t)*value]) {
539
- rb_raise(rb_eArgError, "%02x is not a valid HTTP header value character.", *value);
538
+ return err_set(err, ERR_ARG, "%02x is not a valid HTTP header value character.", *value);
540
539
  }
541
540
  if ('"' == *value) {
542
541
  found = !found;
543
542
  }
544
543
  }
545
544
  if (found) {
546
- rb_raise(rb_eArgError, "HTTP header has unmatched quote.");
545
+ return err_set(err, ERR_ARG, "HTTP header has unmatched quote.");
547
546
  }
547
+ return ERR_OK;
548
548
  }
549
549
 
550
550
  const char*
@@ -5,10 +5,12 @@
5
5
 
6
6
  #include <stdbool.h>
7
7
 
8
+ #include "err.h"
9
+
8
10
  extern void http_init();
9
11
  extern void http_cleanup();
10
12
 
11
- extern void http_header_ok(const char *key, int klen, const char *value, int vlen);
13
+ extern int http_header_ok(Err err, const char *key, int klen, const char *value, int vlen);
12
14
 
13
15
  extern const char* http_code_message(int code);
14
16
 
@@ -8,6 +8,7 @@
8
8
  #include <stdatomic.h>
9
9
  #include <stdbool.h>
10
10
  #include <stdint.h>
11
+ #include <stdio.h>
11
12
 
12
13
  #include "err.h"
13
14
 
@@ -6,14 +6,43 @@
6
6
  #include <sys/stat.h>
7
7
  #include <unistd.h>
8
8
 
9
- #include <ruby.h>
10
-
11
9
  #include "debug.h"
12
10
  #include "dtime.h"
13
11
  #include "page.h"
14
12
 
15
13
  #define PAGE_RECHECK_TIME 5.0
14
+
16
15
  #define MAX_KEY_UNIQ 9
16
+ #define MAX_KEY_LEN 1024
17
+ #define PAGE_BUCKET_SIZE 1024
18
+ #define PAGE_BUCKET_MASK 1023
19
+
20
+ #define MAX_MIME_KEY_LEN 15
21
+ #define MIME_BUCKET_SIZE 64
22
+ #define MIME_BUCKET_MASK 63
23
+
24
+ typedef struct _Slot {
25
+ struct _Slot *next;
26
+ char key[MAX_KEY_LEN + 1];
27
+ Page value;
28
+ uint64_t hash;
29
+ int klen;
30
+ } *Slot;
31
+
32
+ typedef struct _MimeSlot {
33
+ struct _MimeSlot *next;
34
+ char key[MAX_MIME_KEY_LEN + 1];
35
+ char *value;
36
+ uint64_t hash;
37
+ int klen;
38
+ } *MimeSlot;
39
+
40
+ typedef struct _Cache {
41
+ Slot buckets[PAGE_BUCKET_SIZE];
42
+ MimeSlot muckets[MIME_BUCKET_SIZE];
43
+ char *root;
44
+ Group groups;
45
+ } *Cache;
17
46
 
18
47
  typedef struct _Mime {
19
48
  const char *suffix;
@@ -70,6 +99,13 @@ static struct _Mime mime_map[] = {
70
99
 
71
100
  static const char page_fmt[] = "HTTP/1.1 200 OK\r\nContent-Type: %s\r\nContent-Length: %ld\r\n\r\n";
72
101
 
102
+ static struct _Cache cache = {
103
+ .buckets = {0},
104
+ .muckets = {0},
105
+ .root = NULL,
106
+ .groups = NULL,
107
+ };
108
+
73
109
  static uint64_t
74
110
  calc_hash(const char *key, int *lenp) {
75
111
  int len = 0;
@@ -98,21 +134,21 @@ calc_hash(const char *key, int *lenp) {
98
134
 
99
135
  // Buckets are a twist on the hash to mix it up a bit. Odd shifts and XORs.
100
136
  static Slot*
101
- get_bucketp(Cache cache, uint64_t h) {
102
- return cache->buckets + (PAGE_BUCKET_MASK & (h ^ (h << 5) ^ (h >> 7)));
137
+ get_bucketp(uint64_t h) {
138
+ return cache.buckets + (PAGE_BUCKET_MASK & (h ^ (h << 5) ^ (h >> 7)));
103
139
  }
104
140
 
105
141
  static MimeSlot*
106
- get_mime_bucketp(Cache cache, uint64_t h) {
107
- return cache->muckets + (MIME_BUCKET_MASK & (h ^ (h << 5) ^ (h >> 7)));
142
+ get_mime_bucketp(uint64_t h) {
143
+ return cache.muckets + (MIME_BUCKET_MASK & (h ^ (h << 5) ^ (h >> 7)));
108
144
  }
109
145
 
110
146
  const char*
111
- mime_get(Cache cache, const char *key) {
147
+ mime_get(const char *key) {
112
148
  int klen = (int)strlen(key);
113
149
  int len = klen;
114
150
  int64_t h = calc_hash(key, &len);
115
- MimeSlot *bucket = get_mime_bucketp(cache, h);
151
+ MimeSlot *bucket = get_mime_bucketp(h);
116
152
  MimeSlot s;
117
153
  const char *v = NULL;
118
154
 
@@ -127,10 +163,10 @@ mime_get(Cache cache, const char *key) {
127
163
  }
128
164
 
129
165
  Page
130
- cache_get(Cache cache, const char *key, int klen) {
166
+ cache_get(const char *key, int klen) {
131
167
  int len = klen;
132
168
  int64_t h = calc_hash(key, &len);
133
- Slot *bucket = get_bucketp(cache, h);
169
+ Slot *bucket = get_bucketp(h);
134
170
  Slot s;
135
171
  Page v = NULL;
136
172
 
@@ -144,33 +180,31 @@ cache_get(Cache cache, const char *key, int klen) {
144
180
  return v;
145
181
  }
146
182
 
147
- void
148
- mime_set(Cache cache, const char *key, const char *value) {
183
+ int
184
+ mime_set(Err err, const char *key, const char *value) {
149
185
  int klen = (int)strlen(key);
150
186
  int len = klen;
151
187
  int64_t h = calc_hash(key, &len);
152
- MimeSlot *bucket = get_mime_bucketp(cache, h);
188
+ MimeSlot *bucket = get_mime_bucketp(h);
153
189
  MimeSlot s;
154
190
 
155
191
  if (MAX_MIME_KEY_LEN < len) {
156
- rb_raise(rb_eArgError, "%s is too long for a file extension. Maximum is %d", key, MAX_MIME_KEY_LEN);
192
+ return err_set(err, ERR_ARG, "%s is too long for a file extension. Maximum is %d", key, MAX_MIME_KEY_LEN);
157
193
  }
158
194
  for (s = *bucket; NULL != s; s = s->next) {
159
195
  if (h == (int64_t)s->hash && len == s->klen &&
160
196
  ((0 <= len && len <= MAX_KEY_UNIQ) || 0 == strncmp(s->key, key, len))) {
161
- if (h == (int64_t)s->hash && len == s->klen &&
162
- ((0 <= len && len <= MAX_KEY_UNIQ) || 0 == strncmp(s->key, key, len))) {
163
- DEBUG_FREE(mem_mime_slot, s->value)
164
- free(s->value);
165
- s->value = strdup(value);
166
- return;
167
- }
197
+
198
+ DEBUG_FREE(mem_mime_slot, s->value);
199
+ free(s->value);
200
+ s->value = strdup(value);
201
+ return ERR_OK;
168
202
  }
169
203
  }
170
204
  if (NULL == (s = (MimeSlot)malloc(sizeof(struct _MimeSlot)))) {
171
- rb_raise(rb_eArgError, "out of memory adding %s", key);
205
+ return err_set(err, ERR_ARG, "out of memory adding %s", key);
172
206
  }
173
- DEBUG_ALLOC(mem_mime_slot, s)
207
+ DEBUG_ALLOC(mem_mime_slot, s);
174
208
  s->hash = h;
175
209
  s->klen = len;
176
210
  if (NULL == key) {
@@ -181,13 +215,15 @@ mime_set(Cache cache, const char *key, const char *value) {
181
215
  s->value = strdup(value);
182
216
  s->next = *bucket;
183
217
  *bucket = s;
218
+
219
+ return ERR_OK;
184
220
  }
185
221
 
186
222
  static Page
187
- cache_set(Cache cache, const char *key, int klen, Page value) {
223
+ cache_set(const char *key, int klen, Page value) {
188
224
  int len = klen;
189
225
  int64_t h = calc_hash(key, &len);
190
- Slot *bucket = get_bucketp(cache, h);
226
+ Slot *bucket = get_bucketp(h);
191
227
  Slot s;
192
228
  Page old = NULL;
193
229
 
@@ -197,14 +233,12 @@ cache_set(Cache cache, const char *key, int klen, Page value) {
197
233
  for (s = *bucket; NULL != s; s = s->next) {
198
234
  if (h == (int64_t)s->hash && len == s->klen &&
199
235
  ((0 <= len && len <= MAX_KEY_UNIQ) || 0 == strncmp(s->key, key, len))) {
200
- if (h == (int64_t)s->hash && len == s->klen &&
201
- ((0 <= len && len <= MAX_KEY_UNIQ) || 0 == strncmp(s->key, key, len))) {
202
- old = s->value;
203
- // replace
204
- s->value = value;
205
236
 
206
- return old;
207
- }
237
+ old = s->value;
238
+ // replace
239
+ s->value = value;
240
+
241
+ return old;
208
242
  }
209
243
  }
210
244
  if (NULL == (s = (Slot)malloc(sizeof(struct _Slot)))) {
@@ -227,21 +261,41 @@ cache_set(Cache cache, const char *key, int klen, Page value) {
227
261
  }
228
262
 
229
263
  void
230
- pages_init(Cache cache) {
264
+ pages_init() {
231
265
  Mime m;
232
-
233
- memset(cache, 0, sizeof(struct _Cache));
266
+ struct _Err err = ERR_INIT;
267
+
268
+ memset(&cache, 0, sizeof(struct _Cache));
269
+ cache.root = strdup(".");
234
270
  for (m = mime_map; NULL != m->suffix; m++) {
235
- mime_set(cache, m->suffix, m->type);
271
+ mime_set(&err, m->suffix, m->type);
272
+ }
273
+ }
274
+
275
+ void
276
+ pages_set_root(const char *root) {
277
+ free(cache.root);
278
+ cache.root = strdup(root);
279
+ }
280
+
281
+ static void
282
+ page_destroy(Page p) {
283
+ if (NULL != p->resp) {
284
+ text_release(p->resp);
285
+ p->resp = NULL;
236
286
  }
287
+ DEBUG_FREE(mem_page_path, p->path);
288
+ DEBUG_FREE(mem_page, p);
289
+ free(p->path);
290
+ free(p);
237
291
  }
238
292
 
239
293
  void
240
- pages_cleanup(Cache cache) {
241
- Slot *sp = cache->buckets;
294
+ pages_cleanup() {
295
+ Slot *sp = cache.buckets;
242
296
  Slot s;
243
297
  Slot n;
244
- MimeSlot *mp = cache->muckets;
298
+ MimeSlot *mp = cache.muckets;
245
299
  MimeSlot sm;
246
300
  MimeSlot m;
247
301
  int i;
@@ -255,7 +309,6 @@ pages_cleanup(Cache cache) {
255
309
  }
256
310
  *sp = NULL;
257
311
  }
258
-
259
312
  for (i = MIME_BUCKET_SIZE; 0 < i; i--, mp++) {
260
313
  for (sm = *mp; NULL != sm; sm = m) {
261
314
  m = sm->next;
@@ -264,47 +317,107 @@ pages_cleanup(Cache cache) {
264
317
  }
265
318
  *mp = NULL;
266
319
  }
267
- free(cache->root);
320
+ free(cache.root);
268
321
  }
269
322
 
270
- // The page resp contents point to the page resp msg to save memory and reduce
323
+ static const char*
324
+ path_mime(const char *path) {
325
+ const char *suffix = path + strlen(path) - 1;
326
+ const char *mime = NULL;
327
+
328
+ for (; '.' != *suffix; suffix--) {
329
+ if (suffix <= path) {
330
+ suffix = NULL;
331
+ break;
332
+ }
333
+ }
334
+ if (suffix <= path) {
335
+ suffix = NULL;
336
+ }
337
+ if (NULL != suffix) {
338
+ suffix++;
339
+ mime = mime_get(suffix);
340
+ }
341
+ return mime;
342
+ }
343
+
344
+ // The page resp points to the page resp msg to save memory and reduce
271
345
  // allocations.
272
346
  Page
273
347
  page_create(const char *path) {
274
348
  Page p = (Page)malloc(sizeof(struct _Page));
275
349
 
276
350
  if (NULL != p) {
277
- DEBUG_ALLOC(mem_page, p)
351
+ DEBUG_ALLOC(mem_page, p);
278
352
  p->resp = NULL;
279
353
  if (NULL == path) {
280
354
  p->path = NULL;
281
355
  } else {
282
356
  p->path = strdup(path);
283
- DEBUG_ALLOC(mem_page_path, p->path)
357
+ DEBUG_ALLOC(mem_page_path, p->path);
284
358
  }
285
359
  p->mtime = 0;
286
360
  p->last_check = 0.0;
361
+ p->immutable = false;
287
362
  }
288
363
  return p;
289
364
  }
290
365
 
291
- void
292
- page_destroy(Page p) {
293
- if (NULL != p->resp) {
294
- text_release(p->resp);
295
- p->resp = NULL;
366
+ Page
367
+ page_immutable(Err err, const char *path, const char *content, int clen) {
368
+ Page p = (Page)malloc(sizeof(struct _Page));
369
+ const char *mime = path_mime(path);
370
+ long msize;
371
+ int cnt;
372
+ int plen = 0;
373
+
374
+ if (NULL == p) {
375
+ err_set(err, ERR_MEMORY, "Failed to allocate memory for page.");
376
+ return NULL;
296
377
  }
297
- DEBUG_FREE(mem_page_path, p->path);
298
- DEBUG_FREE(mem_page, p);
299
- free(p->path);
300
- free(p);
378
+ DEBUG_ALLOC(mem_page, p);
379
+ if (NULL == path) {
380
+ p->path = NULL;
381
+ } else {
382
+ p->path = strdup(path);
383
+ plen = strlen(path);
384
+ DEBUG_ALLOC(mem_page_path, p->path);
385
+ }
386
+ p->mtime = 0;
387
+ p->last_check = 0.0;
388
+ p->immutable = true;
389
+
390
+ if (NULL == mime) {
391
+ mime = "text/html";
392
+ }
393
+ if (0 == clen) {
394
+ clen = (int)strlen(content);
395
+ }
396
+ // Format size plus space for the length, the mime type, and some
397
+ // padding. Then add the content length.
398
+ msize = sizeof(page_fmt) + 60 + clen;
399
+ if (NULL == (p->resp = text_allocate((int)msize))) {
400
+ DEBUG_FREE(mem_page, p);
401
+ free(p);
402
+ err_set(err, ERR_MEMORY, "Failed to allocate memory for page content.");
403
+ return NULL;
404
+ }
405
+ cnt = sprintf(p->resp->text, page_fmt, mime, (long)clen);
406
+ msize = cnt + clen;
407
+ memcpy(p->resp->text + cnt, content, clen);
408
+ p->resp->text[msize] = '\0';
409
+ p->resp->len = msize;
410
+ text_ref(p->resp);
411
+
412
+ cache_set(path, plen, p);
413
+
414
+ return p;
301
415
  }
302
416
 
303
417
  static bool
304
- update_contents(Cache cache, Page p) {
305
- const char *mime = NULL;
418
+ update_contents(Page p) {
419
+ const char *mime = path_mime(p->path);
306
420
  int plen = (int)strlen(p->path);
307
- const char *suffix = p->path + plen - 1;
308
421
  FILE *f;
309
422
  long size;
310
423
  struct stat fattr;
@@ -313,24 +426,6 @@ update_contents(Cache cache, Page p) {
313
426
  struct stat fs;
314
427
  Text t;
315
428
 
316
- for (; '.' != *suffix; suffix--) {
317
- if (suffix <= p->path) {
318
- suffix = NULL;
319
- break;
320
- }
321
- }
322
- if (suffix <= p->path) {
323
- suffix = NULL;
324
- }
325
- if (NULL != suffix) {
326
- suffix++;
327
- if (NULL == (mime = mime_get(cache, suffix))) {
328
- mime = "text/plain";
329
- }
330
- } else {
331
- mime = "text/plain";
332
- }
333
-
334
429
  f = fopen(p->path, "rb");
335
430
  // On linux a directory is opened by fopen (sometimes? all the time?) so
336
431
  // fstat is called to get the file mode and verify it is a regular file or
@@ -344,7 +439,7 @@ update_contents(Cache cache, Page p) {
344
439
  }
345
440
  if (NULL == f) {
346
441
  // If not found how about with a /index.html added?
347
- if (NULL == suffix) {
442
+ if (NULL == mime) {
348
443
  char path[1024];
349
444
  int cnt;
350
445
 
@@ -364,6 +459,9 @@ update_contents(Cache cache, Page p) {
364
459
  return false;
365
460
  }
366
461
  }
462
+ if (NULL == mime) {
463
+ mime = "text/html";
464
+ }
367
465
  if (0 != fseek(f, 0, SEEK_END)) {
368
466
  fclose(f);
369
467
  return false;
@@ -406,39 +504,68 @@ update_contents(Cache cache, Page p) {
406
504
  return true;
407
505
  }
408
506
 
409
- static Page
410
- page_check(Err err, Cache cache, Page page) {
411
- double now = dtime();
507
+ static void
508
+ page_remove(Page p) {
509
+ int len = strlen(p->path);
510
+ int64_t h = calc_hash(p->path, &len);
511
+ Slot *bucket = get_bucketp(h);
512
+ Slot s;
513
+ Slot prev = NULL;
412
514
 
413
- if (page->last_check + PAGE_RECHECK_TIME < now) {
414
- struct stat fattr;
515
+ for (s = *bucket; NULL != s; s = s->next) {
516
+ if (h == (int64_t)s->hash && len == (int)s->klen &&
517
+ ((0 <= len && len <= MAX_KEY_UNIQ) || 0 == strncmp(s->key, p->path, len))) {
415
518
 
416
- if (0 == stat(page->path, &fattr) && page->mtime != fattr.st_mtime) {
417
- update_contents(cache, page);
418
- if (NULL == page->resp) {
419
- page_destroy(page);
420
- err_set(err, ERR_NOT_FOUND, "not found.");
421
- return NULL;
519
+ if (NULL == prev) {
520
+ *bucket = s->next;
521
+ } else {
522
+ prev->next = s->next;
523
+ }
524
+ DEBUG_FREE(mem_page_slot, s);
525
+ page_destroy(s->value);
526
+ free(s);
527
+
528
+ break;
529
+ }
530
+ prev = s;
531
+ }
532
+ }
533
+
534
+ static Page
535
+ page_check(Err err, Page page) {
536
+ if (!page->immutable) {
537
+ double now = dtime();
538
+
539
+ if (page->last_check + PAGE_RECHECK_TIME < now) {
540
+ struct stat fattr;
541
+
542
+ if (0 == stat(page->path, &fattr) && page->mtime != fattr.st_mtime) {
543
+ update_contents(page);
544
+ if (NULL == page->resp) {
545
+ page_remove(page);
546
+ err_set(err, ERR_NOT_FOUND, "not found.");
547
+ return NULL;
548
+ }
422
549
  }
550
+ page->last_check = now;
423
551
  }
424
- page->last_check = now;
425
552
  }
426
553
  return page;
427
554
  }
428
555
 
429
556
  Page
430
- page_get(Err err, Cache cache, const char *path, int plen) {
557
+ page_get(Err err, const char *path, int plen) {
431
558
  Page page;
432
559
 
433
560
  if (NULL != strstr(path, "../")) {
434
561
  return NULL;
435
562
  }
436
- if (NULL == (page = cache_get(cache, path, plen))) {
563
+ if (NULL == (page = cache_get(path, plen))) {
437
564
  Page old;
438
565
  char full_path[2048];
439
- char *s = stpcpy(full_path, cache->root);
566
+ char *s = stpcpy(full_path, cache.root);
440
567
 
441
- if ('/' != *cache->root && '/' != *path) {
568
+ if ('/' != *cache.root && '/' != *path) {
442
569
  *s++ = '/';
443
570
  }
444
571
  if ((int)sizeof(full_path) <= plen + (s - full_path)) {
@@ -451,22 +578,22 @@ page_get(Err err, Cache cache, const char *path, int plen) {
451
578
  err_set(err, ERR_MEMORY, "Failed to allocate memory for Page.");
452
579
  return NULL;
453
580
  }
454
- if (!update_contents(cache, page) || NULL == page->resp) {
581
+ if (!update_contents(page) || NULL == page->resp) {
455
582
  page_destroy(page);
456
583
  err_set(err, ERR_NOT_FOUND, "not found.");
457
584
  return NULL;
458
585
  }
459
- if (NULL != (old = cache_set(cache, path, plen, page))) {
586
+ if (NULL != (old = cache_set(path, plen, page))) {
460
587
  page_destroy(old);
461
588
  }
462
589
  } else {
463
- page = page_check(err, cache, page);
590
+ page = page_check(err, page);
464
591
  }
465
592
  return page;
466
593
  }
467
594
 
468
595
  Page
469
- group_get(Err err, Cache cache, const char *path, int plen) {
596
+ group_get(Err err, const char *path, int plen) {
470
597
  Page page = NULL;
471
598
  Group g = NULL;
472
599
  char full_path[2048];
@@ -476,7 +603,7 @@ group_get(Err err, Cache cache, const char *path, int plen) {
476
603
  if (NULL != strstr(path, "../")) {
477
604
  return NULL;
478
605
  }
479
- for (g = cache->groups; NULL != g; g = g->next) {
606
+ for (g = cache.groups; NULL != g; g = g->next) {
480
607
  if (g->plen < plen && 0 == strncmp(path, g->path, g->plen) && '/' == path[g->plen]) {
481
608
  break;
482
609
  }
@@ -492,7 +619,7 @@ group_get(Err err, Cache cache, const char *path, int plen) {
492
619
  strncpy(s, path + g->plen, plen - g->plen);
493
620
  s += plen - g->plen;
494
621
  *s = '\0';
495
- if (NULL != (page = cache_get(cache, full_path, s - full_path))) {
622
+ if (NULL != (page = cache_get(full_path, s - full_path))) {
496
623
  break;
497
624
  }
498
625
  }
@@ -514,35 +641,35 @@ group_get(Err err, Cache cache, const char *path, int plen) {
514
641
  }
515
642
  plen = s - full_path;
516
643
  path = full_path;
517
- if (NULL == (page = cache_get(cache, path, plen))) {
644
+ if (NULL == (page = cache_get(path, plen))) {
518
645
  Page old;
519
646
 
520
647
  if (NULL == (page = page_create(path))) {
521
648
  err_set(err, ERR_MEMORY, "Failed to allocate memory for Page.");
522
649
  return NULL;
523
650
  }
524
- if (!update_contents(cache, page) || NULL == page->resp) {
651
+ if (!update_contents(page) || NULL == page->resp) {
525
652
  page_destroy(page);
526
653
  err_set(err, ERR_NOT_FOUND, "not found.");
527
654
  return NULL;
528
655
  }
529
- if (NULL != (old = cache_set(cache, path, plen, page))) {
656
+ if (NULL != (old = cache_set(path, plen, page))) {
530
657
  page_destroy(old);
531
658
  }
532
659
  }
533
660
  return page;
534
661
  }
535
- return page_check(err, cache, page);
662
+ return page_check(err, page);
536
663
  }
537
664
 
538
665
  Group
539
- group_create(Cache cache, const char *path) {
666
+ group_create(const char *path) {
540
667
  Group g = (Group)malloc(sizeof(struct _Group));
541
668
 
542
669
  if (NULL != g) {
543
670
  DEBUG_ALLOC(mem_group, g);
544
- g->next = cache->groups;
545
- cache->groups = g;
671
+ g->next = cache.groups;
672
+ cache.groups = g;
546
673
  g->path = strdup(path);
547
674
  g->plen = strlen(path);
548
675
  DEBUG_ALLOC(mem_group_path, g->path);