예제 #1
0
static HttpHdrExtField *
httpHdrExtFieldDoCreate(const char *name, int name_len,
    const char *value, int value_len)
{
    HttpHdrExtField *f = xcalloc(1, sizeof(HttpHdrExtField));
    stringLimitInit(&f->name, name, name_len);
    stringLimitInit(&f->value, value, value_len);
    return f;
}
예제 #2
0
/* 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;
    if (name_len > 65536) {
	/* String has a 64K limit */
	debug(55, 1) ("WARNING: ignoring header name of %d bytes\n", name_len);
	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++;
    if (field_end - value_start > 65536) {
	/* String has a 64K limit */
	debug(55, 1) ("WARNING: ignoring '%s' header of %d bytes\n",
	    strBuf(e->name), (int) (field_end - value_start));
	if (e->id == HDR_OTHER)
	    stringClean(&e->name);
	memFree(e, MEM_HTTP_HDR_ENTRY);
	return NULL;
    }
    /* 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;
}
예제 #3
0
/**
 * Parses a quoted-string field (RFC 2616 section 2.2), complains if
 * something went wrong, returns non-zero on success.
 * start should point at the first double-quote.
 * RC TODO: This is too looose. We should honour the BNF and exclude CTL's
 */
int
httpHeaderParseQuotedString(const char *start, String * val)
{
    const char *end, *pos;
    stringClean(val);
    if (*start != '"') {
	debug(66, 2) ("failed to parse a quoted-string header field near '%s'\n", start);
	return 0;
    }
    pos = start + 1;

    while (*pos != '"') {
	int quoted = (*pos == '\\');
	if (quoted)
	    pos++;
	if (!*pos) {
	    debug(66, 2) ("failed to parse a quoted-string header field near '%s'\n", start);
	    stringClean(val);
	    return 0;
	}
	end = pos + strcspn(pos + quoted, "\"\\") + quoted;
	stringAppend(val, pos, end - pos);
	pos = end;
    }
    /* Make sure it's defined even if empty "" */
    if (!val->buf)
	stringLimitInit(val, "", 0);
    return 1;
}
예제 #4
0
static HttpHeaderEntry *
httpHeaderEntryCreate2(http_hdr_type id, String name, String 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
	stringLimitInit(&e->name, strBuf(name), strLen(name));
    stringLimitInit(&e->value, strBuf(value), strLen(value));
    Headers[id].stat.aliveCount++;
    debug(55, 9) ("created entry %p: '%s: %s'\n", e, strBuf(e->name), strBuf(e->value));
    return e;
}
예제 #5
0
/* return a string or list of entries with the same id separated by ',' and ws */
String
httpHeaderGetStrOrList(const HttpHeader * hdr, http_hdr_type id)
{
    HttpHeaderEntry *e;

    if (CBIT_TEST(ListHeadersMask, id))
	return httpHeaderGetList(hdr, id);
    if ((e = httpHeaderFindEntry(hdr, id))) {
	String s;
	stringLimitInit(&s, strBuf(e->value), strLen(e->value));
	return s;
    }
    return StringNull;
}
예제 #6
0
/* sync this routine when you update HttpReply struct */
static void
httpReplyHdrCacheInit(HttpReply * rep)
{
    const HttpHeader *hdr = &rep->header;
    const char *str;
    rep->content_length = httpHeaderGetSize(hdr, HDR_CONTENT_LENGTH);
    rep->date = httpHeaderGetTime(hdr, HDR_DATE);
    rep->last_modified = httpHeaderGetTime(hdr, HDR_LAST_MODIFIED);
    str = httpHeaderGetStr(hdr, HDR_CONTENT_TYPE);
    if (str)
	stringLimitInit(&rep->content_type, str, strcspn(str, ";\t "));
    else
	rep->content_type = StringNull;
    rep->cache_control = httpHeaderGetCc(hdr);
    rep->content_range = httpHeaderGetContRange(hdr);
    rep->keep_alive = httpMsgIsPersistent(rep->sline.version, &rep->header);
    /* be sure to set expires after date and cache-control */
    rep->expires = httpReplyHdrExpirationTime(rep);
}
예제 #7
0
/* 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 = memchr(field_start, ':', field_end - field_start);
    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;
    if (name_len > 65534) {
	/* String must be LESS THAN 64K and it adds a terminating NULL */
	debug(55, 1) ("WARNING: ignoring header name of %d bytes\n", name_len);
	return NULL;
    }
    if (Config.onoff.relaxed_header_parser && xisspace(field_start[name_len - 1])) {
	debug(55, Config.onoff.relaxed_header_parser <= 0 ? 1 : 2)
	    ("NOTICE: Whitespace after header name in '%s'\n", getStringPrefix(field_start, field_end));
	while (name_len > 0 && xisspace(field_start[name_len - 1]))
	    name_len--;
	if (!name_len)
	    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++;
    while (value_start < field_end && xisspace(field_end[-1]))
	field_end--;
    if (field_end - value_start > 65534) {
	/* String must be LESS THAN 64K and it adds a terminating NULL */
	debug(55, 1) ("WARNING: ignoring '%s' header of %d bytes\n",
	    strBuf(e->name), (int) (field_end - value_start));
	if (e->id == HDR_OTHER)
	    stringClean(&e->name);
	memFree(e, MEM_HTTP_HDR_ENTRY);
	return NULL;
    }
    /* 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;
}