Since this non-RFC header field isn't in HTTP_Env nor http_t struct, i wrote this snippet :
//Get reply buffer
xbuf_t *reply = get_reply(argv);
// Init & create json buffer
xbuf_t json_buf;
xbuf_init(&json_buf);
jsn_t *params = jsn_add_node(0, "params");
[...]
http_t *http = (http_t*)get_env(argv, HTTP_HEADERS);
xbuf_t *read_buf = (xbuf_t*)get_env(argv, READ_XBUF);
[...]
// Add remote ip (from X-Forwarded-for or REMOTE_ADDR)
char *xforward = xbuf_findstr(read_buf, "X-Forwarded-For:");
if(xforward) {
jsn_add_string(params, "ip", xforward);
} else {
jsn_add_string(params, "ip", get_env(argv, REMOTE_ADDR));
}
The json part is, of course, part of the application and irrelevant with the question. Do you think it's a right way to do it or is xbuf_findstr() inefficient and there is a faster solution (without using ASM or cryptic code) ?
Thank you :)
EDIT : Wow, i forgot the strok() part to get rid of the first field, i just want the ip adress of course.
EDIT2 : Patched version with strtok
// Add remote ip (from X-Forwarded-for or REMOTE_ADDR)
char *xforward = xbuf_findstr(read_buf, "X-Forwarded-For: ");
if(xforward) {
gc_init(argv, 1024);
char *copy = gc_malloc(argv, strlen(xforward)+ 1);
memcpy(copy, xforward, strlen(xforward) + 1);
strtok(copy, ":");
char *ip = strtok(0,"\r");
while (*ip == ' ') ip++; // Trim leading space
jsn_add_string(params, "ip", ip);
} else {
jsn_add_string(params, "ip", get_env(argv, REMOTE_ADDR));
}
If this code is executed AFTER the HTTP request PARSING G-WAN state then you could start searching for
"X-Forwarded-For: "
from the closest place (another HTTP header) instead of doing it from the start of the REQUEST.There is no way to be significantly faster than
xbuf_findstr()
. String search methods are faster than others depending on the length of the input data, and this is not significant here."X-Forwarded-For: "
was parsed by G-WAN in the past but as we have implemented a proxy feature in G-WAN, and since the"X-Forwarded-For: "
header can be a fake, we removed it from the parser.