urlcache.c
上传用户:ladybrid91
上传日期:2007-01-04
资源大小:287k
文件大小:6k
源码类别:

Web服务器

开发平台:

Unix_Linux

  1. /*
  2. ** urlcache.c
  3. **
  4. ** Copyright (c) 1995 Peter Eriksson <pen@signum.se>
  5. **
  6. ** This program is free software; you can redistribute it and/or modify
  7. ** it under the terms of the GNU General Public License as published by
  8. ** the Free Software Foundation; either version 2 of the License, or
  9. ** (at your option) any later version.
  10. **
  11. ** This program is distributed in the hope that it will be useful,
  12. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. ** GNU General Public License for more details.
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program; if not, write to the Free Software
  17. ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. */
  19. #include "phttpd.h"
  20. int urlcache_refresh = 120;
  21. int urlcache_ttl = 120;
  22. int urlcache_gc_interval = 600;
  23. int urlcache_size = 101;
  24. static cache_t urlcache;
  25. #define T(F)   ((flags & (F) ) && (uip->flags & (F)) == 0)
  26. static char *get_handler(char *url)
  27. {
  28.     const char *handler = url_gethandler(url);
  29.     if (handler)
  30. return s_strdup(handler);
  31.     
  32.     return NULL;
  33. }
  34. static char *get_rewrite(char *url)
  35. {
  36.     char buf[2048];
  37.     if (url_getrewrite(url, buf, sizeof(buf)))
  38. return s_strdup(buf);
  39.     return NULL;
  40. }
  41. static char *get_redirect(char *url)
  42. {
  43.     char buf[2048];
  44.     if (url_getredirect(url, buf, sizeof(buf)))
  45.     {
  46. return s_strdup(buf);
  47.     }
  48.     return NULL;
  49. }
  50. static char *get_predirect(char *url)
  51. {
  52.     char buf[2048];
  53.     if (url_getpredirect(url, buf, sizeof(buf)))
  54. return s_strdup(buf);
  55.     return NULL;
  56. }
  57. static char *get_access(char *url)
  58. {
  59.     char buf[2048];
  60.     
  61.     if (host_getaccess(url, buf, sizeof(buf)))
  62. return s_strdup(buf);
  63.     return NULL;
  64. }
  65. static char *get_auth(char *url)
  66. {
  67.     char buf[2048];
  68.     
  69.     if (read_getauthenticate(url, buf, sizeof(buf)))
  70. return s_strdup(buf);
  71.     return NULL;
  72. }
  73. static unsigned  urlinfo_update(urlinfo_t *uip,
  74. unsigned int flags)
  75. {
  76.     if (debug > 2)
  77. fprintf(stderr, "urlinfo_update, url=%sn", uip->rewrite.url);
  78.     
  79.     if (T(UCF_ACCESS))
  80.     {
  81. if (debug > 2)
  82.     fprintf(stderr, "urlinfo_update: accessn");
  83. uip->access.path = get_access(uip->rewrite.url);
  84. uip->flags |= UCF_ACCESS;
  85.     }
  86.     if (T(UCF_AUTH))
  87.     {
  88. char *realm;
  89. if (debug > 2)
  90.     fprintf(stderr, "urlinfo_update: authn");
  91. uip->auth.source = get_auth(uip->rewrite.url);
  92. realm = uip->auth.source;
  93. if (realm)
  94. {
  95.     while (*realm && !s_isspace(*realm))
  96. ++realm;
  97.     if (s_isspace(*realm))
  98. *realm++ = '';
  99.     while (*realm && s_isspace(*realm))
  100. ++realm;
  101. }
  102. uip->auth.realm = realm;
  103. uip->flags |= UCF_AUTH;
  104.     }
  105.     if (T(UCF_REDIRECT))
  106.     {
  107. if (debug > 2)
  108.     fprintf(stderr, "urlinfo_update: redirectn");
  109. uip->redirect.url = get_redirect(uip->rewrite.url);
  110. http_extract_request(uip->redirect.url, &uip->redirect.request);
  111. uip->flags |= UCF_REDIRECT;
  112.     }
  113.     if (T(UCF_PREDIRECT))
  114.     {
  115. if (debug > 2)
  116.     fprintf(stderr, "urlinfo_update: predirectn");
  117. uip->predirect.url = get_predirect(uip->rewrite.url);
  118. http_extract_request(uip->predirect.url, &uip->predirect.request);
  119. uip->flags |= UCF_PREDIRECT;
  120.     }
  121.     if (T(UCF_HANDLER))
  122.     {
  123. if (debug > 2)
  124.     fprintf(stderr, "urlinfo_update: handlern");
  125. uip->handler = get_handler(uip->rewrite.url);
  126. uip->flags |= UCF_HANDLER;
  127.     }
  128.     return uip->flags;
  129. }
  130. static urlinfo_t *urlinfo_alloc(char *url)
  131. {
  132.     urlinfo_t *uip;
  133.     char *new_url;
  134.     
  135.     if (debug > 2)
  136. fprintf(stderr, "urlinfo_alloc(), url=%sn", url);
  137.     
  138.     uip = s_malloc(sizeof(urlinfo_t));
  139.     new_url = get_rewrite(url);
  140.     if (debug > 3)
  141. fprintf(stderr, "urlinfo_alloc(): new_url=%sn",
  142. new_url ? new_url : "<null>");
  143.     
  144.     if (new_url)
  145. uip->rewrite.url = new_url;
  146.     else
  147. uip->rewrite.url = s_strdup(url);
  148.     uip->rewrite.request = NULL;
  149. #if 1
  150.     /* This code breaks URLs like: /cgi-bin/test%3Fcd?ef */
  151.     http_extract_request(uip->rewrite.url, &uip->rewrite.request);
  152. #endif
  153.     return uip;
  154. }
  155. static int cache_update(void *key,
  156. unsigned int keylen,
  157. void *data,
  158. void **new_data,
  159. void *misc)
  160. {
  161.     unsigned int flags;
  162.     char *url;
  163.     urlinfo_t *uip;
  164.     
  165.     
  166.     flags = (misc ? *(unsigned int *)misc : 0) & UCF_ALL;
  167.     url = key;
  168.     uip = urlinfo_alloc(url);
  169.     
  170.     urlinfo_update(uip, flags);
  171.     
  172.     *new_data = uip;
  173.     return 1;
  174. }
  175. static void urlinfo_free(void *data)
  176. {
  177.     urlinfo_t *uip = data;
  178.     
  179.     if (uip->handler)
  180. s_free(uip->handler);
  181.     
  182.     if (uip->rewrite.url)
  183. s_free(uip->rewrite.url);
  184.     if (uip->rewrite.request)
  185. s_free(uip->rewrite.request);
  186.     
  187.     if (uip->access.path)
  188. s_free(uip->access.path);
  189.     
  190.     if (uip->auth.source)
  191. s_free(uip->auth.source);
  192.     if (uip->redirect.url)
  193. s_free(uip->redirect.url);
  194.     if (uip->redirect.request)
  195. s_free(uip->redirect.request);
  196.     if (uip->predirect.url)
  197. s_free(uip->predirect.url);
  198.     
  199.     if (uip->predirect.request)
  200. s_free(uip->predirect.request);
  201.     
  202.     s_free(uip);
  203. }
  204. void urlcache_init(void)
  205. {
  206.     cache_init(&urlcache,
  207.        urlcache_refresh, urlcache_ttl, urlcache_gc_interval,
  208.        urlcache_size, NULL,
  209.        urlinfo_free, cache_update);
  210. }
  211. ucentry_t *urlcache_lookup(char *url,
  212.    unsigned int flags)
  213. {
  214.     cacheentry_t *cep;
  215.     ucentry_t *ucp;
  216.     
  217.     if (debug > 2)
  218. fprintf(stderr, "urlcache_lookup("%s")n", url);
  219.     cep = cache_lookup(&urlcache, url, 0, &flags,
  220.        ((flags&UCF_RELOAD) ? CF_RELOAD : 0));
  221.     if (cep == NULL)
  222. return NULL;
  223.     ucp = s_malloc(sizeof(ucentry_t));
  224.     ucp->cep = cep;
  225.     ucp->uip = cep->data;
  226.     return ucp;
  227. }
  228. void urlcache_release(ucentry_t *ucp)
  229. {
  230.     if (ucp == NULL)
  231. return;
  232.     if (ucp->cep)
  233. cache_release(ucp->cep);
  234.     
  235.     s_free(ucp);
  236. }
  237. int urlcache_getdata(ucentry_t *ucp,
  238.      unsigned int flags)
  239. {
  240.     int status;
  241.     urlinfo_t *uip;
  242.     if (debug > 1)
  243. fprintf(stderr, "urlcache_getdata()n");
  244.     
  245.     uip = ucp->uip;
  246.     
  247.     mutex_lock(&uip->lock);
  248.     status = urlinfo_update(uip, flags);
  249.     mutex_unlock(&uip->lock);
  250.     return status;
  251. }
  252. int urlcache_getstats(cachestat_t *csp)
  253. {
  254.     return cache_getstats(&urlcache, csp);
  255. }