Skip to content

Add user-defined headers before forward response to client #872

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Feb 26, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 62 additions & 1 deletion etc/tempesta_fw.conf
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,66 @@
# Default:
# None.

# TAG: resp_hdr_add
#
# Append a user-defined header to HTTP response message before forwarding
# it to client.
#
# Syntax:
# resp_hdr_add <name> <value>;
#
# Example:
# resp_hdr_add Expires "Thu, 15 Apr 2020 20:00:00 GMT"
#
# Default:
# None.

# TAG: resp_hdr_set
#
# Replace or remove a user-defined header from HTTP response message before
# forwarding it to client.
#
# Syntax:
# resp_hdr_set <name> <value>;
# resp_hdr_set <name>;
#
# Example:
# resp_hdr_add Expires "Thu, 15 Apr 2020 20:00:00 GMT"
# resp_hdr_add Expires
#
# Default:
# None.

# TAG: req_hdr_add
#
# Append a user-defined header to HTTP request message before forwarding
# it to backend server.
#
# Syntax:
# req_hdr_add <name> <value>;
#
# Example:
# req_hdr_add X-Forwarded-Host "mydomain.com"
#
# Default:
# None.

# TAG: req_hdr_set
#
# Replace or remove a user-defined header from HTTP request message before
# forwarding it to backend server.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, make sense. But isn't it better to leave only one configuration option like req_hdr_xfrm? E.g. to add or replace content of X-Forwarded-For (as oposite to current hardcoded version it replaces the header if it's present in the request:

req_hdr_xfrm X-Forwarded-For 127.0.0.1

or to remove we just omit the value:

req_hdr_xfrm X-Forwarded-For

Just like tfw_http_msg_hdr_xfrm(). The same for responses.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only difference between req_hdr_add and req_hdr_set is ability of _add to append user defined string to the existing header. In this case original value of header will be saved, but a user defined string will be added to the header. If the feature is not required, req_hdr_add directive can be easily removed.

E.g. for the configuration resp_hdr_add Set-Cookie "ck=djnfsdnfkdn" the header
Set-Cookie: c=fvfkm will be transformed into Set-Cookie: c=fvfkm, ck=djnfsdnfkdn

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So resp_hdr_set deletes a header, adds it to a HTTP message or replaces a header if it's already present, is it correct? If so, then please describe the difference in https://github.com/tempesta-tech/tempesta/wiki/Modify-HTTP-Messages , preferably with some examples.

#
# Syntax:
# req_hdr_set <name> <value>;
# req_hdr_set <name>;
#
# Example:
# req_hdr_set Host "mydomain.com"
# req_hdr_set Cookie
#
# Default:
# None.

# TAG: location
#
# Group of directives applied to specific location defined my a string
Expand All @@ -502,7 +562,8 @@
#
# <OP> is a match operator, one of "eq", "prefix", "suffix", or "*".
# <string> is a verbatim string matched against URL in a request.
# <directive> is one of "cache_bypass", "cache_fulfill", "nonidempotent".
# <directive> is one of "cache_bypass", "cache_fulfill", "nonidempotent" or
# "hdr_add".
#
# Default:
# None.
Expand Down
34 changes: 34 additions & 0 deletions tempesta_fw/http.c
Original file line number Diff line number Diff line change
Expand Up @@ -1725,6 +1725,30 @@ tfw_http_add_x_forwarded_for(TfwHttpMsg *hm)
return r;
}

static int
tfw_http_set_loc_hdrs(TfwHttpMsg *hm, TfwHttpReq *req)
{
int r;
size_t i;
int mod_type = (hm == (TfwHttpMsg *)req) ? TFW_VHOST_HDRMOD_REQ
: TFW_VHOST_HDRMOD_RESP;
TfwHdrMods *h_mods = tfw_vhost_get_hdr_mods(req->location, req->vhost,
mod_type);

for (i = 0; i < h_mods->sz; ++i) {
TfwHdrModsDesc *d = &h_mods->hdrs[i];
r = tfw_http_msg_hdr_xfrm_str(hm, d->hdr, d->hid, d->append);
if (r) {
TFW_ERR("can't update location-specific header in msg %p\n",
hm);
return r;
}
TFW_DBG2("updated location-specific header in msg %p\n", hm);
}

return 0;
}

/**
* Adjust the request before proxying it to real server.
*/
Expand All @@ -1746,6 +1770,10 @@ tfw_http_adjust_req(TfwHttpReq *req)
if (r < 0)
return r;

r = tfw_http_set_loc_hdrs(hm, req);
if (r < 0)
return r;

return tfw_http_set_hdr_connection(hm, TFW_HTTP_CONN_KA);
}

Expand Down Expand Up @@ -1778,6 +1806,10 @@ tfw_http_adjust_resp(TfwHttpResp *resp, TfwHttpReq *req)
if (r < 0)
return r;

r = tfw_http_set_loc_hdrs(hm, req);
if (r < 0)
return r;

if (resp->flags & TFW_HTTP_RESP_STALE) {
#define S_WARN_110 "Warning: 110 - Response is stale"
/* TODO: ajust for #215 */
Expand Down Expand Up @@ -2030,6 +2062,8 @@ tfw_http_req_mark_nip(TfwHttpReq *req)
* the current vhost. If there are no entries there either, then
* search in the default location of the default vhost - that is,
* in the global policies.
*
* TODO #862: req->location must be the full set of options.
*/
if (loc && loc->nipdef_sz) {
if (tfw_nipdef_match(loc, req->method, &req->uri_path))
Expand Down
3 changes: 2 additions & 1 deletion tempesta_fw/http.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,8 @@ typedef struct {
* for unconditionally hop-by-hop header or in __parse_connection() otherwize.
* If the header is end-to-end it must be listed in __hbh_parser_add_data().
*
* Note: don't forget to update __http_msg_hdr_val() upon adding a new header.
* Note: don't forget to update __http_msg_hdr_val() and
* tfw_http_msg_(resp|req)_spec_hid() upon adding a new header.
*
* Cookie: singular according to RFC 6265 5.4.
*
Expand Down
Loading