Jay Taylor's notes

back to listing index

SpectoLabs/hoverfly

[web search]
Original source (github.com)
Tags: golang go http hoverfly service-virtualization proxy github.com
Clipped on: 2015-12-11

Skip to content
Open source service virtualization http://hoverfly.io
Go CSS JavaScript HTML
examples new line in a response body mw 8 hours ago
static actually the logo a day ago
vendor/github.com commiting dependencies 2 days ago
.gitattributes added gitattributes file 9 days ago
.gitignore removed Vagrant stuff a day ago
.gitmodules submodule info 2 days ago
Dockerfile updated Dockerfile 2 days ago
LICENSE Update LICENSE 11 days ago
Vagrantfile updated Vagrantfile a day ago
admin.go some order 2 days ago
ca.pem added self signed cert and updated readme 11 days ago
cache.go more debug info 2 days ago
cache_test.go cache set/get key 2 days ago
docker-compose.yml added simple version of docker compose 14 days ago
glide.yaml cleanup 14 days ago
hoverfly.go admin server startup moved to admin.py 2 days ago
manipulation.go removing new payload information, too much for debugging 3 days ago
manipulation_test.go testing middleware request body change 3 days ago
middleware.go debug 7 days ago
middleware_test.go new line in a response body mw 8 hours ago
models.go adding error messages if hoverfly failed to delete keys 8 hours ago
models_test.go adding error messages if hoverfly failed to delete keys 8 hours ago
readme.md Update readme.md 20 hours ago
settings.go admin and settings updated 8 days ago
synthesize.go handle case when middleware not provided 2 days ago
synthesize_test.go test when middleware not provided 2 days ago
test_tools.go cleanup 29 days ago

readme.md

Image (Asset 3/3) alt=

Dependencies without the sting

Hoverfly is a lightweight, open source service virtualization tool. Using Hoverfly, you can virtualize your application dependencies to create a self-contained development or test environment.

Hoverfly is a proxy written in Go. It can capture HTTP(s) traffic between an application under test and external services, and then replace the external services. Another powerful feature: middleware modules, where users can introduce their own custom logic. Middleware modules can be written in any language. Hoverfly uses Redis for persistence.

Installation

If you have Vagrant, it's as simple as

normalvagrant up
normal

Alternatively, you can just grab a binary or you can build it yourself. Use glide to fetch the dependencies with:

normalglide up
normal

Then build Hoverfly:

normalgo build
normal

And run it:

normal./hoverfly
normal

The Hoverfly admin UI is available at http://localhost:8888/.

Hoverfly is a proxy

Configuring your application to use Hoverfly is simple. All you have to do is set the HTTP_PROXY environment variable:

normal export HTTP_PROXY=http://localhost:8500/
normal

Destination configuration

You can specify which site to capture or virtualize with a regular expression (by default, Hoverfly processes everything):

normal./hoverfly --destination="."
normal

Modes (Virtualize / Capture / Synthesize / Modify)

Hoverfly has different operating modes. Each mode changes the behavior of the proxy. Based on the selected mode, Hoverfly can either capture the requests and responses, look for them in the cache, or send them directly to the middleware and respond with a payload that is generated by the middleware (more on middleware below).

Virtualize

By default, the proxy starts in virtualize mode. You can apply middleware to each response.

Capture

When capture mode is active, Hoverfly acts as a "man-in-the-middle". It makes requests on behalf of a client and records the responses. The response is then sent back to the original client.

To switch to capture mode, you can add the "--capture" flag during startup:

normal./hoverfly --capture
normal

Or you can select "Capture" using the admin UI at http://localhost:8888/

Or you can use API call to change proxy state while running (see API below).

Do a curl request with proxy details:

normalcurl http://mirage.readthedocs.org --proxy http://localhost:8500/
normal

Synthesize

Hoverfly can create responses to requests on the fly. Synthesize mode intercepts requests (it also respects the --destination flag) and applies the supplied middleware (the user is required to supply --middleware flag, you can read more about it below). The middleware is expected to populate response payload, so Hoverfly can then reconstruct it and return it to the client. An example of a synthetic service can be found in this_repo/examples/middleware/synthetic_service/synthetic.py. You can test it by running:

normal./hoverfly --synthesize --middleware "./examples/middleware/synthetic_service/synthetic.py"
normal

Modify

Modify mode applies the selected middleware (the user is required to supply the --middleware flag - you can read more about this below) to outgoing requests and incoming responses (before they are returned to the client). It allows users to use Hoverfly without storing any data about requests. It can be used when it's difficult to - or there is little point in - describing a service, and you only need to change certain parts of the requests or responses (eg: adding authentication headers through with middleware). The example below changes the destination host to "mirage.readthedocs.org" and sets the method to "GET":

normal./hoverfly --modify --middleware "./examples/middleware/modify_request/modify_request.py
normal

HTTPS capture

Add ca.pem to your trusted certificates or turn off verification. With curl you can make insecure requests with -k:

normalcurl https://www.bbc.co.uk --proxy http://localhost:8500 -k
normal

Administrator web UI

By default, the proxy launches the admin API and UI on port 8888. You can access the admin interface for basic operations on http://localhost:8888/. It uses the same API as described below to change state. It also allows you to wipe the captured requests/responses and shows the number of captured records. For other functions, such as export/import, you can use the API directly.

API

You can access the administrator API under default port 8888:

  • Recorded requests: GET http://proxy_hostname:8888/records ( curl http://proxy_hostname:8888/records )
  • Wipe cache: DELETE http://proxy_hostname:8888/records ( curl -X DELETE http://proxy_hostname:8888/records )
  • Get current proxy state: GET http://proxy_hostname:8888/state ( curl http://proxy_hostname:8888/state )
  • Set proxy state: POST http://proxy_hostname:8888/state, where
    • body to start virtualizing: {"mode":"virtualize"}
    • body to start capturing: {"mode":"capture"}
  • Exporting recorded requests to a file: curl http://proxy_hostname:8888/records > requests.json
  • Importing requests from file: curl --data "@/path/to/requests.json" http://localhost:8888/records

Middleware

Hoverfly supports external middleware modules. You can write them in any language you want !. These middleware modules are expected to take standard input (stdin) and should output a structured JSON string to stdout. Payload example:

{
    "response": {
        "status": 200,
        "body": "body here",
        "headers": {
            "Content-Type": ["text/html"],
            "Date": ["Tue, 01 Dec 2015 16:49:08 GMT"],
        }
    },
    "request": {
        "path": "/",
        "method": "GET",
        "destination": "1stalphaomega.readthedocs.org",
        "query": ""
    },
    "id": "5d4f6b1d9f7c2407f78e4d4e211ec769"
}

Middleware is executed only when request is matched so for fully dynamic responses where you are generating response on the fly you can use ""--synthesize" flag.

In order to use your middleware, just add path to executable:

normal./hoverfly --middleware "./examples/middleware/modify_response/modify_response.py"
normal

Basic example of a Python module to change response body and add 2 second delay:

#!/usr/bin/env python
import sys
import logging
import json
from time import sleep


logging.basicConfig(filename='middleware.log', level=logging.DEBUG)
logging.debug('Middleware is called')


def main():
    data = sys.stdin.readlines()
    # this is a json string in one line so we are interested in that one line
    payload = data[0]
    logging.debug(payload)

    payload_dict = json.loads(payload)

    payload_dict['response']['status'] = 201
    payload_dict['response']['body'] = "body was replaced by middleware"

    # now let' sleep for 2 seconds
    sleep(2)

    # returning new payload
    print(json.dumps(payload_dict))

if __name__ == "__main__":
    main()

Save this file with python extension, chmod +x it and run hoverfly:

normal./hoverfly --middleware "./this_file.py"
normal

How middleware interacts with different modes

Each mode is affected by middleware in a different way. Since the JSON payload has request and response structures, some middleware will not change anything. Some information about middleware behaviour:

  • Capture Mode: middleware affects only outgoing requests.
  • Virtualize Mode: middleware affects only responses (cache contents remain untouched).
  • Synthesize Mode: middleware creates responses.
  • Modify Mode: middleware affects requests and responses.

Debugging

You can supply "-v" flag to enable verbose logging.

License

Apache License version 2.0 See LICENSE for details.

(c) SpectoLabs 2015.