buger / goreplay

GoReplay is an open-source tool for capturing and replaying live HTTP traffic into a test environment in order to continuously test your system with real data. It can be used to increase confidence in code deployments, configuration changes and infrastructure changes.
https://goreplay.org
Other
18.53k stars 13 forks source link

http-set-param does not work when setting the same value filtered by http-allow-url #1139

Open pamarcos opened 1 year ago

pamarcos commented 1 year ago

Given 2 HTTP servers in port 8000 and 8001, respectively, I'm trying to do the following:

  1. Forward what goes into 8000 to 8001
  2. Filter only those requests where param=0000
  3. Rewrite the param value and set it to 1234

Point 1) and 2) work ok doing like so:

sudo ./goreplay --input-raw :8000 --output-http http://0.0.0.0:8001 --http-allow-url param=0000
curl http://0.0.0.0:8000/api\?param\=0000
...
127.0.0.1 - - [08/Nov/2022 10:49:36] "GET /api?param=0000 HTTP/1.1" 404 - # Server @8000
127.0.0.1 - - [08/Nov/2022 10:49:37] "GET /api?param=0000 HTTP/1.1" 404 - # Server @8001

However, whenever I try to use http-set-param to modify the value of param as per point 3), I get nothing in server at 8001:

sudo ./goreplay --input-raw :8000 --output-http http://0.0.0.0:8001 --http-allow-url param=0000 --http-set-param param=1234 --verbose 3
curl http://0.0.0.0:8000/api\?param\=0000
[DEBUG][elapsed 2.052766556s]: [EMITTER] input:  1 9c201f407f0000012eedb394 1667901130398690371 0  from:  Intercepting traffic from: :[8000]
[DEBUG][elapsed 55.314µs]: [EMITTER] modifier: [57 99 50 48 49 102 52 48 55 102 48 48 48 48 48 49 50 101 101 100 98 51 57 52] from: Intercepting traffic from: :[8000]
127.0.0.1 - - [08/Nov/2022 10:51:51] "GET /api?param=0000 HTTP/1.1" 404 - # Server @8000
# Server @8001 receives nothing :(

It looks like trying to rewrite the same param using http-set-param that is used for filtering through http-allow-url is incompatible. Maybe the same regex used from http-allow-url for input is used for the output and it's not allowed to get to server at 8001? It's just a wild guess.

The workaround I found is to use http-rewrite-url instead like so:

sudo ./goreplay --input-raw :8000 --output-http http://0.0.0.0:8001 --http-allow-url 0000 --http-rewrite-url 'param=\d{4}:param=1234' --verbose 3
curl http://0.0.0.0:8000/api\?param\=0000
[DEBUG][elapsed 6.186485785s]: [EMITTER] input:  1 a4d21f407f000001d6f960bf 1667901301554383707 0  from:  Intercepting traffic from: :[8000]
[DEBUG][elapsed 172.997µs]: [EMITTER] modifier: [97 52 100 50 49 102 52 48 55 102 48 48 48 48 48 49 100 54 102 57 54 48 98 102] from: Intercepting traffic from: :[8000]
[DEBUG][elapsed 216.857µs]: [EMITTER] Rewritten input: [97 52 100 50 49 102 52 48 55 102 48 48 48 48 48 49 100 54 102 57 54 48 98 102] from: Intercepting traffic from: :[8000]
127.0.0.1 - - [08/Nov/2022 10:55:01] "GET /api?param=0000 HTTP/1.1" 404 - # Server @8000
127.0.0.1 - - [08/Nov/2022 10:55:03] "GET /api?param=1234 HTTP/1.1" 404 - # Server @8001

As you can see, there is a Rewritten input line that is not present in the previous command.

I'm using a compiled version of GoReplay from master at commit 243b2cf484ec12aaf37cb37a2d05905d84df775b. Same happens with latest stable release 1.3.3.