mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-02-07 14:01:54 +00:00
MINOR: http_htx: Add functions to retrieve a specific occurrence of a header
There are 2 functions. The first one considers any comma as a delimiter for distinct values. The second one considers full-line headers.
This commit is contained in:
parent
e010c80753
commit
7ff1ceaa5e
@ -42,5 +42,9 @@ int http_replace_res_reason(struct htx *htx, const struct ist reason);
|
|||||||
int http_replace_header_value(struct htx *htx, struct http_hdr_ctx *ctx, const struct ist data);
|
int http_replace_header_value(struct htx *htx, struct http_hdr_ctx *ctx, const struct ist data);
|
||||||
int http_replace_header(struct htx *htx, struct http_hdr_ctx *ctx, const struct ist name, const struct ist value);
|
int http_replace_header(struct htx *htx, struct http_hdr_ctx *ctx, const struct ist name, const struct ist value);
|
||||||
int http_remove_header(struct htx *htx, struct http_hdr_ctx *ctx);
|
int http_remove_header(struct htx *htx, struct http_hdr_ctx *ctx);
|
||||||
|
unsigned int http_get_htx_hdr(const struct htx *htx, const struct ist hdr,
|
||||||
|
int occ, struct http_hdr_ctx *ctx, char **vptr, size_t *vlen);
|
||||||
|
unsigned int http_get_htx_fhdr(const struct htx *htx, const struct ist hdr,
|
||||||
|
int occ, struct http_hdr_ctx *ctx, char **vptr, size_t *vlen);
|
||||||
|
|
||||||
#endif /* _PROTO_HTTP_HTX_H */
|
#endif /* _PROTO_HTTP_HTX_H */
|
||||||
|
129
src/http_htx.c
129
src/http_htx.c
@ -535,3 +535,132 @@ int http_remove_header(struct htx *htx, struct http_hdr_ctx *ctx)
|
|||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Return in <vptr> and <vlen> the pointer and length of occurrence <occ> of
|
||||||
|
* header whose name is <hname> of length <hlen>. If <ctx> is null, lookup is
|
||||||
|
* performed over the whole headers. Otherwise it must contain a valid header
|
||||||
|
* context, initialised with ctx->blk=NULL for the first lookup in a series. If
|
||||||
|
* <occ> is positive or null, occurrence #occ from the beginning (or last ctx)
|
||||||
|
* is returned. Occ #0 and #1 are equivalent. If <occ> is negative (and no less
|
||||||
|
* than -MAX_HDR_HISTORY), the occurrence is counted from the last one which is
|
||||||
|
* -1. The value fetch stops at commas, so this function is suited for use with
|
||||||
|
* list headers.
|
||||||
|
* The return value is 0 if nothing was found, or non-zero otherwise.
|
||||||
|
*/
|
||||||
|
unsigned int http_get_htx_hdr(const struct htx *htx, const struct ist hdr,
|
||||||
|
int occ, struct http_hdr_ctx *ctx, char **vptr, size_t *vlen)
|
||||||
|
{
|
||||||
|
struct http_hdr_ctx local_ctx;
|
||||||
|
struct ist val_hist[MAX_HDR_HISTORY];
|
||||||
|
unsigned int hist_idx;
|
||||||
|
int found;
|
||||||
|
|
||||||
|
if (!ctx) {
|
||||||
|
local_ctx.blk = NULL;
|
||||||
|
ctx = &local_ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (occ >= 0) {
|
||||||
|
/* search from the beginning */
|
||||||
|
while (http_find_header(htx, hdr, ctx, 0)) {
|
||||||
|
occ--;
|
||||||
|
if (occ <= 0) {
|
||||||
|
*vptr = ctx->value.ptr;
|
||||||
|
*vlen = ctx->value.len;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* negative occurrence, we scan all the list then walk back */
|
||||||
|
if (-occ > MAX_HDR_HISTORY)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
found = hist_idx = 0;
|
||||||
|
while (http_find_header(htx, hdr, ctx, 0)) {
|
||||||
|
val_hist[hist_idx] = ctx->value;
|
||||||
|
if (++hist_idx >= MAX_HDR_HISTORY)
|
||||||
|
hist_idx = 0;
|
||||||
|
found++;
|
||||||
|
}
|
||||||
|
if (-occ > found)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* OK now we have the last occurrence in [hist_idx-1], and we need to
|
||||||
|
* find occurrence -occ. 0 <= hist_idx < MAX_HDR_HISTORY, and we have
|
||||||
|
* -10 <= occ <= -1. So we have to check [hist_idx%MAX_HDR_HISTORY+occ]
|
||||||
|
* to remain in the 0..9 range.
|
||||||
|
*/
|
||||||
|
hist_idx += occ + MAX_HDR_HISTORY;
|
||||||
|
if (hist_idx >= MAX_HDR_HISTORY)
|
||||||
|
hist_idx -= MAX_HDR_HISTORY;
|
||||||
|
*vptr = val_hist[hist_idx].ptr;
|
||||||
|
*vlen = val_hist[hist_idx].len;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return in <vptr> and <vlen> the pointer and length of occurrence <occ> of
|
||||||
|
* header whose name is <hname> of length <hlen>. If <ctx> is null, lookup is
|
||||||
|
* performed over the whole headers. Otherwise it must contain a valid header
|
||||||
|
* context, initialised with ctx->blk=NULL for the first lookup in a series. If
|
||||||
|
* <occ> is positive or null, occurrence #occ from the beginning (or last ctx)
|
||||||
|
* is returned. Occ #0 and #1 are equivalent. If <occ> is negative (and no less
|
||||||
|
* than -MAX_HDR_HISTORY), the occurrence is counted from the last one which is
|
||||||
|
* -1. This function differs from http_get_hdr() in that it only returns full
|
||||||
|
* line header values and does not stop at commas.
|
||||||
|
* The return value is 0 if nothing was found, or non-zero otherwise.
|
||||||
|
*/
|
||||||
|
unsigned int http_get_htx_fhdr(const struct htx *htx, const struct ist hdr,
|
||||||
|
int occ, struct http_hdr_ctx *ctx, char **vptr, size_t *vlen)
|
||||||
|
{
|
||||||
|
struct http_hdr_ctx local_ctx;
|
||||||
|
struct ist val_hist[MAX_HDR_HISTORY];
|
||||||
|
unsigned int hist_idx;
|
||||||
|
int found;
|
||||||
|
|
||||||
|
if (!ctx) {
|
||||||
|
local_ctx.blk = NULL;
|
||||||
|
ctx = &local_ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (occ >= 0) {
|
||||||
|
/* search from the beginning */
|
||||||
|
while (http_find_header(htx, hdr, ctx, 1)) {
|
||||||
|
occ--;
|
||||||
|
if (occ <= 0) {
|
||||||
|
*vptr = ctx->value.ptr;
|
||||||
|
*vlen = ctx->value.len;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* negative occurrence, we scan all the list then walk back */
|
||||||
|
if (-occ > MAX_HDR_HISTORY)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
found = hist_idx = 0;
|
||||||
|
while (http_find_header(htx, hdr, ctx, 1)) {
|
||||||
|
val_hist[hist_idx] = ctx->value;
|
||||||
|
if (++hist_idx >= MAX_HDR_HISTORY)
|
||||||
|
hist_idx = 0;
|
||||||
|
found++;
|
||||||
|
}
|
||||||
|
if (-occ > found)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* OK now we have the last occurrence in [hist_idx-1], and we need to
|
||||||
|
* find occurrence -occ. 0 <= hist_idx < MAX_HDR_HISTORY, and we have
|
||||||
|
* -10 <= occ <= -1. So we have to check [hist_idx%MAX_HDR_HISTORY+occ]
|
||||||
|
* to remain in the 0..9 range.
|
||||||
|
*/
|
||||||
|
hist_idx += occ + MAX_HDR_HISTORY;
|
||||||
|
if (hist_idx >= MAX_HDR_HISTORY)
|
||||||
|
hist_idx -= MAX_HDR_HISTORY;
|
||||||
|
*vptr = val_hist[hist_idx].ptr;
|
||||||
|
*vlen = val_hist[hist_idx].len;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user