void httpRequestSetHeaders(request_t * req, method_t method, const char *uri, const char *header_str) { assert(req && uri && header_str); assert(!req->header.len); httpHeaderParse(&req->header, header_str, header_str + strlen(header_str)); }
int httpRequestParseHeader(request_t * req, const char *parse_start) { const char *blk_start, *blk_end; if (!httpMsgIsolateHeaders(&parse_start, &blk_start, &blk_end)) return 0; return httpHeaderParse(&req->header, blk_start, blk_end); }
int httpMsgParseRequestHeader(request_t * req, HttpMsgBuf * hmsg) { const char *s, *e; s = hmsg->buf + hmsg->h_start; e = hmsg->buf + hmsg->h_end + 1; return httpHeaderParse(&req->header, s, e); }
/* * parses a given string then packs compiled headers and compares the result * with the original, reports discrepancies */ void httpHeaderTestParser(const char *hstr) { static int bug_count = 0; int hstr_len; int parse_success; HttpHeader hdr; int pos; Packer p; MemBuf mb; assert(hstr); /* skip start line if any */ if (!strncasecmp(hstr, "HTTP/", 5)) { const char *p = strchr(hstr, '\n'); if (p) hstr = p + 1; } /* skip invalid first line if any */ if (xisspace(*hstr)) { const char *p = strchr(hstr, '\n'); if (p) hstr = p + 1; } hstr_len = strlen(hstr); /* skip terminator if any */ if (strstr(hstr, "\n\r\n")) hstr_len -= 2; else if (strstr(hstr, "\n\n")) hstr_len -= 1; httpHeaderInit(&hdr, hoReply); /* debugLevels[55] = 8; */ parse_success = httpHeaderParse(&hdr, hstr, hstr + hstr_len); /* debugLevels[55] = 2; */ if (!parse_success) { debug(66, 2) ("TEST (%d): failed to parsed a header: {\n%s}\n", bug_count, hstr); return; } /* we think that we parsed it, veryfy */ memBufDefInit(&mb); packerToMemInit(&p, &mb); httpHeaderPackInto(&hdr, &p); if ((pos = abs(httpHeaderStrCmp(hstr, mb.buf, hstr_len)))) { bug_count++; debug(66, 2) ("TEST (%d): hdr parsing bug (pos: %d near '%s'): expected: {\n%s} got: {\n%s}\n", bug_count, pos, hstr + pos, hstr, mb.buf); } httpHeaderClean(&hdr); packerClean(&p); memBufClean(&mb); }
/* * parses a 0-terminating buffer into HttpReply. * Returns: * +1 -- success * 0 -- need more data (partial parse) * -1 -- parse error */ static int httpReplyParseStep(HttpReply * rep, const char *buf, int atEnd) { const char *parse_start = buf; const char *blk_start, *blk_end; const char **parse_end_ptr = &blk_end; assert(rep); assert(parse_start); assert(rep->pstate < psParsed); *parse_end_ptr = parse_start; if (rep->pstate == psReadyToParseStartLine) { if (!httpReplyIsolateStart(&parse_start, &blk_start, &blk_end)) return 0; if (!httpStatusLineParse(&rep->sline, blk_start, blk_end)) return httpReplyParseError(rep); *parse_end_ptr = parse_start; rep->hdr_sz = *parse_end_ptr - buf; rep->pstate++; } if (rep->pstate == psReadyToParseHeaders) { if (!httpMsgIsolateHeaders(&parse_start, &blk_start, &blk_end)) { if (atEnd) blk_start = parse_start, blk_end = blk_start + strlen(blk_start); else return 0; } if (!httpHeaderParse(&rep->header, blk_start, blk_end)) return httpReplyParseError(rep); httpReplyHdrCacheInit(rep); *parse_end_ptr = parse_start; rep->hdr_sz = *parse_end_ptr - buf; rep->pstate++; } return 1; }
/* * The helper program receives queries on stdin, one * per line, and must return the result on on stdout */ static void refreshCheckHandleReply(void *data, char *reply) { refreshCheckState *state = data; refreshCheckState *next; int freshness = -1; char *log = NULL; MemBuf hdrs = MemBufNULL; debug(84, 2) ("refreshCheckHandleReply: reply=\"%s\"\n", reply); if (reply) { char *t = NULL; char *token = strwordtok(reply, &t); if (token && strcmp(token, "FRESH") == 0) freshness = 0; else if (token && strcmp(token, "OK") == 0) freshness = 0; while ((token = strwordtok(NULL, &t))) { char *value = strchr(token, '='); if (value) { *value++ = '\0'; /* terminate the token, and move up to the value */ rfc1738_unescape(value); if (strcmp(token, "freshness") == 0) freshness = atoi(value); else if (strcmp(token, "log") == 0) log = value; else if (strncmp(token, "res{", 4) == 0) { char *header, *t; header = token + 4; t = strrchr(header, '}'); if (!t) continue; *t = '\0'; if (!hdrs.buf) memBufDefInit(&hdrs); memBufPrintf(&hdrs, "%s: %s\r\n", header, value); } } } } if (freshness >= 0) { if (hdrs.size) { HttpReply *rep = httpReplyCreate(); httpHeaderParse(&rep->header, hdrs.buf, hdrs.buf + hdrs.size); httpReplyUpdateOnNotModified(state->entry->mem_obj->reply, rep); storeTimestampsSet(state->entry); if (!httpHeaderHas(&rep->header, HDR_DATE)) { state->entry->timestamp = squid_curtime; state->entry->expires = squid_curtime + freshness; } else if (freshness) { state->entry->expires = squid_curtime + freshness; } httpReplyDestroy(rep); storeUpdate(state->entry, NULL); } else { state->entry->timestamp = squid_curtime; state->entry->expires = squid_curtime + freshness; } } if (hdrs.buf) memBufClean(&hdrs); dlinkDelete(&state->list, &state->def->queue); do { cbdataUnlock(state->def); state->def = NULL; if (state->callback && cbdataValid(state->callback_data)) state->callback(state->callback_data, freshness >= 0, log); cbdataUnlock(state->callback_data); state->callback_data = NULL; next = state->queue; cbdataFree(state); state = next; } while (state); }