This lightweight application acts as a HTTP logging proxy for developing and staging environments. If you put it between an HTTP client and the respective server you can easily monitor requests and responses.
Pull the Docker image from Docker Hub
docker pull jdschulze/restinthemiddle:2
Pinning the version to (at least) the major version is highly recommended. Use latest at your own risk. ATM the latest tag is always the HEAD of the main branch but this can change without notice anytime.
Clone this repository and run make docker.
git clone https://github.com/restinthemiddle/restinthemiddle.git
cd restinthemiddle
git checkout main
make docker
Clone this repository and run make build.
git clone https://github.com/restinthemiddle/restinthemiddle.git
cd restinthemiddle
git checkout main
make build
Typically, you place the logging proxy between an application and an API. This is the use case Restinthemiddle was developed for.
+-----------------+ +-----------------+ +-----------------+
| +-------->+ +-------->+ |
| Application | | Restinthemiddle | | API |
| +<--------+ +<--------+ |
+-----------------+ +-----------------+ +-----------------+
But there are cases where it makes sense to place it between your browser and the application. For example, you could want to add custom headers to every request (kind of off-label use, because no logging is needed):
+-----------------+ +-----------------+ +-----------------+
| +-------->+ +-------->+ |
| Browser | | Restinthemiddle | | Application |
| +<--------+ +<--------+ |
+-----------------+ +-----------------+ +-----------------+
You may as well use Restinthemiddle as an alternative entrypoint for your application.
Configuration is handled by spf13/viper.
Restinthemiddle is intended for use in a containerized environment. Therefore it is configurable entirely via environment variables - almost! Headers have to be set via command line arguments or the configuration file.
The ascending order of precedence (last wins) is:
Example configuration file:
targetHostDsn: www.example.com
listenIp: 0.0.0.0
listenPort: "8000"
headers:
X-My-Header: myexamplevalue
loggingEnabled: true
setRequestId: false
exclude: ""
logPostBody: true
logResponseBody: true
excludePostBody: ""
excludeResponseBody: ""
readTimeout: 30
readHeaderTimeout: 10
writeTimeout: 30
idleTimeout: 120
There are several file locations where configuration is being searched for. The ascending order of precedence (last wins) is:
/etc/restinthemiddle/config.yaml$HOME/.restinthemiddle/config.yaml./config.yaml| Configuration key | Environment variable | Command line flag | Description | Default value |
|---|---|---|---|---|
targetHostDsn (required) | TARGET_HOST_DSN | --target-host-dsn | The DSN of the target host in the form schema://username:password@hostname:port/basepath?query. Find a detailed description below. | - |
listenIp (optional) | LISTEN_IP | --listen-ip | The IP Restinthemiddle is bound to. | 0.0.0.0 |
listenPort (optional) | LISTEN_PORT | --listen-port | The port Restinthemiddle is bound to. | 8000 |
metricsEnabled (optional) | METRICS_ENABLED | --metrics-enabled | Enable Prometheus metrics endpoint. | true |
metricsPort (optional) | METRICS_PORT | --metrics-port | The port on which the Prometheus metrics endpoint listens. | 9090 |
headers (optional) | - | --header | A dictionary of HTTP headers. | User-Agent: Rest in the middle logging proxy |
loggingEnabled (optional) | LOGGING_ENABLED | --logging-enabled | Enable logging. | true |
setRequestId (optional) | SET_REQUEST_ID | --set-request-id | If not already present in the request, add an X-Request-Id header with a version 4 UUID. | false |
exclude (optional) | EXCLUDE | --exclude | If the given URL path matches this Regular Expression this request+response will not be logged. | "" |
logPostBody (optional) | LOG_POST_BODY | --log-post-body | Log the request's body. | true |
logResponseBody (optional) | LOG_RESPONSE_BODY | --log-response-body | Log the response's body. | true |
excludePostBody (optional) | EXCLUDE_POST_BODY | --exclude-post-body | If the given URL path matches this Regular Expression the request body (post) is set empty. | "" |
excludeResponseBody (optional) | EXCLUDE_RESPONSE_BODY | --exclude-response-body | If the given URL path matches this Regular Expression the response body is set emtpy. | "" |
readTimeout (optional) | READ_TIMEOUT | --read-timeout | Read timeout in seconds. See Timeout Configuration below. | 0 (no timeout) |
readHeaderTimeout (optional) | READ_HEADER_TIMEOUT | --read-header-timeout | Read header timeout in seconds. See Timeout Configuration below. | 0 (no timeout) |
writeTimeout (optional) | WRITE_TIMEOUT | --write-timeout | Write timeout in seconds. See Timeout Configuration below. | 0 (no timeout) |
idleTimeout (optional) | IDLE_TIMEOUT | --idle-timeout | Idle timeout in seconds. See Timeout Configuration below. | 0 (no timeout) |
Note: See the net/http.Server documentation for detailed information about the behavior of ReadTimeout, ReadHeaderTimeout, WriteTimeout, and IdleTimeout.
Important: The default timeout values are 0 (no timeout), which matches the behavior of Go's net/http.Server. While this provides maximum flexibility, it can expose your service to resource exhaustion and security vulnerabilities.
Recommended production values:
readTimeout: 30
readHeaderTimeout: 10
writeTimeout: 30
idleTimeout: 120
Why you should configure timeouts:
Without explicit timeouts:
With proper timeouts:
schema://username:password@hostname:port/basepath?query
schema (required) is http or httpsusername:password@ is optional and will be evaluated only if both values are set.hostname (required)port is optional. Standard ports are 80 (http) and 443 (https).basepath is optional. Will be prefixed to any request URL path pointed at Restinthemiddle. See examples section.query is optional. If set, query will precede the actual request's query.If a header is defined multiple times, the last assignment wins.
If you need to make a HTTP Basic Authentication and need to send another Authorization header at the same time (e.g. a JWT) we have got you covered. Just put the HTTP Basic Auth credentials into the target host DSN string:
docker run -it --rm -e TARGET_HOST_DSN=http://user:[email protected] -p 8000:8000 jdschulze/restinthemiddle:2 --header="Authorization:Bearer ABCD1234"
We want to log HTTP calls against www.example.com over an insecure connection.
# Set up the proxy
docker run -it --rm -e TARGET_HOST_DSN=http://www.example.com -p 8000:8000 jdschulze/restinthemiddle:2
# In another terminal window we make the API call against http://www.example.com/api/visitors
curl -i http://127.0.0.1:8000/api/visitors
We want to log HTTP calls against www.example.com:4430 over a TLS connection (https://…). The API is protected by HTTP basic auth (username: user; password: pass). The base path always starts with api/.
Note that the base path defined in TARGET_HOST_DSN prefixes any subsequent calls!
# Set up the proxy
docker run -it --rm -e TARGET_HOST_DSN=https://user:[email protected]:4430/api?start=1577833200 -p 8000:8000 jdschulze/restinthemiddle:2
# In another terminal window we make the API call against https://user:[email protected]:4430/api/visitors?start=1577833200
curl -i http://127.0.0.1:8000/visitors
We want to log HTTP calls against www.example.com over an insecure connection. Every request has to be enhanced with a custom header X-App-Version: 3.0.0. No logging shall take place.
targetHostDsn: http://www.example.com
headers:
X-App-Version: '3.0.0'
loggingEnabled: false
# Set up the proxy
docker run -it --rm -v ./config.yaml:/restinthemiddle/config.yaml -p 8000:8000 jdschulze/restinthemiddle:2
# In another terminal window we make the API call against http://www.example.com/home
curl -i http://127.0.0.1:8000/home
# Set up the proxy
docker run -it --rm -p 8000:8000 jdschulze/restinthemiddle:2 restinthemiddle --target-host-dsn=http://www.example.com --header=x-app-version:3.0.0
There is a Helm Chart for Restinthemiddle at https://github.com/restinthemiddle/helm. You may want to add the Restinthemiddle Helm repository:
helm repo add restinthemiddle https://restinthemiddle.github.io/helm
helm repo update
Restinthemiddle exposes Prometheus metrics on a separate HTTP endpoint for monitoring proxy performance and health. See METRICS.md for detailed documentation on available metrics, configuration options, and example queries.
Content type
Image
Digest
sha256:2e0b03eda…
Size
8.8 MB
Last updated
1 day ago
docker pull jdschulze/restinthemiddle