00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 #include "P_Cache.h"
00025 
00026 #include "api/ts/ts.h"
00027 #include "Show.h"
00028 #include "I_Tasks.h"
00029 #include "CacheControl.h"
00030 
00031 struct ShowCache: public ShowCont {
00032   enum scan_type {
00033     scan_type_lookup,
00034     scan_type_delete,
00035     scan_type_invalidate
00036   };
00037 
00038   int vol_index;
00039   int seg_index;
00040   scan_type scan_flag;
00041   int urlstrs_index;
00042   int linecount;
00043   char (*show_cache_urlstrs)[500];
00044   URL url;
00045   CacheKey show_cache_key;
00046   CacheVC *cache_vc;
00047   MIOBuffer *buffer;
00048   IOBufferReader *buffer_reader;
00049   int64_t content_length;
00050   VIO *cvio;
00051   int showMain(int event, Event *e);
00052   int lookup_url_form(int event, Event *e);
00053   int delete_url_form(int event, Event *e);
00054   int lookup_regex_form(int event, Event *e);
00055   int delete_regex_form(int event, Event *e);
00056   int invalidate_regex_form(int event, Event *e);
00057 
00058   int lookup_url(int event, Event *e);
00059   int delete_url(int event, Event *e);
00060   int lookup_regex(int event, Event *e);
00061   int delete_regex(int event, Event *e);
00062   int invalidate_regex(int event, Event *e);
00063 
00064   int handleCacheEvent(int event, Event *e);
00065   int handleCacheDeleteComplete(int event, Event *e);
00066   int handleCacheScanCallback(int event, Event *e);
00067 
00068   ShowCache(Continuation *c, HTTPHdr *h): 
00069     ShowCont(c, h), vol_index(0), seg_index(0), scan_flag(scan_type_lookup),
00070     cache_vc(0), buffer(0), buffer_reader(0), content_length(0), cvio(0)
00071   {
00072     urlstrs_index = 0;
00073     linecount = 0;
00074     int query_len;
00075     char query[4096];
00076     char unescapedQuery[sizeof(query)];
00077     show_cache_urlstrs = NULL;
00078     URL *u = h->url_get();
00079 
00080     
00081     if (u->query_get(&query_len) && query_len < (int)sizeof(query)) {
00082       strncpy(query, u->query_get(&query_len), query_len);
00083       strncpy(unescapedQuery, u->query_get(&query_len), query_len);
00084 
00085       query[query_len] = unescapedQuery[query_len] = '\0';
00086 
00087       query_len = unescapifyStr(query);
00088 
00089       Debug("cache_inspector", "query params: '%s' len %d [unescaped]", unescapedQuery, query_len);
00090       Debug("cache_inspector", "query params: '%s' len %d [escaped]", query, query_len);
00091 
00092       
00093       unsigned l, m;
00094       for (l = 0, m = 0; l < (unsigned)query_len; l++) {
00095         if (query[l] != '\015') {
00096             query[m++] = query[l];
00097         }
00098       }
00099       query[m] = '\0';
00100 
00101       unsigned nstrings = 1;
00102       char *p = strstr(query, "url=");
00103       
00104       if (p) {
00105         while ((p = strstr(p, "\n"))) {
00106           nstrings++;
00107           if ((size_t) (p - query) >= strlen(query) - 1)
00108             break;
00109           else
00110             p++;
00111         }
00112       }
00113       
00114       show_cache_urlstrs = new char[nstrings + 1][500];
00115       memset(show_cache_urlstrs, '\0', (nstrings + 1) * 500 * sizeof (char));
00116 
00117       char *q, *t;
00118       p = strstr(unescapedQuery, "url=");
00119       if (p) {
00120         p += 4;                 
00121         t = strchr(p, '&');
00122         if (!t)
00123           t = (char *) unescapedQuery + strlen(unescapedQuery);
00124         for (int s = 0; p < t; s++) {
00125           show_cache_urlstrs[s][0] = '\0';
00126           q = strstr(p, "%0D%0A" );      
00127           if (!q)
00128             q = t;
00129           ink_strlcpy(show_cache_urlstrs[s], p, sizeof(show_cache_urlstrs[s]));
00130           p = q + 6;            
00131         }
00132       }
00133 
00134       Debug("cache_inspector", "there were %d url(s) passed in", nstrings == 1 ? 1 : nstrings - 1);
00135 
00136       for (unsigned i = 0; i < nstrings; i++) {
00137         if (show_cache_urlstrs[i][0] == '\0') {
00138           continue;
00139         }
00140         Debug("cache_inspector", "URL %d: '%s'", i + 1, show_cache_urlstrs[i]);
00141         unescapifyStr(show_cache_urlstrs[i]);
00142         Debug("cache_inspector", "URL %d: '%s'", i + 1, show_cache_urlstrs[i]);
00143       }
00144 
00145     }
00146 
00147     SET_HANDLER(&ShowCache::showMain);
00148   }
00149 
00150   ~ShowCache() {
00151     if (show_cache_urlstrs)
00152       delete[]show_cache_urlstrs;
00153     url.destroy();
00154   }
00155 
00156 };
00157 
00158 #define STREQ_PREFIX(_x,_s) (!strncasecmp(_x,_s,sizeof(_s)-1))
00159 #define STREQ_LEN_PREFIX(_x,_l,_s) (path_len < sizeof(_s) && !strncasecmp(_x,_s,sizeof(_s)-1))
00160 
00161 
00162 Action *
00163 register_ShowCache(Continuation *c, HTTPHdr *h) {
00164   ShowCache * theshowcache = new ShowCache(c, h);
00165   URL *u = h->url_get();
00166   int path_len;
00167   const char *path = u->path_get(&path_len);
00168 
00169   if (!path) {
00170   } else if (STREQ_PREFIX(path, "lookup_url_form")) {
00171     SET_CONTINUATION_HANDLER(theshowcache, &ShowCache::lookup_url_form);
00172   } else if (STREQ_PREFIX(path, "delete_url_form")) {
00173     SET_CONTINUATION_HANDLER(theshowcache, &ShowCache::delete_url_form);
00174   } else if (STREQ_PREFIX(path, "lookup_regex_form")) {
00175     SET_CONTINUATION_HANDLER(theshowcache, &ShowCache::lookup_regex_form);
00176   } else if (STREQ_PREFIX(path, "delete_regex_form")) {
00177     SET_CONTINUATION_HANDLER(theshowcache, &ShowCache::delete_regex_form);
00178   } else if (STREQ_PREFIX(path, "invalidate_regex_form")) {
00179     SET_CONTINUATION_HANDLER(theshowcache, &ShowCache::invalidate_regex_form);
00180   }
00181 
00182   else if (STREQ_PREFIX(path, "lookup_url")) {
00183     SET_CONTINUATION_HANDLER(theshowcache, &ShowCache::lookup_url);
00184   } else if (STREQ_PREFIX(path, "delete_url")) {
00185     SET_CONTINUATION_HANDLER(theshowcache, &ShowCache::delete_url);
00186   } else if (STREQ_PREFIX(path, "lookup_regex")) {
00187     SET_CONTINUATION_HANDLER(theshowcache, &ShowCache::lookup_regex);
00188   } else if (STREQ_PREFIX(path, "delete_regex")) {
00189     SET_CONTINUATION_HANDLER(theshowcache, &ShowCache::delete_regex);
00190   } else if (STREQ_PREFIX(path, "invalidate_regex")) {
00191     SET_CONTINUATION_HANDLER(theshowcache, &ShowCache::invalidate_regex);
00192   }
00193 
00194   if (theshowcache->mutex->thread_holding) {
00195     CONT_SCHED_LOCK_RETRY(theshowcache);
00196   } else {
00197     eventProcessor.schedule_imm(theshowcache, ET_TASK);
00198   }
00199 
00200   return &theshowcache->action;
00201 }
00202 
00203 int
00204 ShowCache::showMain(int event, Event *e) {
00205   CHECK_SHOW(begin("Cache"));
00206   CHECK_SHOW(show("<H3><A HREF=\"./lookup_url_form\">Lookup url</A></H3>\n"
00207                   "<H3><A HREF=\"./delete_url_form\">Delete url</A></H3>\n"
00208                   "<H3><A HREF=\"./lookup_regex_form\">Regex lookup</A></H3>\n"
00209                   "<H3><A HREF=\"./delete_regex_form\">Regex delete</A></H3>\n"
00210                   "<H3><A HREF=\"./invalidate_regex_form\">Regex invalidate</A></H3>\n\n"));
00211   return complete(event, e);
00212 }
00213 
00214 int
00215 ShowCache::lookup_url_form(int event, Event *e)
00216 {
00217   CHECK_SHOW(begin("Cache Lookup"));
00218   CHECK_SHOW(show("<FORM METHOD=\"GET\" ACTION=\"./lookup_url\">\n"
00219                   "<H3>Lookup</H3>\n"
00220                   "<INPUT TYPE=\"TEXT\" NAME=\"url\" value=\"http://\">\n"
00221                   "<INPUT TYPE=\"SUBMIT\" value=\"Lookup\">\n" "</FORM>\n\n"));
00222   return complete(event, e);
00223 }
00224 
00225 int
00226 ShowCache::delete_url_form(int event, Event *e) {
00227   CHECK_SHOW(begin("Cache Delete"));
00228   CHECK_SHOW(show("<FORM METHOD=\"GET\" ACTION=\"./delete_url\">\n"
00229                   "<P><B>Type the list urls that you want to delete\n"
00230                   "in the box below. The urls MUST be separated by\n"
00231                   "new lines</B></P>\n\n"
00232                   "<TEXTAREA NAME=\"url\" rows=10 cols=50>"
00233                   "http://" "</TEXTAREA>\n" "<INPUT TYPE=\"SUBMIT\" value=\"Delete\">\n" "</FORM>\n\n"));
00234   return complete(event, e);
00235 }
00236 
00237 int
00238 ShowCache::lookup_regex_form(int event, Event *e)
00239 {
00240   CHECK_SHOW(begin("Cache Regex Lookup"));
00241   CHECK_SHOW(show("<FORM METHOD=\"GET\" ACTION=\"./lookup_regex\">\n"
00242                   "<P><B>Type the list of regular expressions that you want to lookup\n"
00243                   "in the box below. The regular expressions MUST be separated by\n"
00244                   "new lines</B></P>\n\n"
00245                   "<TEXTAREA NAME=\"url\" rows=10 cols=50>"
00246                   "http://" "</TEXTAREA>\n" "<INPUT TYPE=\"SUBMIT\" value=\"Lookup\">\n" "</FORM>\n\n"));
00247   return complete(event, e);
00248 }
00249 
00250 int
00251 ShowCache::delete_regex_form(int event, Event *e) {
00252   CHECK_SHOW(begin("Cache Regex delete"));
00253   CHECK_SHOW(show("<FORM METHOD=\"GET\" ACTION=\"./delete_regex\">\n"
00254                   "<P><B>Type the list of regular expressions that you want to delete\n"
00255                   "in the box below. The regular expressions MUST be separated by\n"
00256                   "new lines</B></P>\n\n"
00257                   "<TEXTAREA NAME=\"url\" rows=10 cols=50>"
00258                   "http://" "</TEXTAREA>\n" "<INPUT TYPE=\"SUBMIT\" value=\"Delete\">\n" "</FORM>\n\n"));
00259   return complete(event, e);
00260 }
00261 
00262 int
00263 ShowCache::invalidate_regex_form(int event, Event *e) {
00264   CHECK_SHOW(begin("Cache Regex Invalidate"));
00265   CHECK_SHOW(show("<FORM METHOD=\"GET\" ACTION=\"./invalidate_regex\">\n"
00266                   "<P><B>Type the list of regular expressions that you want to invalidate\n"
00267                   "in the box below. The regular expressions MUST be separated by\n"
00268                   "new lines</B></P>\n\n"
00269                   "<TEXTAREA NAME=\"url\" rows=10 cols=50>"
00270                   "http://" "</TEXTAREA>\n" "<INPUT TYPE=\"SUBMIT\" value=\"Invalidate\">\n" "</FORM>\n"));
00271   return complete(event, e);
00272 }
00273 
00274 
00275 int
00276 ShowCache::handleCacheEvent(int event, Event *e) {
00277   
00278   switch (event) {
00279     case VC_EVENT_EOS:
00280     case VC_EVENT_READ_COMPLETE: {
00281       
00282       CHECK_SHOW(show("<P><TABLE border=1 width=100%%>"));
00283       CHECK_SHOW(show("<TR><TH bgcolor=\"#FFF0E0\" colspan=2>Doc Hit from Cluster</TH></TR>\n"));
00284       CHECK_SHOW(show("<tr><td>Size</td><td>%" PRId64 "</td>\n", content_length));
00285 
00286       
00287       CHECK_SHOW(show("<tr><td>Action</td>\n"
00288                       "<td><FORM action=\"./delete_url\" method=get>\n"
00289                       "<Input type=HIDDEN name=url value=\"%s\">\n"
00290                       "<input type=submit value=\"Delete URL\">\n" "</FORM></td></tr>\n",
00291                       show_cache_urlstrs[0]));
00292       CHECK_SHOW(show("</TABLE></P>"));
00293 
00294       if (buffer_reader) {
00295         buffer->dealloc_reader(buffer_reader);
00296         buffer_reader = 0;
00297       }
00298       if (buffer) {
00299         free_MIOBuffer(buffer);
00300         buffer = 0;
00301       }
00302       cvio = 0;
00303       cache_vc->do_io_close(-1);
00304       cache_vc = 0;
00305       return complete(event, e);
00306     }
00307     case CACHE_EVENT_OPEN_READ: {
00308       
00309       cache_vc = (CacheVC *) e;
00310       CacheHTTPInfoVector *vec = &(cache_vc->vector);
00311       int alt_count = vec->count();
00312       if (alt_count) {
00313         Doc *d = (Doc *) (cache_vc->first_buf->data());
00314         time_t t;
00315         char tmpstr[4096];
00316 
00317         
00318         CHECK_SHOW(show("<P><TABLE border=1 width=100%%>"));
00319         CHECK_SHOW(show("<TR><TH bgcolor=\"#FFF0E0\" colspan=2>Doc</TH></TR>\n"));
00320         CHECK_SHOW(show("<TR><TD>Volume</td> <td>#%d - store='%s'</td></tr>\n", cache_vc->vol->cache_vol->vol_number, cache_vc->vol->path));
00321         CHECK_SHOW(show("<TR><TD>first key</td> <td>%s</td></tr>\n", d->first_key.toHexStr(tmpstr)));
00322         CHECK_SHOW(show("<TR><TD>key</td> <td>%s</td></tr>\n", d->key.toHexStr(tmpstr)));
00323         CHECK_SHOW(show("<tr><td>sync_serial</td><td>%lu</tr>\n", d->sync_serial));
00324         CHECK_SHOW(show("<tr><td>write_serial</td><td>%lu</tr>\n", d->write_serial));
00325         CHECK_SHOW(show("<tr><td>header length</td><td>%lu</tr>\n", d->hlen));
00326         CHECK_SHOW(show("<tr><td>fragment type</td><td>%lu</tr>\n", d->doc_type));
00327         CHECK_SHOW(show("<tr><td>No of Alternates</td><td>%d</td></tr>\n", alt_count));
00328 
00329         CHECK_SHOW(show("<tr><td>Action</td>\n"
00330                         "<td><FORM action=\"./delete_url\" method=get>\n"
00331                         "<Input type=HIDDEN name=url value=\"%s\">\n"
00332                         "<input type=submit value=\"Delete URL\">\n" "</FORM></td></tr>\n",
00333                         show_cache_urlstrs[0]));
00334         CHECK_SHOW(show("</TABLE></P>"));
00335 
00336         for (int i = 0; i < alt_count; i++) {
00337           
00338           CHECK_SHOW(show("<p><table border=1>\n"));
00339           CHECK_SHOW(show("<tr><th bgcolor=\"#FFF0E0\" colspan=2>Alternate %d</th></tr>\n", i + 1));
00340           CacheHTTPInfo *obj = vec->get(i);
00341           CacheKey obj_key = obj->object_key_get();
00342           HTTPHdr *cached_request = obj->request_get();
00343           HTTPHdr *cached_response = obj->response_get();
00344           int64_t obj_size = obj->object_size_get();
00345           int offset, tmp, used, done;
00346           char b[4096];
00347 
00348           
00349           CHECK_SHOW(show("<tr><td>Request Header</td><td><PRE>"));
00350           offset = 0;
00351           do {
00352             used = 0;
00353             tmp = offset;
00354             done = cached_request->print(b, 4095, &used, &tmp);
00355             offset += used;
00356             b[used] = '\0';
00357             CHECK_SHOW(show("%s", b));
00358           } while (!done);
00359           CHECK_SHOW(show("</PRE></td><tr>\n"));
00360 
00361           
00362           CHECK_SHOW(show("<tr><td>Response Header</td><td><PRE>"));
00363           offset = 0;
00364           do {
00365             used = 0;
00366             tmp = offset;
00367             done = cached_response->print(b, 4095, &used, &tmp);
00368             offset += used;
00369             b[used] = '\0';
00370             CHECK_SHOW(show("%s", b));
00371           } while (!done);
00372           CHECK_SHOW(show("</PRE></td></tr>\n"));
00373           CHECK_SHOW(show("<tr><td>Size</td><td>%" PRId64 "</td>\n", obj_size));
00374           CHECK_SHOW(show("<tr><td>Key</td><td>%s</td>\n", obj_key.toHexStr(tmpstr)));
00375           t = obj->request_sent_time_get();
00376           ink_ctime_r(&t, tmpstr);
00377           CHECK_SHOW(show("<tr><td>Request sent time</td><td>%s</td></tr>\n", tmpstr));
00378           t = obj->response_received_time_get();
00379           ink_ctime_r(&t, tmpstr);
00380 
00381           CHECK_SHOW(show("<tr><td>Response received time</td><td>%s</td></tr>\n", tmpstr));
00382           CHECK_SHOW(show("</TABLE></P>"));
00383         }
00384 
00385         cache_vc->do_io_close(-1);
00386         return complete(event, e);
00387       }
00388       
00389     }
00390     case VC_EVENT_READ_READY:
00391       if (!cvio) {
00392         buffer = new_empty_MIOBuffer();
00393         buffer_reader = buffer->alloc_reader();
00394         content_length = cache_vc->get_object_size();
00395         cvio = cache_vc->do_io_read(this, content_length, buffer);
00396       } else
00397         buffer_reader->consume(buffer_reader->read_avail());
00398       return EVENT_DONE;
00399     case CACHE_EVENT_OPEN_READ_FAILED:
00400       
00401       CHECK_SHOW(show("<H3>Cache Lookup Failed, or missing in cluster</H3>\n"));
00402       return complete(event, e);
00403     default:
00404       CHECK_SHOW(show("<H3>Cache Miss</H3>\n"));
00405       return complete(event, e);
00406   }
00407 }
00408 
00409 int
00410 ShowCache::lookup_url(int event, Event *e) {
00411   char header_str[300];
00412 
00413   snprintf(header_str, sizeof(header_str), "<font color=red>%s</font>", show_cache_urlstrs[0]);
00414   CHECK_SHOW(begin(header_str));
00415   url.create(NULL);
00416   const char *s;
00417   s = show_cache_urlstrs[0];
00418   url.parse(&s, s + strlen(s));
00419   INK_MD5 md5;
00420   int len;
00421   url.hash_get(&md5);
00422   const char *hostname = url.host_get(&len);
00423   SET_HANDLER(&ShowCache::handleCacheEvent);
00424   Action *lookup_result = cacheProcessor.open_read(this, &md5, getClusterCacheLocal(&url, (char *)hostname), CACHE_FRAG_TYPE_HTTP, (char *) hostname, len);
00425   if (!lookup_result)
00426     lookup_result = ACTION_IO_ERROR;
00427   if (lookup_result == ACTION_RESULT_DONE)
00428     return EVENT_DONE;        
00429   else if (lookup_result == ACTION_IO_ERROR) {
00430     handleEvent(CACHE_EVENT_OPEN_READ_FAILED, 0);
00431     return EVENT_DONE;        
00432   } else
00433     return EVENT_CONT;        
00434 }
00435 
00436 
00437 int
00438 ShowCache::delete_url(int event, Event *e)
00439 {
00440   if (urlstrs_index == 0) {
00441     
00442     CHECK_SHOW(begin("Delete URL"));
00443     CHECK_SHOW(show("<B><TABLE border=1>\n"));
00444   }
00445 
00446 
00447   if (strcmp(show_cache_urlstrs[urlstrs_index], "") == 0) {
00448     
00449     
00450     CHECK_SHOW(show("</TABLE></B>\n"));
00451     return complete(event, e);
00452   }
00453   url.create(NULL);
00454   const char *s;
00455   s = show_cache_urlstrs[urlstrs_index];
00456   CHECK_SHOW(show("<TR><TD>%s</TD>", s));
00457   url.parse(&s, s + strlen(s));
00458   SET_HANDLER(&ShowCache::handleCacheDeleteComplete);
00459   
00460   
00461   urlstrs_index++;
00462   int len;
00463   const char *hostname = url.host_get(&len);
00464   cacheProcessor.remove(this, &url, getClusterCacheLocal(&url, (char *)hostname), CACHE_FRAG_TYPE_HTTP);
00465   return EVENT_DONE;
00466 }
00467 
00468 int
00469 ShowCache::handleCacheDeleteComplete(int event, Event *e)
00470 {
00471 
00472   if (event == CACHE_EVENT_REMOVE) {
00473     CHECK_SHOW(show("<td>Delete <font color=green>succeeded</font></td></tr>\n"));
00474   } else {
00475     CHECK_SHOW(show("<td>Delete <font color=red>failed</font></td></tr>\n"));
00476   }
00477   return delete_url(event, e);
00478 
00479 }
00480 
00481 
00482 int
00483 ShowCache::lookup_regex(int event, Event *e)
00484 {
00485   CHECK_SHOW(begin("Regex Lookup"));
00486   CHECK_SHOW(show("<SCRIPT LANGIAGE=\"Javascript1.2\">\n"
00487                   "urllist = new Array(100);\n"
00488                   "index = 0;\n"
00489                   "function addToUrlList(input) {\n"
00490                   "     for (c=0; c < index; c++) {\n"
00491                   "             if (urllist[c] == encodeURIComponent(input.name)) {\n"
00492                   "                     urllist.splice(c,1);\n"
00493                   "                     index--;\n"
00494                   "                     return true;\n"
00495                   "             }\n"
00496                   "     }\n"
00497                   "     urllist[index++] = encodeURIComponent(input.name);\n"
00498                   "     return true;\n"
00499                   "}\n"
00500                   "function setUrls(form) {\n"
00501                   "     form.elements[0].value=\"\";\n"
00502                   "   if (index > 10) {\n"
00503                   "           alert(\"Can't choose more than 10 urls for deleting\");\n"
00504                   "           return true;\n"
00505                   "}\n"
00506                   "     for (c=0; c < index; c++){\n"
00507                   "             form.elements[0].value += urllist[c]+ \"%%0D%%0A\";\n"
00508                   "     }\n"
00509                   "   if (form.elements[0].value == \"\"){\n"
00510                   "         alert(\"Please select atleast one url before clicking delete\");\n"
00511                   "       return true;\n"
00512                   "}\n"
00513                   "   srcfile=\"./delete_url?url=\" + form.elements[0].value;\n"
00514                   "   document.location=srcfile;\n " "  return true;\n" "}\n" "</SCRIPT>\n"));
00515 
00516   CHECK_SHOW(show("<FORM NAME=\"f\" ACTION=\"./delete_url\" METHOD=GET> \n"
00517                   "<INPUT TYPE=HIDDEN NAME=\"url\">\n" "<B><TABLE border=1>\n"));
00518 
00519   scan_flag = scan_type_lookup;                
00520   SET_HANDLER(&ShowCache::handleCacheScanCallback);
00521   cacheProcessor.scan(this);
00522   return EVENT_DONE;
00523 }
00524 
00525 int
00526 ShowCache::delete_regex(int event, Event *e)
00527 {
00528   CHECK_SHOW(begin("Regex Delete"));
00529   CHECK_SHOW(show("<B><TABLE border=1>\n"));
00530   scan_flag = scan_type_delete;                
00531   SET_HANDLER(&ShowCache::handleCacheScanCallback);
00532   cacheProcessor.scan(this);
00533   return EVENT_DONE;
00534 
00535 }
00536 
00537 
00538 int
00539 ShowCache::invalidate_regex(int event, Event *e)
00540 {
00541   CHECK_SHOW(begin("Regex Invalidate"));
00542   CHECK_SHOW(show("<B><TABLE border=1>\n"));
00543   scan_flag = scan_type_invalidate;                
00544   SET_HANDLER(&ShowCache::handleCacheScanCallback);
00545   cacheProcessor.scan(this);
00546   return EVENT_DONE;
00547 
00548 }
00549 
00550 
00551 
00552 int
00553 ShowCache::handleCacheScanCallback(int event, Event *e)
00554 {
00555   switch (event) {
00556   case CACHE_EVENT_SCAN:{
00557       cache_vc = (CacheVC *) e;
00558       return EVENT_CONT;
00559     }
00560   case CACHE_EVENT_SCAN_OBJECT:{
00561       HTTPInfo *alt = (HTTPInfo *) e;
00562       char xx[501], m[501];
00563       int ib = 0, xd = 0, ml = 0;
00564 
00565       alt->request_get()->url_print(xx, 500, &ib, &xd);
00566       xx[ib] = '\0';
00567 
00568       const char *mm = alt->request_get()->method_get(&ml);
00569 
00570       memcpy(m, mm, ml);
00571       m[ml] = 0;
00572 
00573       int res = CACHE_SCAN_RESULT_CONTINUE;
00574 
00575       for (unsigned s = 0; show_cache_urlstrs[s][0] != '\0'; s++) {
00576         const char* error;
00577         int erroffset;
00578         pcre* preq =  pcre_compile(show_cache_urlstrs[s], 0, &error, &erroffset, NULL);
00579 
00580         Debug("cache_inspector", "matching url '%s' '%s' with regex '%s'\n", m, xx, show_cache_urlstrs[s]);
00581 
00582         if (preq) {
00583           int r = pcre_exec(preq, NULL, xx, ib, 0, 0, NULL, 0);
00584 
00585           pcre_free(preq);
00586           if (r != -1) {
00587             linecount++;
00588             if ((linecount % 5) == 0) {
00589               CHECK_SHOW(show("<TR bgcolor=\"#FFF0E0\">"));
00590             } else {
00591               CHECK_SHOW(show("<TR>"));
00592             }
00593 
00594             switch (scan_flag) {
00595             case scan_type_lookup:
00596               
00597               CHECK_SHOW(show("<TD><INPUT TYPE=CHECKBOX NAME=\"%s\" "
00598                               "onClick=\"addToUrlList(this)\"></TD>"
00599                               "<TD><A onClick='window.location.href=\"./lookup_url?url=\"+ encodeURIComponent(\"%s\");' HREF=\"#\">"
00600                               "<B>%s</B></A></br></TD></TR>\n", xx, xx, xx));
00601               break;
00602             case scan_type_delete:
00603               CHECK_SHOW(show("<TD><B>%s</B></TD>" "<TD><font color=red>deleted</font></TD></TR>\n", xx));
00604               res = CACHE_SCAN_RESULT_DELETE;
00605               break;
00606             case scan_type_invalidate:
00607               HTTPInfo new_info;
00608               res = CACHE_SCAN_RESULT_UPDATE;
00609               new_info.copy(alt);
00610               new_info.response_get()->set_cooked_cc_need_revalidate_once();
00611               CHECK_SHOW(show("<TD><B>%s</B></TD>" "<TD><font color=red>Invalidate</font></TD>" "</TR>\n", xx));
00612               cache_vc->set_http_info(&new_info);
00613             }
00614 
00615             break;
00616           }
00617         } else {
00618           
00619           Debug("cache_inspector", "regex '%s' didn't compile", show_cache_urlstrs[s]);
00620         }
00621       }
00622       return res;
00623     }
00624   case CACHE_EVENT_SCAN_DONE:
00625     CHECK_SHOW(show("</TABLE></B>\n"));
00626     if (scan_flag == 0)
00627       if (linecount) {
00628         CHECK_SHOW(show("<P><INPUT TYPE=button value=\"Delete\" "
00629                         "onClick=\"setUrls(window.document.f)\"></P>" "</FORM>\n"));
00630       }
00631     CHECK_SHOW(show("<H3>Done</H3>\n"));
00632     Debug("cache_inspector", "scan done");
00633     complete(event, e);
00634     return EVENT_DONE;
00635   case CACHE_EVENT_SCAN_FAILED:
00636   default:
00637     CHECK_SHOW(show("<H3>Error while scanning disk</H3>\n"));
00638     return EVENT_DONE;
00639   }
00640 }
00641