/* return 1 if the request should be aborted */ static int CheckQuickAbort2(StoreEntry * entry) { squid_off_t curlen; squid_off_t minlen; squid_off_t expectlen; MemObject *mem = entry->mem_obj; assert(mem); debug(20, 3) ("CheckQuickAbort2: entry=%p, mem=%p\n", entry, mem); if (mem->request && !mem->request->flags.cachable) { debug(20, 3) ("CheckQuickAbort2: YES !mem->request->flags.cachable\n"); return 1; } expectlen = httpReplyBodySize(mem->method, mem->reply) + mem->reply->hdr_sz; curlen = mem->inmem_hi; if (expectlen == curlen) { debug(20, 3) ("CheckQuickAbort2: NO already finished\n"); return 0; } if (EBIT_TEST(entry->flags, KEY_PRIVATE)) { debug(20, 3) ("CheckQuickAbort2: YES KEY_PRIVATE\n"); return 1; } minlen = Config.quickAbort.min << 10; if (minlen < 0) { debug(20, 3) ("CheckQuickAbort2: NO disabled\n"); return 0; } if (curlen > expectlen) { debug(20, 3) ("CheckQuickAbort2: YES bad content length\n"); return 1; } if ((expectlen - curlen) < minlen) { debug(20, 3) ("CheckQuickAbort2: NO only little more left\n"); return 0; } if ((expectlen - curlen) > (Config.quickAbort.max << 10)) { debug(20, 3) ("CheckQuickAbort2: YES too much left to go\n"); return 1; } if (expectlen < 100) { debug(20, 3) ("CheckQuickAbort2: NO avoid FPE\n"); return 0; } if ((curlen / (expectlen / 100)) > Config.quickAbort.pct) { debug(20, 3) ("CheckQuickAbort2: NO past point of no return\n"); return 0; } debug(20, 3) ("CheckQuickAbort2: YES default, returning 1\n"); return 1; }
static int buildRespModHeader(MemBuf * mb, IcapStateData * icap, char *buf, ssize_t len, int theEnd) { MemBuf mb_hdr; char *client_addr; int o2=0; int o3=0; int hlen; int consumed; icap_service *service; HttpReply *r; if (memBufIsNull(&icap->respmod.req_hdr_copy)) memBufDefInit(&icap->respmod.req_hdr_copy); memBufAppend(&icap->respmod.req_hdr_copy, buf, len); if (icap->respmod.req_hdr_copy.size > 4 && strncmp(icap->respmod.req_hdr_copy.buf, "HTTP/", 5)) { debug(81, 3) ("buildRespModHeader: Non-HTTP-compliant header: '%s'\n", buf); /* *Possible we can consider that we did not have http responce headers *(maybe HTTP 0.9 protocol), lets returning -1... */ consumed=-1; o2=-1; memBufDefInit(&mb_hdr); } else{ hlen = headersEnd(icap->respmod.req_hdr_copy.buf, icap->respmod.req_hdr_copy.size); debug(81, 3) ("buildRespModHeader: headersEnd = %d(%s)\n", hlen,buf); if (0 == hlen) return 0; /* * calc how many bytes from this 'buf' went towards the * reply header. */ consumed = hlen - (icap->respmod.req_hdr_copy.size - len); debug(81, 3) ("buildRespModHeader: consumed = %d\n", consumed); /* * now, truncate our req_hdr_copy at the header end. * this 'if' statement might be unncessary? */ if (hlen < icap->respmod.req_hdr_copy.size) icap->respmod.req_hdr_copy.size = hlen; /* Copy request header */ memBufDefInit(&mb_hdr); httpBuildRequestPrefix(icap->request, icap->request, icap->respmod.entry, &mb_hdr, icap->http_flags); o2 = mb_hdr.size; } /* Copy response header - Append to request header mbuffer */ memBufAppend(&mb_hdr, icap->respmod.req_hdr_copy.buf, icap->respmod.req_hdr_copy.size); o3 = mb_hdr.size; service = icap->current_service; assert(service); client_addr = inet_ntoa(icap->request->client_addr); r = httpReplyCreate(); httpReplyParse(r, icap->respmod.req_hdr_copy.buf, icap->respmod.req_hdr_copy.size); icap->respmod.res_body_sz = httpReplyBodySize(icap->request->method, r); httpReplyDestroy(r); if (icap->respmod.res_body_sz) getICAPRespModString(mb, 0, o2, o3, client_addr, icap, service); else getICAPRespModString(mb, 0, o2, -o3, client_addr, icap, service); if (Config.icapcfg.preview_enable) if (icap->preview_size >= 0) { memBufPrintf(mb, "Preview: %d\r\n", icap->preview_size); icap->flags.preview_done = 0; } if(service->keep_alive){ icap->flags.keep_alive = 1; memBufAppend(mb, "Connection: keep-alive\r\n", 24); } else{ icap->flags.keep_alive = 0; memBufAppend(mb, "Connection: close\r\n", 19); } memBufAppend(mb, crlf, 2); memBufAppend(mb, mb_hdr.buf, mb_hdr.size); memBufClean(&mb_hdr); return consumed; }