-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
Middleware for custom request rewrite logic #162
Conversation
Thanks to #160 we how have access to raw response output. |
Conflicts: Dockerfile Makefile output_http.go output_http_test.go settings.go
STDERR.puts "[DEBUG] Original data: #{data}" | ||
STDERR.puts "[DEBUG] Decoded request: #{decoded}" | ||
STDERR.puts "[DEBUG] Encoded data: #{encoded}" | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Final newline missing.
Conflicts: Dockerfile emitter.go http_client.go plugins.go proto/proto.go
Conflicts: Makefile
Hi, this work looks really interesting! I currently rewrite JSON data by dumping to a file and editing certain fields with sed :D. This looks more robust, hope it lands soon. |
@alexjurkiewicz moreover it allows you to read both original and replayed response, and allow to implement complex stuff like oAuth (rewriting tokens), and much more. |
Hi buger, My middleware is written in java. Thanks |
@lovewhll ensure that requests emitted to STDOUT properly hex encoded, if you will still have issues after that, sharing your middleware code may help. |
Hi buger, The middleware is just a echo program. the code: import java.io.BufferedReader; import org.apache.commons.io.IOUtils; public class Echo {
} |
Hi buger, I`d never seen 2 - original response. Is this a problem? Thanks |
@lovewhll can you also show how you run gor with middleware (which inputs/outputs do you use), maybe issue happens with specific combinations of plugins. |
Hi buger, /usr/local/project/gor/gor -verbose=true -debug=true --output-http-stats=true -stats=true --input-file /usr/local/project/gor/requests.gor --middleware "/usr/local/project/gor/gor-echo.sh" --output-http "http://192.168.0.10:8090" gor-echo.sh Thanks |
@lovewhll since new file format is human readable, can you ensure that responses included into "requests.gor" file? |
(and how you generated requests.gor file) |
Hi buger, /usr/local/project/gor/gor --input-raw :8090 --output-file /usr/local/project/gor/requests.gor Thanks |
Hi buger, I use examples/middleware/echo_modifier.sh to run gor with middleware,it works well. What is the default charcter code? Thanks |
@lovewhll should be utf |
This looks great! The token_modifier example is pretty much the use case I have for this. Hope to try it out soon. |
@lovewhll i just tested your middleware and it worked great (i included it into examples folder). I included java into my Docker development image, and you can test it using |
@buger it works well, thank you! |
Middleware for custom request rewrite logic
Middleware
Middleware is a program that accepts request and response payload at STDIN and emits modified requests at STDOUT. You can implement any custom logic like stripping private data, advanced rewriting, support for oAuth and etc.
Middleware can be written in any language, see
examples/middleware
folder for examples.Middleware program should accept the fact that all communication with Gor is asynchronous, there is no guarantee that original request and response messages will come one after each other. Your app should take care of the state if logic depends on original or replayed response, see
examples/middleware/token_modifier.go
as example.Simple bash echo middleware (returns same request) will look like this:
Middleware can be enabled using
--middleware
option, by specifying path to executable file:Communication protocol
All messages should be hex encoded, new line character specifieds the end of the message, eg. new message per line.
Decoded payload consist of 2 parts: header and HTTP payload, separated by new line character.
Example request payload:
Example response payload:
Header contains request meta information separated by spaces. First value is payload type, possible values:
1
- request,2
- original response,3
- replayed response.Next goes request id: unique among all requests (sha1 of time and Ack), but remain same for original and replayed response, so you can create associations between request and responses. Third argument varies depending on payload type: for request - start time, for responses - round-trip time.
HTTP payload is unmodified HTTP requests/responses intercepted from network. You can read more about request format here, here and here. You can operate with payload as you want, add headers, change path, and etc. Basically you just editing a string, just ensure that it is RCF compliant.
At the end modified (or untouched) request should be emitted back to STDOUT, keeping original header, and hex-encoded. If you want to filter request, just not send it. Emitting responses back is optional, and does not affect anything at the moment.
Advanced example
Imagine that you have auth system that randomly generate access tokens, which used later for accessing secure content. Since there is no pre-defined token value, naive approach without middleware (or if middleware use only request payloads) will fail, because replayed server have own tokens, not synced with origin. To fix this, our middleware should take in account responses of replayed and origin server, store
originalToken -> replayedToken
aliases and rewrite all requests using this token to use replayed alias. Seeexamples/middleware/token_modifier.go
andmiddleware_test.go#TestTokenMiddleware
as example of described scheme.Latest precompiled binaries:
https://www.dropbox.com/s/27chmbsqxrolvz4/gor_0.9.9_middleware_x64.tar.gz?dl=1
https://www.dropbox.com/s/vmeg5sexcleoo2e/gor_0.9.9_middleware_x86.tar.gz?dl=1