Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
strategy:
max-parallel: 4
matrix:
python-version: [3.6, 3.7]
python-version: [3.6, 3.7, 3.8, 3.9]

steps:
- uses: actions/checkout@v1
Expand Down
20 changes: 15 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,18 +1,28 @@
FROM python:3.7-slim
FROM python:3.9-slim

ENV PYTHONUNBUFFERED=1
ENV PIP_DISABLE_PIP_VERSION_CHECK=1

ENV HTTPDUMMY_ADDRESS=0.0.0.0
ENV HTTPDUMMY_PORT=5000
ENV HTTPDUMMY_HEADERS=yes
ENV HTTPDUMMY_BODY=yes
ENV HTTPDUMMY_RELOADER_TYPE=stat
ENV HTTPDUMMY_PRINT_HEADERS=on
ENV HTTPDUMMY_PRINT_BODY=on
ENV HTTPDUMMY_SERVER_RELOADER=on
ENV HTTPDUMMY_SERVER_RELOADER_TYPE=stat
ENV HTTPDUMMY_SERVER_DEBUGGER=off

EXPOSE 5000

COPY . /usr/src/app

RUN pip install /usr/src/app

CMD ["httpdummy"]
CMD [ "sh", "-c", "httpdummy\
--address=${HTTPDUMMY_ADDRESS}\
--port=${HTTPDUMMY_PORT}\
--print-headers=${HTTPDUMMY_PRINT_HEADERS}\
--print-body=${HTTPDUMMY_PRINT_BODY}\
--server-reloader=${HTTPDUMMY_SERVER_RELOADER}\
--server-reloader-type=${HTTPDUMMY_SERVER_RELOADER_TYPE}\
--server-debugger=${HTTPDUMMY_SERVER_DEBUGGER}\
${HTTPDUMMY_CONFIG_FILE}"]
69 changes: 41 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# HTTPDummy

HTTPDummy is a development HTTP server tool that prints information about the requests it receives to stdout.

```
__________________
                                /        ________  \
Expand All @@ -20,8 +22,6 @@
                                                         |___/
```

HTTPDummy is a development HTTP server tool that prints information about the requests it receives to stdout.

## Installation

With PIP:
Expand All @@ -39,30 +39,42 @@ docker pull ksofa2/httpdummy
## Usage

```
usage: httpdummy [-h] [-H [HEADERS]] [-B [BODY]] [-a ADDRESS] [-p PORT]
[-r [RESPONSE_FILE]]
usage: httpdummy [-h] [-a ADDRESS] [-p PORT] [-H | --print-headers {on,off}]
[-B | --print-body {on,off}] [--server-reloader {on,off}]
[--server-reloader-type {stat,watchdog}]
[--server-debugger {on,off}]
[config_file]

A dummy http server that prints requests and responds

positional arguments:
config_file path to configuration file

optional arguments:
-h, --help show this help message and exit
-H [HEADERS], --headers [HEADERS]
-B [BODY], --body [BODY]
-a ADDRESS, --address ADDRESS
-p PORT, --port PORT
-r [RESPONSE_FILE], --response-file [RESPONSE_FILE]
address to bind to (default 127.0.0.1)
-p PORT, --port PORT port to open on (default 5000)
-H
--print-headers {on,off}
print request headers to stdout
-B
--print-body {on,off}
print request body to stdout
--server-reloader {on,off}
enable Werkzeug server reloader (default on if
config_file is specified)
--server-reloader-type {stat,watchdog}
Werkzeug server reloader type (default watchdog)
--server-debugger {on,off}
enable Werkzeug server debugger (default off)
```

- Add the `-H` flag to print request headers.
- Add the `-B` flag to print request body.

Use the `--response-file` to specify a YAML file to set up custom responses for arbitrary method / path combinations. For example, this command...

```
httpdummy --response-file ~/repsonses.yaml
httpdummy ~/httpdummy_config.yml
```

... with `~/responses.yaml` contents ...
... with `~/httpdummy_config.yml` contents ...

```
---
Expand All @@ -87,17 +99,7 @@ responses:

... will make HTTPDummy respond to POST requests to `/api/foo` with the 201 status code, and the configured headers and body.

NOTE: When started with a response file, HTTPDummy will listen for changes to that file and restart when a change is detected to reload the response definitions.

## Environment Variables

These environmental variables will be used as values for their corresponding command-line options. If the command-line option is used, that value will override the one set in the environment.

- `HTTPDUMMY_ADDRESS`
- `HTTPDUMMY_PORT`
- `HTTPDUMMY_HEADERS`
- `HTTPDUMMY_BODY`
- `HTTPDUMMY_RESPONSE_FILE`
NOTE: When started with a config file, HTTPDummy will listen for changes to that file and restart when a change is detected to reload the config file.

## Docker

Expand All @@ -107,7 +109,18 @@ An image for HTTPDummy is available on DockerHub: <https://hub.docker.com/r/ksof
docker run -it -p 127.0.0.1:5000:5000 ksofa2/httpdummy
```

NOTE: The `HTTPDUMMY_HEADERS` and `HTTPDUMMY_BODY` are turned on by default in the Docker image.
The Docker image can be configured with environment variables, which are set with these defaults:

```
HTTPDUMMY_ADDRESS=0.0.0.0
HTTPDUMMY_PORT=5000
HTTPDUMMY_PRINT_HEADERS=on
HTTPDUMMY_PRINT_BODY=on
HTTPDUMMY_SERVER_RELOADER=on
HTTPDUMMY_SERVER_RELOADER_TYPE=stat
HTTPDUMMY_SERVER_DEBUGGER=off
HTTPDUMMY_CONFIG_FILE=
```

An example `docker-compose.yaml` file:

Expand All @@ -119,7 +132,7 @@ services:
httpdummy:
image: ksofa2/httpdummy
environment:
- HTTPDUMMY_RESPONSE_FILE=/srv/responses.yaml
- HTTPDUMMY_CONFIG_FILE=/srv/httpdummy_config.yml
ports:
- 127.0.0.1:5000:5000
volumes:
Expand Down
116 changes: 116 additions & 0 deletions httpdummy/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import argparse

from werkzeug.serving import run_simple

from httpdummy.server import HttpDummy, NoLogRequestHandler, print_logo


def main():

parser = argparse.ArgumentParser(
prog='httpdummy',
description='A dummy http server that prints requests and responds')

parser.add_argument(
'-a', '--address',
help='address to bind to (default 127.0.0.1)',
default='127.0.0.1',
type=str,
)

parser.add_argument(
'-p', '--port',
help='port to open on (default 5000)',
default=5000,
type=int,
)

print_headers_subgroup = parser.add_mutually_exclusive_group()
print_headers_subgroup.add_argument(
'-H',
dest='print_headers',
action='store_const',
const='on',
default='off',
)
print_headers_subgroup.add_argument(
'--print-headers',
help='print request headers to stdout (default "off")',
choices=['on', 'off'],
default='off',
)

print_body_subgroup = parser.add_mutually_exclusive_group()
print_body_subgroup.add_argument(
'-B',
dest='print_body',
action='store_const',
const='on',
default='off',
)
print_body_subgroup.add_argument(
'--print-body',
help='print request body to stdout (default "off")',
choices=['on', 'off'],
default='off',
)

parser.add_argument(
'--server-reloader',
help=(
'enable Werkzeug server reloader (default on if config_file is '
'specified)'),
choices=['on', 'off'],
default='on',
)

parser.add_argument(
'--server-reloader-type',
help='Werkzeug server reloader type (default watchdog)',
choices=['stat', 'watchdog'],
default='watchdog',
)

parser.add_argument(
'--server-debugger',
help='enable Werkzeug server debugger (default off)',
choices=['on', 'off'],
default='off',
)

parser.add_argument(
dest='config_file',
help='path to configuration file',
type=argparse.FileType('r'),
nargs='?',
)

args = parser.parse_args()

for a in [
'print_headers', 'print_body',
'server_reloader', 'server_debugger',
]:
setattr(args, a, getattr(args, a) == 'on')

extra_files = ['server.py']
if args.config_file:
args.server_reloader = True
extra_files.append(args.config_file.name)

app = HttpDummy(**vars(args))

print_logo()

run_simple(
args.address, args.port, app,
request_handler=NoLogRequestHandler,
use_debugger=args.server_debugger,
reloader_type=args.server_reloader_type,
use_reloader=args.server_reloader,
extra_files=extra_files,
)


if __name__ == "__main__":
main()
Loading