Squid configuration: acl extGood1 external extGoodT1 # always OK acl extGood2 external extGoodT2 # always OK acl extBad1 external extBadT1 # always ERR acl rare port 1111 acl common port 80 acl bad1 any-of rare !common !extGood1 acl good1 all-of all !rare common extBad1 acl good1 all-of !rare extGood1 all extGood2 common !extBad1 http_access deny bad1 http_access deny !good1 acl uGood url_regex \bgood\b acl uBad url_regex \bbad\b http_access deny uBad http_access deny !uGood http_access allow manager localhost http_access deny manager http_access deny !Safe_ports http_access deny CONNECT !SSL_ports http_access allow localnet Annotated sanitized cache.log: preCheck: 0x... checking slow rules matches: checking http_access matches: checking http_access#1 matches: checking bad1 matches: checking rare matches: checked: rare = 0 ... note that "checking" means going down the tree while "checked" reports the result of a match test (and starts the climb back up the tree) ... matches: checking !common matches: checking common matches: checked: common = 1 matches: checked: !common = 0 matches: checking !extGood1 matches: checking extGood1 ... going async here: extGood1 is an external ACL ... matches: checked: extGood1 = -1 async matches: checked: !extGood1 = -1 async matches: checked: bad1 = -1 async matches: checked: http_access#1 = -1 async matches: checked: http_access = -1 async ... async lookup completed, resuming matching but do not match until we reach the extGood1 node! ... resumeMatchingAt: checking http_access at 0 resumeMatchingAt: checking http_access#1 at 0 resumeMatchingAt: checking bad1 at 2 resumeMatchingAt: checking !extGood1 at 0 matches: checking extGood1 matches: checked: extGood1 = 1 resumeMatchingAt: checked: !extGood1 = 0 resumeMatchingAt: checked: bad1 = 0 resumeMatchingAt: checked: http_access#1 = 0 ... OK, the first http_access line processed and it is not a match, move on to the second one ... matches: checking http_access#2 matches: checking !good1 matches: checking good1 matches: checking (good1 lines) matches: checking (good1 line #1) matches: checking all matches: checked: all = 1 matches: checking !rare matches: checking rare matches: checked: rare = 0 matches: checked: !rare = 1 matches: checking common matches: checked: common = 1 matches: checking extBad1 ... hit another external ACL. Going async here ... matches: checked: extBad1 = -1 async matches: checked: (good1 line #1) = -1 async matches: checked: (good1 lines) = -1 async matches: checked: good1 = -1 async matches: checked: !good1 = -1 async matches: checked: http_access#2 = -1 async ... async lookup completed, resume with extBad1 ... resumeMatchingAt: checked: http_access = -1 async resumeMatchingAt: checking http_access at 1 resumeMatchingAt: checking http_access#2 at 0 resumeMatchingAt: checking !good1 at 0 resumeMatchingAt: checking good1 at 0 resumeMatchingAt: checking (good1 lines) at 0 resumeMatchingAt: checking (good1 line #1) at 3 matches: checking extBad1 matches: checked: extBad1 = 0 resumeMatchingAt: checked: (good1 line #1) = 0 matches: checking (good1 line #2) matches: checking !rare matches: checking rare matches: checked: rare = 0 matches: checked: !rare = 1 matches: checking extGood1 matches: checked: extGood1 = 1 matches: checking all matches: checked: all = 1 matches: checking extGood2 ... hit another external ACL. Going async here ... ... note that we went async while already resuming another async check; that is why we see "resumeMatchingAt: checked:" and not "matches: checked:" below ... matches: checked: extGood2 = -1 async matches: checked: (good1 line #2) = -1 async resumeMatchingAt: checked: (good1 lines) = -1 async resumeMatchingAt: checked: good1 = -1 async resumeMatchingAt: checked: !good1 = -1 async resumeMatchingAt: checked: http_access#2 = -1 async resumeMatchingAt: checked: http_access = -1 async ... async lookup over, resume with extGood2 inside the second http_access line .... resumeMatchingAt: checking http_access at 1 resumeMatchingAt: checking http_access#2 at 0 resumeMatchingAt: checking !good1 at 0 resumeMatchingAt: checking good1 at 0 resumeMatchingAt: checking (good1 lines) at 1 resumeMatchingAt: checking (good1 line #2) at 3 matches: checking extGood2 matches: checked: extGood2 = 1 matches: checking common matches: checked: common = 1 matches: checking !extBad1 matches: checking extBad1 matches: checked: extBad1 = 0 matches: checked: !extBad1 = 1 resumeMatchingAt: checked: (good1 line #2) = 1 resumeMatchingAt: checked: (good1 lines) = 1 resumeMatchingAt: checked: good1 = 1 resumeMatchingAt: checked: !good1 = 0 resumeMatchingAt: checked: http_access#2 = 0 matches: checking http_access#3 matches: checking uBad matches: checked: uBad = 0 matches: checked: http_access#3 = 0 matches: checking http_access#4 matches: checking !uGood matches: checking uGood matches: checked: uGood = 1 matches: checked: !uGood = 0 matches: checked: http_access#4 = 0 matches: checking http_access#5 matches: checking manager matches: checked: manager = 0 matches: checked: http_access#5 = 0 matches: checking http_access#6 matches: checking manager matches: checked: manager = 0 matches: checked: http_access#6 = 0 matches: checking http_access#7 matches: checking !Safe_ports matches: checking Safe_ports matches: checked: Safe_ports = 1 matches: checked: !Safe_ports = 0 matches: checked: http_access#7 = 0 matches: checking http_access#8 matches: checking CONNECT matches: checked: CONNECT = 0 matches: checked: http_access#8 = 0 matches: checking http_access#9 matches: checking localnet matches: checked: localnet = 1 matches: checked: http_access#9 = 1 resumeMatchingAt: checked: http_access = 1 client_side_ clientAccessCheckDone: The request GET http://172.16.103.151/req=debug,url=1152811308/resp=debug/other=good/ is ALLOWED; last ACL checked: localnet