Skip to content

DeepfakeHTTP is a web server that uses HTTP dumps as a source for responses.

License

Notifications You must be signed in to change notification settings

xnbox/DeepfakeHTTP

Repository files navigation

DeepfakeHTTP
Your 100% static dynamic backend

What are people using it for?
  • Creating the product POC or demo before even starting out with the backend
  • REST, GraphQL, and other APIs prototyping and testing
  • Hiding critical enterprise infrastructure behind a simple static facade
  • Hacking and fine-tuning HTTP communications on both server and client sides

Get started

  1. Download the latest release of df.jar
  2. Copy-paste the content of the dump example to the file dump.txt:
    GET /api/customer/123 HTTP/1.1
    
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
        "id": 123,
        "fname": "John",
        "lname": "Doe",
        "email": ["john@example.com", "johndoe@example.com"]
    }
    
  3. Start the server from command line:
    java -jar df.jar dump.txt
    
  4. Use a browser to check whether the server is running: http://localhost:8080/api/customer/123
That's it! For more examples see: APPENDIX C.

Usage

java -jar df.jar [OPTIONS] [FLAGS] [COMMANDS] <file>...

OPTIONS:                                                           
    --port <number>        HTTP TCP port number, default: 8080
    --port-ssl <number>    HTTPS TCP port number, default: 8443
    --openapi-path <path>  serve OpenAPI client at specified context path
    --openapi-title <text> provide custom OpenAPI spec title
    --collect <file>       collect live request/response to file
    --data <file>          specify json/yaml data file to populate templates
    --format <json|yaml>   output format for --print-* commands, default: json

FLAGS:
    --no-log               disable request/response console logging
    --no-etag              disable ETag optimization
    --no-watch             disable watch files for changes
    --no-pretty            disable prettyprint for --print-* commands
    --redirect             redirect HTTP to HTTPS

COMMANDS:
    --help                 print help message
    --print-info           print dump files statistics to stdout as json/yaml
    --print-requests       print dump requests to stdout as json/yaml
    --print-openapi        print OpenAPI specification to stdout as json/yaml
                                                                              
️ARGS:
    <file>...               dump text file(s) and/or OpenAPI json/yaml file(s)

Usage Exampes

Start server on dump file:
java -jar df.jar dump.txt
Start server on OpenAPI file:
java -jar df.jar openapi.json
Start server with built-in OpenAPI client:
java -jar df.jar --openapi-path /api dump.txt
more examples…
Start server on few dump files:
java -jar df.jar dump1.txt dump2.txt dump3.txt
Start server on mix of dump and OpenAPI files:
java -jar df.jar dump1.txt openapi2.json dump3.txt openapi4.yaml
Provide custom OpenAPI spec title:
java -jar df.jar --openapi-path /api --openapi-title 'My Killer REST API v18.2.1' dump.txt

Prerequisites

  • Java 15 or above

How does it work?

  1. Got client request
  2. Search dump entries (request-response pairs) for appropriate entry by matching all specified request parts:
    method, URI, headers, and body
  3. If entry is found, the server generates a corresponded response and sends it to the client
  4. If entry is not found, the server search dump entries for response with status 400 (Bad request).
  5. If entry is found, the server send entry to the client
  6. If entry is not found, the server sends status 400 with no body.
That's all.  🎉🎉🎉

Features

  • No dependencies
  • No installation
  • No configuration files
  • Single-file executable
  • Built-in OpenAPI client

Supports:

  • Asynchronous requests and responses.
  • HTTP message formats (RFC 7230)
  • Unlimited number of request/response pairs in the dump
  • Scriptable response body
  • GET, HEAD, POST, PUT, DELETE etc.
  • Multi-line and multi-value headers (RFC 7230).
  • OpenAPI-styled templates in paths.
  • Wildcards ( * and ? with escape / ) in query string and header values.
  • Templates in response body
  • Response body fetching from external sources like URLs, local files, and data URI
  • Per entry user-defined request and response delays
  • Comments # in dumps
  • Live request/response collection
  • Optional watching dump files for changes
  • Optional ETag optimization
  • Optional live request/response logging
  • TLS(SSL) connections and HTTP to HTTPS redirect
  • Customizable OpenAPI client path
  • Latest OpenAPI specification (v3.0.3) in JSON and YAML format

License

The DeepfakeHTTP is released under the MIT license.




APPENDIX A.
Optional request headers (OpenAPI)

HeaderDescription
X-OpenAPI-Summary

OpenAPI request summary text.

Example:
HTTP/1.1 200 OK
Content-Type: application/json
X-OpenAPI-Summary: Get customer information

{"id": 5, "name": "John Doe"}
X-OpenAPI-Description

OpenAPI request description text.

Example:
HTTP/1.1 200 OK
Content-Type: application/json
X-OpenAPI-Summary: Get customer information
X-OpenAPI-Description: This API extracts customer info from db

{"id": 5, "name": "John Doe"}
X-OpenAPI-Tags

OpenAPI request comma-separated tag list.

Example:
HTTP/1.1 200 OK
Content-Type: application/json
X-OpenAPI-Summary: Get customer information
X-OpenAPI-Description: This API extracts customer info from db
X-OpenAPI-Tags: Work with customer, Buyers, Login info

{"id": 5, "name": "John Doe"}
NOTE: Optional request headers are used as OpenAPI annotations and will not be sent to the server engine.

APPENDIX B.
Optional response headers

Header Description
X-Body-Type

Tells the server what the content type (media type) of the body content actually is. Value of this header has same rules as value of standard HTTP Content-Type header.

This header is useful when you want to use binary data, template or script as a response body.

Examples:

A response body is a character data (default).
No X-Body-Type header is needed.

HTTP/1.1 200 OK
Content-Type: application/json

{"id": 5, "name": "John Doe"}

Get a response body from a remote server.
Body type is text/uri-list (RFC 2483)

HTTP/1.1 200 OK
Content-Type: application/json
X-Body-Type: text/uri-list

http://example.com/api/car/1234.json

Get a response body from a file.
Body type is text/uri-list (RFC 2483)

HTTP/1.1 200 OK
Content-Type: image/jpeg
X-Body-Type: text/uri-list

file:///home/john/photo.jpeg

Get a response body from a data URI.
Body type is text/uri-list (RFC 2483)

HTTP/1.1 200 OK
Content-Type: image/gif
X-Body-Type: text/uri-list

data:image/gif;base64,R0lGODlhAQABAIAAAP...

Get a response body from a template.
Body type is text/template. Useful for forms processing.

HTTP/1.1 200 OK
Content-Type: text/html
X-Body-Type: text/template

<!DOCTYPE html>
<html lang="en">
    <body>
        <h1>Hello, ${fname[0]} ${lname[0]}!</h1>
    </body>
</html>
X-Request-Delay

Request delay (in milliseconds).

Example:
# Two seconds request delay.

HTTP/1.1 200 OK
X-Request-Delay: 2000

{"id": 5, "name": "John Doe"}
X-Response-Delay

Response delay (in milliseconds).

Example:
# Two seconds response delay.

HTTP/1.1 200 OK
X-Response-Delay: 2000

{"id": 5, "name": "John Doe"}
NOTE: Optional response headers will not be sent to clients.

APPENDIX C.
Dump examples


Example 1.

# Comments are welcome! :)
# Please don't miss a single carriage return between headers and body!

GET /form.html HTTP/1.1

.
# Fake HTML file :)
HTTP/1.1 200 OK

<!DOCTYPE html>
<html lang="en">
<body>
    <form action="/add_user.php" method="POST">
        <label for="fname">First name:</label><input type="text" name="fname"><br><br>
        <label for="lname">Last name: </label><input type="text" name="lname"><br><br>
        <input type="submit" value="Submit">
    </form>
</body>
</html>
.

POST /add_user.php HTTP/1.1
Content-Type: application/x-www-form-urlencoded

.
# Fake PHP file :)
HTTP/1.1 200 OK
Content-Type: text/html
X-Body-Type: text/template

<!DOCTYPE html>
<html lang="en">
<body>
    <h1>Hello, ${fname[0]} ${lname[0]}!</h1>
</body>
</html>

Example 2.

#
# First request-response entry
#

# Client request
GET /api/customer/5 HTTP/1.1
Accept-Language: ru;*

.
# Server response
HTTP/1.1 200 OK
Content-Type: application/json

{
    "id": 5,
    "name": "Джон Доу"
}
.

#
# Second request-response entry
#

# Client request
GET /api/customer/5 HTTP/1.1

.
# Server response
HTTP/1.1 200 OK
Content-Type: application/json

{
    "id": 5,
    "name": "John Doe"
}

Example 3.

#
# Work with HTML forms (1)
#

GET /form.html HTTP/1.1

HTTP/1.1 200 OK

<!DOCTYPE html>
<html lang="en">
<body>
    <form action="/action_page.php" method="POST">
        <label for="fname">First name:</label><input type="text" name="fname"><br><br>
        <label for="lname">Last name: </label><input type="text" name="lname"><br><br>
        <input type="submit" value="Submit">
    </form>
</body>
</html>


POST /action_page.php HTTP/1.1
Content-Type: application/x-www-form-urlencoded

HTTP/1.1 200 OK
Content-Type: text/html
X-Body-Type: text/template

<!DOCTYPE html>
<html lang="en">
<body>
    <h1>Hello, ${fname[0]} ${lname[0]}!</h1>
</body>
</html>

Example 4.

#
# Work with HTML forms (2)
#

GET /form.html HTTP/1.1

HTTP/1.1 200 OK

<!DOCTYPE html>
<html lang="en">
<body>
    <form action="/action_page.php" method="POST">
        <label for="fname">First name:</label><input type="text" name="fname"><br><br>
        <label for="lname">Last name: </label><input type="text" name="lname"><br><br>
        <p>Only first name 'John' and last name 'Doe' are supported.<br>
        Expected output is: Hello, John Doe!,<br>
        or HTTP status 400 Bad request if first name is not 'John' or last name is not 'Doe'.
        </p><br><br>
        <input type="submit" value="Submit">
    </form>
</body>
</html>


POST /action_page.php HTTP/1.1
Content-Type: application/x-www-form-urlencoded

fname=John&lname=Doe

HTTP/1.1 200 OK
Content-Type: text/html
X-Body-Type: text/template

<!DOCTYPE html>
<body>
    <h1>Hello, ${fname[0]} ${lname[0]}!</h1>
</body>
</html>