# Copy content from one header to the other

**URL:** <https://discourse.haproxy.org/t/copy-content-from-one-header-to-the-other/8562>\
**Category:** Help!\
**Created:** [March 31, 2023, 4:36pm UTC](https://discourse.haproxy.org/t/copy-content-from-one-header-to-the-other/8562 "2023-03-31T16:36:44Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![igor](https://avatars.discourse-cdn.com/v4/letter/i/dec6dc/32.png) [@igor](https://discourse.haproxy.org/u/igor)\
**Post date:** [March 31, 2023, 4:36pm UTC](https://discourse.haproxy.org/t/copy-content-from-one-header-to-the-other/8562/1 "2023-03-31T16:36:44Z")

</div>

Hi all,

As one problem was solved, the other popped in. Does anyone know if is there a way to copy the content of one header into the other?

What I mean is that a client firewall is receiving an HTTP packet forwarded from HAproxy with two headers: 1) X-Forwarded-For (this header doesn’t contain real client IP but an IP from our router)  
2) X-Original-Forwarded-For (this header contains real client IP which visits our website)

The question is how to copy the real client IP from X-Original-Forwarded-For into X-Forwarded-For.

Is this doable?

Thanks,  
I

---

<div class="post-metadata">

**Author:** ![stormrover](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.haproxy.org/stormrover/32/1847_2.png) [@stormrover](https://discourse.haproxy.org/u/stormrover)\
**Post date:** [April 1, 2023, 6:14pm UTC](https://discourse.haproxy.org/t/copy-content-from-one-header-to-the-other/8562/2 "2023-04-01T18:14:07Z")

</div>

These are examples. I’ve not tested them for syntax, so you might have to adjust them a bit.

Assuming the router always sends this header:

```auto
    http-request set-header X-Forwarded-For %[req.hdr(X-Original-Forwarded-For)] if { src <router_IP> }

```

If there is ever a scenario where this header may not be present (like requests directly from the router), use this:

```auto
    http-request set-header X-Forwarded-For %[req.hdr(X-Original-Forwarded-For)] if { src <router_IP> } { req.hdr(X-Original-Forwarded-For) -m found }

```

Always add the router’s IP address to prevent someone else from setting `X-Forwarded-For`. It’s probably rare, but it’s good security practice.

---

<div class="post-metadata">

**Author:** ![igor](https://avatars.discourse-cdn.com/v4/letter/i/dec6dc/32.png) [@igor](https://discourse.haproxy.org/u/igor)\
**Post date:** [April 4, 2023, 11:39am UTC](https://discourse.haproxy.org/t/copy-content-from-one-header-to-the-other/8562/3 "2023-04-04T11:39:25Z")

</div>

Thanks, this is a working solution.

---

<div class="post-metadata">

**Author:** ![davama](https://avatars.discourse-cdn.com/v4/letter/d/c89c15/32.png) [@davama](https://discourse.haproxy.org/u/davama)\
**Post date:** [June 28, 2024, 6:45pm UTC](https://discourse.haproxy.org/t/copy-content-from-one-header-to-the-other/8562/4 "2024-06-28T18:45:52Z")

</div>

This was very helpful. Thank you for that.

Just to add here, if you are copying from a header with a string that has commas, `req.hdr` will split it, you need to use `req.fhdr()` instead

Reference:

> <https://github.com/haproxy/haproxy/issues/794#issuecomment-668803777>
>
> I am using the "http-request capture" directive as described in the docs: https:…//www.haproxy.com/documentation/hapee/latest/onepage/#4.2-capture%20request%20header
> 
> Expected behaviour: 
> When setting "\`http-request capture req.hdr(User-Agent) len 50\`" I want to have logged "50 characters, beginning from position 0" (left end of the line).
> 
> Observed behaviour:
> I get "50 characters, beginning from position 50".
> 
> Conclusion: It seems like the "len" parameter is not only interpreted for the "num of characters", but also for the starting position.
> 
> please find below my haproxy.cfg:
> 
> \`\`\`
> global
> daemon
> maxconn 256
> ssl-server-verify none
> tune.ssl.default-dh-param 2048
> log stdout daemon
> 
> defaults
> mode http
> timeout connect 5000ms
> timeout client 50000ms
> timeout server 50000ms
> 
> frontend website
> bind :8080
> http-request capture req.hdr(x-forwarded-client-cert) len 58
> http-request capture req.hdr(User-Agent) len 50
> option httplog
> log global
> default\_backend drm-service
>     
> backend drm-service
> server backend drm-service:8080
> \`\`\`
