General 31-May-2019 .NetRussell No comments

Accio – Summoning Fake Web Servers with Custom Responses

Accio – Summoning Fake Webservers with Custom Responses

So something that I seem to keep running into is, you’re working on some project and you need to build out some web request functionality. For what ever reason, you’re having trouble accessing an endpoint.

Maybe you don’t have an API key yet, or the endpoint is down, or maybe it’s a chicken and egg problem. You can’t make the request you want to and you’re trying to build out functionality that relies on prerequisite requests.

In the past I would have probably just spun up netcat real quick with an output file to return or even maybe just mocked the data in the application.

This approach isn’t wrong, it’s just not…. complete…. If you’re mocking data then that means your code is going to have to change at some point to implement the actual request call. Sure you can create fake services but it doesn’t really allow you to try out any asynchronous functionality unless you bake that into your fake service also. Sometimes I just wish I had a fake web endpoint that gave me what I wanted. That way, I could build my application exactly how I expect to build it, without all the testing code.

Accio

Accio is a simple python web server that allows you to quickly configure endpoints for testing. In just a few moments you can have an endpoint setup for your application to make calls to and all you need is python installed.

How To Use

First you’re going to want to head over to github and grab the code.

Once you have the code pulled down you just need to configure your config.json file and also write any responses you’ll need.

Let’s start with your config.json

At time of writing, this config only has one property called routes. The routes property is an array of route objects. Each route object is made of a url and a definition object. The url is the endpoint that you application will call to and your definition object is the path, the method and a delay that defines the response payload that Accio will send back.

{
        "routes" : [
                {
                        "url" : "/endpoint1",
                        "definition" : {
                                "filePath" : "./examples/endpoint1.json",
                                "method" : "GET",
                                "delay" : 5
                        }
                },
                {
                        "url" : "/endpoint1",
                        "definition" : {
                                "filePath" : "./examples/endpoint1_post.json",
                                "method" : "POST",
                                "delay" : 2
                        }
                },
                {
                        "url" : "/endpoint2",
                        "definition" : {
                                "filePath" : "./examples/endpoint2.json"

                        }
                }

        ]

}

Next you’ll need your response payload file. This can be anything. Just make sure that the path in your config.json file matches

So for my example, I will create one of my endpoint files, endpoint1.json

{ "test1" : "testValue" }

Finally, I can run the applications

python accio.py [config file path] [target localhost port] [calling port (because of CORS)]
python accio.py ./config.json 8080 4200

Now you’ll notice that not only did I pass in my config file, but also two other cli parameters. Those parameters are the port you want to listen on and the port that your application is running on locally.

(But wait … why do I need to pass the port my app is running on locally….)

GREAT QUESTION! Because of something called Cross Origin Resource Sharing (CORS) prevention. I know that Chrome has prevention enabled by default. To work around this, the Accio script injects an Access-Control-Allow-Origin header into the response which allows the content to be loaded.

I’m by no means an expert on CORS, please visit developer.mozilla.org to learn more about this.

Once you run the application you’ll have a working web server ready to call into!

~>$ python accio.py ./config.json 8080 4200

Server Listening On Port 8080
Press CTRL+C to stop the server
127.0.0.1 - - [31/May/2019 08:28:07] "GET /endpoint1 HTTP/1.1" 200 -
127.0.0.1 - - [31/May/2019 08:28:30] "GET /endpoint1 HTTP/1.1" 200 -
127.0.0.1 - - [31/May/2019 08:28:34] "GET /endpoint1 HTTP/1.1" 200 -
127.0.0.1 - - [31/May/2019 08:28:35] "GET /endpoint1 HTTP/1.1" 200 -
127.0.0.1 - - [31/May/2019 08:28:36] "GET /endpoint1 HTTP/1.1" 200 -

Wrapping up

I struggle to say this is version one of this application. There’s a lot of features I’d like to add to expand on it’s capabilities.

If you have ideas of things you’d like to see please feel free to hit me up or just create a pull request. I think there’s a lot of value in being able to spin up a fake intelligent web server quickly for testing against.

Leave a Reply

Your email address will not be published. Required fields are marked *