int errorMapStart(const errormap * map, request_t * client_req, HttpReply * reply, const char *aclname, ERRMAPCB * callback, void *callback_data) { char squid_error[100]; int len = 0; const char *errorUrl; ErrorMapState *state; const char *tmp; http_status status; request_t *req; HttpHeaderPos hdrpos; HttpHeaderEntry *hdr; if (!client_req || !reply) return 0; status = reply->sline.status; tmp = httpHeaderGetStr(&reply->header, HDR_X_SQUID_ERROR); squid_error[0] = '\0'; if (tmp) { xstrncpy(squid_error, tmp, sizeof(squid_error)); len = strcspn(squid_error, " "); } squid_error[len] = '\0'; errorUrl = getErrorMap(map, status, squid_error, aclname); if (!errorUrl) return 0; req = urlParse(urlMethodGetKnownByCode(METHOD_GET), (char *) errorUrl); if (!req) { debug(0, 0) ("errorMapStart: Invalid error URL '%s'\n", errorUrl); return 0; } req->urlgroup = xstrdup("error"); state = cbdataAlloc(ErrorMapState); state->req = requestLink(req); state->e = storeCreateEntry(errorUrl, req->flags, req->method); state->sc = storeClientRegister(state->e, state); state->callback = callback; state->callback_data = callback_data; cbdataLock(callback_data); hdrpos = HttpHeaderInitPos; while ((hdr = httpHeaderGetEntry(&client_req->header, &hdrpos)) != NULL) { if (CBIT_TEST(client_headers, hdr->id)) httpHeaderAddClone(&req->header, hdr); } hdrpos = HttpHeaderInitPos; while ((hdr = httpHeaderGetEntry(&reply->header, &hdrpos)) != NULL) { if (CBIT_TEST(server_headers, hdr->id)) httpHeaderAddClone(&req->header, hdr); } httpHeaderPutInt(&req->header, HDR_X_ERROR_STATUS, (int) reply->sline.status); httpHeaderPutStr(&req->header, HDR_X_REQUEST_URI, urlCanonical(client_req)); fwdStart(-1, state->e, req); storeClientRef(state->sc, state->e, 0, 0, SM_PAGE_SIZE, errorMapFetchHeaders, state); return 1; }
/* use fresh entries to replace old ones */ void httpHeaderUpdate(HttpHeader * old, const HttpHeader * fresh, const HttpHeaderMask * denied_mask) { const HttpHeaderEntry *e; HttpHeaderPos pos = HttpHeaderInitPos; assert(old && fresh); assert(old != fresh); debug(55, 7) ("updating hdr: %p <- %p\n", old, fresh); while ((e = httpHeaderGetEntry(fresh, &pos))) { /* deny bad guys (ok to check for HDR_OTHER) here */ if (denied_mask && CBIT_TEST(*denied_mask, e->id)) continue; if (e->id != HDR_OTHER) httpHeaderDelById(old, e->id); else httpHeaderDelByName(old, strBuf(e->name)); } pos = HttpHeaderInitPos; while ((e = httpHeaderGetEntry(fresh, &pos))) { /* deny bad guys (ok to check for HDR_OTHER) here */ if (denied_mask && CBIT_TEST(*denied_mask, e->id)) continue; httpHeaderAddClone(old, e); } /* And now, repack the array to "fill in the holes" */ httpHeaderRepack(old); }
/* append entries (also see httpHeaderUpdate) */ void httpHeaderAppend(HttpHeader * dest, const HttpHeader * src) { const HttpHeaderEntry *e; HttpHeaderPos pos = HttpHeaderInitPos; assert(src && dest); assert(src != dest); debug(55, 7) ("appending hdr: %p += %p\n", dest, src); while ((e = httpHeaderGetEntry(src, &pos))) { httpHeaderAddClone(dest, e); } }