📄 httpheader.c
字号:
assert(Headers[id].type == ftDate_1123); /* must be of an appropriate type */ if ((e = httpHeaderFindEntry(hdr, id))) { value = parse_rfc1123(strBuf(e->value)); httpHeaderNoteParsedEntry(e->id, e->value, value < 0); } return value;}/* sync with httpHeaderGetLastStr */const char *httpHeaderGetStr(const HttpHeader * hdr, http_hdr_type id){ HttpHeaderEntry *e; assert_eid(id); assert(Headers[id].type == ftStr); /* must be of an appropriate type */ if ((e = httpHeaderFindEntry(hdr, id))) { httpHeaderNoteParsedEntry(e->id, e->value, 0); /* no errors are possible */ return strBuf(e->value); } return NULL;}/* unusual */const char *httpHeaderGetLastStr(const HttpHeader * hdr, http_hdr_type id){ HttpHeaderEntry *e; assert_eid(id); assert(Headers[id].type == ftStr); /* must be of an appropriate type */ if ((e = httpHeaderFindLastEntry(hdr, id))) { httpHeaderNoteParsedEntry(e->id, e->value, 0); /* no errors are possible */ return strBuf(e->value); } return NULL;}HttpHdrCc *httpHeaderGetCc(const HttpHeader * hdr){ HttpHdrCc *cc; String s; if (!CBIT_TEST(hdr->mask, HDR_CACHE_CONTROL)) return NULL; s = httpHeaderGetList(hdr, HDR_CACHE_CONTROL); cc = httpHdrCcParseCreate(&s); HttpHeaderStats[hdr->owner].ccParsedCount++; if (cc) httpHdrCcUpdateStats(cc, &HttpHeaderStats[hdr->owner].ccTypeDistr); httpHeaderNoteParsedEntry(HDR_CACHE_CONTROL, s, !cc); stringClean(&s); return cc;}HttpHdrRange *httpHeaderGetRange(const HttpHeader * hdr){ HttpHdrRange *r = NULL; HttpHeaderEntry *e; /* some clients will send "Request-Range" _and_ *matching* "Range" * who knows, some clients might send Request-Range only; * this "if" should work correctly in both cases; * hopefully no clients send mismatched headers! */ if ((e = httpHeaderFindEntry(hdr, HDR_RANGE)) || (e = httpHeaderFindEntry(hdr, HDR_REQUEST_RANGE))) { r = httpHdrRangeParseCreate(&e->value); httpHeaderNoteParsedEntry(e->id, e->value, !r); } return r;}HttpHdrContRange *httpHeaderGetContRange(const HttpHeader * hdr){ HttpHdrContRange *cr = NULL; HttpHeaderEntry *e; if ((e = httpHeaderFindEntry(hdr, HDR_CONTENT_RANGE))) { cr = httpHdrContRangeParseCreate(strBuf(e->value)); httpHeaderNoteParsedEntry(e->id, e->value, !cr); } return cr;}const char *httpHeaderGetAuth(const HttpHeader * hdr, http_hdr_type id, const char *authScheme){ const char *field; int l; assert(hdr && authScheme); field = httpHeaderGetStr(hdr, id); if (!field) /* no authorization field */ return NULL; l = strlen(authScheme); if (!l || strncasecmp(field, authScheme, l)) /* wrong scheme */ return NULL; field += l; if (!xisspace(*field)) /* wrong scheme */ return NULL; /* skip white space */ field += xcountws(field); if (!*field) /* no authorization cookie */ return NULL; return base64_decode(field);}ETaghttpHeaderGetETag(const HttpHeader * hdr, http_hdr_type id){ ETag etag = {NULL, -1}; HttpHeaderEntry *e; assert(Headers[id].type == ftETag); /* must be of an appropriate type */ if ((e = httpHeaderFindEntry(hdr, id))) etagParseInit(&etag, strBuf(e->value)); return etag;}TimeOrTaghttpHeaderGetTimeOrTag(const HttpHeader * hdr, http_hdr_type id){ TimeOrTag tot; HttpHeaderEntry *e; assert(Headers[id].type == ftDate_1123_or_ETag); /* must be of an appropriate type */ memset(&tot, 0, sizeof(tot)); if ((e = httpHeaderFindEntry(hdr, id))) { const char *str = strBuf(e->value); /* try as an ETag */ if (etagParseInit(&tot.tag, str)) { tot.valid = tot.tag.str != NULL; tot.time = -1; } else { /* or maybe it is time? */ tot.time = parse_rfc1123(str); tot.valid = tot.time >= 0; tot.tag.str = NULL; } } assert(tot.time < 0 || !tot.tag.str); /* paranoid */ return tot;}/* * HttpHeaderEntry */static HttpHeaderEntry *httpHeaderEntryCreate(http_hdr_type id, const char *name, const char *value){ HttpHeaderEntry *e; assert_eid(id); e = memAllocate(MEM_HTTP_HDR_ENTRY); e->id = id; if (id != HDR_OTHER) e->name = Headers[id].name; else stringInit(&e->name, name); stringInit(&e->value, value); Headers[id].stat.aliveCount++; debug(55, 9) ("created entry %p: '%s: %s'\n", e, strBuf(e->name), strBuf(e->value)); return e;}static voidhttpHeaderEntryDestroy(HttpHeaderEntry * e){ assert(e); assert_eid(e->id); debug(55, 9) ("destroying entry %p: '%s: %s'\n", e, strBuf(e->name), strBuf(e->value)); /* clean name if needed */ if (e->id == HDR_OTHER) stringClean(&e->name); stringClean(&e->value); assert(Headers[e->id].stat.aliveCount); Headers[e->id].stat.aliveCount--; e->id = -1; memFree(e, MEM_HTTP_HDR_ENTRY);}/* parses and inits header entry, returns new entry on success */static HttpHeaderEntry *httpHeaderEntryParseCreate(const char *field_start, const char *field_end){ HttpHeaderEntry *e; int id; /* note: name_start == field_start */ const char *name_end = strchr(field_start, ':'); const int name_len = name_end ? name_end - field_start : 0; const char *value_start = field_start + name_len + 1; /* skip ':' */ /* note: value_end == field_end */ HeaderEntryParsedCount++; /* do we have a valid field name within this field? */ if (!name_len || name_end > field_end) return NULL; /* now we know we can parse it */ e = memAllocate(MEM_HTTP_HDR_ENTRY); debug(55, 9) ("creating entry %p: near '%s'\n", e, getStringPrefix(field_start, field_end)); /* is it a "known" field? */ id = httpHeaderIdByName(field_start, name_len, Headers, HDR_ENUM_END); if (id < 0) id = HDR_OTHER; assert_eid(id); e->id = id; /* set field name */ if (id == HDR_OTHER) stringLimitInit(&e->name, field_start, name_len); else e->name = Headers[id].name; /* trim field value */ while (value_start < field_end && xisspace(*value_start)) value_start++; /* set field value */ stringLimitInit(&e->value, value_start, field_end - value_start); Headers[id].stat.seenCount++; Headers[id].stat.aliveCount++; debug(55, 9) ("created entry %p: '%s: %s'\n", e, strBuf(e->name), strBuf(e->value)); return e;}HttpHeaderEntry *httpHeaderEntryClone(const HttpHeaderEntry * e){ return httpHeaderEntryCreate(e->id, strBuf(e->name), strBuf(e->value));}voidhttpHeaderEntryPackInto(const HttpHeaderEntry * e, Packer * p){ assert(e && p); packerAppend(p, strBuf(e->name), strLen(e->name)); packerAppend(p, ": ", 2); packerAppend(p, strBuf(e->value), strLen(e->value)); packerAppend(p, "\r\n", 2);}static voidhttpHeaderNoteParsedEntry(http_hdr_type id, String context, int error){ Headers[id].stat.parsCount++; if (error) { Headers[id].stat.errCount++; debug(55, 2) ("cannot parse hdr field: '%s: %s'\n", strBuf(Headers[id].name), strBuf(context)); }}/* * Reports *//* tmp variable used to pass stat info to dumpers */extern const HttpHeaderStat *dump_stat; /* argh! */const HttpHeaderStat *dump_stat = NULL;static voidhttpHeaderFieldStatDumper(StoreEntry * sentry, int idx, double val, double size, int count){ const int id = (int) val; const int valid_id = id >= 0 && id < HDR_ENUM_END; const char *name = valid_id ? strBuf(Headers[id].name) : "INVALID"; int visible = count > 0; /* for entries with zero count, list only those that belong to current type of message */ if (!visible && valid_id && dump_stat->owner_mask) visible = CBIT_TEST(*dump_stat->owner_mask, id); if (visible) storeAppendPrintf(sentry, "%2d\t %-20s\t %5d\t %6.2f\n", id, name, count, xdiv(count, dump_stat->busyDestroyedCount));}static voidhttpHeaderFldsPerHdrDumper(StoreEntry * sentry, int idx, double val, double size, int count){ if (count) storeAppendPrintf(sentry, "%2d\t %5d\t %5d\t %6.2f\n", idx, (int) val, count, xpercent(count, dump_stat->destroyedCount));}static voidhttpHeaderStatDump(const HttpHeaderStat * hs, StoreEntry * e){ assert(hs && e); dump_stat = hs; storeAppendPrintf(e, "\nHeader Stats: %s\n", hs->label); storeAppendPrintf(e, "\nField type distribution\n"); storeAppendPrintf(e, "%2s\t %-20s\t %5s\t %6s\n", "id", "name", "count", "#/header"); statHistDump(&hs->fieldTypeDistr, e, httpHeaderFieldStatDumper); storeAppendPrintf(e, "\nCache-control directives distribution\n"); storeAppendPrintf(e, "%2s\t %-20s\t %5s\t %6s\n", "id", "name", "count", "#/cc_field"); statHistDump(&hs->ccTypeDistr, e, httpHdrCcStatDumper); storeAppendPrintf(e, "\nNumber of fields per header distribution\n"); storeAppendPrintf(e, "%2s\t %-5s\t %5s\t %6s\n", "id", "#flds", "count", "%total"); statHistDump(&hs->hdrUCountDistr, e, httpHeaderFldsPerHdrDumper); dump_stat = NULL;}voidhttpHeaderStoreReport(StoreEntry * e){ int i; http_hdr_type ht; assert(e); HttpHeaderStats[0].parsedCount = HttpHeaderStats[hoRequest].parsedCount + HttpHeaderStats[hoReply].parsedCount; HttpHeaderStats[0].ccParsedCount = HttpHeaderStats[hoRequest].ccParsedCount + HttpHeaderStats[hoReply].ccParsedCount; HttpHeaderStats[0].destroyedCount = HttpHeaderStats[hoRequest].destroyedCount + HttpHeaderStats[hoReply].destroyedCount; HttpHeaderStats[0].busyDestroyedCount = HttpHeaderStats[hoRequest].busyDestroyedCount + HttpHeaderStats[hoReply].busyDestroyedCount; for (i = 1; i < HttpHeaderStatCount; i++) { httpHeaderStatDump(HttpHeaderStats + i, e); storeAppendPrintf(e, "%s\n", "<br>"); } /* field stats for all messages */ storeAppendPrintf(e, "\nHttp Fields Stats (replies and requests)\n"); storeAppendPrintf(e, "%2s\t %-20s\t %5s\t %6s\t %6s\n", "id", "name", "#alive", "%err", "%repeat"); for (ht = 0; ht < HDR_ENUM_END; ht++) { HttpHeaderFieldInfo *f = Headers + ht; storeAppendPrintf(e, "%2d\t %-20s\t %5d\t %6.3f\t %6.3f\n", f->id, strBuf(f->name), f->stat.aliveCount, xpercent(f->stat.errCount, f->stat.parsCount), xpercent(f->stat.repCount, f->stat.seenCount)); } storeAppendPrintf(e, "Headers Parsed: %d + %d = %d\n", HttpHeaderStats[hoRequest].parsedCount, HttpHeaderStats[hoReply].parsedCount, HttpHeaderStats[0].parsedCount); storeAppendPrintf(e, "Hdr Fields Parsed: %d\n", HeaderEntryParsedCount);}inthttpHeaderIdByName(const char *name, int name_len, const HttpHeaderFieldInfo * info, int end){ int i; for (i = 0; i < end; ++i) { if (name_len >= 0 && name_len != strLen(info[i].name)) continue; if (!strncasecmp(name, strBuf(info[i].name), name_len < 0 ? strLen(info[i].name) + 1 : name_len)) return i; } return -1;}inthttpHeaderIdByNameDef(const char *name, int name_len){ if (!Headers) Headers = httpHeaderBuildFieldsInfo(HeadersAttrs, HDR_ENUM_END); return httpHeaderIdByName(name, name_len, Headers, HDR_ENUM_END);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -