[
  {
    "path": ".clang-format",
    "content": "Language: Cpp\nBasedOnStyle: LLVM\n\nAccessModifierOffset: -2\nAlignConsecutiveMacros: true\nAllowAllArgumentsOnNextLine: false\nAllowAllParametersOfDeclarationOnNextLine: false\nAllowShortIfStatementsOnASingleLine: false\nBinPackArguments: false\nColumnLimit: 0\nContinuationIndentWidth: 2\nFixNamespaceComments: false\nIndentAccessModifiers: true\nIndentCaseLabels: true\nIndentPPDirectives: BeforeHash\nIndentWidth: 2\nNamespaceIndentation: All\nPointerAlignment: Left\nReferenceAlignment: Left\nTabWidth: 2\nUseTab: Never\nBreakBeforeBraces: Linux\nAllowShortLambdasOnASingleLine: All\nAlignAfterOpenBracket: DontAlign\n\n"
  },
  {
    "path": ".github/workflows/arduino.yml",
    "content": "name: Arduino Lint\n\non:\n  push:\n    branches: []\n  pull_request:\n    branches: []\n  schedule:\n    - cron: \"0 1 * * 6\" # Every Saturday at 1AM  \n\nconcurrency:\n  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}\n  cancel-in-progress: true\n    \njobs:\n  lint:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n      - uses: arduino/arduino-lint-action@v1\n        with:\n          library-manager: update\n          project-type: library\n          compliance: strict"
  },
  {
    "path": ".github/workflows/esp-idf.yml",
    "content": "name: ESP-IDF\n\non:\n  push:\n    branches: []\n  pull_request:\n    branches: []\n  schedule:\n    - cron: \"0 1 * * 6\" # Every Saturday at 1AM\n\nconcurrency:\n  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}\n  cancel-in-progress: true\n\njobs:\n\n  build:\n    name: \"ESP-IDF ${{ matrix.idf_ver }}\"\n    runs-on: ubuntu-latest\n    timeout-minutes: 10\n\n    strategy:\n      fail-fast: false\n      matrix:\n        idf_ver: [\"v4.4.8\", \"release-v5.5\"] # \"release-v6.0\" removed until arduino-esp32 v4.0 ships with ESP-IDF v6.0 support\n        idf_target: [\"esp32\", \"esp32s3\"]\n\n    steps:\n      - uses: actions/checkout@v4\n        with:\n          path: ${{ github.workspace }}/app\n\n      - name: Prepare Secret\n        run: cp ${{ github.workspace }}/app/examples/esp-idf/main/secret.h ${{ github.workspace }}/app/examples/esp-idf/main/_secret.h\n\n      - name: Compile\n        uses: espressif/esp-idf-ci-action@v1\n        with:\n          esp_idf_version: ${{ matrix.idf_ver }}\n          target: ${{ matrix.idf_target }}\n          path: app/examples/esp-idf\n          command: apt-get update && apt-get install -y python3-venv && idf.py build\n"
  },
  {
    "path": ".github/workflows/platformio.yml",
    "content": "name: Platform IO\n\non:\n  push:\n    branches: []\n  pull_request:\n    branches: []\n  schedule:\n    - cron: \"0 1 * * 6\" # Every Saturday at 1AM\n\nconcurrency:\n  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}\n  cancel-in-progress: true\n\njobs:\n  build:\n    name: \"pio:${{ matrix.board }}:${{ matrix.platform }}:${{ matrix.flags }}\"\n    runs-on: ubuntu-latest\n\n    strategy:\n      fail-fast: false\n      matrix:\n        flags: [\"-DPSY_ENABLE_SSL\", \"-DPSY_ENABLE_REGEX\"]\n        platform: [\n          \"stable\"\n        ]\n        board:\n          [\n            \"esp32dev\",\n            \"esp32-s2-saola-1\",\n            \"esp32-s3-devkitc-1\",\n            \"esp32-c3-devkitc-02\",\n            \"esp32-c6-devkitc-1\",\n          ]\n\n    steps:\n      - uses: actions/checkout@v4\n\n      - name: Cache PlatformIO\n        uses: actions/cache@v4\n        with:\n          key: ${{ runner.os }}-pio\n          path: |\n            ~/.cache/pip\n            ~/.platformio\n\n      - name: Set up Python\n        uses: actions/setup-python@v5\n        with:\n          python-version: \"3.13\"\n\n      - name: Install Platform IO\n        run: |\n          python -m pip install --upgrade pip\n          pip install --upgrade platformio\n\n      - name: Install Checked out PsychicHttp\n        run: pio lib -g install -f $GITHUB_WORKSPACE\n\n      - name: Prepare Secret\n        run: |\n          cd examples/platformio\n          cp src/secret.h src/_secret.h\n\n      - run: PIO_BOARD=${{ matrix.board }} PIO_PLATFORM=\"https://github.com/pioarduino/platform-espressif32/releases/download/${{ matrix.platform }}/platform-espressif32.zip\" PLATFORMIO_BUILD_FLAGS=\"${{ matrix.flags }}\" pio run -e ci\n"
  },
  {
    "path": ".github/workflows/release.yml",
    "content": "---\n\nname: Release to Platform IO and Arduino\n\non:\n  release:\n    types:\n      - released\n\njobs:\n  release_number:\n    name: Release Number Validation\n    runs-on: ubuntu-latest\n\n    steps:\n      ### Check the version number in the code matches the tag number\n      - uses: actions/checkout@v4\n\n      - name: Retrieve the version number(s)\n        run: |\n          TAG_VERSION=$(sed \"s/^v//\" <<< $GITHUB_REF_NAME)\n          PLATFORMIO_VERSION=$(jq \".version\" library.json -r)\n          ARDUINO_VERSION=$(awk -F= '/version/{gsub(/\"/, \"\", $2); print $2}' library.properties)\n          echo TAG_VERSION=$TAG_VERSION >> $GITHUB_ENV\n          echo PLATFORMIO_VERSION=$PLATFORMIO_VERSION >> $GITHUB_ENV\n          echo ARDUINO_VERSION=$ARDUINO_VERSION >> $GITHUB_ENV\n      - name: Check the version number is semver compliant\n        run: |\n          if ! [[ $TAG_VERSION =~ ^[0-9]+\\.[0-9]+\\.[0-9]+(-[a-z]*[0-9]+)?$ ]]; then\n            echo \"ERROR: The version number is not semver compliant\"\n            exit 1\n          fi\n      - name: Check the Platformio version matches the tag number\n        run: |\n          if [ \"$TAG_VERSION\" != \"$PLATFORMIO_VERSION\" ]; then\n            echo \"ERROR: The version number in library.json ($PLATFORMIO_VERSION) does not match the tag number ($TAG_VERSION)\"\n            exit 1\n          fi\n      - name: Check the Arduino version matches the tag number\n        run: |\n          if [ \"$TAG_VERSION\" != \"$ARDUINO_VERSION\" ]; then\n            echo \"ERROR: The version number in library.properties ($ARDUINO_VERSION) does not match the tag number ($TAG_VERSION)\"\n            exit 1\n          fi\n\n  release_to_platformio:\n    name: Release to PlatformIO Registry\n    runs-on: ubuntu-latest\n    needs: release_number\n\n    steps:\n      - uses: actions/checkout@v4\n\n      - name: Set up Python\n        uses: actions/setup-python@v4\n\n      - name: Install Platform IO\n        run: |\n          pip install -U platformio\n          platformio update\n\n      - name: Register new library version\n        run: |\n          PLATFORMIO_AUTH_TOKEN=${{ secrets.PLATFORMIO_AUTH_TOKEN }} pio pkg publish --type library --no-interactive --notify\n"
  },
  {
    "path": ".gitignore",
    "content": "_secret.h\n.$request flow.drawio.bkp\n.$request flow.drawio.dtmp\n.clang_complete\n.gcc-flags.json\n.pio\n.pioenvs\n.pioenvs\n.piolibdeps\n.vscode/.browse.c_cpp.db*\n.vscode/c_cpp_properties.json\n.vscode/ipch\n.vscode/launch.json\n.vscode/settings.json\n*.a\n*.app\n*.dll\n*.dylib\n*.exe\n*.gch\n*.la\n*.lai\n*.lib\n*.lo\n*.mod\n*.o\n*.obj\n*.opensdf\n*.out\n*.pch\n*.sdf\n*.slo\n*.so\n*.suo\n**.DS_Store\n**.pio\n**.vscode\n/build\n/psychic-http-loadtest.log\n/psychic-websocket-loadtest.log\nbenchmark/_psychic-http-loadtest.json\nbenchmark/.~lock.comparison.ods#\nbenchmark/http-loadtest-results.csv\nbenchmark/node_modules\nbenchmark/package-lock.json\nbenchmark/psychic-http-loadtest.log\nbenchmark/psychic-websocket-loadtest.json\nbenchmark/psychic-websocket-loadtest.log\nbenchmark/websocket-loadtest-results.csv\nexamples/arduino/\nexamples/platformio/lib/PsychicHttp\nexamples/websockets/lib/PsychicHttp\nsrc/cookie.txt\nsrc/secret.h\nVisual\\ Micro"
  },
  {
    "path": ".gitmodules",
    "content": "[submodule \"examples/esp-idf/components/ArduinoJson\"]\n\tpath = examples/esp-idf/components/ArduinoJson\n\turl = https://github.com/bblanchon/ArduinoJson\n\tbranch = 7.x\n[submodule \"examples/esp-idf/components/arduino-esp32\"]\n\tpath = examples/esp-idf/components/arduino-esp32\n\turl = https://github.com/espressif/arduino-esp32\n\tbranch = idf-release/v4.4\n[submodule \"examples/esp-idf/components/esp_littlefs\"]\n\tpath = examples/esp-idf/components/esp_littlefs\n\turl = https://github.com/joltwallet/esp_littlefs.git\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "## 2.2.0\n\n- fix: memory leaks — add PsychicEndpoint destructor to delete handler; removeEndpoint/removeHandler/removeRewrite now delete removed objects; reset() deletes middleware chain\n- fix: stale endpoint state — removeEndpoint now cleans up _esp_idf_endpoints so WebSocket entries are properly unregistered across server restarts\n- fix: HTTPS server now syncs max_uri_handlers and stack_size from config before starting (both were silently ignored before)\n- fix: path traversal attack blocked in static file handler (#security)\n- fix: redirect response code was initialized wrong, breaking redirects (#239)\n- fix: correct integer comparisons in indexOf() checks, char overflow in auth buffer, and format specifiers for size_t\n- fix: urlDecode bounds-checks before reading past a trailing %\n- fix: regex URI matching now catches invalid patterns instead of crashing\n- fix: closeCallback guards against null handler before calling checkForClosedClient\n- fix: improper delegation call in PsychicJSONResponse\n- feat: removed urlencode external dependency — pulled into repository as src/UrlEncode.cpp\n- feat: replaced WiFi.h/ETH.h dependencies with generic esp_netif API; isConnected(), ON_STA_FILTER, and ON_AP_FILTER now work on all interface types including ESP32-P4\n- feat: esp_netif compatibility — use esp_netif_next loop for older ESP-IDF versions (#235)\n- feat: added warning when registering WebSocket handler after start() call (#233)\n- feat: ESP-IDF v5.5 support added; v6.0 removed pending Arduino support\n- fix: NTP/DHCP handling for ESP-IDF\n- examples: increased stack size to fix multipart file upload issues; added start() call to HTTPS redirect server example\n\n## 2.1.3\n\n- fix: Added getParams() to access all parameters from issue #236\n\n## 2.1.2\n\n- fix: close _file before PsychicFileResponse to prevent LittleFS remove() failure\n\n## 2.1.1\n\n- Re-added deleted MAX function per #230\n\n## 2.1.0 (since 2.0.0)\n\n- send to all clients, not bail on the first one.\n- Fix issue whereby H2 encoding ignores method and defaults to HTTP_GET. (#202)\n- now using the stable version of pioarduino.\n- V2 dev rollup: update PsychicFileResponse (set status and content type before chunked responses), fix getCookie, and add pong reply to ping. (#228, #207, #209, #222)\n- Update async_worker.cpp to fix compatibility with Arduino ESP32 3.3.0. (#225)\n- fixed a mistake from the pull merge.\n- Moved setting content type and response code into sendHeaders(). (PR #220)\n- Check if content size is 0 before sending a response. (#218)\n- Fix crash with Event Source and update CI / IDF examples. (#221)\n- fixed EventSource error with missing headers (content type, cache-control, keep-alive).\n- fixed the CI to use the latest stable versions.\n- ugh. CI so annoying.\n- bump to v2.1.0.\n\n\n# v2.0\n\nI apologize for sitting on this release for so long.  Its been almost a year and life just sort of got away from me.  I'd like to get this release out and then start working through the backlog of issues.  v2.0 has been very stable for me, so it's more than time to release it.\n\n* Huge amount of work was done to add MiddleWare and some more under the hood updates\n* Modified the request handling to bring initial url matching and filtering into PsychicHttpServer itself.\n    * Fixed a bug with filter() where endpoint is matched, but filter fails and it doesn't continue matching further endpoints on same uri (checks were in different codebases)\n    * HTTP_ANY support\n    * unlimited endpoints (no more need to manually set config.max_uri_handlers)\n    * much more flexibility for future\n* Endpoint Matching Updates\n    * Endpoint matching functions can be set on server level (```server.setURIMatchFunction()```) or endpoint level (```endpoint.setURIMatchFunction()```)\n    * Added convenience macros MATCH_SIMPLE, MATCH_WILDCARD, and MATCH_REGEX\n    * Added regex matching of URIs, enable it with define PSY_ENABLE_REGEX\n    * On regex matched requests, you can get match data with request->getRegexMatches()\n* Ported URL rewrite functionality from ESPAsyncWS\n\n## Changes required from v1.x to v2.0:\n\n* add a ```server.begin()``` or ```server.start()``` after all your ```server.on()``` calls\n* remove any calls to ```config.max_uri_handlers```\n* if you are using a custom ```server.config.uri_match_fn``` to match uris, change it to ```server.setURIMatchFunction()```\n\n# v1.2.1\n\n* Fix bug with missing include preventing the HTTPS server from compiling.\n\n# v1.2\n\n* Added TemplatePrinter from https://github.com/Chris--A/PsychicHttp/tree/templatePrint\n* Support using as ESP IDF component\n* Optional using https server in ESP IDF\n* Fixed bug with headers\n* Add ESP IDF example + CI script\n* Added Arduino Captive Portal example and OTAUpdate from @06GitHub\n* HTTPS fix for ESP-IDF v5.0.2+ from @06GitHub\n* lots of bugfixes from @mathieucarbou\n\nThanks to @Chris--A, @06GitHub, and @dzungpv for your contributions.\n\n# v1.1\n\n* Changed the internal structure to support request handlers on endpoints and generic requests that do not match an endpoint\n    * websockets, uploads, etc should now create an appropriate handler and attach to an endpoint with the server.on() syntax\n* Added PsychicClient to abstract away some of the internals of ESP-IDF sockets + add convenience\n    * onOpen and onClose callbacks have changed as a result\n* Added support for EventSource / SSE\n* Added support for multipart file uploads\n* changed getParam() to return a PsychicWebParameter in line with ESPAsyncWebserver\n* Renamed various classes / files:\n    * PsychicHttpFileResponse -> PsychicFileResponse\n    * PsychicHttpServerEndpoint -> PsychicEndpoint\n    * PsychicHttpServerRequest -> PsychicRequest\n    * PsychicHttpServerResponse -> PsychicResponse\n    * PsychicHttpWebsocket.h -> PsychicWebSocket.h\n    * Websocket => WebSocket\n* Quite a few bugfixes from the community. Thank you @glennsky, @gb88, @KastanEr, @kstam, and @zekageri"
  },
  {
    "path": "CMakeLists.txt",
    "content": "set(COMPONENT_SRCDIRS\n    \"src\"\n)\n\nset(COMPONENT_ADD_INCLUDEDIRS\n    \"src\"\n)\n\nset(COMPONENT_REQUIRES\n    \"arduino-esp32\"\n    \"esp_https_server\"\n    \"arduinojson\"\n)\n\nregister_component()\n\ntarget_compile_definitions(${COMPONENT_TARGET} PUBLIC -DESP32)\ntarget_compile_options(${COMPONENT_TARGET} PRIVATE -fno-rtti)\n"
  },
  {
    "path": "LICENSE",
    "content": "Copyright (c) 2024 Jeremy Poulter, Zachary Smith, and Mathieu Carbou\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
  },
  {
    "path": "README.md",
    "content": "# PsychicHttp - HTTP on your ESP 🧙🔮\n\nPsychicHttp is a webserver library for ESP32 + Arduino framework which uses the [ESP-IDF HTTP Server](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/protocols/esp_http_server.html) library under the hood.  It is written in a similar style to the [Arduino WebServer](https://github.com/espressif/arduino-esp32/tree/master/libraries/WebServer), [ESPAsyncWebServer](https://github.com/me-no-dev/ESPAsyncWebServer), and [ArduinoMongoose](https://github.com/jeremypoulter/ArduinoMongoose) libraries to make writing code simple and porting from those other libraries straightforward.\n\n**Discord**: [https://discord.gg/TAQrTR3f9C](https://discord.gg/TAQrTR3f9C)\n\n# Features\n\n* Asynchronous approach (server runs in its own FreeRTOS thread)\n* Handles all HTTP methods with lots of convenience functions:\n    * GET/POST parameters\n    * get/set headers\n    * get/set cookies\n    * basic key/value session data storage\n    * authentication (basic and digest mode)\n* HTTPS / SSL support\n* Static fileserving (SPIFFS, LittleFS, etc.)\n* Chunked response serving for large files\n* File uploads (Basic + Multipart)\n* Websocket support with onOpen, onFrame, and onClose callbacks\n* EventSource / SSE support with onOpen, and onClose callbacks\n* Request filters, including Client vs AP mode (ON_STA_FILTER / ON_AP_FILTER)\n* Middleware system (logging, authentication, CORS, and custom)\n* URL rewriting\n* Regex URI matching\n* JSON request/response support (via ArduinoJson)\n* TemplatePrinter class for dynamic variables at runtime\n\n## Differences from ESPAsyncWebserver\n\n* No templating system (anyone actually use this?)\n\n# Usage\n\n## Installation\n\n### Platformio\n\n[PlatformIO](http://platformio.org) is an open source ecosystem for IoT development.\n\n Add \"PsychicHttp\" to project using [Project Configuration File `platformio.ini`](http://docs.platformio.org/page/projectconf.html) and [lib_deps](http://docs.platformio.org/page/projectconf/section_env_library.html#lib-deps) option:\n\n```ini\n[env:myboard]\nplatform = espressif...\nboard = ...\nframework = arduino\n\n# using the latest stable version\nlib_deps = hoeken/PsychicHttp\n\n# or using GIT Url (the latest development version)\nlib_deps = https://github.com/hoeken/PsychicHttp\n```\n\n### Installation - Arduino\n\nOpen *Tools -> Manage Libraries...* and search for PsychicHttp.\n\n# Principles of Operation\n\n## Things to Note\n\n* PsychicHttp is a fully asynchronous server and as such does not run on the loop thread.\n* You should not use yield or delay or any function that uses them inside the callbacks.\n* The server is smart enough to know when to close the connection and free resources.\n* You can not send more than one response to a single request.\n\n## PsychicHttp\n\n* Listens for connections.\n* Wraps the incoming request into PsychicRequest.\n* Keeps track of clients + calls optional callbacks on client open and close.\n* Find the appropriate handler (if any) for a request and pass it on.\n\n## Request Life Cycle\n\n* TCP connection is received by the server.\n* HTTP request is wrapped inside ```PsychicRequest``` object + TCP Connection wrapped inside PsychicConnection object.\n* When the request head is received, the server goes through all ```PsychicEndpoints``` and finds one that matches the url + method.\n    * ```handler->filter()``` and ```handler->canHandle()``` are called on the handler to verify the handler should process the request.\n    * Any middleware attached to the server or endpoint is run in order.\n    * ```handler->handleRequest()``` is called to actually process the HTTP request.\n* If the handler cannot process the request, the server will loop through any global handlers and call that handler if it passes filter(), canHandle(), and middleware.\n* If no global handlers are called, the server.onNotFound handler will be called.\n* Each handler is responsible for processing the request and sending a response.\n* When the response is sent, the client is closed and freed from the memory.\n    * Unless its a special handler like websockets or eventsource.\n\n![Flowchart of Request Lifecycle](/assets/request-flow.svg)\n\n### Handlers\n\n* ```PsychicHandler``` is used for processing and responding to specific HTTP requests.\n* ```PsychicHandler``` instances can be attached to any endpoint or as global handlers.\n* Setting a ```Filter``` to the ```PsychicHandler``` controls when to apply the handler, decision can be based on\n  request method, url, request host/port/target host, the request client's localIP or remoteIP.\n* Two filter callbacks are provided: ```ON_AP_FILTER``` to execute the rewrite when request is made to the AP interface,\n  ```ON_STA_FILTER``` to execute the rewrite when request is made to the STA interface.\n* The ```canHandle``` method is used for handler specific control on whether the requests can be handled. Decision can be based on request method, request url, request host/port/target host.\n* Depending on how the handler is implemented, it may provide callbacks for adding your own custom processing code to the handler.\n* Global ```Handlers``` are evaluated in the order they are attached to the server. The ```canHandle``` is called only\n  if the ```Filter``` that was set to the ```Handler``` return true.\n* The first global ```Handler``` that can handle the request is selected, no further processing of handlers is called.\n\n![Flowchart of Request Lifecycle](/assets/handler-callbacks.svg)\n\n### Responses and how do they work\n\n* The ```PsychicResponse``` objects are used to send the response data back to the client.\n* Typically the response should be fully generated and sent from the callback.\n* It may be possible to generate the response outside the callback, but it will be difficult.\n   * The exceptions are websockets + eventsource where the response is sent, but the connection is maintained and new data can be sent/received outside the handler.\n\n# Porting From ESPAsyncWebserver\n\nIf you have existing code using ESPAsyncWebserver, you will feel right at home with PsychicHttp.  Even if internally it is much different, the external interface is very similar.  Some things are mostly cosmetic, like different class names and callback definitions.  A few things might require a bit more in-depth approach.  If you're porting your code and run into issues that aren't covered here, please post an issue.\n\n## Globals Stuff\n\n* Change your #include to ```#include <PsychicHttp.h>```\n* Change your server instance: ```PsychicHttpServer server;```\n* Define websocket handler if you have one: ```PsychicWebSocketHandler websocketHandler;```\n* Define eventsource if you have one: ```PsychicEventSource eventSource;```\n\n## setup() Stuff\n\n* add your handlers and call `server.start()` at the end\n* server now supports unlimited endpoints — no need to set `config.max_uri_handlers`\n* check your callback function definitions:\n   * All request callbacks now take two parameters: `PsychicRequest *request` and `PsychicResponse *response`\n   * `AsyncWebServerRequest` -> `PsychicRequest`\n   * no more onBody() event\n      * for small bodies (up to `MAX_REQUEST_BODY_SIZE`, default 16k) it will be automatically loaded and accessed by `request->body()`\n      * for large bodies, use an upload handler and `onUpload()`\n   * websocket callbacks are much different (and simpler!)\n   * websocket / eventsource handlers get attached to url in `server.on(\"/url\", &handler)` instead of passing url to handler constructor\n   * eventsource callbacks are onOpen and onClose now\n\n## Requests / Responses\n\n* `request->send` is now `response->send()`\n* if you create a response, call `response->send()` directly, not `request->send(reply)`\n* `request->headers()` is not supported by ESP-IDF, you have to just check for the header you need\n* No `request->beginResponse()`. Instantiate a `PsychicResponse` instead: ```PsychicResponse response(request);```\n* No PROGMEM support (it's not relevant to ESP32: https://esp32.com/viewtopic.php?t=20595)\n* No Stream response support just yet\n\n# Usage\n\n## Create the Server\n\nHere is an example of the typical server setup:\n\n```cpp\n#include <PsychicHttp.h>\nPsychicHttpServer server;\n\nvoid setup()\n{\n   //connect to wifi\n\n   //optional: set default headers on every response\n   DefaultHeaders::Instance().addHeader(\"Server\", \"PsychicHttp\");\n\n   //call server methods to attach endpoints and handlers\n   server.on(...);\n   server.serveStatic(...);\n\n   //call start at the end.  you can add/remove handlers after, except for websockets.\n   server.start();\n}\n```\n\n## Add Handlers\n\nOne major difference from ESPAsyncWebserver is that handlers can be attached to a specific url (endpoint) or as a global handler.  The reason for this, is that attaching to a specific URL is more efficient and makes for cleaner code.\n\n### Endpoint Handlers\n\nAn endpoint is basically just the URL path (eg. /path/to/file) without any query string.  The ```server.on(...)``` function is a convenience function for creating endpoints and attaching a handler to them.  There are two main styles: attaching a basic ```WebRequest``` handler and attaching an external handler.\n\n```cpp\n//creates a basic PsychicWebHandler that calls the request_callback callback\nserver.on(\"/url\", HTTP_GET, request_callback);\n\n//same as above, but defaults to HTTP_GET\nserver.on(\"/url\", request_callback);\n\n//attaches a websocket handler to /ws\nPsychicWebSocketHandler websocketHandler;\nserver.on(\"/ws\", &websocketHandler);\n\n//handle any HTTP method on a URL\nserver.on(\"/any\", HTTP_ANY, request_callback);\n```\n\nThe ```server.on(...)``` returns a pointer to the endpoint, which can be used to call various functions like ```setHandler()```, ```addFilter()```, ```addMiddleware()```, and ```setURIMatchFunction()```.\n\n```cpp\n//respond to /url only from requests to the AP\nserver.on(\"/url\", HTTP_GET, request_callback)->addFilter(ON_AP_FILTER);\n\n//add middleware to a specific endpoint\nserver.on(\"/secure\", HTTP_GET, request_callback)->addMiddleware(&authMiddleware);\n\n//set the URI matching function on a specific endpoint\nserver.on(\"/simple\", HTTP_GET, request_callback)->setURIMatchFunction(MATCH_SIMPLE);\n\n//attach websocket handler to /ws\nPsychicWebSocketHandler websocketHandler;\nserver.on(\"/ws\")->setHandler(&websocketHandler);\n```\n\n### Basic Requests\n\nThe ```PsychicWebHandler``` class is for handling standard web requests.  It provides a single callback: ```onRequest()```.  This callback is called when the handler receives a valid HTTP request.\n\nOne major difference from ESPAsyncWebserver is that this callback needs to return an esp_err_t variable to let the server know the result of processing the request.  The ```response->send()``` function will return this.  It is a good habit to return the result of these functions as sending the response will close the connection.\n\nThe function definition for the onRequest callback is:\n\n```cpp\nesp_err_t function_name(PsychicRequest *request, PsychicResponse *response);\n```\n\nHere is a simple example that sends back the client's IP on the URL /ip\n\n```cpp\nserver.on(\"/ip\", [](PsychicRequest *request, PsychicResponse *response)\n{\n   String output = \"Your IP is: \" + request->client()->remoteIP().toString();\n   return response->send(output.c_str());\n});\n```\n\n`PsychicWebHandler` also has `onOpen()` and `onClose()` callbacks to track connections to a specific endpoint:\n\n```cpp\nPsychicWebHandler *handler = new PsychicWebHandler();\nhandler->onRequest([](PsychicRequest *request, PsychicResponse *response) {\n  return response->send(\"OK\");\n});\nhandler->onOpen([](PsychicClient *client) {\n  Serial.printf(\"[handler] connection #%u connected from %s\\n\", client->socket(), client->remoteIP().toString().c_str());\n});\nhandler->onClose([](PsychicClient *client) {\n  Serial.printf(\"[handler] connection #%u closed\\n\", client->socket());\n});\nserver.on(\"/handler\", handler);\n```\n\n### Uploads\n\nThe ```PsychicUploadHandler``` class is for handling uploads, both large POST bodies and multipart encoded forms.  It provides two callbacks: ```onUpload()``` and ```onRequest()```.\n\n```onUpload(...)``` is called when there is new data.  This function may be called multiple times so that you can process the data in chunks. The function definition for the onUpload callback is:\n\n```cpp\nesp_err_t function_name(PsychicRequest *request, const String& filename, uint64_t index, uint8_t *data, size_t len, bool final);\n```\n\n* request is a pointer to the Request object\n* filename is the name of the uploaded file\n* index is the overall byte position of the current data\n* data is a pointer to the data buffer\n* len is the length of the data buffer\n* final is a flag to tell if its the last chunk of data\n\n```onRequest(...)``` is called after the successful handling of the upload.  Its definition and usage is the same as the basic request example as above.\n\n#### Basic Upload (file is the entire POST body)\n\nIt's worth noting that there is no standard way of passing in a filename for this method, so the handler attempts to guess the filename with the following methods:\n\n* Checking the Content-Disposition header\n* Checking the _filename query parameter (eg. /upload?filename=filename.txt becomes filename.txt)\n* Checking the url and taking the last part as filename (eg. /upload/filename.txt becomes filename.txt).  You must set a wildcard url for this to work as in the example below.\n\n```cpp\n//handle a very basic upload as post body\n PsychicUploadHandler *uploadHandler = new PsychicUploadHandler();\n uploadHandler->onUpload([](PsychicRequest *request, const String& filename, uint64_t index, uint8_t *data, size_t len, bool last) {\n   File file;\n   String path = \"/www/\" + filename;\n\n   Serial.printf(\"Writing %d/%d bytes to: %s\\n\", (int)index+(int)len, request->contentLength(), path.c_str());\n\n   if (last)\n     Serial.printf(\"%s is finished. Total bytes: %llu\\n\", path.c_str(), (uint64_t)index+(uint64_t)len);\n\n   //our first call?\n   if (!index)\n     file = LittleFS.open(path, FILE_WRITE);\n   else\n     file = LittleFS.open(path, FILE_APPEND);\n   \n   if(!file) {\n     Serial.println(\"Failed to open file\");\n     return ESP_FAIL;\n   }\n\n   if(!file.write(data, len)) {\n     Serial.println(\"Write failed\");\n     return ESP_FAIL;\n   }\n\n   return ESP_OK;\n });\n\n //gets called after upload has been handled\n uploadHandler->onRequest([](PsychicRequest *request, PsychicResponse *response)\n {\n   String url = \"/\" + request->getFilename();\n   String output = \"<a href=\\\"\" + url + \"\\\">\" + url + \"</a>\";\n\n   return response->send(output.c_str());\n });\n\n //wildcard basic file upload - POST to /upload/filename.ext\n server.on(\"/upload/*\", HTTP_POST, uploadHandler);\n```\n\n#### Multipart Upload\n\nVery similar to the basic upload, with 2 key differences:\n\n* multipart requests don't know the total size of the file until after it has been fully processed.  You can get a rough idea with request->contentLength(), but that is the length of the entire multipart encoded request.\n* you can access form variables, including multipart file info (name + size) in the onRequest handler using request->getParam()\n\n```cpp\n //a little bit more complicated multipart form\n PsychicUploadHandler *multipartHandler = new PsychicUploadHandler();\n multipartHandler->onUpload([](PsychicRequest *request, const String& filename, uint64_t index, uint8_t *data, size_t len, bool last) {\n   File file;\n   String path = \"/www/\" + filename;\n\n   //some progress over serial.\n   Serial.printf(\"Writing %d bytes to: %s\\n\", (int)len, path.c_str());\n   if (last)\n     Serial.printf(\"%s is finished. Total bytes: %llu\\n\", path.c_str(), (uint64_t)index+(uint64_t)len);\n\n   //our first call?\n   if (!index)\n     file = LittleFS.open(path, FILE_WRITE);\n   else\n     file = LittleFS.open(path, FILE_APPEND);\n   \n   if(!file) {\n     Serial.println(\"Failed to open file\");\n     return ESP_FAIL;\n   }\n\n   if(!file.write(data, len)) {\n     Serial.println(\"Write failed\");\n     return ESP_FAIL;\n   }\n\n   return ESP_OK;\n });\n\n //gets called after upload has been handled\n multipartHandler->onRequest([](PsychicRequest *request, PsychicResponse *response)\n {\n   PsychicWebParameter *file = request->getParam(\"file_upload\");\n\n   String url = \"/\" + file->value();\n   String output;\n\n   output += \"<a href=\\\"\" + url + \"\\\">\" + url + \"</a><br/>\\n\";\n   output += \"Bytes: \" + String(file->size()) + \"<br/>\\n\";\n   output += \"Param 1: \" + request->getParam(\"param1\")->value() + \"<br/>\\n\";\n   output += \"Param 2: \" + request->getParam(\"param2\")->value() + \"<br/>\\n\";\n   \n   return response->send(output.c_str());\n });\n\n //upload to /multipart url\n server.on(\"/multipart\", HTTP_POST, multipartHandler);\n```\n\n### Static File Serving\n\nThe ```PsychicStaticFileHandler``` is a special handler that does not provide any callbacks.  It is used to serve a file or files from a specific directory in a filesystem to a directory on the webserver.  The syntax is exactly the same as ESPAsyncWebserver. Anything that is derived from the ```FS``` class should work (eg. SPIFFS, LittleFS, SD, etc)\n\nA couple important notes:\n\n* If it finds a file with an extra .gz extension, it will serve it as gzip encoded (eg: /targetfile.ext -> {targetfile.ext}.gz)\n* If the file is larger than FILE_CHUNK_SIZE (default 8kb) then it will send it as a chunked response.\n* It will detect most basic filetypes and automatically set the appropriate Content-Type\n\nThe ```server.serveStatic()``` function handles creating the handler and assigning it to the server:\n\n```cpp\n//serve static files from LittleFS/www on / only to clients on same wifi network\n//this is where our /index.html file lives\nserver.serveStatic(\"/\", LittleFS, \"/www/\")->addFilter(ON_STA_FILTER);\n\n//serve static files from LittleFS/www-ap on / only to clients on SoftAP\n//this is where our /index.html file lives\nserver.serveStatic(\"/\", LittleFS, \"/www-ap/\")->addFilter(ON_AP_FILTER);\n\n//serve static files from LittleFS/img on /img\n//it's more efficient to serve everything from a single www directory, but this is also possible.\nserver.serveStatic(\"/img\", LittleFS, \"/img/\");\n\n//you can also serve single files\nserver.serveStatic(\"/myfile.txt\", LittleFS, \"/custom.txt\");\n\n//set cache control headers\nserver.serveStatic(\"/\", LittleFS, \"/www/\")->setCacheControl(\"max-age=60\");\n```\n\nYou could also theoretically use the file response directly:\n\n```cpp\nserver.on(\"/ip\", [](PsychicRequest *request, PsychicResponse *response)\n{\n   String filename = \"/path/to/file\";\n   PsychicFileResponse fileResponse(request, LittleFS, filename);\n\n   return fileResponse.send();\n});\n```\n\n### Websockets\n\nThe ```PsychicWebSocketHandler``` class is for handling WebSocket connections.  It provides 3 callbacks:\n\n```onOpen(...)``` is called when a new WebSocket client connects.\n```onFrame(...)``` is called when a new WebSocket frame has arrived.\n```onClose(...)``` is called when a new WebSocket client disconnects.\n\nHere are the callback definitions:\n\n```cpp\nvoid open_function(PsychicWebSocketClient *client);\nesp_err_t frame_function(PsychicWebSocketRequest *request, httpd_ws_frame *frame);\nvoid close_function(PsychicWebSocketClient *client);\n```\n\nWebSockets were the main reason for starting PsychicHttp, so they are well tested.  They are also much simplified from the ESPAsyncWebserver style.  You do not need to worry about error handling, partial frame assembly, PONG messages, etc.  The onFrame() function is called when a complete frame has been received, and can handle frames up to the entire available heap size.\n\nHere is a basic example of using WebSockets:\n\n```cpp\n //create our handler... note this should be located as a global or somewhere it wont go out of scope and be destroyed.\n PsychicWebSocketHandler websocketHandler;\n\n websocketHandler.onOpen([](PsychicWebSocketClient *client) {\n   Serial.printf(\"[socket] connection #%u connected from %s\\n\", client->socket(), client->remoteIP().toString().c_str());\n   client->sendMessage(\"Hello!\");\n });\n\n websocketHandler.onFrame([](PsychicWebSocketRequest *request, httpd_ws_frame *frame) {\n     Serial.printf(\"[socket] #%d sent: %s\\n\", request->client()->socket(), (char *)frame->payload);\n     return request->reply(frame);\n });\n\n websocketHandler.onClose([](PsychicWebSocketClient *client) {\n   Serial.printf(\"[socket] connection #%u closed from %s\\n\", client->socket(), client->remoteIP().toString().c_str());\n });\n\n //attach the handler to /ws.  You can then connect to ws://ip.address/ws\n //NOTE: the handler must be registered before server.start() is called, otherwise it will not work.\n server.on(\"/ws\", &websocketHandler);\n```\n\nThe onFrame() callback has 2 parameters:\n\n* ```PsychicWebSocketRequest *request``` a special request with helper functions for replying in websocket format.\n* ```httpd_ws_frame *frame``` ESP-IDF websocket struct.  The important struct members we care about are:\n   * ```uint8_t *payload; /*!< Pre-allocated data buffer */```\n   * ```size_t len; /*!< Length of the WebSocket data */```\n \nFor sending data on the websocket connection, there are 3 methods:\n\n* ```request->reply()``` - only available in the onFrame() callback context.\n* ```webSocketHandler.sendAll()``` - can be used anywhere to send websocket messages to all connected clients.\n* ```client->sendMessage()``` - can be used anywhere* to send a websocket message to a specific client\n\nAll of the above functions either accept a simple ```char *``` string or you can pass a constructed ```httpd_ws_frame```.\n\n*Special Note:*  Do not hold on to the ```PsychicWebSocketClient``` for sending messages to clients outside the callbacks. That pointer is destroyed when a client disconnects.  Instead, store the ```int client->socket()```.  Then when you want to send a message, use this code:\n\n```cpp\n//make sure our client is still connected.\nPsychicWebSocketClient *client = websocketHandler.getClient(socket);\nif (client != NULL)\n  client->sendMessage(\"Your Message\");\n```\n\n### EventSource / SSE\n\nThe ```PsychicEventSource``` class is for handling EventSource / SSE connections.  It provides 2 callbacks:\n\n```onOpen(...)``` is called when a new EventSource client connects.\n```onClose(...)``` is called when a new EventSource client disconnects.\n\nHere are the callback definitions:\n\n```cpp\nvoid open_function(PsychicEventSourceClient *client);\nvoid close_function(PsychicEventSourceClient *client);\n```\n\nHere is a basic example of using PsychicEventSource:\n\n```cpp\n //create our handler... note this should be located as a global or somewhere it wont go out of scope and be destroyed.\n PsychicEventSource eventSource;\n\n eventSource.onOpen([](PsychicEventSourceClient *client) {\n   Serial.printf(\"[eventsource] connection #%u connected from %s\\n\", client->socket(), client->remoteIP().toString().c_str());\n   client->send(\"Hello user!\", NULL, millis(), 1000);\n });\n\n eventSource.onClose([](PsychicEventSourceClient *client) {\n   Serial.printf(\"[eventsource] connection #%u closed from %s\\n\", client->socket(), client->remoteIP().toString().c_str());\n });\n\n //attach the handler to /events\n server.on(\"/events\", &eventSource);\n```\n\nFor sending data on the EventSource connection, there are 2 methods:\n\n* ```eventSource.send()``` - can be used anywhere to send events to all connected clients.\n* ```client->send()``` - can be used anywhere* to send events to a specific client\n\nAll of the above functions accept a simple ```char *``` message, and optionally: ```char *``` event name, id, and reconnect time.\n\n*Special Note:*  Do not hold on to the ```PsychicEventSourceClient``` for sending messages to clients outside the callbacks. That pointer is destroyed when a client disconnects.  Instead, store the ```int client->socket()```.  Then when you want to send a message, use this code:\n\n```cpp\n//make sure our client is still connected.\nPsychicEventSourceClient *client = eventSource.getClient(socket);\nif (client != NULL)\n  client->send(\"Your Event\");\n```\n\n### JSON\n\nPsychicHttp has built-in support for JSON via ArduinoJson.  There are two ways to use it:\n\n#### JSON Request Callback\n\nThe simplest approach is to use the `PsychicJsonRequestCallback` signature directly with `server.on()`.  The JSON body is parsed automatically and passed as a `JsonVariant`:\n\n```cpp\nserver.on(\"/api\", HTTP_POST, [](PsychicRequest *request, PsychicResponse *resp, JsonVariant &json) {\n  JsonObject input = json.as<JsonObject>();\n\n  PsychicJsonResponse response(resp);\n  JsonObject output = response.getRoot();\n  output[\"status\"] = \"success\";\n  output[\"millis\"] = millis();\n\n  if (input.containsKey(\"foo\"))\n    output[\"foo\"] = input[\"foo\"];\n\n  return response.send();\n});\n```\n\n#### JSON Response\n\nUse `PsychicJsonResponse` to build and send a JSON response from any handler:\n\n```cpp\nserver.on(\"/json\", HTTP_GET, [](PsychicRequest *request, PsychicResponse *response) {\n  PsychicJsonResponse jsonResponse(response);\n  JsonObject root = jsonResponse.getRoot();\n  root[\"status\"] = \"ok\";\n  root[\"millis\"] = millis();\n  return jsonResponse.send();\n});\n```\n\n### Middleware\n\nPsychicHttp has a middleware system that allows you to run code before and after a request is handled.  Middleware can be attached to the server (runs on every request) or to a specific endpoint.\n\nThe `PsychicMiddlewareNext` function must be called to pass the request to the next middleware or handler:\n\n```cpp\nesp_err_t run(PsychicRequest *request, PsychicResponse *response, PsychicMiddlewareNext next);\n```\n\n#### Built-in Middleware\n\nThree built-in middleware classes are included:\n\n**LoggingMiddleware** - logs requests in a curl-like format:\n\n```cpp\nLoggingMiddleware loggingMiddleware;\nloggingMiddleware.setOutput(Serial);\nserver.addMiddleware(&loggingMiddleware);\n```\n\n**AuthenticationMiddleware** - handles HTTP Basic or Digest authentication:\n\n```cpp\nAuthenticationMiddleware auth;\nauth.setUsername(\"admin\");\nauth.setPassword(\"admin\");\nauth.setRealm(\"My App\");\nauth.setAuthMethod(HTTPAuthMethod::BASIC_AUTH);   // or DIGEST_AUTH\nauth.setAuthFailureMessage(\"You must log in.\");\n\n//attach to the whole server\nserver.addMiddleware(&auth);\n\n//or attach to a specific endpoint\nserver.on(\"/secure\", HTTP_GET, [](PsychicRequest *request, PsychicResponse *response) {\n  return response->send(\"Authenticated!\");\n})->addMiddleware(&auth);\n```\n\n**CorsMiddleware** - adds CORS headers for cross-origin requests:\n\n```cpp\nCorsMiddleware corsMiddleware;\n//optional customization (defaults shown)\ncorsMiddleware.setOrigin(\"*\");\ncorsMiddleware.setMethods(\"*\");\ncorsMiddleware.setHeaders(\"*\");\ncorsMiddleware.setAllowCredentials(true);\ncorsMiddleware.setMaxAge(86400);\n\nserver.addMiddleware(&corsMiddleware);\n```\n\n#### Custom Middleware\n\nYou can write custom middleware by either subclassing `PsychicMiddleware` or by using a lambda:\n\n```cpp\nserver.addMiddleware([](PsychicRequest *request, PsychicResponse *response, PsychicMiddlewareNext next) {\n  Serial.printf(\"Before: %s\\n\", request->path().c_str());\n  esp_err_t ret = next(request, response);\n  Serial.printf(\"After: %d\\n\", response->getCode());\n  return ret;\n});\n```\n\n### URL Rewriting\n\nPsychicHttp supports URL rewriting, which allows you to map one URL to another before the request is matched to a handler:\n\n```cpp\n//rewrite /rewrite to /api?foo=rewrite\nserver.rewrite(\"/rewrite\", \"/api?foo=rewrite\");\n\n//rewrites can also have filters\nserver.rewrite(\"/mobile\", \"/mobile-index.html\")->setFilter(ON_AP_FILTER);\n```\n\n### URI Matching\n\nPsychicHttp supports three URI matching modes that can be set at the server level or per-endpoint:\n\n* `MATCH_SIMPLE` - exact string matching\n* `MATCH_WILDCARD` - ESP-IDF wildcard matching (e.g., `/files/*`)\n* `MATCH_REGEX` - regular expression matching (requires `PSY_ENABLE_REGEX` define)\n\n```cpp\n//set default for all endpoints\nserver.setURIMatchFunction(MATCH_WILDCARD);\n\n//or set per-endpoint\nserver.on(\"/files/*\", HTTP_GET, handler)->setURIMatchFunction(MATCH_WILDCARD);\n```\n\n#### Regex URI Matching\n\nTo use regex matching, add `#define PSY_ENABLE_REGEX` before including PsychicHttp, or define it in your build flags.  Then use `MATCH_REGEX` as the URI match function and capture groups via `request->getRegexMatches()`:\n\n```cpp\nserver.on(\"^/user/([\\\\w]+)/?$\", HTTP_GET, [](PsychicRequest *request, PsychicResponse *response) {\n  std::smatch matches;\n  if (request->getRegexMatches(matches)) {\n    String username = matches.str(1).c_str();\n    return response->send((\"Hello \" + username).c_str());\n  }\n  return response->send(404, \"text/plain\", \"Not found\");\n})->setURIMatchFunction(MATCH_REGEX);\n```\n\n### Default Headers\n\nYou can set headers that will be automatically added to every response:\n\n```cpp\nDefaultHeaders::Instance().addHeader(\"Server\", \"PsychicHttp\");\nDefaultHeaders::Instance().addHeader(\"X-Custom-Header\", \"value\");\n```\n\n### HTTPS / SSL\n\nPsychicHttp supports HTTPS / SSL out of the box, however there are some limitations (see performance below).  Enabling it also increases the code size by about 100kb.\n\nSSL connections require significant RAM — each TLS session consumes roughly 40–100KB of internal RAM plus two 16KB record buffers.  **A board with PSRAM is strongly recommended**, and PSRAM must be enabled in your project configuration (see below).  Without PSRAM, you will likely be limited to a single simultaneous SSL connection before the heap is exhausted.\n\nTo use HTTPS, you need to modify your setup like so:\n\n```cpp\n#include <PsychicHttp.h>\n#include <PsychicHttpsServer.h>\nPsychicHttpsServer server;\nserver.setCertificate(server_cert, server_key);\n```\n\n```server_cert``` and ```server_key``` are both ```const char *``` parameters which contain the server certificate and private key, respectively.\n\nTo generate your own key and self signed certificate, you can use the command below:\n\n```\nopenssl req -x509 -newkey rsa:4096 -nodes -keyout server.key -out server.crt -sha256 -days 365\n```\n\nYou can also generate a self-signed certificate directly on the ESP32 at runtime using mbedTLS, which is already bundled with ESP-IDF.  This is useful for devices that need a unique certificate without any external tooling — generate once on first boot, store the PEM strings to NVS or LittleFS, and load them on every subsequent boot.  An example implementation can be found [here](https://github.com/hoeken/YarrboardFramework/blob/34be5c9457355a5e0dcdc0afacca9e2907cfab03/src/controllers/HTTPController.cpp#L328).\n\nIncluding the ```PsychicHttpsServer.h``` also defines ```PSY_ENABLE_SSL``` which you can use in your code to allow enabling / disabling calls in your code based on if the HTTPS server is available:\n\n```cpp\n//our main server object\n#ifdef PSY_ENABLE_SSL\n  PsychicHttpsServer server;\n#else\n  PsychicHttpServer server;\n#endif\n```\n\nLast, but not least, you can create a separate HTTP server on port 80 that redirects all requests to the HTTPS server:\n\n```cpp\n//this creates a 2nd server listening on port 80 and redirects all requests HTTPS\nPsychicHttpServer *redirectServer = new PsychicHttpServer();\nredirectServer->config.ctrl_port = 20420; // just a random port different from the default one\nredirectServer->config.stack_size = 4096; // we dont need a large stack size for this.\nredirectServer->onNotFound([](PsychicRequest *request, PsychicResponse *response) {\n   String url = \"https://\" + request->host() + request->url();\n   return response->redirect(url.c_str());\n});\nredirectServer->start();\n```\n\n#### Enabling PSRAM for SSL\n\nTo offload mbedTLS allocations to PSRAM and avoid exhausting internal heap under multiple SSL connections, add the following to your project.  The example below targets an **ESP32-S3-WROOM-1-N16R8** (8 MB OPI PSRAM) but the mbedTLS options apply to any ESP32 variant with PSRAM.\n\n`sdkconfig.defaults`:\n```\n# Enable OPI PSRAM (8MB on ESP32-S3-WROOM-1-N16R8).\n# board_build.arduino.memory_type = qio_opi selects the right bootloader/linker,\n# but IDF still needs these Kconfig options to actually map PSRAM into the heap.\nCONFIG_SPIRAM=y\nCONFIG_SPIRAM_MODE_OCT=y\nCONFIG_SPIRAM_SPEED_80M=y\nCONFIG_SPIRAM_USE_MALLOC=y\n\n# Move mbedTLS dynamic allocations to PSRAM.\n# Without this, each TLS session chews ~40-100KB of internal RAM plus two 16KB\n# record buffers, exhausting internal heap when multiple clients connect.\n# Has no effect on targets without SPIRAM (CONFIG_MBEDTLS_EXTERNAL_MEM_ALLOC\n# depends on SPIRAM in Kconfig, so it is silently ignored on C3/C5/C6/esp32).\nCONFIG_MBEDTLS_EXTERNAL_MEM_ALLOC=y\n\n# Use asymmetric record buffer sizes: full 16KB in (needed for receiving TLS\n# records from browsers) but only 4KB out (sufficient for JSON API responses).\n# Saves ~24KB of PSRAM per session vs the default symmetric 32KB allocation.\nCONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y\nCONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384\nCONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096\n```\n\n`platformio.ini`:\n```ini\nbuild_flags = -D BOARD_HAS_PSRAM\n```\n\n# TemplatePrinter\n\n**This is not specific to PsychicHttp, and it works with any `Print` object. You could for example, template data out to `File`, `Serial`, etc...**.\n\nThe template engine is a `Print` interface and can be printed to directly, however,  if you are just templating a few short strings, I'd probably just use `response.printf()` instead. **Its benefit will be seen when templating large inputs such as files.**\n\nOne benefit may be **templating a **JSON** file avoiding the need to use ArduinoJson.**\n\nBefore closing the underlying `Print`/`Stream` that this writes to, it must be flushed as small amounts of data can be buffered. A convenience method to take care of this is shows in `example 3`.\n\nThe header file is not currently added to `PsychicHttp.h` and users will have to add it manually:\n\n```C++\n#include <TemplatePrinter.h>\n```\n \n## Template parameter definition:\n\n- Must start and end with a preset delimiter, the default is `%`\n- Can only contain `a-z`, `A-Z`, `0-9`, and `_`\n- Maximum length of 63 characters (buffer is 64 including `null`).\n- A parameter must not be zero length (not including delimiters).\n- Spaces or any other character do not match as a parameter, and will be output as is.\n- Valid examples\n  - `%MY_PARAM%`\n  - `%SOME1%`\n- **Invalid** examples\n  - `%MY PARAM%`\n  - `%SOME1 %`\n  - `%UNFINISHED`\n  - `%%`\n\n## Template processing\nA function or lambda is used to receive the parameter replacement.\n\n```C++\nbool templateHandler(Print &output, const char *param){\n  //...\n}\n\n[](Print &output, const char *param){\n  //...\n}\n```\n\nParameters:\n- `Print &output` - the underlying `Print`, print the results of templating to this.\n- `const char *param` - a string containing the current parameter.\n\nThe handler must return a `bool`.\n- `true`: the parameter was handled, continue as normal.\n- `false`: the input detected as a parameter is not, print literal.\n\nSee output in **example 1** regarding the effects of returning `true` or `false`.\n\n## Template input handler\nThis is not needed unless using the static convenience function `TemplatePrinter::start()`. See **example 3**.\n\n```C++\nbool inputHandler(TemplatePrinter &printer){\n  //...\n}\n\n[](TemplatePrinter &printer){\n  //...\n}\n```\n\nParameters:\n- `TemplatePrinter &printer` - The template engine, print your template text to this for processing.\n\n\n## Example 1 - Simple use with `PsychicStreamResponse`:\nThis example highlights its most basic usage.\n\n```C++\n\n//  Function to handle parameter requests.\n\nbool templateHandler(Print &output, const char *param){\n\n  if(strcmp(param, \"FREE_HEAP\") == 0){\n    output.print((double)ESP.getFreeHeap() / 1024.0, 2);\n\n  }else if(strcmp(param, \"MIN_FREE_HEAP\") == 0){\n    output.print((double)ESP.getMinFreeHeap() / 1024.0, 2);\n\n  }else if(strcmp(param, \"MAX_ALLOC_HEAP\") == 0){\n    output.print((double)ESP.getMaxAllocHeap() / 1024.0, 2);\n    \n  }else if(strcmp(param, \"HEAP_SIZE\") == 0){\n    output.print((double)ESP.getHeapSize() / 1024.0, 2);\n  }else{\n    return false;\n  }\n  output.print(\"Kb\");\n  return true;\n}\n\n//  Example serving a request\nserver.on(\"/template\", [](PsychicRequest *request, PsychicResponse *response) {\n  PsychicStreamResponse streamResponse(request, \"text/plain\");\n\n  streamResponse.beginSend();\n  \n  TemplatePrinter printer(streamResponse, templateHandler);\n\n  printer.println(\"My ESP has %FREE_HEAP% left. Its lifetime minimum heap is %MIN_FREE_HEAP%.\");\n  printer.println(\"The maximum allocation size is %MAX_ALLOC_HEAP%, and its total size is %HEAP_SIZE%.\");\n  printer.println(\"This is an unhandled parameter: %UNHANDLED_PARAM% and this is an invalid param %INVALID PARAM%.\");\n  printer.println(\"This line finished with %UNFIN\");\n  printer.flush();\n\n  return streamResponse.endSend();\n});   \n```\n\nThe output for example looks like:\n```\nMy ESP has 170.92Kb left. Its lifetime minimum heap is 169.83Kb.\nThe maximum allocation size is 107.99Kb, and its total size is 284.19Kb.\nThis is an unhandled parameter: %UNHANDLED_PARAM% and this is an invalid param %INVALID PARAM%.\nThis line finished with %UNFIN\n```\n\n## Example 2 - Templating a file\n\n```C++\nserver.on(\"/home\", [](PsychicRequest *request, PsychicResponse *response) {\n  PsychicStreamResponse streamResponse(request, \"text/html\");\n  File file = SD.open(\"/www/index.html\");\n\n  streamResponse.beginSend();\n\n  TemplatePrinter printer(streamResponse, templateHandler);\n\n  printer.copyFrom(file);\n  printer.flush();\n  file.close();\n\n  return streamResponse.endSend();\n}); \n```\n\n## Example 3 - Using the `TemplatePrinter::start` method.\nThis static method allows an RAII approach, allowing you to template a stream, etc... without needing a `flush()`. The function call is laid out as:\n\n```C++\nTemplatePrinter::start(host_stream, template_handler, input_handler);\n```\n\n\\*these examples use the `templateHandler` function defined in example 1.\n\n### Serve a file like example 2\n```C++\nserver.on(\"/home\", [](PsychicRequest *request, PsychicResponse *response) {\n  PsychicStreamResponse streamResponse(request, \"text/html\");\n  File file = SD.open(\"/www/index.html\");\n\n  streamResponse.beginSend();\n  TemplatePrinter::start(streamResponse, templateHandler, [&file](TemplatePrinter &printer){\n    printer.copyFrom(file);\n  });\n  file.close();\n\n  return streamResponse.endSend();\n});\n```\n\n### Template a string like example 1\n```C++\nserver.on(\"/template2\", [](PsychicRequest *request, PsychicResponse *response) {\n\n  PsychicStreamResponse streamResponse(request, \"text/plain\");\n\n  streamResponse.beginSend();\n\n  TemplatePrinter::start(streamResponse, templateHandler, [](TemplatePrinter &printer){\n    printer.println(\"My ESP has %FREE_HEAP% left. Its lifetime minimum heap is %MIN_FREE_HEAP%.\");\n    printer.println(\"The maximum allocation size is %MAX_ALLOC_HEAP%, and its total size is %HEAP_SIZE%.\");\n    printer.println(\"This is an unhandled parameter: %UNHANDLED_PARAM% and this is an invalid param %INVALID PARAM%.\");\n  });\n\n  return streamResponse.endSend();\n});\n```\n\n# Performance\n\nIn order to really see the differences between libraries, I created some basic benchmark firmwares for PsychicHttp, ESPAsyncWebserver, and ArduinoMongoose.  I then ran the loadtest-http.sh and loadtest-websocket.sh scripts against each firmware to get some real numbers on the performance of each server library.  All of the code and results are available in the /benchmark folder.  If you want to see the collated data and graphs, there is a [LibreOffice spreadsheet](/benchmark/comparison.ods).\n\n![Performance graph](/benchmark/performance.png)\n![Latency graph](/benchmark/latency.png)\n\n## HTTPS / SSL\n\nYes, PsychicHttp supports SSL out of the box, but there are a few caveats:\n\n* SSL connections are memory-intensive — each TLS session consumes roughly 40–100KB of internal RAM plus two 16KB record buffers.  On a board without PSRAM, a blank PsychicHttp sketch has around 150KB free, which limits you to 1–2 simultaneous SSL connections.  **A board with PSRAM is strongly recommended** for any production HTTPS use.  See the [Enabling PSRAM for SSL](#enabling-psram-for-ssl) section above for the required `sdkconfig.defaults` and `platformio.ini` settings to route mbedTLS allocations to PSRAM.\n* Speed and latency are still pretty good (see graph above) but the SSH handshake seems to take 1500ms.  With websockets or browser its not an issue since the connection is kept alive, but if you are loading requests in another way it will be a bit slow\n* Unless you want to expose your ESP to the internet, you are limited to self signed keys and the annoying browser security warnings that come with them.\n\n## Analysis\n\nThe results clearly show some of the reasons for writing PsychicHttp: ESPAsyncWebserver crashes under heavy load on each test, across the board in a 60s test.  That means in normal usage, you're just rolling the dice with how long it will go until it crashes.  Every other number is moot, IMHO.\n\nArduinoMongoose doesn't crash under heavy load, but it does bog down with extremely high latency (15s) for web requests and appears to not even respond at the highest loadings as the loadtest script crashes instead.  The code itself doesnt crash, so bonus points there.  After the high load, it does go back to serving normally.  One area ArduinoMongoose does shine, is in websockets where its performance is almost 2x the performance of PsychicHttp.  Both in requests per second and latency.  Clearly an area of improvement for PsychicHttp.\n\nPsychicHttp has good performance across the board.  No crashes and continously responds during each test.  It is a clear winner in requests per second when serving files from memory, dynamic JSON, and has consistent performance when serving files from LittleFS. The only real downside is the lower performance of the websockets with a single connection handling 38rps, and maxing out at 120rps across multiple connections.\n\n## Takeaways\n\nWith all due respect to @me-no-dev who has done some amazing work in the open source community, I cannot recommend anyone use the ESPAsyncWebserver for anything other than simple projects that don't need to be reliable.  Even then, PsychicHttp has taken the arcane api of the ESP-IDF web server library and made it nice and friendly to use with a very similar API to ESPAsyncWebserver.  Also, ESPAsyncWebserver is more or less abandoned, with 150 open issues, 77 pending pull requests, and the last commit in over 2 years.\n\nArduinoMongoose is a good alternative, although the latency issues when it gets fully loaded can be very annoying. I believe it is also cross platform to other microcontrollers as well, but I haven't tested that. The other issue here is that it is based on an old version of a modified Mongoose library that will be difficult to update as it is a major revision behind and several security updates behind as well.  Big thanks to @jeremypoulter though as PsychicHttp is a fork of ArduinoMongoose so it's built on strong bones.\n\n# Community / Support\n\nThe best way to get support is probably with Github issues.  There is also a [Discord chat](https://discord.gg/CM5abjGG) that is pretty active.\n\n# Roadmap\n\n## Longterm Wants\n\n* investigate websocket performance gap\n* Enable worker based multithreading with esp-idf v5.x\n* 100-continue support?\n     \nIf anyone wants to take a crack at implementing any of the above features I am more than happy to accept pull requests.\n"
  },
  {
    "path": "RELEASE.md",
    "content": "* Update CHANGELOG\n* Bump version in src/PsychicVersion.h\n* Bump version in library.json\n* Bump version in library.properties\n* Bump version in idf_component.yml\n* Make new release + tag\n\t* this will get pulled in automatically by Arduino Library Indexer\n\t* Platformio automatically publishes on release via .github hook"
  },
  {
    "path": "benchmark/arduinomongoose/.gitignore",
    "content": ".pio\n.vscode/\n.vscode/.browse.c_cpp.db*\n.vscode/c_cpp_properties.json\n.vscode/launch.json\n.vscode/ipch\n"
  },
  {
    "path": "benchmark/arduinomongoose/include/README",
    "content": "\nThis directory is intended for project header files.\n\nA header file is a file containing C declarations and macro definitions\nto be shared between several project source files. You request the use of a\nheader file in your project source file (C, C++, etc) located in `src` folder\nby including it, with the C preprocessing directive `#include'.\n\n```src/main.c\n\n#include \"header.h\"\n\nint main (void)\n{\n ...\n}\n```\n\nIncluding a header file produces the same results as copying the header file\ninto each source file that needs it. Such copying would be time-consuming\nand error-prone. With a header file, the related declarations appear\nin only one place. If they need to be changed, they can be changed in one\nplace, and programs that include the header file will automatically use the\nnew version when next recompiled. The header file eliminates the labor of\nfinding and changing all the copies as well as the risk that a failure to\nfind one copy will result in inconsistencies within a program.\n\nIn C, the usual convention is to give header files names that end with `.h'.\nIt is most portable to use only letters, digits, dashes, and underscores in\nheader file names, and at most one dot.\n\nRead more about using header files in official GCC documentation:\n\n* Include Syntax\n* Include Operation\n* Once-Only Headers\n* Computed Includes\n\nhttps://gcc.gnu.org/onlinedocs/cpp/Header-Files.html\n"
  },
  {
    "path": "benchmark/arduinomongoose/lib/README",
    "content": "\nThis directory is intended for project specific (private) libraries.\nPlatformIO will compile them to static libraries and link into executable file.\n\nThe source code of each library should be placed in a an own separate directory\n(\"lib/your_library_name/[here are source files]\").\n\nFor example, see a structure of the following two libraries `Foo` and `Bar`:\n\n|--lib\n|  |\n|  |--Bar\n|  |  |--docs\n|  |  |--examples\n|  |  |--src\n|  |     |- Bar.c\n|  |     |- Bar.h\n|  |  |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html\n|  |\n|  |--Foo\n|  |  |- Foo.c\n|  |  |- Foo.h\n|  |\n|  |- README --> THIS FILE\n|\n|- platformio.ini\n|--src\n   |- main.c\n\nand a contents of `src/main.c`:\n```\n#include <Foo.h>\n#include <Bar.h>\n\nint main (void)\n{\n  ...\n}\n\n```\n\nPlatformIO Library Dependency Finder will find automatically dependent\nlibraries scanning project source files.\n\nMore information about PlatformIO Library Dependency Finder\n- https://docs.platformio.org/page/librarymanager/ldf.html\n"
  },
  {
    "path": "benchmark/arduinomongoose/platformio.ini",
    "content": "; PlatformIO Project Configuration File\n;\n;   Build options: build flags, source filter\n;   Upload options: custom upload port, speed and extra flags\n;   Library options: dependencies, extra library storages\n;   Advanced options: extra scripting\n;\n; Please visit documentation for the other options and examples\n; https://docs.platformio.org/page/projectconf.html\n\n[env]\nplatform = espressif32\nframework = arduino\nboard = esp32dev\nmonitor_speed = 115200\nmonitor_filters = esp32_exception_decoder\nlib_deps = \n    jeremypoulter/ArduinoMongoose\n    bblanchon/ArduinoJson\nboard_build.filesystem = littlefs\n\n[env:default]"
  },
  {
    "path": "benchmark/arduinomongoose/src/main.cpp",
    "content": "/* Wi-Fi STA Connect and Disconnect Example\n\n   This example code is in the Public Domain (or CC0 licensed, at your option.)\n\n   Unless required by applicable law or agreed to in writing, this\n   software is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n   CONDITIONS OF ANY KIND, either express or implied.\n\n*/\n#include <Arduino.h>\n#include <ArduinoJSON.h>\n#include <LittleFS.h>\n#include <MongooseCore.h>\n#include <MongooseHttpServer.h>\n#include <WiFi.h>\n\nconst char* ssid = \"\";\nconst char* password = \"\";\n\nMongooseHttpServer server;\n\nconst char* htmlContent = R\"(\n<!DOCTYPE html>\n<html>\n<head>\n    <title>Sample HTML</title>\n</head>\n<body>\n    <h1>Hello, World!</h1>\n    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod\n    rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper\n    arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit\n    accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.\n    Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo\n    dapibus elit, id varius sem dui id lacus.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod\n    rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper\n    arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit\n    accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.\n    Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo\n    dapibus elit, id varius sem dui id lacus.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod\n    rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper\n    arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit\n    accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.\n    Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo\n    dapibus elit, id varius sem dui id lacus.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod\n    rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper\n    arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit\n    accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.\n    Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo\n    dapibus elit, id varius sem dui id lacus.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod\n    rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper\n    arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit\n    accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.\n    Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo\n    dapibus elit, id varius sem dui id lacus.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod\n    rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper\n    arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit\n    accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.\n    Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo\n    dapibus elit, id varius sem dui id lacus.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod\n    rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper\n    arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit\n    accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.\n    Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo\n    dapibus elit, id varius sem dui id lacus.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod\n    rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper\n    arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit\n    accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.\n    Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo\n    dapibus elit, id varius sem dui id lacus.</p>\n</body>\n</html>\n)\";\n\nbool connectToWifi()\n{\n  Serial.println();\n  Serial.print(\"[WiFi] Connecting to \");\n  Serial.println(ssid);\n\n  WiFi.setSleep(false);\n  WiFi.useStaticBuffers(true);\n\n  WiFi.begin(ssid, password);\n\n  // Will try for about 10 seconds (20x 500ms)\n  int tryDelay = 500;\n  int numberOfTries = 20;\n\n  // Wait for the WiFi event\n  while (true)\n  {\n    switch (WiFi.status())\n    {\n      case WL_NO_SSID_AVAIL:\n        Serial.println(\"[WiFi] SSID not found\");\n        break;\n      case WL_CONNECT_FAILED:\n        Serial.print(\"[WiFi] Failed - WiFi not connected! Reason: \");\n        return false;\n        break;\n      case WL_CONNECTION_LOST:\n        Serial.println(\"[WiFi] Connection was lost\");\n        break;\n      case WL_SCAN_COMPLETED:\n        Serial.println(\"[WiFi] Scan is completed\");\n        break;\n      case WL_DISCONNECTED:\n        Serial.println(\"[WiFi] WiFi is disconnected\");\n        break;\n      case WL_CONNECTED:\n        Serial.println(\"[WiFi] WiFi is connected!\");\n        Serial.print(\"[WiFi] IP address: \");\n        Serial.println(WiFi.localIP());\n        return true;\n        break;\n      default:\n        Serial.print(\"[WiFi] WiFi Status: \");\n        Serial.println(WiFi.status());\n        break;\n    }\n    delay(tryDelay);\n\n    if (numberOfTries <= 0)\n    {\n      Serial.print(\"[WiFi] Failed to connect to WiFi!\");\n      // Use disconnect function to force stop trying to connect\n      WiFi.disconnect();\n      return false;\n    }\n    else\n    {\n      numberOfTries--;\n    }\n  }\n\n  return false;\n}\n\nvoid setup()\n{\n  Serial.begin(115200);\n  delay(10);\n  Serial.println(\"ArduinoMongoose Benchmark\");\n\n  // We start by connecting to a WiFi network\n  // To debug, please enable Core Debug Level to Verbose\n  if (connectToWifi())\n  {\n    if (!LittleFS.begin())\n    {\n      Serial.println(\"LittleFS Mount Failed. Do Platform -> Build Filesystem Image and Platform -> Upload Filesystem Image from VSCode\");\n      return;\n    }\n\n    // start our server\n    Mongoose.begin();\n    server.begin(80);\n\n    // index file\n    server.on(\"/\", HTTP_GET, [](MongooseHttpServerRequest* request)\n              { request->send(200, \"text/html\", htmlContent); });\n\n    // api - parameters passed in via query eg. /api/endpoint?foo=bar\n    server.on(\"/api\", HTTP_GET, [](MongooseHttpServerRequest* request)\n              {\n      //create a response object\n      StaticJsonDocument<128> output;\n      output[\"msg\"] = \"status\";\n      output[\"status\"] = \"success\";\n      output[\"millis\"] = millis();\n\n      //work with some params\n      if (request->hasParam(\"foo\"))\n      {\n        String foo = request->getParam(\"foo\");\n        output[\"foo\"] = foo;\n      }\n\n      //serialize and return\n      String jsonBuffer;\n      serializeJson(output, jsonBuffer);\n      request->send(200, \"application/json\", jsonBuffer.c_str()); });\n\n    // websocket\n    server.on(\"/ws$\")->onFrame([](MongooseHttpWebSocketConnection* connection, int flags, uint8_t* data, size_t len)\n                               {\n                                 connection->send(WEBSOCKET_OP_TEXT, data, len);\n                                 // server.sendAll(connection, (char *)data);\n                               });\n\n    // hack - no servestatic\n    server.on(\"/alien.png\", HTTP_GET, [](MongooseHttpServerRequest* request)\n              {\n      //open our file\n      File fp = LittleFS.open(\"/www/alien.png\");\n      size_t length = fp.size();\n\n      //read our data\n      uint8_t * data = (uint8_t *)malloc(length);\n      if (data != NULL)\n      {\n        fp.readBytes((char *)data, length);\n\n        //send it off\n        MongooseHttpServerResponseBasic *response = request->beginResponse();\n        response->setContent(data, length);\n        response->setContentType(\"image/png\");\n        response->setCode(200);\n        request->send(response);\n\n        //free the memory\n        free(data);\n      }\n      else\n        request->send(503); });\n  }\n}\n\nvoid loop()\n{\n  Mongoose.poll(1000);\n}"
  },
  {
    "path": "benchmark/arduinomongoose/test/README",
    "content": "\nThis directory is intended for PlatformIO Test Runner and project tests.\n\nUnit Testing is a software testing method by which individual units of\nsource code, sets of one or more MCU program modules together with associated\ncontrol data, usage procedures, and operating procedures, are tested to\ndetermine whether they are fit for use. Unit testing finds problems early\nin the development cycle.\n\nMore information about PlatformIO Unit Testing:\n- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html\n"
  },
  {
    "path": "benchmark/espasyncwebserver/.gitignore",
    "content": ".pio\n.vscode/\n.vscode/.browse.c_cpp.db*\n.vscode/c_cpp_properties.json\n.vscode/launch.json\n.vscode/ipch\n"
  },
  {
    "path": "benchmark/espasyncwebserver/include/README",
    "content": "\nThis directory is intended for project header files.\n\nA header file is a file containing C declarations and macro definitions\nto be shared between several project source files. You request the use of a\nheader file in your project source file (C, C++, etc) located in `src` folder\nby including it, with the C preprocessing directive `#include'.\n\n```src/main.c\n\n#include \"header.h\"\n\nint main (void)\n{\n ...\n}\n```\n\nIncluding a header file produces the same results as copying the header file\ninto each source file that needs it. Such copying would be time-consuming\nand error-prone. With a header file, the related declarations appear\nin only one place. If they need to be changed, they can be changed in one\nplace, and programs that include the header file will automatically use the\nnew version when next recompiled. The header file eliminates the labor of\nfinding and changing all the copies as well as the risk that a failure to\nfind one copy will result in inconsistencies within a program.\n\nIn C, the usual convention is to give header files names that end with `.h'.\nIt is most portable to use only letters, digits, dashes, and underscores in\nheader file names, and at most one dot.\n\nRead more about using header files in official GCC documentation:\n\n* Include Syntax\n* Include Operation\n* Once-Only Headers\n* Computed Includes\n\nhttps://gcc.gnu.org/onlinedocs/cpp/Header-Files.html\n"
  },
  {
    "path": "benchmark/espasyncwebserver/lib/README",
    "content": "\nThis directory is intended for project specific (private) libraries.\nPlatformIO will compile them to static libraries and link into executable file.\n\nThe source code of each library should be placed in a an own separate directory\n(\"lib/your_library_name/[here are source files]\").\n\nFor example, see a structure of the following two libraries `Foo` and `Bar`:\n\n|--lib\n|  |\n|  |--Bar\n|  |  |--docs\n|  |  |--examples\n|  |  |--src\n|  |     |- Bar.c\n|  |     |- Bar.h\n|  |  |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html\n|  |\n|  |--Foo\n|  |  |- Foo.c\n|  |  |- Foo.h\n|  |\n|  |- README --> THIS FILE\n|\n|- platformio.ini\n|--src\n   |- main.c\n\nand a contents of `src/main.c`:\n```\n#include <Foo.h>\n#include <Bar.h>\n\nint main (void)\n{\n  ...\n}\n\n```\n\nPlatformIO Library Dependency Finder will find automatically dependent\nlibraries scanning project source files.\n\nMore information about PlatformIO Library Dependency Finder\n- https://docs.platformio.org/page/librarymanager/ldf.html\n"
  },
  {
    "path": "benchmark/espasyncwebserver/platformio.ini",
    "content": "; PlatformIO Project Configuration File\n;\n;   Build options: build flags, source filter\n;   Upload options: custom upload port, speed and extra flags\n;   Library options: dependencies, extra library storages\n;   Advanced options: extra scripting\n;\n; Please visit documentation for the other options and examples\n; https://docs.platformio.org/page/projectconf.html\n\n[env]\nplatform = espressif32\nframework = arduino\n; board = esp32dev\nboard = esp32-s3-devkitc-1\nupload_port = /dev/ttyACM0\nmonitor_port = /dev/ttyACM1\nmonitor_speed = 115200\nmonitor_filters = esp32_exception_decoder\n\nlib_compat_mode = strict\nlib_ldf_mode = chain\nlib_deps =\n  ; mathieucarbou/AsyncTCP @ 3.2.10\n  https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip\n  mathieucarbou/ESPAsyncWebServer @ 3.3.16\n  bblanchon/ArduinoJson\nlib_ignore =\n  AsyncTCP\n  mathieucarbou/AsyncTCP\n\nboard_build.filesystem = littlefs\nbuild_flags =\n  -D CONFIG_ASYNC_TCP_MAX_ACK_TIME=3000\n  -D CONFIG_ASYNC_TCP_PRIORITY=10\n  -D CONFIG_ASYNC_TCP_QUEUE_SIZE=128\n  -D CONFIG_ASYNC_TCP_RUNNING_CORE=1\n  -D CONFIG_ASYNC_TCP_STACK_SIZE=4096\n  -D WS_MAX_QUEUED_MESSAGES=128\n\n[env:default]"
  },
  {
    "path": "benchmark/espasyncwebserver/src/main.cpp",
    "content": "/* Wi-Fi STA Connect and Disconnect Example\n\n   This example code is in the Public Domain (or CC0 licensed, at your option.)\n\n   Unless required by applicable law or agreed to in writing, this\n   software is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n   CONDITIONS OF ANY KIND, either express or implied.\n\n*/\n#include \"_secret.h\"\n#include <Arduino.h>\n#include <ArduinoJson.h>\n#include <ESPAsyncWebServer.h>\n#include <ESPmDNS.h>\n#include <LittleFS.h>\n#include <WiFi.h>\n\n#ifndef WIFI_SSID\n  #error \"You need to enter your wifi credentials.  Copy secret.h to _secret.h and enter your credentials there.\"\n#endif\n\n// Enter your WIFI credentials in secret.h\nconst char* ssid = WIFI_SSID;\nconst char* password = WIFI_PASS;\n\n// hostname for mdns (psychic.local)\nconst char* local_hostname = \"psychic\";\n\nAsyncWebServer server(80);\nAsyncWebSocket ws(\"/ws\");\n\nconst char* htmlContent = R\"(\n<!DOCTYPE html>\n<html>\n<head>\n    <title>Sample HTML</title>\n</head>\n<body>\n    <h1>Hello, World!</h1>\n    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod\n    rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper\n    arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit\n    accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.\n    Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo\n    dapibus elit, id varius sem dui id lacus.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod\n    rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper\n    arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit\n    accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.\n    Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo\n    dapibus elit, id varius sem dui id lacus.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod\n    rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper\n    arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit\n    accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.\n    Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo\n    dapibus elit, id varius sem dui id lacus.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod\n    rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper\n    arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit\n    accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.\n    Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo\n    dapibus elit, id varius sem dui id lacus.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod\n    rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper\n    arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit\n    accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.\n    Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo\n    dapibus elit, id varius sem dui id lacus.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod\n    rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper\n    arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit\n    accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.\n    Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo\n    dapibus elit, id varius sem dui id lacus.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod\n    rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper\n    arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit\n    accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.\n    Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo\n    dapibus elit, id varius sem dui id lacus.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod\n    rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper\n    arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit\n    accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.\n    Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo\n    dapibus elit, id varius sem dui id lacus.</p>\n</body>\n</html>\n)\";\n\nconst size_t htmlContentLen = strlen(htmlContent);\n\nbool connectToWifi()\n{\n  Serial.println();\n  Serial.print(\"[WiFi] Connecting to \");\n  Serial.println(ssid);\n\n  // WiFi.setSleep(false);\n  // WiFi.useStaticBuffers(true);\n\n  WiFi.begin(ssid, password);\n\n  // Will try for about 10 seconds (20x 500ms)\n  int tryDelay = 500;\n  int numberOfTries = 20;\n\n  // Wait for the WiFi event\n  while (true) {\n    switch (WiFi.status()) {\n      case WL_NO_SSID_AVAIL:\n        Serial.println(\"[WiFi] SSID not found\");\n        break;\n      case WL_CONNECT_FAILED:\n        Serial.print(\"[WiFi] Failed - WiFi not connected! Reason: \");\n        return false;\n        break;\n      case WL_CONNECTION_LOST:\n        Serial.println(\"[WiFi] Connection was lost\");\n        break;\n      case WL_SCAN_COMPLETED:\n        Serial.println(\"[WiFi] Scan is completed\");\n        break;\n      case WL_DISCONNECTED:\n        Serial.println(\"[WiFi] WiFi is disconnected\");\n        break;\n      case WL_CONNECTED:\n        Serial.println(\"[WiFi] WiFi is connected!\");\n        Serial.print(\"[WiFi] IP address: \");\n        Serial.println(WiFi.localIP());\n        return true;\n        break;\n      default:\n        Serial.print(\"[WiFi] WiFi Status: \");\n        Serial.println(WiFi.status());\n        break;\n    }\n    delay(tryDelay);\n\n    if (numberOfTries <= 0) {\n      Serial.print(\"[WiFi] Failed to connect to WiFi!\");\n      // Use disconnect function to force stop trying to connect\n      WiFi.disconnect();\n      return false;\n    } else {\n      numberOfTries--;\n    }\n  }\n\n  return false;\n}\n\nvoid onEvent(AsyncWebSocket* server, AsyncWebSocketClient* client, AwsEventType type, void* arg, uint8_t* data, size_t len)\n{\n  if (type == WS_EVT_CONNECT) {\n    // client connected\n    //  Serial.printf(\"ws[%s][%u] connect\\n\", server->url(), client->id());\n    //  client->printf(\"Hello Client %u :)\", client->id());\n    //  client->ping();\n  } else if (type == WS_EVT_DISCONNECT) {\n    // client disconnected\n    //  Serial.printf(\"ws[%s][%u] disconnect: %u\\n\", server->url(), client->id());\n  } else if (type == WS_EVT_ERROR) {\n    // error was received from the other end\n    //  Serial.printf(\"ws[%s][%u] error(%u): %s\\n\", server->url(), client->id(), *((uint16_t*)arg), (char*)data);\n  } else if (type == WS_EVT_PONG) {\n    // pong message was received (in response to a ping request maybe)\n    //  Serial.printf(\"ws[%s][%u] pong[%u]: %s\\n\", server->url(), client->id(), len, (len)?(char*)data:\"\");\n  } else if (type == WS_EVT_DATA) {\n    // data packet\n    AwsFrameInfo* info = (AwsFrameInfo*)arg;\n    if (info->final && info->index == 0 && info->len == len) {\n      // the whole message is in a single frame and we got all of it's data\n      //  Serial.printf(\"ws[%s][%u] %s-message[%llu]: \", server->url(), client->id(), (info->opcode == WS_TEXT)?\"text\":\"binary\", info->len);\n      if (info->opcode == WS_TEXT) {\n        data[len] = 0;\n        // Serial.printf(\"%s\\n\", (char*)data);\n      } else {\n        // for(size_t i=0; i < info->len; i++){\n        //   Serial.printf(\"%02x \", data[i]);\n        // }\n        // Serial.printf(\"\\n\");\n      }\n      if (info->opcode == WS_TEXT) {\n        client->text((char*)data, len);\n      }\n      // else\n      //   client->binary(\"I got your binary message\");\n    } else {\n      // message is comprised of multiple frames or the frame is split into multiple packets\n      if (info->index == 0) {\n        // if(info->num == 0)\n        //   Serial.printf(\"ws[%s][%u] %s-message start\\n\", server->url(), client->id(), (info->message_opcode == WS_TEXT)?\"text\":\"binary\");\n        // Serial.printf(\"ws[%s][%u] frame[%u] start[%llu]\\n\", server->url(), client->id(), info->num, info->len);\n      }\n\n      Serial.printf(\"ws[%s][%u] frame[%u] %s[%llu - %llu]: \", server->url(), client->id(), info->num, (info->message_opcode == WS_TEXT) ? \"text\" : \"binary\", info->index, info->index + len);\n      if (info->message_opcode == WS_TEXT) {\n        data[len] = 0;\n        // Serial.printf(\"%s\\n\", (char*)data);\n      } else {\n        // for(size_t i=0; i < len; i++){\n        //   Serial.printf(\"%02x \", data[i]);\n        // }\n        // Serial.printf(\"\\n\");\n      }\n\n      if ((info->index + len) == info->len) {\n        // Serial.printf(\"ws[%s][%u] frame[%u] end[%llu]\\n\", server->url(), client->id(), info->num, info->len);\n        if (info->final) {\n          // Serial.printf(\"ws[%s][%u] %s-message end\\n\", server->url(), client->id(), (info->message_opcode == WS_TEXT)?\"text\":\"binary\");\n          if (info->message_opcode == WS_TEXT) {\n            client->text((char*)data, info->len);\n          }\n          // else\n          //   client->binary(\"I got your binary message\");\n        }\n      }\n    }\n  }\n}\n\nvoid setup()\n{\n  Serial.begin(115200);\n  delay(10);\n  Serial.println(\"ESPAsyncWebserver Benchmark\");\n\n  // We start by connecting to a WiFi network\n  // To debug, please enable Core Debug Level to Verbose\n  if (connectToWifi()) {\n    // set up our esp32 to listen on the local_hostname.local domain\n    if (!MDNS.begin(local_hostname)) {\n      Serial.println(\"Error starting mDNS\");\n      return;\n    }\n    MDNS.addService(\"http\", \"tcp\", 80);\n\n    if (!LittleFS.begin()) {\n      Serial.println(\"LittleFS Mount Failed. Do Platform -> Build Filesystem Image and Platform -> Upload Filesystem Image from VSCode\");\n      return;\n    }\n\n    // api - parameters passed in via query eg. /api/endpoint?foo=bar\n    server.on(\"/\", HTTP_GET, [](AsyncWebServerRequest* request) {\n      // ESPAsyncWebServer, sending a char* does a buffer copy, unlike Psychic.\n      // Sending flash data is done with the uint8_t* overload.\n      request->send(200, \"text/html\", (uint8_t*)htmlContent, htmlContentLen);\n    });\n\n    // api - parameters passed in via query eg. /api/endpoint?foo=bar\n    server.on(\"/api\", HTTP_GET, [](AsyncWebServerRequest* request) {\n      // create a response object\n      JsonDocument output;\n      output[\"msg\"] = \"status\";\n      output[\"status\"] = \"success\";\n      output[\"millis\"] = millis();\n\n      // work with some params\n      if (request->hasParam(\"foo\")) {\n        const AsyncWebParameter* foo = request->getParam(\"foo\");\n        output[\"foo\"] = foo->value();\n      }\n\n      // serialize and return\n      String jsonBuffer;\n      serializeJson(output, jsonBuffer);\n      request->send(200, \"application/json\", jsonBuffer.c_str());\n    });\n\n    ws.onEvent(onEvent);\n    server.addHandler(&ws);\n\n    // put this last, otherwise it clogs the other requests\n    // serve static files from LittleFS/www on /\n    server.serveStatic(\"/\", LittleFS, \"/www/\");\n\n    server.begin();\n  }\n}\n\nvoid loop()\n{\n  ws.cleanupClients();\n  Serial.printf(\"Free Heap: %d\\n\", esp_get_free_heap_size());\n  delay(1000);\n}"
  },
  {
    "path": "benchmark/espasyncwebserver/src/secret.h",
    "content": "#define WIFI_SSID \"Your_SSID\"\n#define WIFI_PASS \"Your_PASS\""
  },
  {
    "path": "benchmark/espasyncwebserver/test/README",
    "content": "\nThis directory is intended for PlatformIO Test Runner and project tests.\n\nUnit Testing is a software testing method by which individual units of\nsource code, sets of one or more MCU program modules together with associated\ncontrol data, usage procedures, and operating procedures, are tested to\ndetermine whether they are fit for use. Unit testing finds problems early\nin the development cycle.\n\nMore information about PlatformIO Unit Testing:\n- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html\n"
  },
  {
    "path": "benchmark/eventsource-client-test.js",
    "content": "#!/usr/bin/env node\n//stress test the client opening/closing code\n\nconst EventSource = require('eventsource');\nconst url = 'http://psychic.local/events';\n\nasync function eventSourceClient() {\n  console.log(`Starting test`);\n  for (let i = 0; i < 1000000; i++)\n  {\n    if (i % 100 == 0)\n      console.log(`Count: ${i}`);\n\n    let eventSource = new EventSource(url);\n\n    eventSource.onopen = () => {\n        //console.log('EventSource connection opened.');\n    };\n    \n    eventSource.onerror = (error) => {\n        console.error('EventSource error:', error);\n        \n        // Close the connection on error\n        eventSource.close();\n    };\n\n    await new Promise((resolve) => {\n        eventSource.onmessage = (event) => {\n            //console.log('Received message:', event.data);\n        \n            // Close the connection after receiving the first message\n            eventSource.close();\n    \n            resolve();\n        }\n    });  \n  }\n}\n\neventSourceClient();"
  },
  {
    "path": "benchmark/http-client-test.js",
    "content": "#!/usr/bin/env node\n//stress test the http request code\n\nconst axios = require('axios');\n\nconst url = 'http://psychic.local/api';\nconst queryParams = {\n  foo: 'bar',\n  foo1: 'bar',\n  foo2: 'bar',\n  foo3: 'bar',\n  foo4: 'bar',\n  foo5: 'bar',\n  foo6: 'bar',\n};\n\nconst totalRequests = 1000000;\nconst requestsPerCount = 100;\n\nlet requestCount = 0;\n\nfunction fetchData() {\n  axios.get(url, { params: queryParams })\n    .then(response => {\n      requestCount++;\n\n      if (requestCount % requestsPerCount === 0) {\n        console.log(`Requests completed: ${requestCount}`);\n      }\n\n      if (requestCount < totalRequests) {\n        fetchData();\n      } else {\n        console.log('All requests completed.');\n      }\n    })\n    .catch(error => {\n      console.error('Error making request:', error.message);\n    });\n}\n\n// Start making requests\nconsole.log(`Starting test`);\nfetchData();"
  },
  {
    "path": "benchmark/loadtest-http.sh",
    "content": "#!/usr/bin/env bash\n#Command to install the testers:\n# npm install\n\nTEST_IP=\"psychic.local\"\nTEST_TIME=10\n#LOG_FILE=psychic-http-loadtest.log\nLOG_FILE=_psychic-http-loadtest.json\nRESULTS_FILE=http-loadtest-results.csv\nTIMEOUT=10000\nWORKERS=1\nPROTOCOL=http\n#PROTOCOL=https\n\necho \"url,connections,rps,latency,errors\" > $RESULTS_FILE\n\nfor CONCURRENCY in 1 2 3 4 5 6 7 8 9 10 15 20\ndo\n  printf \"\\n\\nCLIENTS: *** $CONCURRENCY ***\\n\\n\" >> $LOG_FILE\n  echo \"Testing $CONCURRENCY clients on $PROTOCOL://$TEST_IP/\"\n  autocannon -c $CONCURRENCY -w $WORKERS -d $TEST_TIME -j \"$PROTOCOL://$TEST_IP/\" > $LOG_FILE\n  node parse-http-test.js $LOG_FILE $RESULTS_FILE\n  sleep 5\ndone\n\nfor CONCURRENCY in 1 2 3 4 5 6 7 8 9 10 15 20\ndo\n  echo \"Testing $CONCURRENCY clients on $PROTOCOL://$TEST_IP/api\"\n  autocannon -c $CONCURRENCY -w $WORKERS -d $TEST_TIME -j \"$PROTOCOL://$TEST_IP/api?foo=bar\" > $LOG_FILE\n  node parse-http-test.js $LOG_FILE $RESULTS_FILE\n  sleep 5\ndone\n\nfor CONCURRENCY in 1 2 3 4 5 6 7 8 9 10 15 20\ndo\n  echo \"Testing $CONCURRENCY clients on $PROTOCOL://$TEST_IP/alien.png\"\n  autocannon -c $CONCURRENCY -w $WORKERS -d $TEST_TIME -j \"$PROTOCOL://$TEST_IP/alien.png\" > $LOG_FILE\n  node parse-http-test.js $LOG_FILE $RESULTS_FILE\n  sleep 5\ndone\n\nrm $LOG_FILE\n"
  },
  {
    "path": "benchmark/loadtest-websocket.sh",
    "content": "#!/usr/bin/env bash\n#Command to install the testers:\n# npm install\n\nTEST_IP=\"psychic.local\"\nTEST_TIME=60\nLOG_FILE=psychic-websocket-loadtest.json\nRESULTS_FILE=websocket-loadtest-results.csv\nPROTOCOL=ws\n#PROTOCOL=wss\n\nif test -f \"$LOG_FILE\"; then\n  rm $LOG_FILE\nfi\n\necho \"url,clients,rps,latency,errors\" > $RESULTS_FILE\n\nCORES=1\nfor CONCURRENCY in 1 2 3 4 5\ndo\n  echo \"Testing $CONCURRENCY clients on $PROTOCOL://$TEST_IP/ws\"\n  loadtest -c $CONCURRENCY --cores $CORES -t $TEST_TIME --insecure $PROTOCOL://$TEST_IP/ws --quiet  2> /dev/null >> $LOG_FILE\n  node parse-websocket-test.js $LOG_FILE $RESULTS_FILE\n  sleep 2\ndone\n\nCORES=2\nfor CONNECTIONS in 6 8 10 12 14\ndo\n  CONCURRENCY=$((CONNECTIONS / 2))\n  echo \"Testing $CONNECTIONS clients on $PROTOCOL://$TEST_IP/ws\"\n  loadtest -c $CONCURRENCY --cores $CORES -t $TEST_TIME --insecure $PROTOCOL://$TEST_IP/ws --quiet  2> /dev/null >> $LOG_FILE\n  node parse-websocket-test.js $LOG_FILE $RESULTS_FILE\n  sleep 2\ndone\n\nCORES=4\nfor CONNECTIONS in 16 20 24 28 32\ndo\n CONCURRENCY=$((CONNECTIONS / CORES))\n echo \"Testing $CONNECTIONS clients on $PROTOCOL://$TEST_IP/ws\"\n loadtest -c $CONCURRENCY --cores $CORES -t $TEST_TIME --insecure $PROTOCOL://$TEST_IP/ws --quiet 2> /dev/null >> $LOG_FILE\n node parse-websocket-test.js $LOG_FILE $RESULTS_FILE\n sleep 2\ndone\n"
  },
  {
    "path": "benchmark/package.json",
    "content": "{\n  \"dependencies\": {\n    \"autocannon\": \"^7.15.0\",\n    \"axios\": \"^1.6.2\",\n    \"csv-writer\": \"^1.6.0\",\n    \"eventsource\": \"^2.0.2\",\n    \"loadtest\": \"^8.0.9\",\n    \"ws\": \"^8.14.2\"\n  }\n}\n"
  },
  {
    "path": "benchmark/parse-http-test.js",
    "content": "const fs = require('fs');\nconst createCsvWriter = require('csv-writer').createObjectCsvWriter;\n\n// Get the input and output file paths from the command line arguments\nconst inputFilePath = process.argv[2];\nconst outputFilePath = process.argv[3];\n\nif (!inputFilePath || !outputFilePath) {\n    console.error('Usage: node script.js <inputFilePath> <outputFilePath>');\n    process.exit(1);\n}\n\n// Read and parse the JSON file\nfs.readFile(inputFilePath, 'utf8', (err, data) => {\n    if (err) {\n        console.error('Error reading the input file:', err);\n        return;\n    }\n\n    // Parse the JSON data\n    const jsonData = JSON.parse(data);\n\n    // Extract the desired fields\n    const { url, connections, latency, requests, errors } = jsonData;\n    const latencyMean = latency.mean;\n    const requestsMean = requests.mean;\n\n    // Set up the CSV writer\n    const csvWriter = createCsvWriter({\n        path: outputFilePath,\n        header: [\n            {id: 'url', title: 'URL'},\n            {id: 'connections', title: 'Connections'},\n            {id: 'requestsMean', title: 'Requests Mean'},\n            {id: 'latencyMean', title: 'Latency Mean'},\n            {id: 'errors', title: 'Errors'},\n        ],\n        append: true // this will append to the existing file\n    });\n\n    // Prepare the data to be written\n    const records = [\n        { url: url, connections: connections, latencyMean: latencyMean, requestsMean: requestsMean, errors: errors }\n    ];\n\n    // Write the data to the CSV file\n    csvWriter.writeRecords(records)\n        .then(() => {\n            console.log('Data successfully appended to CSV file.');\n        })\n        .catch(err => {\n            console.error('Error writing to the CSV file:', err);\n        });\n});\n\n"
  },
  {
    "path": "benchmark/parse-websocket-test.js",
    "content": "const fs = require('fs');\nconst readline = require('readline');\n\nif (process.argv.length !== 4) {\n    console.error('Usage: node parse-websocket-test.js <input_file> <output_file>');\n    process.exit(1);\n}\n\nconst inputFile = process.argv[2];\nconst outputFile = process.argv[3];\n\nasync function parseFile() {\n    const fileStream = fs.createReadStream(inputFile);\n\n    const rl = readline.createInterface({\n        input: fileStream,\n        crlfDelay: Infinity\n    });\n\n    let targetUrl = null;\n    let totalErrors = null;\n    let meanLatency = null;\n    let effectiveRps = null;\n    let concurrentClients = null;\n\n    for await (const line of rl) {\n        if (line.startsWith('Target URL:')) {\n            targetUrl = line.split(':').slice(1).join(':').trim();\n        }\n        if (line.startsWith('Total errors:')) {\n            totalErrors = parseInt(line.split(':')[1].trim(), 10);\n        }\n        if (line.startsWith('Mean latency:')) {\n            meanLatency = parseFloat(line.split(':')[1].trim());\n        }\n        if (line.startsWith('Effective rps:')) {\n            effectiveRps = parseInt(line.split(':')[1].trim(), 10);\n        }\n        if (line.startsWith('Concurrent clients:')) {\n            concurrentClients = parseInt(line.split(':')[1].trim(), 10);\n        }\n    }\n\n    if (targetUrl === null || totalErrors === null || meanLatency === null || effectiveRps === null || concurrentClients === null) {\n        console.error('Failed to extract necessary data from the input file');\n        process.exit(1);\n    }\n\n    const csvLine = `${targetUrl},${concurrentClients},${effectiveRps},${meanLatency},${totalErrors}\\n`;\n\n    fs.appendFile(outputFile, csvLine, (err) => {\n        if (err) {\n            console.error('Failed to append to CSV file:', err);\n            process.exit(1);\n        }\n        console.log('Data successfully appended to CSV file.');\n    });\n}\n\nparseFile().catch(err => {\n    console.error('Error reading file:', err);\n    process.exit(1);\n});\n\n"
  },
  {
    "path": "benchmark/psychichttp/.gitignore",
    "content": ".pio\n.vscode/\n.vscode/.browse.c_cpp.db*\n.vscode/c_cpp_properties.json\n.vscode/launch.json\n.vscode/ipch\n"
  },
  {
    "path": "benchmark/psychichttp/include/README",
    "content": "\nThis directory is intended for project header files.\n\nA header file is a file containing C declarations and macro definitions\nto be shared between several project source files. You request the use of a\nheader file in your project source file (C, C++, etc) located in `src` folder\nby including it, with the C preprocessing directive `#include'.\n\n```src/main.c\n\n#include \"header.h\"\n\nint main (void)\n{\n ...\n}\n```\n\nIncluding a header file produces the same results as copying the header file\ninto each source file that needs it. Such copying would be time-consuming\nand error-prone. With a header file, the related declarations appear\nin only one place. If they need to be changed, they can be changed in one\nplace, and programs that include the header file will automatically use the\nnew version when next recompiled. The header file eliminates the labor of\nfinding and changing all the copies as well as the risk that a failure to\nfind one copy will result in inconsistencies within a program.\n\nIn C, the usual convention is to give header files names that end with `.h'.\nIt is most portable to use only letters, digits, dashes, and underscores in\nheader file names, and at most one dot.\n\nRead more about using header files in official GCC documentation:\n\n* Include Syntax\n* Include Operation\n* Once-Only Headers\n* Computed Includes\n\nhttps://gcc.gnu.org/onlinedocs/cpp/Header-Files.html\n"
  },
  {
    "path": "benchmark/psychichttp/lib/README",
    "content": "\nThis directory is intended for project specific (private) libraries.\nPlatformIO will compile them to static libraries and link into executable file.\n\nThe source code of each library should be placed in a an own separate directory\n(\"lib/your_library_name/[here are source files]\").\n\nFor example, see a structure of the following two libraries `Foo` and `Bar`:\n\n|--lib\n|  |\n|  |--Bar\n|  |  |--docs\n|  |  |--examples\n|  |  |--src\n|  |     |- Bar.c\n|  |     |- Bar.h\n|  |  |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html\n|  |\n|  |--Foo\n|  |  |- Foo.c\n|  |  |- Foo.h\n|  |\n|  |- README --> THIS FILE\n|\n|- platformio.ini\n|--src\n   |- main.c\n\nand a contents of `src/main.c`:\n```\n#include <Foo.h>\n#include <Bar.h>\n\nint main (void)\n{\n  ...\n}\n\n```\n\nPlatformIO Library Dependency Finder will find automatically dependent\nlibraries scanning project source files.\n\nMore information about PlatformIO Library Dependency Finder\n- https://docs.platformio.org/page/librarymanager/ldf.html\n"
  },
  {
    "path": "benchmark/psychichttp/platformio.ini",
    "content": "; PlatformIO Project Configuration File\n;\n;   Build options: build flags, source filter\n;   Upload options: custom upload port, speed and extra flags\n;   Library options: dependencies, extra library storages\n;   Advanced options: extra scripting\n;\n; Please visit documentation for the other options and examples\n; https://docs.platformio.org/page/projectconf.html\n\n[env]\nplatform = espressif32\nframework = arduino\nboard = esp32dev\nmonitor_speed = 115200\nmonitor_filters = esp32_exception_decoder\nlib_deps = \n    bblanchon/ArduinoJson\nboard_build.filesystem = littlefs\n\n[env:default]\nlib_deps = https://github.com/hoeken/PsychicHttp\n\n[env:v2-dev]\nlib_deps = https://github.com/hoeken/PsychicHttp#v2-dev\nboard = esp32-s3-devkitc-1\nupload_port = /dev/ttyACM0\nmonitor_port = /dev/ttyACM1"
  },
  {
    "path": "benchmark/psychichttp/src/main.cpp",
    "content": "/* Wi-Fi STA Connect and Disconnect Example\n\n   This example code is in the Public Domain (or CC0 licensed, at your option.)\n\n   Unless required by applicable law or agreed to in writing, this\n   software is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n   CONDITIONS OF ANY KIND, either express or implied.\n\n*/\n#include \"_secret.h\"\n#include <Arduino.h>\n#include <ArduinoJson.h>\n#include <ESPmDNS.h>\n#include <LittleFS.h>\n#include <PsychicHttp.h>\n#include <WiFi.h>\n\n#ifndef WIFI_SSID\n  #error \"You need to enter your wifi credentials.  Copy secret.h to _secret.h and enter your credentials there.\"\n#endif\n\n// Enter your WIFI credentials in secret.h\nconst char* ssid = WIFI_SSID;\nconst char* password = WIFI_PASS;\n\n// hostname for mdns (psychic.local)\nconst char* local_hostname = \"psychic\";\n\nPsychicHttpServer server;\nPsychicWebSocketHandler websocketHandler;\nPsychicEventSource eventSource;\n\nconst char* htmlContent = R\"(\n<!DOCTYPE html>\n<html>\n<head>\n    <title>Sample HTML</title>\n</head>\n<body>\n    <h1>Hello, World!</h1>\n    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod\n    rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper\n    arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit\n    accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.\n    Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo\n    dapibus elit, id varius sem dui id lacus.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod\n    rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper\n    arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit\n    accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.\n    Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo\n    dapibus elit, id varius sem dui id lacus.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod\n    rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper\n    arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit\n    accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.\n    Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo\n    dapibus elit, id varius sem dui id lacus.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod\n    rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper\n    arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit\n    accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.\n    Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo\n    dapibus elit, id varius sem dui id lacus.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod\n    rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper\n    arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit\n    accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.\n    Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo\n    dapibus elit, id varius sem dui id lacus.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod\n    rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper\n    arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit\n    accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.\n    Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo\n    dapibus elit, id varius sem dui id lacus.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod\n    rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper\n    arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit\n    accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.\n    Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo\n    dapibus elit, id varius sem dui id lacus.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod\n    rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper\n    arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit\n    accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.\n    Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo\n    dapibus elit, id varius sem dui id lacus.</p>\n</body>\n</html>\n)\";\n\nbool connectToWifi()\n{\n  Serial.println();\n  Serial.print(\"[WiFi] Connecting to \");\n  Serial.println(ssid);\n\n  // WiFi.setSleep(false);\n  // WiFi.useStaticBuffers(true);\n\n  WiFi.begin(ssid, password);\n\n  // Will try for about 10 seconds (20x 500ms)\n  int tryDelay = 500;\n  int numberOfTries = 20;\n\n  // Wait for the WiFi event\n  while (true) {\n    switch (WiFi.status()) {\n      case WL_NO_SSID_AVAIL:\n        Serial.println(\"[WiFi] SSID not found\");\n        break;\n      case WL_CONNECT_FAILED:\n        Serial.print(\"[WiFi] Failed - WiFi not connected! Reason: \");\n        return false;\n        break;\n      case WL_CONNECTION_LOST:\n        Serial.println(\"[WiFi] Connection was lost\");\n        break;\n      case WL_SCAN_COMPLETED:\n        Serial.println(\"[WiFi] Scan is completed\");\n        break;\n      case WL_DISCONNECTED:\n        Serial.println(\"[WiFi] WiFi is disconnected\");\n        break;\n      case WL_CONNECTED:\n        Serial.println(\"[WiFi] WiFi is connected!\");\n        Serial.print(\"[WiFi] IP address: \");\n        Serial.println(WiFi.localIP());\n        return true;\n        break;\n      default:\n        Serial.print(\"[WiFi] WiFi Status: \");\n        Serial.println(WiFi.status());\n        break;\n    }\n    delay(tryDelay);\n\n    if (numberOfTries <= 0) {\n      Serial.print(\"[WiFi] Failed to connect to WiFi!\");\n      // Use disconnect function to force stop trying to connect\n      WiFi.disconnect();\n      return false;\n    } else {\n      numberOfTries--;\n    }\n  }\n\n  return false;\n}\n\nvoid setup()\n{\n  Serial.begin(115200);\n  delay(10);\n  Serial.println(\"PsychicHTTP Benchmark\");\n\n  if (connectToWifi()) {\n    // set up our esp32 to listen on the local_hostname.local domain\n    if (!MDNS.begin(local_hostname)) {\n      Serial.println(\"Error starting mDNS\");\n      return;\n    }\n    MDNS.addService(\"http\", \"tcp\", 80);\n\n    if (!LittleFS.begin()) {\n      Serial.println(\"LittleFS Mount Failed. Do Platform -> Build Filesystem Image and Platform -> Upload Filesystem Image from VSCode\");\n      return;\n    }\n\n    // our index\n    server.on(\"/\", HTTP_GET, [](PsychicRequest* request, PsychicResponse* response) { return response->send(200, \"text/html\", htmlContent); });\n\n    // serve static files from LittleFS/www on /\n    server.serveStatic(\"/\", LittleFS, \"/www/\");\n\n    // a websocket echo server\n    websocketHandler.onOpen([](PsychicWebSocketClient* client) {\n      // client->sendMessage(\"Hello!\");\n    });\n    websocketHandler.onFrame([](PsychicWebSocketRequest* request, httpd_ws_frame* frame) {\n      response->send(frame);\n      return ESP_OK; });\n    server.on(\"/ws\", &websocketHandler);\n\n    // EventSource server\n    eventSource.onOpen([](PsychicEventSourceClient* client) { client->send(\"Hello\", NULL, millis(), 1000); });\n    server.on(\"/events\", &eventSource);\n\n    // api - parameters passed in via query eg. /api/endpoint?foo=bar\n    server.on(\"/api\", HTTP_GET, [](PsychicRequest* request, PsychicResponse* response) {\n      //create a response object\n      JsonDocument output;\n      output[\"msg\"] = \"status\";\n      output[\"status\"] = \"success\";\n      output[\"millis\"] = millis();\n\n      //work with some params\n      if (request->hasParam(\"foo\"))\n      {\n        String foo = request->getParam(\"foo\")->value();\n        output[\"foo\"] = foo;\n      }\n\n      //serialize and return\n      String jsonBuffer;\n      serializeJson(output, jsonBuffer);\n      return response->send(200, \"application/json\", jsonBuffer.c_str()); });\n\n    server.begin();\n  }\n}\n\nunsigned long last;\nvoid loop()\n{\n  if (millis() - last > 1000) {\n    Serial.printf(\"Free Heap: %d\\n\", esp_get_free_heap_size());\n    last = millis();\n  }\n}"
  },
  {
    "path": "benchmark/psychichttp/src/secret.h",
    "content": "#define WIFI_SSID \"Your_SSID\"\n#define WIFI_PASS \"Your_PASS\""
  },
  {
    "path": "benchmark/psychichttp/test/README",
    "content": "\nThis directory is intended for PlatformIO Test Runner and project tests.\n\nUnit Testing is a software testing method by which individual units of\nsource code, sets of one or more MCU program modules together with associated\ncontrol data, usage procedures, and operating procedures, are tested to\ndetermine whether they are fit for use. Unit testing finds problems early\nin the development cycle.\n\nMore information about PlatformIO Unit Testing:\n- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html\n"
  },
  {
    "path": "benchmark/psychichttps/.gitignore",
    "content": ".pio\n.vscode/\n.vscode/.browse.c_cpp.db*\n.vscode/c_cpp_properties.json\n.vscode/launch.json\n.vscode/ipch\n"
  },
  {
    "path": "benchmark/psychichttps/data/server.crt",
    "content": "-----BEGIN CERTIFICATE-----\nMIIDKzCCAhOgAwIBAgIUBxM3WJf2bP12kAfqhmhhjZWv0ukwDQYJKoZIhvcNAQEL\nBQAwJTEjMCEGA1UEAwwaRVNQMzIgSFRUUFMgc2VydmVyIGV4YW1wbGUwHhcNMTgx\nMDE3MTEzMjU3WhcNMjgxMDE0MTEzMjU3WjAlMSMwIQYDVQQDDBpFU1AzMiBIVFRQ\nUyBzZXJ2ZXIgZXhhbXBsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB\nALBint6nP77RCQcmKgwPtTsGK0uClxg+LwKJ3WXuye3oqnnjqJCwMEneXzGdG09T\nsA0SyNPwrEgebLCH80an3gWU4pHDdqGHfJQa2jBL290e/5L5MB+6PTs2NKcojK/k\nqcZkn58MWXhDW1NpAnJtjVniK2Ksvr/YIYSbyD+JiEs0MGxEx+kOl9d7hRHJaIzd\nGF/vO2pl295v1qXekAlkgNMtYIVAjUy9CMpqaQBCQRL+BmPSJRkXBsYk8GPnieS4\nsUsp53DsNvCCtWDT6fd9D1v+BB6nDk/FCPKhtjYOwOAZlX4wWNSZpRNr5dfrxKsb\njAn4PCuR2akdF4G8WLUeDWECAwEAAaNTMFEwHQYDVR0OBBYEFMnmdJKOEepXrHI/\nivM6mVqJgAX8MB8GA1UdIwQYMBaAFMnmdJKOEepXrHI/ivM6mVqJgAX8MA8GA1Ud\nEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBADiXIGEkSsN0SLSfCF1VNWO3\nemBurfOcDq4EGEaxRKAU0814VEmU87btIDx80+z5Dbf+GGHCPrY7odIkxGNn0DJY\nW1WcF+DOcbiWoUN6DTkAML0SMnp8aGj9ffx3x+qoggT+vGdWVVA4pgwqZT7Ybntx\nbkzcNFW0sqmCv4IN1t4w6L0A87ZwsNwVpre/j6uyBw7s8YoJHDLRFT6g7qgn0tcN\nZufhNISvgWCVJQy/SZjNBHSpnIdCUSJAeTY2mkM4sGxY0Widk8LnjydxZUSxC3Nl\nhb6pnMh3jRq4h0+5CZielA4/a+TdrNPv/qok67ot/XJdY3qHCCd8O2b14OVq9jo=\n-----END CERTIFICATE-----"
  },
  {
    "path": "benchmark/psychichttps/data/server.key",
    "content": "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCwYp7epz++0QkH\nJioMD7U7BitLgpcYPi8Cid1l7snt6Kp546iQsDBJ3l8xnRtPU7ANEsjT8KxIHmyw\nh/NGp94FlOKRw3ahh3yUGtowS9vdHv+S+TAfuj07NjSnKIyv5KnGZJ+fDFl4Q1tT\naQJybY1Z4itirL6/2CGEm8g/iYhLNDBsRMfpDpfXe4URyWiM3Rhf7ztqZdveb9al\n3pAJZIDTLWCFQI1MvQjKamkAQkES/gZj0iUZFwbGJPBj54nkuLFLKedw7DbwgrVg\n0+n3fQ9b/gQepw5PxQjyobY2DsDgGZV+MFjUmaUTa+XX68SrG4wJ+DwrkdmpHReB\nvFi1Hg1hAgMBAAECggEAaTCnZkl/7qBjLexIryC/CBBJyaJ70W1kQ7NMYfniWwui\nf0aRxJgOdD81rjTvkINsPp+xPRQO6oOadjzdjImYEuQTqrJTEUnntbu924eh+2D9\nMf2CAanj0mglRnscS9mmljZ0KzoGMX6Z/EhnuS40WiJTlWlH6MlQU/FDnwC6U34y\nJKy6/jGryfsx+kGU/NRvKSru6JYJWt5v7sOrymHWD62IT59h3blOiP8GMtYKeQlX\n49om9Mo1VTIFASY3lrxmexbY+6FG8YO+tfIe0tTAiGrkb9Pz6tYbaj9FjEWOv4Vc\n+3VMBUVdGJjgqvE8fx+/+mHo4Rg69BUPfPSrpEg7sQKBgQDlL85G04VZgrNZgOx6\npTlCCl/NkfNb1OYa0BELqWINoWaWQHnm6lX8YjrUjwRpBF5s7mFhguFjUjp/NW6D\n0EEg5BmO0ePJ3dLKSeOA7gMo7y7kAcD/YGToqAaGljkBI+IAWK5Su5yldrECTQKG\nYnMKyQ1MWUfCYEwHtPvFvE5aPwKBgQDFBWXekpxHIvt/B41Cl/TftAzE7/f58JjV\nMFo/JCh9TDcH6N5TMTRS1/iQrv5M6kJSSrHnq8pqDXOwfHLwxetpk9tr937VRzoL\nCuG1Ar7c1AO6ujNnAEmUVC2DppL/ck5mRPWK/kgLwZSaNcZf8sydRgphsW1ogJin\n7g0nGbFwXwKBgQCPoZY07Pr1TeP4g8OwWTu5F6dSvdU2CAbtZthH5q98u1n/cAj1\nnoak1Srpa3foGMTUn9CHu+5kwHPIpUPNeAZZBpq91uxa5pnkDMp3UrLIRJ2uZyr8\n4PxcknEEh8DR5hsM/IbDcrCJQglM19ZtQeW3LKkY4BsIxjDf45ymH407IQKBgE/g\nUl6cPfOxQRlNLH4VMVgInSyyxWx1mODFy7DRrgCuh5kTVh+QUVBM8x9lcwAn8V9/\nnQT55wR8E603pznqY/jX0xvAqZE6YVPcw4kpZcwNwL1RhEl8GliikBlRzUL3SsW3\nq30AfqEViHPE3XpE66PPo6Hb1ymJCVr77iUuC3wtAoGBAIBrOGunv1qZMfqmwAY2\nlxlzRgxgSiaev0lTNxDzZkmU/u3dgdTwJ5DDANqPwJc6b8SGYTp9rQ0mbgVHnhIB\njcJQBQkTfq6Z0H6OoTVi7dPs3ibQJFrtkoyvYAbyk36quBmNRjVh6rc8468bhXYr\nv/t+MeGJP/0Zw8v/X2CFll96\n-----END PRIVATE KEY-----"
  },
  {
    "path": "benchmark/psychichttps/include/README",
    "content": "\nThis directory is intended for project header files.\n\nA header file is a file containing C declarations and macro definitions\nto be shared between several project source files. You request the use of a\nheader file in your project source file (C, C++, etc) located in `src` folder\nby including it, with the C preprocessing directive `#include'.\n\n```src/main.c\n\n#include \"header.h\"\n\nint main (void)\n{\n ...\n}\n```\n\nIncluding a header file produces the same results as copying the header file\ninto each source file that needs it. Such copying would be time-consuming\nand error-prone. With a header file, the related declarations appear\nin only one place. If they need to be changed, they can be changed in one\nplace, and programs that include the header file will automatically use the\nnew version when next recompiled. The header file eliminates the labor of\nfinding and changing all the copies as well as the risk that a failure to\nfind one copy will result in inconsistencies within a program.\n\nIn C, the usual convention is to give header files names that end with `.h'.\nIt is most portable to use only letters, digits, dashes, and underscores in\nheader file names, and at most one dot.\n\nRead more about using header files in official GCC documentation:\n\n* Include Syntax\n* Include Operation\n* Once-Only Headers\n* Computed Includes\n\nhttps://gcc.gnu.org/onlinedocs/cpp/Header-Files.html\n"
  },
  {
    "path": "benchmark/psychichttps/lib/README",
    "content": "\nThis directory is intended for project specific (private) libraries.\nPlatformIO will compile them to static libraries and link into executable file.\n\nThe source code of each library should be placed in a an own separate directory\n(\"lib/your_library_name/[here are source files]\").\n\nFor example, see a structure of the following two libraries `Foo` and `Bar`:\n\n|--lib\n|  |\n|  |--Bar\n|  |  |--docs\n|  |  |--examples\n|  |  |--src\n|  |     |- Bar.c\n|  |     |- Bar.h\n|  |  |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html\n|  |\n|  |--Foo\n|  |  |- Foo.c\n|  |  |- Foo.h\n|  |\n|  |- README --> THIS FILE\n|\n|- platformio.ini\n|--src\n   |- main.c\n\nand a contents of `src/main.c`:\n```\n#include <Foo.h>\n#include <Bar.h>\n\nint main (void)\n{\n  ...\n}\n\n```\n\nPlatformIO Library Dependency Finder will find automatically dependent\nlibraries scanning project source files.\n\nMore information about PlatformIO Library Dependency Finder\n- https://docs.platformio.org/page/librarymanager/ldf.html\n"
  },
  {
    "path": "benchmark/psychichttps/platformio.ini",
    "content": "; PlatformIO Project Configuration File\n;\n;   Build options: build flags, source filter\n;   Upload options: custom upload port, speed and extra flags\n;   Library options: dependencies, extra library storages\n;   Advanced options: extra scripting\n;\n; Please visit documentation for the other options and examples\n; https://docs.platformio.org/page/projectconf.html\n\n[env]\nplatform = espressif32\nframework = arduino\nboard = esp32dev\nmonitor_speed = 115200\nmonitor_filters = esp32_exception_decoder\nlib_deps = \n    https://github.com/hoeken/PsychicHttp\n    bblanchon/ArduinoJson\nboard_build.filesystem = littlefs\n\n[env:default]\n"
  },
  {
    "path": "benchmark/psychichttps/src/main.cpp",
    "content": "/* Wi-Fi STA Connect and Disconnect Example\n\n   This example code is in the Public Domain (or CC0 licensed, at your option.)\n\n   Unless required by applicable law or agreed to in writing, this\n   software is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n   CONDITIONS OF ANY KIND, either express or implied.\n\n*/\n#include \"_secret.h\"\n#include <Arduino.h>\n#include <ArduinoJSON.h>\n#include <LittleFS.h>\n#include <PsychicHttp.h>\n#include <PsychicHttpsServer.h>\n#include <WiFi.h>\n\n#ifndef WIFI_SSID\n  #error \"You need to enter your wifi credentials. Rename secret.h to _secret.h and enter your credentials there.\"\n#endif\n\n// Enter your WIFI credentials in secret.h\nconst char* ssid = WIFI_SSID;\nconst char* password = WIFI_PASS;\n\nPsychicHttpsServer server;\nPsychicWebSocketHandler websocketHandler;\n\nString server_cert;\nString server_key;\n\nconst char* htmlContent = R\"(\n<!DOCTYPE html>\n<html>\n<head>\n    <title>Sample HTML</title>\n</head>\n<body>\n    <h1>Hello, World!</h1>\n    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod\n    rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper\n    arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit\n    accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.\n    Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo\n    dapibus elit, id varius sem dui id lacus.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod\n    rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper\n    arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit\n    accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.\n    Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo\n    dapibus elit, id varius sem dui id lacus.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod\n    rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper\n    arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit\n    accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.\n    Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo\n    dapibus elit, id varius sem dui id lacus.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod\n    rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper\n    arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit\n    accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.\n    Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo\n    dapibus elit, id varius sem dui id lacus.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod\n    rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper\n    arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit\n    accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.\n    Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo\n    dapibus elit, id varius sem dui id lacus.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod\n    rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper\n    arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit\n    accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.\n    Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo\n    dapibus elit, id varius sem dui id lacus.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod\n    rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper\n    arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit\n    accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.\n    Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo\n    dapibus elit, id varius sem dui id lacus.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod\n    rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper\n    arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit\n    accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.\n    Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo\n    dapibus elit, id varius sem dui id lacus.</p>\n</body>\n</html>\n)\";\n\nbool connectToWifi()\n{\n  Serial.println();\n  Serial.print(\"[WiFi] Connecting to \");\n  Serial.println(ssid);\n\n  WiFi.setSleep(false);\n\n  WiFi.begin(ssid, password);\n\n  // Will try for about 10 seconds (20x 500ms)\n  int tryDelay = 500;\n  int numberOfTries = 20;\n\n  // Wait for the WiFi event\n  while (true)\n  {\n    switch (WiFi.status())\n    {\n      case WL_NO_SSID_AVAIL:\n        Serial.println(\"[WiFi] SSID not found\");\n        break;\n      case WL_CONNECT_FAILED:\n        Serial.print(\"[WiFi] Failed - WiFi not connected! Reason: \");\n        return false;\n        break;\n      case WL_CONNECTION_LOST:\n        Serial.println(\"[WiFi] Connection was lost\");\n        break;\n      case WL_SCAN_COMPLETED:\n        Serial.println(\"[WiFi] Scan is completed\");\n        break;\n      case WL_DISCONNECTED:\n        Serial.println(\"[WiFi] WiFi is disconnected\");\n        break;\n      case WL_CONNECTED:\n        Serial.println(\"[WiFi] WiFi is connected!\");\n        Serial.print(\"[WiFi] IP address: \");\n        Serial.println(WiFi.localIP());\n        return true;\n        break;\n      default:\n        Serial.print(\"[WiFi] WiFi Status: \");\n        Serial.println(WiFi.status());\n        break;\n    }\n    delay(tryDelay);\n\n    if (numberOfTries <= 0)\n    {\n      Serial.print(\"[WiFi] Failed to connect to WiFi!\");\n      // Use disconnect function to force stop trying to connect\n      WiFi.disconnect();\n      return false;\n    }\n    else\n    {\n      numberOfTries--;\n    }\n  }\n\n  return false;\n}\n\nvoid setup()\n{\n  Serial.begin(115200);\n  delay(10);\n  Serial.println(\"PsychicHTTP Benchmark\");\n\n  if (connectToWifi())\n  {\n    if (!LittleFS.begin())\n    {\n      Serial.println(\"LittleFS Mount Failed. Do Platform -> Build Filesystem Image and Platform -> Upload Filesystem Image from VSCode\");\n      return;\n    }\n\n    File fp = LittleFS.open(\"/server.crt\");\n    if (fp)\n    {\n      server_cert = fp.readString();\n    }\n    else\n    {\n      Serial.println(\"server.pem not found, SSL not available\");\n      return;\n    }\n    fp.close();\n\n    File fp2 = LittleFS.open(\"/server.key\");\n    if (fp2)\n    {\n      server_key = fp2.readString();\n    }\n    else\n    {\n      Serial.println(\"server.key not found, SSL not available\");\n      return;\n    }\n    fp2.close();\n\n    // start our server\n    server.setCertificate(server_cert.c_str(), server_key.c_str());\n\n    // our index\n    server.on(\"/\", HTTP_GET, [](PsychicRequest* request)\n              { return response->send(200, \"text/html\", htmlContent); });\n\n    // serve static files from LittleFS/www on /\n    server.serveStatic(\"/\", LittleFS, \"/www/\");\n\n    // a websocket echo server\n    websocketHandler.onFrame([](PsychicWebSocketRequest* request, httpd_ws_frame* frame)\n                             {\n      response->send(frame);\n      return ESP_OK; });\n    server.on(\"/ws\", &websocketHandler);\n\n    // api - parameters passed in via query eg. /api/endpoint?foo=bar\n    server.on(\"/api\", HTTP_GET, [](PsychicRequest* request)\n              {\n      //create a response object\n      StaticJsonDocument<128> output;\n      output[\"msg\"] = \"status\";\n      output[\"status\"] = \"success\";\n      output[\"millis\"] = millis();\n\n      //work with some params\n      if (request->hasParam(\"foo\"))\n      {\n        String foo = request->getParam(\"foo\")->value();\n        output[\"foo\"] = foo;\n      }\n\n      //serialize and return\n      String jsonBuffer;\n      serializeJson(output, jsonBuffer);\n      return response->send(200, \"application/json\", jsonBuffer.c_str()); });\n  }\n}\n\nunsigned long last;\nvoid loop()\n{\n  if (millis() - last > 1000)\n  {\n    Serial.printf(\"Free Heap: %d\\n\", esp_get_free_heap_size());\n    last = millis();\n  }\n}"
  },
  {
    "path": "benchmark/psychichttps/src/secret.h",
    "content": "#define WIFI_SSID \"Your_SSID\"\n#define WIFI_PASS \"Your_PASS\""
  },
  {
    "path": "benchmark/psychichttps/test/README",
    "content": "\nThis directory is intended for PlatformIO Test Runner and project tests.\n\nUnit Testing is a software testing method by which individual units of\nsource code, sets of one or more MCU program modules together with associated\ncontrol data, usage procedures, and operating procedures, are tested to\ndetermine whether they are fit for use. Unit testing finds problems early\nin the development cycle.\n\nMore information about PlatformIO Unit Testing:\n- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html\n"
  },
  {
    "path": "benchmark/results/arduinomongoose-http-loadtest.log",
    "content": "\n\nCLIENTS: *** 1 ***\n\nRunning 60s test @ http://192.168.2.131/\n1 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬─────────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬──────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg         \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max      \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼─────────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 720 ms \u001b[90m│\u001b[39m 14880 ms \u001b[90m│\u001b[39m 29087 ms \u001b[90m│\u001b[39m 29519 ms \u001b[90m│\u001b[39m 15024.03 ms \u001b[90m│\u001b[39m 8572.14 ms \u001b[90m│\u001b[39m 29737 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴─────────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴──────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 11      \u001b[90m│\u001b[39m 11      \u001b[90m│\u001b[39m 12      \u001b[90m│\u001b[39m 14      \u001b[90m│\u001b[39m 12.47   \u001b[90m│\u001b[39m 0.87    \u001b[90m│\u001b[39m 11      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 48.2 kB \u001b[90m│\u001b[39m 48.2 kB \u001b[90m│\u001b[39m 52.6 kB \u001b[90m│\u001b[39m 61.3 kB \u001b[90m│\u001b[39m 54.6 kB \u001b[90m│\u001b[39m 3.79 kB \u001b[90m│\u001b[39m 48.2 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 748   \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n1k requests in 60.07s, 3.28 MB read\n748 errors (0 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/api?foo=bar\n1 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬─────────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬──────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg         \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max      \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼─────────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 781 ms \u001b[90m│\u001b[39m 15061 ms \u001b[90m│\u001b[39m 29571 ms \u001b[90m│\u001b[39m 30046 ms \u001b[90m│\u001b[39m 15137.29 ms \u001b[90m│\u001b[39m 8833.98 ms \u001b[90m│\u001b[39m 30393 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴─────────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴──────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 17      \u001b[90m│\u001b[39m 18      \u001b[90m│\u001b[39m 20      \u001b[90m│\u001b[39m 23      \u001b[90m│\u001b[39m 20.34   \u001b[90m│\u001b[39m 1.27  \u001b[90m│\u001b[39m 17      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 2.99 kB \u001b[90m│\u001b[39m 3.15 kB \u001b[90m│\u001b[39m 3.52 kB \u001b[90m│\u001b[39m 4.03 kB \u001b[90m│\u001b[39m 3.57 kB \u001b[90m│\u001b[39m 220 B \u001b[90m│\u001b[39m 2.99 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 1220  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n2k requests in 60.06s, 214 kB read\n1k errors (0 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/alien.png\n1 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬─────────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬──────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg         \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max      \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼─────────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 969 ms \u001b[90m│\u001b[39m 15300 ms \u001b[90m│\u001b[39m 29831 ms \u001b[90m│\u001b[39m 30132 ms \u001b[90m│\u001b[39m 15143.83 ms \u001b[90m│\u001b[39m 8807.54 ms \u001b[90m│\u001b[39m 30385 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴─────────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴──────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 3       \u001b[90m│\u001b[39m 3       \u001b[90m│\u001b[39m 3       \u001b[90m│\u001b[39m 4      \u001b[90m│\u001b[39m 3.15    \u001b[90m│\u001b[39m 0.36    \u001b[90m│\u001b[39m 3       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 86.1 kB \u001b[90m│\u001b[39m 86.1 kB \u001b[90m│\u001b[39m 86.1 kB \u001b[90m│\u001b[39m 115 kB \u001b[90m│\u001b[39m 90.4 kB \u001b[90m│\u001b[39m 10.3 kB \u001b[90m│\u001b[39m 86.1 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 189   \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n378 requests in 60.06s, 5.43 MB read\n188 errors (0 timeouts)\n\n\n----------------\n\n\n\nCLIENTS: *** 2 ***\n\nRunning 60s test @ http://192.168.2.131/\n2 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬─────────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬──────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg         \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max      \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼─────────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 803 ms \u001b[90m│\u001b[39m 14773 ms \u001b[90m│\u001b[39m 29269 ms \u001b[90m│\u001b[39m 29642 ms \u001b[90m│\u001b[39m 14925.25 ms \u001b[90m│\u001b[39m 8556.82 ms \u001b[90m│\u001b[39m 29974 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴─────────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴──────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 17      \u001b[90m│\u001b[39m 17      \u001b[90m│\u001b[39m 19      \u001b[90m│\u001b[39m 21    \u001b[90m│\u001b[39m 18.9    \u001b[90m│\u001b[39m 0.98    \u001b[90m│\u001b[39m 17      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 74.5 kB \u001b[90m│\u001b[39m 74.5 kB \u001b[90m│\u001b[39m 83.3 kB \u001b[90m│\u001b[39m 92 kB \u001b[90m│\u001b[39m 82.8 kB \u001b[90m│\u001b[39m 4.29 kB \u001b[90m│\u001b[39m 74.5 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 1134  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n2k requests in 60.06s, 4.97 MB read\n29 errors (0 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/api?foo=bar\n2 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬─────────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬──────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg         \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max      \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼─────────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 772 ms \u001b[90m│\u001b[39m 15252 ms \u001b[90m│\u001b[39m 29307 ms \u001b[90m│\u001b[39m 29709 ms \u001b[90m│\u001b[39m 15094.92 ms \u001b[90m│\u001b[39m 8732.51 ms \u001b[90m│\u001b[39m 30070 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴─────────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴──────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 26      \u001b[90m│\u001b[39m 27      \u001b[90m│\u001b[39m 29      \u001b[90m│\u001b[39m 32      \u001b[90m│\u001b[39m 29.72   \u001b[90m│\u001b[39m 1.43  \u001b[90m│\u001b[39m 26      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 4.58 kB \u001b[90m│\u001b[39m 4.75 kB \u001b[90m│\u001b[39m 5.11 kB \u001b[90m│\u001b[39m 5.63 kB \u001b[90m│\u001b[39m 5.23 kB \u001b[90m│\u001b[39m 251 B \u001b[90m│\u001b[39m 4.58 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 1783  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n4k requests in 60.06s, 314 kB read\n1k errors (0 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/alien.png\n2 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬─────────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬──────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg         \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max      \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼─────────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 856 ms \u001b[90m│\u001b[39m 15635 ms \u001b[90m│\u001b[39m 28880 ms \u001b[90m│\u001b[39m 29310 ms \u001b[90m│\u001b[39m 15261.99 ms \u001b[90m│\u001b[39m 8577.65 ms \u001b[90m│\u001b[39m 29700 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴─────────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴──────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 4      \u001b[90m│\u001b[39m 4      \u001b[90m│\u001b[39m 5      \u001b[90m│\u001b[39m 6      \u001b[90m│\u001b[39m 4.64   \u001b[90m│\u001b[39m 0.64    \u001b[90m│\u001b[39m 4      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 115 kB \u001b[90m│\u001b[39m 115 kB \u001b[90m│\u001b[39m 144 kB \u001b[90m│\u001b[39m 172 kB \u001b[90m│\u001b[39m 133 kB \u001b[90m│\u001b[39m 18.1 kB \u001b[90m│\u001b[39m 115 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 278   \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n558 requests in 60.06s, 7.98 MB read\n17 errors (0 timeouts)\n\n\n----------------\n\n\n\nCLIENTS: *** 3 ***\n\nRunning 60s test @ http://192.168.2.131/\n3 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬─────────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬──────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg         \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max      \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼─────────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 794 ms \u001b[90m│\u001b[39m 15166 ms \u001b[90m│\u001b[39m 29323 ms \u001b[90m│\u001b[39m 29697 ms \u001b[90m│\u001b[39m 15066.78 ms \u001b[90m│\u001b[39m 8676.25 ms \u001b[90m│\u001b[39m 30114 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴─────────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴──────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 22      \u001b[90m│\u001b[39m 23     \u001b[90m│\u001b[39m 26     \u001b[90m│\u001b[39m 29     \u001b[90m│\u001b[39m 25.99  \u001b[90m│\u001b[39m 1.42    \u001b[90m│\u001b[39m 22      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 96.4 kB \u001b[90m│\u001b[39m 101 kB \u001b[90m│\u001b[39m 114 kB \u001b[90m│\u001b[39m 127 kB \u001b[90m│\u001b[39m 114 kB \u001b[90m│\u001b[39m 6.22 kB \u001b[90m│\u001b[39m 96.4 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 1559  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n3k requests in 60.06s, 6.83 MB read\n14 errors (0 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/api?foo=bar\n3 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬─────────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬──────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg         \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max      \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼─────────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 826 ms \u001b[90m│\u001b[39m 14949 ms \u001b[90m│\u001b[39m 29377 ms \u001b[90m│\u001b[39m 29790 ms \u001b[90m│\u001b[39m 15049.95 ms \u001b[90m│\u001b[39m 8720.15 ms \u001b[90m│\u001b[39m 30168 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴─────────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴──────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 32      \u001b[90m│\u001b[39m 32      \u001b[90m│\u001b[39m 36      \u001b[90m│\u001b[39m 39      \u001b[90m│\u001b[39m 36.1    \u001b[90m│\u001b[39m 1.82  \u001b[90m│\u001b[39m 32      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 5.63 kB \u001b[90m│\u001b[39m 5.63 kB \u001b[90m│\u001b[39m 6.34 kB \u001b[90m│\u001b[39m 6.87 kB \u001b[90m│\u001b[39m 6.36 kB \u001b[90m│\u001b[39m 319 B \u001b[90m│\u001b[39m 5.63 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 2166  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n4k requests in 60.1s, 381 kB read\n1k errors (0 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/alien.png\n3 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬─────────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬──────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg         \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max      \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼─────────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 995 ms \u001b[90m│\u001b[39m 15127 ms \u001b[90m│\u001b[39m 29464 ms \u001b[90m│\u001b[39m 29993 ms \u001b[90m│\u001b[39m 15219.94 ms \u001b[90m│\u001b[39m 8704 ms \u001b[90m│\u001b[39m 30258 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴─────────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴──────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 3       \u001b[90m│\u001b[39m 3       \u001b[90m│\u001b[39m 6      \u001b[90m│\u001b[39m 6      \u001b[90m│\u001b[39m 5.62   \u001b[90m│\u001b[39m 0.99    \u001b[90m│\u001b[39m 3       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 86.1 kB \u001b[90m│\u001b[39m 86.1 kB \u001b[90m│\u001b[39m 172 kB \u001b[90m│\u001b[39m 172 kB \u001b[90m│\u001b[39m 161 kB \u001b[90m│\u001b[39m 28.3 kB \u001b[90m│\u001b[39m 86.1 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 337   \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n677 requests in 60.07s, 9.67 MB read\n54 errors (0 timeouts)\n\n\n----------------\n\n\n\nCLIENTS: *** 4 ***\n\nRunning 60s test @ http://192.168.2.131/\n4 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬─────────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬──────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg         \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max      \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼─────────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 702 ms \u001b[90m│\u001b[39m 15255 ms \u001b[90m│\u001b[39m 29811 ms \u001b[90m│\u001b[39m 30226 ms \u001b[90m│\u001b[39m 15144.93 ms \u001b[90m│\u001b[39m 8830.16 ms \u001b[90m│\u001b[39m 30616 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴─────────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴──────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 26     \u001b[90m│\u001b[39m 27     \u001b[90m│\u001b[39m 29     \u001b[90m│\u001b[39m 32     \u001b[90m│\u001b[39m 29.05  \u001b[90m│\u001b[39m 1.58   \u001b[90m│\u001b[39m 26     \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 114 kB \u001b[90m│\u001b[39m 118 kB \u001b[90m│\u001b[39m 127 kB \u001b[90m│\u001b[39m 140 kB \u001b[90m│\u001b[39m 127 kB \u001b[90m│\u001b[39m 6.9 kB \u001b[90m│\u001b[39m 114 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 1743  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n3k requests in 60.06s, 7.63 MB read\n20 errors (0 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/api?foo=bar\n4 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬─────────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬──────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg         \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max      \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼─────────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 762 ms \u001b[90m│\u001b[39m 15231 ms \u001b[90m│\u001b[39m 29096 ms \u001b[90m│\u001b[39m 29534 ms \u001b[90m│\u001b[39m 15112.66 ms \u001b[90m│\u001b[39m 8660.6 ms \u001b[90m│\u001b[39m 29997 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴─────────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴──────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 35      \u001b[90m│\u001b[39m 35      \u001b[90m│\u001b[39m 41      \u001b[90m│\u001b[39m 44      \u001b[90m│\u001b[39m 40.89  \u001b[90m│\u001b[39m 1.9   \u001b[90m│\u001b[39m 35      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 6.16 kB \u001b[90m│\u001b[39m 6.16 kB \u001b[90m│\u001b[39m 7.22 kB \u001b[90m│\u001b[39m 7.75 kB \u001b[90m│\u001b[39m 7.2 kB \u001b[90m│\u001b[39m 334 B \u001b[90m│\u001b[39m 6.16 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 2453  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n5k requests in 60.06s, 432 kB read\n977 errors (0 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/alien.png\n4 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬─────────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬──────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg         \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max      \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼─────────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 1175 ms \u001b[90m│\u001b[39m 15413 ms \u001b[90m│\u001b[39m 29485 ms \u001b[90m│\u001b[39m 30066 ms \u001b[90m│\u001b[39m 15217.07 ms \u001b[90m│\u001b[39m 8604.35 ms \u001b[90m│\u001b[39m 30126 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴─────────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴──────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 4      \u001b[90m│\u001b[39m 4      \u001b[90m│\u001b[39m 8      \u001b[90m│\u001b[39m 8      \u001b[90m│\u001b[39m 6.47   \u001b[90m│\u001b[39m 1.87    \u001b[90m│\u001b[39m 4      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 115 kB \u001b[90m│\u001b[39m 115 kB \u001b[90m│\u001b[39m 230 kB \u001b[90m│\u001b[39m 230 kB \u001b[90m│\u001b[39m 186 kB \u001b[90m│\u001b[39m 53.6 kB \u001b[90m│\u001b[39m 115 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 388   \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n780 requests in 60.05s, 11.1 MB read\n39 errors (0 timeouts)\n\n\n----------------\n\n\n\nCLIENTS: *** 5 ***\n\nRunning 60s test @ http://192.168.2.131/\n5 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬─────────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬──────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg         \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max      \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼─────────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 802 ms \u001b[90m│\u001b[39m 14978 ms \u001b[90m│\u001b[39m 29391 ms \u001b[90m│\u001b[39m 29863 ms \u001b[90m│\u001b[39m 15042.57 ms \u001b[90m│\u001b[39m 8642.88 ms \u001b[90m│\u001b[39m 30280 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴─────────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴──────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 26     \u001b[90m│\u001b[39m 29     \u001b[90m│\u001b[39m 33     \u001b[90m│\u001b[39m 37     \u001b[90m│\u001b[39m 33.19  \u001b[90m│\u001b[39m 2.13   \u001b[90m│\u001b[39m 26     \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 114 kB \u001b[90m│\u001b[39m 127 kB \u001b[90m│\u001b[39m 145 kB \u001b[90m│\u001b[39m 162 kB \u001b[90m│\u001b[39m 145 kB \u001b[90m│\u001b[39m 9.3 kB \u001b[90m│\u001b[39m 114 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 1991  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n4k requests in 60.07s, 8.72 MB read\n10 errors (0 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/api?foo=bar\n5 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬─────────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬──────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg         \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max      \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼─────────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 724 ms \u001b[90m│\u001b[39m 15356 ms \u001b[90m│\u001b[39m 29304 ms \u001b[90m│\u001b[39m 29791 ms \u001b[90m│\u001b[39m 15198.71 ms \u001b[90m│\u001b[39m 8761.23 ms \u001b[90m│\u001b[39m 30174 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴─────────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴──────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 40      \u001b[90m│\u001b[39m 40      \u001b[90m│\u001b[39m 45      \u001b[90m│\u001b[39m 50      \u001b[90m│\u001b[39m 44.84   \u001b[90m│\u001b[39m 2.78  \u001b[90m│\u001b[39m 40      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 7.04 kB \u001b[90m│\u001b[39m 7.04 kB \u001b[90m│\u001b[39m 7.92 kB \u001b[90m│\u001b[39m 8.81 kB \u001b[90m│\u001b[39m 7.89 kB \u001b[90m│\u001b[39m 489 B \u001b[90m│\u001b[39m 7.04 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 2690  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n5k requests in 60.07s, 473 kB read\n603 errors (0 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/alien.png\n5 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬─────────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬──────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg         \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max      \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼─────────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 1250 ms \u001b[90m│\u001b[39m 15289 ms \u001b[90m│\u001b[39m 29607 ms \u001b[90m│\u001b[39m 30193 ms \u001b[90m│\u001b[39m 15345.82 ms \u001b[90m│\u001b[39m 8719.55 ms \u001b[90m│\u001b[39m 30354 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴─────────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴──────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 5      \u001b[90m│\u001b[39m 5      \u001b[90m│\u001b[39m 6      \u001b[90m│\u001b[39m 10     \u001b[90m│\u001b[39m 7.25   \u001b[90m│\u001b[39m 2.25    \u001b[90m│\u001b[39m 5      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 144 kB \u001b[90m│\u001b[39m 144 kB \u001b[90m│\u001b[39m 172 kB \u001b[90m│\u001b[39m 287 kB \u001b[90m│\u001b[39m 208 kB \u001b[90m│\u001b[39m 64.5 kB \u001b[90m│\u001b[39m 144 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 435   \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n875 requests in 60.06s, 12.5 MB read\n36 errors (0 timeouts)\n\n\n----------------\n\n\n\nCLIENTS: *** 6 ***\n\nRunning 60s test @ http://192.168.2.131/\n6 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬─────────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬──────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg         \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max      \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼─────────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 847 ms \u001b[90m│\u001b[39m 14920 ms \u001b[90m│\u001b[39m 28899 ms \u001b[90m│\u001b[39m 29392 ms \u001b[90m│\u001b[39m 15008.54 ms \u001b[90m│\u001b[39m 8456.33 ms \u001b[90m│\u001b[39m 29870 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴─────────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴──────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 33     \u001b[90m│\u001b[39m 33     \u001b[90m│\u001b[39m 36     \u001b[90m│\u001b[39m 39     \u001b[90m│\u001b[39m 35.75  \u001b[90m│\u001b[39m 1.75    \u001b[90m│\u001b[39m 33     \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 145 kB \u001b[90m│\u001b[39m 145 kB \u001b[90m│\u001b[39m 158 kB \u001b[90m│\u001b[39m 171 kB \u001b[90m│\u001b[39m 157 kB \u001b[90m│\u001b[39m 7.65 kB \u001b[90m│\u001b[39m 145 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 2145  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n4k requests in 60.06s, 9.4 MB read\n3 errors (0 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/api?foo=bar\n6 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬─────────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬──────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg         \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max      \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼─────────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 890 ms \u001b[90m│\u001b[39m 14807 ms \u001b[90m│\u001b[39m 29142 ms \u001b[90m│\u001b[39m 29732 ms \u001b[90m│\u001b[39m 14934.33 ms \u001b[90m│\u001b[39m 8513.39 ms \u001b[90m│\u001b[39m 30168 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴─────────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴──────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 44      \u001b[90m│\u001b[39m 44      \u001b[90m│\u001b[39m 48     \u001b[90m│\u001b[39m 53      \u001b[90m│\u001b[39m 48.3    \u001b[90m│\u001b[39m 2.22  \u001b[90m│\u001b[39m 44      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 7.75 kB \u001b[90m│\u001b[39m 7.75 kB \u001b[90m│\u001b[39m 8.5 kB \u001b[90m│\u001b[39m 9.38 kB \u001b[90m│\u001b[39m 8.54 kB \u001b[90m│\u001b[39m 395 B \u001b[90m│\u001b[39m 7.74 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 2898  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n6k requests in 60.07s, 512 kB read\n386 errors (0 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/alien.png\n6 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬──────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg        \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max      \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 853 ms \u001b[90m│\u001b[39m 15325 ms \u001b[90m│\u001b[39m 29742 ms \u001b[90m│\u001b[39m 30578 ms \u001b[90m│\u001b[39m 15287.1 ms \u001b[90m│\u001b[39m 8714.92 ms \u001b[90m│\u001b[39m 30650 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴──────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 6      \u001b[90m│\u001b[39m 6      \u001b[90m│\u001b[39m 6      \u001b[90m│\u001b[39m 12     \u001b[90m│\u001b[39m 7.7    \u001b[90m│\u001b[39m 2.44  \u001b[90m│\u001b[39m 6      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 172 kB \u001b[90m│\u001b[39m 172 kB \u001b[90m│\u001b[39m 172 kB \u001b[90m│\u001b[39m 345 kB \u001b[90m│\u001b[39m 221 kB \u001b[90m│\u001b[39m 70 kB \u001b[90m│\u001b[39m 172 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 462   \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n930 requests in 60.06s, 13.3 MB read\n24 errors (0 timeouts)\n\n\n----------------\n\n\n\nCLIENTS: *** 7 ***\n\nRunning 60s test @ http://192.168.2.131/\n7 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬─────────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬──────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg         \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max      \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼─────────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 785 ms \u001b[90m│\u001b[39m 15141 ms \u001b[90m│\u001b[39m 29506 ms \u001b[90m│\u001b[39m 29981 ms \u001b[90m│\u001b[39m 15124.91 ms \u001b[90m│\u001b[39m 8769.84 ms \u001b[90m│\u001b[39m 30379 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴─────────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴──────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 32     \u001b[90m│\u001b[39m 33     \u001b[90m│\u001b[39m 37     \u001b[90m│\u001b[39m 40     \u001b[90m│\u001b[39m 36.64  \u001b[90m│\u001b[39m 2.04   \u001b[90m│\u001b[39m 32     \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 140 kB \u001b[90m│\u001b[39m 145 kB \u001b[90m│\u001b[39m 162 kB \u001b[90m│\u001b[39m 175 kB \u001b[90m│\u001b[39m 160 kB \u001b[90m│\u001b[39m 8.9 kB \u001b[90m│\u001b[39m 140 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 2198  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n4k requests in 60.06s, 9.63 MB read\n1 errors (0 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/api?foo=bar\n7 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬─────────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬──────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg         \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max      \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼─────────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 773 ms \u001b[90m│\u001b[39m 15322 ms \u001b[90m│\u001b[39m 29472 ms \u001b[90m│\u001b[39m 29911 ms \u001b[90m│\u001b[39m 15145.75 ms \u001b[90m│\u001b[39m 8792.14 ms \u001b[90m│\u001b[39m 30238 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴─────────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴──────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 45      \u001b[90m│\u001b[39m 45      \u001b[90m│\u001b[39m 51      \u001b[90m│\u001b[39m 56      \u001b[90m│\u001b[39m 50.62   \u001b[90m│\u001b[39m 3.07  \u001b[90m│\u001b[39m 45      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 7.97 kB \u001b[90m│\u001b[39m 7.97 kB \u001b[90m│\u001b[39m 9.03 kB \u001b[90m│\u001b[39m 9.92 kB \u001b[90m│\u001b[39m 8.96 kB \u001b[90m│\u001b[39m 541 B \u001b[90m│\u001b[39m 7.96 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 3037  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n6k requests in 60.06s, 538 kB read\n252 errors (0 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/alien.png\n7 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬─────────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬──────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg         \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max      \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼─────────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 903 ms \u001b[90m│\u001b[39m 15426 ms \u001b[90m│\u001b[39m 29337 ms \u001b[90m│\u001b[39m 30187 ms \u001b[90m│\u001b[39m 15395.14 ms \u001b[90m│\u001b[39m 8592.24 ms \u001b[90m│\u001b[39m 30239 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴─────────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴──────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 7      \u001b[90m│\u001b[39m 7      \u001b[90m│\u001b[39m 7      \u001b[90m│\u001b[39m 14     \u001b[90m│\u001b[39m 8.06   \u001b[90m│\u001b[39m 2.03  \u001b[90m│\u001b[39m 7      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 201 kB \u001b[90m│\u001b[39m 201 kB \u001b[90m│\u001b[39m 201 kB \u001b[90m│\u001b[39m 402 kB \u001b[90m│\u001b[39m 231 kB \u001b[90m│\u001b[39m 58 kB \u001b[90m│\u001b[39m 201 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 483   \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n973 requests in 60.06s, 13.9 MB read\n27 errors (0 timeouts)\n\n\n----------------\n\n\n\nCLIENTS: *** 8 ***\n\nRunning 60s test @ http://192.168.2.131/\n8 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬─────────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬──────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg         \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max      \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼─────────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 947 ms \u001b[90m│\u001b[39m 15230 ms \u001b[90m│\u001b[39m 29194 ms \u001b[90m│\u001b[39m 29710 ms \u001b[90m│\u001b[39m 15139.81 ms \u001b[90m│\u001b[39m 8698.37 ms \u001b[90m│\u001b[39m 30418 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴─────────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴──────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 31     \u001b[90m│\u001b[39m 33     \u001b[90m│\u001b[39m 38     \u001b[90m│\u001b[39m 43     \u001b[90m│\u001b[39m 37.92  \u001b[90m│\u001b[39m 2.7     \u001b[90m│\u001b[39m 31     \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 136 kB \u001b[90m│\u001b[39m 145 kB \u001b[90m│\u001b[39m 167 kB \u001b[90m│\u001b[39m 188 kB \u001b[90m│\u001b[39m 166 kB \u001b[90m│\u001b[39m 11.8 kB \u001b[90m│\u001b[39m 136 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 2275  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n5k requests in 60.06s, 9.96 MB read\n1 errors (0 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/api?foo=bar\n8 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬─────────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬──────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg         \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max      \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼─────────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 818 ms \u001b[90m│\u001b[39m 15102 ms \u001b[90m│\u001b[39m 29043 ms \u001b[90m│\u001b[39m 29502 ms \u001b[90m│\u001b[39m 14999.69 ms \u001b[90m│\u001b[39m 8454.75 ms \u001b[90m│\u001b[39m 30295 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴─────────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴──────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 44      \u001b[90m│\u001b[39m 45      \u001b[90m│\u001b[39m 51      \u001b[90m│\u001b[39m 60      \u001b[90m│\u001b[39m 51.37   \u001b[90m│\u001b[39m 3.35  \u001b[90m│\u001b[39m 44      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 7.79 kB \u001b[90m│\u001b[39m 7.97 kB \u001b[90m│\u001b[39m 9.03 kB \u001b[90m│\u001b[39m 10.6 kB \u001b[90m│\u001b[39m 9.09 kB \u001b[90m│\u001b[39m 591 B \u001b[90m│\u001b[39m 7.79 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 3082  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n6k requests in 60s, 546 kB read\n222 errors (0 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/alien.png\n8 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬─────────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬──────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg         \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max      \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼─────────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 951 ms \u001b[90m│\u001b[39m 15565 ms \u001b[90m│\u001b[39m 30182 ms \u001b[90m│\u001b[39m 30252 ms \u001b[90m│\u001b[39m 15396.59 ms \u001b[90m│\u001b[39m 8860.08 ms \u001b[90m│\u001b[39m 31138 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴─────────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴──────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 7      \u001b[90m│\u001b[39m 8      \u001b[90m│\u001b[39m 8      \u001b[90m│\u001b[39m 14     \u001b[90m│\u001b[39m 8.56   \u001b[90m│\u001b[39m 1.59    \u001b[90m│\u001b[39m 7      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 201 kB \u001b[90m│\u001b[39m 230 kB \u001b[90m│\u001b[39m 230 kB \u001b[90m│\u001b[39m 402 kB \u001b[90m│\u001b[39m 245 kB \u001b[90m│\u001b[39m 45.5 kB \u001b[90m│\u001b[39m 201 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 513   \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n1k requests in 60.06s, 14.7 MB read\n31 errors (0 timeouts)\n\n\n----------------\n\n\n\nCLIENTS: *** 9 ***\n\nRunning 60s test @ http://192.168.2.131/\n9 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬─────────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬──────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg         \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max      \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼─────────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 951 ms \u001b[90m│\u001b[39m 15246 ms \u001b[90m│\u001b[39m 28914 ms \u001b[90m│\u001b[39m 29402 ms \u001b[90m│\u001b[39m 15108.58 ms \u001b[90m│\u001b[39m 8543.6 ms \u001b[90m│\u001b[39m 30524 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴─────────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴──────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 31     \u001b[90m│\u001b[39m 32     \u001b[90m│\u001b[39m 37     \u001b[90m│\u001b[39m 43     \u001b[90m│\u001b[39m 37.42  \u001b[90m│\u001b[39m 2.9     \u001b[90m│\u001b[39m 31     \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 136 kB \u001b[90m│\u001b[39m 140 kB \u001b[90m│\u001b[39m 162 kB \u001b[90m│\u001b[39m 188 kB \u001b[90m│\u001b[39m 164 kB \u001b[90m│\u001b[39m 12.7 kB \u001b[90m│\u001b[39m 136 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 2245  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n5k requests in 60.05s, 9.83 MB read\n1 errors (0 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/api?foo=bar\n9 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬──────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg        \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max      \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 885 ms \u001b[90m│\u001b[39m 15043 ms \u001b[90m│\u001b[39m 29217 ms \u001b[90m│\u001b[39m 29730 ms \u001b[90m│\u001b[39m 14953.4 ms \u001b[90m│\u001b[39m 8530.16 ms \u001b[90m│\u001b[39m 30399 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴──────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 44      \u001b[90m│\u001b[39m 46      \u001b[90m│\u001b[39m 52      \u001b[90m│\u001b[39m 58      \u001b[90m│\u001b[39m 52.1    \u001b[90m│\u001b[39m 3.22  \u001b[90m│\u001b[39m 44      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 7.79 kB \u001b[90m│\u001b[39m 8.14 kB \u001b[90m│\u001b[39m 9.21 kB \u001b[90m│\u001b[39m 10.3 kB \u001b[90m│\u001b[39m 9.22 kB \u001b[90m│\u001b[39m 570 B \u001b[90m│\u001b[39m 7.79 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 3126  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n6k requests in 60.07s, 553 kB read\n189 errors (0 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/alien.png\n9 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬─────────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬──────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg         \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max      \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼─────────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 1079 ms \u001b[90m│\u001b[39m 15444 ms \u001b[90m│\u001b[39m 28978 ms \u001b[90m│\u001b[39m 29935 ms \u001b[90m│\u001b[39m 15389.63 ms \u001b[90m│\u001b[39m 8469.15 ms \u001b[90m│\u001b[39m 30003 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴─────────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴──────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 9      \u001b[90m│\u001b[39m 10     \u001b[90m│\u001b[39m 8.56   \u001b[90m│\u001b[39m 2.21    \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 258 kB \u001b[90m│\u001b[39m 287 kB \u001b[90m│\u001b[39m 245 kB \u001b[90m│\u001b[39m 63.4 kB \u001b[90m│\u001b[39m 28.7 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 513   \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n1k requests in 60.06s, 14.7 MB read\n20 errors (0 timeouts)\n\n\n----------------\n\n\n\nCLIENTS: *** 10 ***\n\nRunning 60s test @ http://192.168.2.131/\n10 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬─────────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬──────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg         \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max      \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼─────────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 996 ms \u001b[90m│\u001b[39m 15183 ms \u001b[90m│\u001b[39m 29343 ms \u001b[90m│\u001b[39m 29946 ms \u001b[90m│\u001b[39m 15135.07 ms \u001b[90m│\u001b[39m 8665.13 ms \u001b[90m│\u001b[39m 30794 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴─────────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴──────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 32     \u001b[90m│\u001b[39m 32     \u001b[90m│\u001b[39m 37     \u001b[90m│\u001b[39m 43     \u001b[90m│\u001b[39m 37.59  \u001b[90m│\u001b[39m 2.43    \u001b[90m│\u001b[39m 32     \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 140 kB \u001b[90m│\u001b[39m 140 kB \u001b[90m│\u001b[39m 162 kB \u001b[90m│\u001b[39m 188 kB \u001b[90m│\u001b[39m 165 kB \u001b[90m│\u001b[39m 10.6 kB \u001b[90m│\u001b[39m 140 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 2255  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n5k requests in 60.06s, 9.88 MB read\n5 errors (0 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/api?foo=bar\n10 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬─────────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬──────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg         \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max      \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼─────────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 876 ms \u001b[90m│\u001b[39m 15390 ms \u001b[90m│\u001b[39m 29322 ms \u001b[90m│\u001b[39m 29837 ms \u001b[90m│\u001b[39m 15193.95 ms \u001b[90m│\u001b[39m 8726.45 ms \u001b[90m│\u001b[39m 30887 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴─────────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴──────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 46      \u001b[90m│\u001b[39m 47      \u001b[90m│\u001b[39m 52      \u001b[90m│\u001b[39m 60      \u001b[90m│\u001b[39m 52.42   \u001b[90m│\u001b[39m 3.63  \u001b[90m│\u001b[39m 46      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 8.14 kB \u001b[90m│\u001b[39m 8.32 kB \u001b[90m│\u001b[39m 9.21 kB \u001b[90m│\u001b[39m 10.6 kB \u001b[90m│\u001b[39m 9.28 kB \u001b[90m│\u001b[39m 642 B \u001b[90m│\u001b[39m 8.14 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 3145  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n6k requests in 60.07s, 557 kB read\n193 errors (0 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/alien.png\n10 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬─────────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬──────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg         \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max      \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼─────────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 1126 ms \u001b[90m│\u001b[39m 15812 ms \u001b[90m│\u001b[39m 30288 ms \u001b[90m│\u001b[39m 31239 ms \u001b[90m│\u001b[39m 15913.56 ms \u001b[90m│\u001b[39m 8747.22 ms \u001b[90m│\u001b[39m 32439 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴─────────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴──────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 2       \u001b[90m│\u001b[39m 10     \u001b[90m│\u001b[39m 10     \u001b[90m│\u001b[39m 8.84   \u001b[90m│\u001b[39m 2.37  \u001b[90m│\u001b[39m 2       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 57.4 kB \u001b[90m│\u001b[39m 287 kB \u001b[90m│\u001b[39m 287 kB \u001b[90m│\u001b[39m 254 kB \u001b[90m│\u001b[39m 68 kB \u001b[90m│\u001b[39m 57.4 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 530   \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n1k requests in 60.06s, 15.2 MB read\n42 errors (0 timeouts)\n\n\n----------------\n\n\n\nCLIENTS: *** 15 ***\n\nRunning 60s test @ http://192.168.2.131/\n15 connections\n1 workers\n\nnode:internal/event_target:1084\n  process.nextTick(() => { throw err; });\n                           ^\n\nTypeError: colorize is not a function\n    at /Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/printResult.js:46:31\n    at Array.forEach (<anonymous>)\n    at printResult (/Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/printResult.js:43:43)\n    at EventEmitter.<anonymous> (/Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/progressTracker.js:79:28)\n    at EventEmitter.emit (node:events:527:35)\n    at _cb (/Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/init.js:76:13)\n    at handleFinish (/Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/manager.js:41:5)\n    at Worker.<anonymous> (/Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/manager.js:78:13)\n    at Worker.emit (node:events:515:28)\n    at MessagePort.<anonymous> (node:internal/worker:263:53)\n\nNode.js v21.1.0\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/api?foo=bar\n15 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬─────────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬──────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg         \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max      \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼─────────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 690 ms \u001b[90m│\u001b[39m 12131 ms \u001b[90m│\u001b[39m 28685 ms \u001b[90m│\u001b[39m 29798 ms \u001b[90m│\u001b[39m 13051.88 ms \u001b[90m│\u001b[39m 8385.32 ms \u001b[90m│\u001b[39m 32739 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴─────────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴──────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 46      \u001b[90m│\u001b[39m 50      \u001b[90m│\u001b[39m 56      \u001b[90m│\u001b[39m 63      \u001b[90m│\u001b[39m 55.99   \u001b[90m│\u001b[39m 3.53  \u001b[90m│\u001b[39m 46      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 8.14 kB \u001b[90m│\u001b[39m 8.86 kB \u001b[90m│\u001b[39m 9.92 kB \u001b[90m│\u001b[39m 11.2 kB \u001b[90m│\u001b[39m 9.91 kB \u001b[90m│\u001b[39m 624 B \u001b[90m│\u001b[39m 8.14 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 3359  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n7k requests in 60.06s, 595 kB read\n269 errors (5 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/alien.png\n15 connections\n1 workers\n\nnode:internal/event_target:1084\n  process.nextTick(() => { throw err; });\n                           ^\n\nTypeError: colorize is not a function\n    at /Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/printResult.js:46:31\n    at Array.forEach (<anonymous>)\n    at printResult (/Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/printResult.js:43:43)\n    at EventEmitter.<anonymous> (/Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/progressTracker.js:79:28)\n    at EventEmitter.emit (node:events:527:35)\n    at _cb (/Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/init.js:76:13)\n    at handleFinish (/Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/manager.js:41:5)\n    at Worker.<anonymous> (/Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/manager.js:78:13)\n    at Worker.emit (node:events:515:28)\n    at MessagePort.<anonymous> (node:internal/worker:263:53)\n\nNode.js v21.1.0\n\n\n----------------\n\n\n\nCLIENTS: *** 20 ***\n\nRunning 60s test @ http://192.168.2.131/\n20 connections\n1 workers\n\nnode:internal/event_target:1084\n  process.nextTick(() => { throw err; });\n                           ^\n\nTypeError: colorize is not a function\n    at /Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/printResult.js:46:31\n    at Array.forEach (<anonymous>)\n    at printResult (/Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/printResult.js:43:43)\n    at EventEmitter.<anonymous> (/Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/progressTracker.js:79:28)\n    at EventEmitter.emit (node:events:527:35)\n    at _cb (/Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/init.js:76:13)\n    at handleFinish (/Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/manager.js:41:5)\n    at Worker.<anonymous> (/Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/manager.js:78:13)\n    at Worker.emit (node:events:515:28)\n    at MessagePort.<anonymous> (node:internal/worker:263:53)\n\nNode.js v21.1.0\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/api?foo=bar\n20 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬──────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg        \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max      \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 377 ms \u001b[90m│\u001b[39m 5749 ms \u001b[90m│\u001b[39m 19598 ms \u001b[90m│\u001b[39m 21657 ms \u001b[90m│\u001b[39m 6953.55 ms \u001b[90m│\u001b[39m 5299.16 ms \u001b[90m│\u001b[39m 23969 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴──────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 45      \u001b[90m│\u001b[39m 45      \u001b[90m│\u001b[39m 55      \u001b[90m│\u001b[39m 60      \u001b[90m│\u001b[39m 54.27   \u001b[90m│\u001b[39m 3.9   \u001b[90m│\u001b[39m 45      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 7.88 kB \u001b[90m│\u001b[39m 7.88 kB \u001b[90m│\u001b[39m 9.63 kB \u001b[90m│\u001b[39m 10.6 kB \u001b[90m│\u001b[39m 9.53 kB \u001b[90m│\u001b[39m 687 B \u001b[90m│\u001b[39m 7.88 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 3256  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n7k requests in 60.06s, 571 kB read\n312 errors (30 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/alien.png\n20 connections\n1 workers\n\nnode:internal/event_target:1084\n  process.nextTick(() => { throw err; });\n                           ^\n\nTypeError: colorize is not a function\n    at /Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/printResult.js:46:31\n    at Array.forEach (<anonymous>)\n    at printResult (/Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/printResult.js:43:43)\n    at EventEmitter.<anonymous> (/Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/progressTracker.js:79:28)\n    at EventEmitter.emit (node:events:527:35)\n    at _cb (/Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/init.js:76:13)\n    at handleFinish (/Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/manager.js:41:5)\n    at Worker.<anonymous> (/Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/manager.js:78:13)\n    at Worker.emit (node:events:515:28)\n    at MessagePort.<anonymous> (node:internal/worker:263:53)\n\nNode.js v21.1.0\n\n\n----------------\n\n"
  },
  {
    "path": "benchmark/results/arduinomongoose-websocket-loadtest.log",
    "content": "\n\nCLIENTS: *** 1 ***\n\n\nTarget URL:          ws://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  1\nAgent:               none\n\nCompleted requests:  3750\nTotal errors:        0\nTotal time:          60.001 s\nMean latency:        15.5 ms\nEffective rps:       62\n\nPercentage of requests served within a certain time\n  50%      12 ms\n  90%      18 ms\n  95%      36 ms\n  99%      80 ms\n 100%      223 ms (longest request)\n\n\nCLIENTS: *** 2 ***\n\n\nTarget URL:          ws://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  2\nAgent:               none\n\nCompleted requests:  5795\nTotal errors:        0\nTotal time:          60.004 s\nMean latency:        20.2 ms\nEffective rps:       97\n\nPercentage of requests served within a certain time\n  50%      16 ms\n  90%      27 ms\n  95%      64 ms\n  99%      86 ms\n 100%      108 ms (longest request)\n\n\nCLIENTS: *** 3 ***\n\n\nTarget URL:          ws://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  3\nAgent:               none\n\nCompleted requests:  7445\nTotal errors:        0\nTotal time:          60.003 s\nMean latency:        23.6 ms\nEffective rps:       124\n\nPercentage of requests served within a certain time\n  50%      19 ms\n  90%      32 ms\n  95%      70 ms\n  99%      92 ms\n 100%      121 ms (longest request)\n\n\nCLIENTS: *** 4 ***\n\n\nTarget URL:          ws://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  4\nAgent:               none\n\nCompleted requests:  8751\nTotal errors:        0\nTotal time:          60.005 s\nMean latency:        26.9 ms\nEffective rps:       146\n\nPercentage of requests served within a certain time\n  50%      22 ms\n  90%      38 ms\n  95%      73 ms\n  99%      95 ms\n 100%      115 ms (longest request)\n\n\nCLIENTS: *** 5 ***\n\n\nTarget URL:          ws://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  5\nAgent:               none\n\nCompleted requests:  9953\nTotal errors:        0\nTotal time:          60.004 s\nMean latency:        29.6 ms\nEffective rps:       166\n\nPercentage of requests served within a certain time\n  50%      25 ms\n  90%      42 ms\n  95%      74 ms\n  99%      93 ms\n 100%      116 ms (longest request)\n\n\nCLIENTS: *** 6 ***\n\n\nTarget URL:          ws://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  6\nAgent:               none\n\nCompleted requests:  10871\nTotal errors:        0\nTotal time:          60.005 s\nMean latency:        32.6 ms\nEffective rps:       181\n\nPercentage of requests served within a certain time\n  50%      27 ms\n  90%      50 ms\n  95%      82 ms\n  99%      100 ms\n 100%      116 ms (longest request)\n\n\nCLIENTS: *** 7 ***\n\n\nTarget URL:          ws://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  7\nAgent:               none\n\nCompleted requests:  11777\nTotal errors:        0\nTotal time:          60.003 s\nMean latency:        35.1 ms\nEffective rps:       196\n\nPercentage of requests served within a certain time\n  50%      30 ms\n  90%      66 ms\n  95%      83 ms\n  99%      101 ms\n 100%      137 ms (longest request)\n\n\nCLIENTS: *** 8 ***\n\n\nTarget URL:          ws://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  8\nRunning on cores:    2\nAgent:               none\n\nCompleted requests:  11639\nTotal errors:        0\nTotal time:          60.004 s\nMean latency:        35.4 ms\nEffective rps:       194\n\nPercentage of requests served within a certain time\n  50%      30 ms\n  90%      67 ms\n  95%      86 ms\n  99%      106 ms\n 100%      135 ms (longest request)\n\n\nCLIENTS: *** 10 ***\n\n\nTarget URL:          ws://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  10\nRunning on cores:    2\nAgent:               none\n\nCompleted requests:  11619\nTotal errors:        0\nTotal time:          60.004 s\nMean latency:        35.6 ms\nEffective rps:       194\n\nPercentage of requests served within a certain time\n  50%      30 ms\n  90%      71 ms\n  95%      87 ms\n  99%      105 ms\n 100%      125 ms (longest request)\n\n\nCLIENTS: *** 16 ***\n\n\nTarget URL:          ws://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  16\nRunning on cores:    2\nAgent:               none\n\nCompleted requests:  15314\nTotal errors:        0\nTotal time:          60.005 s\nMean latency:        54.2 ms\nEffective rps:       255\n\nPercentage of requests served within a certain time\n  50%      46 ms\n  90%      91 ms\n  95%      105 ms\n  99%      127 ms\n 100%      826 ms (longest request)\n\n\nCLIENTS: *** 20 ***\n\n\nTarget URL:          ws://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  20\nRunning on cores:    2\nAgent:               none\n\nCompleted requests:  15370\nTotal errors:        0\nTotal time:          60.005 s\nMean latency:        57.7 ms\nEffective rps:       256\n\nPercentage of requests served within a certain time\n  50%      48 ms\n  90%      96 ms\n  95%      110 ms\n  99%      132 ms\n 100%      851 ms (longest request)\n"
  },
  {
    "path": "benchmark/results/espasync-http-loadtest.log",
    "content": "\n\nCLIENTS: *** 1 ***\n\nRunning 60s test @ http://192.168.2.131/\n1 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 32 ms \u001b[90m│\u001b[39m 40 ms \u001b[90m│\u001b[39m 118 ms \u001b[90m│\u001b[39m 118 ms \u001b[90m│\u001b[39m 54.67 ms \u001b[90m│\u001b[39m 29.29 ms \u001b[90m│\u001b[39m 118 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m 0.1   \u001b[90m│\u001b[39m 0.31    \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 4.38 kB \u001b[90m│\u001b[39m 438 B \u001b[90m│\u001b[39m 1.31 kB \u001b[90m│\u001b[39m 4.38 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 6     \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n12 requests in 60.08s, 26.3 kB read\n5 errors (5 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/api?foo=bar\n1 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 61 ms \u001b[90m│\u001b[39m 64 ms \u001b[90m│\u001b[39m 131 ms \u001b[90m│\u001b[39m 131 ms \u001b[90m│\u001b[39m 93.84 ms \u001b[90m│\u001b[39m 31.05 ms \u001b[90m│\u001b[39m 131 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min   \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 1     \u001b[90m│\u001b[39m 0.1    \u001b[90m│\u001b[39m 0.31   \u001b[90m│\u001b[39m 1     \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 174 B \u001b[90m│\u001b[39m 17.4 B \u001b[90m│\u001b[39m 52.2 B \u001b[90m│\u001b[39m 174 B \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 6     \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n12 requests in 60.08s, 1.04 kB read\n5 errors (5 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/alien.png\n1 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg       \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 135 ms \u001b[90m│\u001b[39m 142 ms \u001b[90m│\u001b[39m 162 ms \u001b[90m│\u001b[39m 162 ms \u001b[90m│\u001b[39m 145.84 ms \u001b[90m│\u001b[39m 10.32 ms \u001b[90m│\u001b[39m 162 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m 0.1     \u001b[90m│\u001b[39m 0.31    \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 28.8 kB \u001b[90m│\u001b[39m 2.88 kB \u001b[90m│\u001b[39m 8.63 kB \u001b[90m│\u001b[39m 28.8 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 6     \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n12 requests in 60.07s, 173 kB read\n5 errors (5 timeouts)\n\n\n----------------\n\n\n\nCLIENTS: *** 2 ***\n\nRunning 60s test @ http://192.168.2.131/\n2 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max   \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 29 ms \u001b[90m│\u001b[39m 52 ms \u001b[90m│\u001b[39m 93 ms \u001b[90m│\u001b[39m 93 ms \u001b[90m│\u001b[39m 56.09 ms \u001b[90m│\u001b[39m 17.92 ms \u001b[90m│\u001b[39m 93 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 2       \u001b[90m│\u001b[39m 0.2   \u001b[90m│\u001b[39m 0.61    \u001b[90m│\u001b[39m 2       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 8.76 kB \u001b[90m│\u001b[39m 876 B \u001b[90m│\u001b[39m 2.63 kB \u001b[90m│\u001b[39m 8.76 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 12    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n24 requests in 60.08s, 52.5 kB read\n10 errors (10 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/api?foo=bar\n2 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 60 ms \u001b[90m│\u001b[39m 106 ms \u001b[90m│\u001b[39m 126 ms \u001b[90m│\u001b[39m 126 ms \u001b[90m│\u001b[39m 102.5 ms \u001b[90m│\u001b[39m 21.86 ms \u001b[90m│\u001b[39m 126 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min   \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 2     \u001b[90m│\u001b[39m 0.2    \u001b[90m│\u001b[39m 0.61  \u001b[90m│\u001b[39m 2     \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 348 B \u001b[90m│\u001b[39m 34.8 B \u001b[90m│\u001b[39m 104 B \u001b[90m│\u001b[39m 348 B \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 12    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n24 requests in 60.08s, 2.09 kB read\n10 errors (10 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/alien.png\n2 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg       \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 228 ms \u001b[90m│\u001b[39m 245 ms \u001b[90m│\u001b[39m 268 ms \u001b[90m│\u001b[39m 268 ms \u001b[90m│\u001b[39m 245.34 ms \u001b[90m│\u001b[39m 13.38 ms \u001b[90m│\u001b[39m 268 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 2       \u001b[90m│\u001b[39m 0.2     \u001b[90m│\u001b[39m 0.61    \u001b[90m│\u001b[39m 2       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 57.5 kB \u001b[90m│\u001b[39m 5.75 kB \u001b[90m│\u001b[39m 17.3 kB \u001b[90m│\u001b[39m 57.5 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 12    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n24 requests in 60.07s, 345 kB read\n10 errors (10 timeouts)\n\n\n----------------\n\n\n\nCLIENTS: *** 3 ***\n\nRunning 60s test @ http://192.168.2.131/\n3 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 40 ms \u001b[90m│\u001b[39m 97 ms \u001b[90m│\u001b[39m 133 ms \u001b[90m│\u001b[39m 133 ms \u001b[90m│\u001b[39m 95.45 ms \u001b[90m│\u001b[39m 30.82 ms \u001b[90m│\u001b[39m 133 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 3       \u001b[90m│\u001b[39m 0.3     \u001b[90m│\u001b[39m 0.91    \u001b[90m│\u001b[39m 3       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 13.1 kB \u001b[90m│\u001b[39m 1.31 kB \u001b[90m│\u001b[39m 3.94 kB \u001b[90m│\u001b[39m 13.1 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 18    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n36 requests in 60.08s, 78.8 kB read\n15 errors (15 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/api?foo=bar\n3 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 55 ms \u001b[90m│\u001b[39m 66 ms \u001b[90m│\u001b[39m 211 ms \u001b[90m│\u001b[39m 211 ms \u001b[90m│\u001b[39m 82.78 ms \u001b[90m│\u001b[39m 37.03 ms \u001b[90m│\u001b[39m 211 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min   \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 3     \u001b[90m│\u001b[39m 0.3    \u001b[90m│\u001b[39m 0.91  \u001b[90m│\u001b[39m 3     \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 522 B \u001b[90m│\u001b[39m 52.2 B \u001b[90m│\u001b[39m 157 B \u001b[90m│\u001b[39m 522 B \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 18    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n36 requests in 60.1s, 3.13 kB read\n15 errors (15 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/alien.png\n3 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg       \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 215 ms \u001b[90m│\u001b[39m 278 ms \u001b[90m│\u001b[39m 348 ms \u001b[90m│\u001b[39m 348 ms \u001b[90m│\u001b[39m 280.56 ms \u001b[90m│\u001b[39m 30.51 ms \u001b[90m│\u001b[39m 348 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 3       \u001b[90m│\u001b[39m 0.3     \u001b[90m│\u001b[39m 0.91    \u001b[90m│\u001b[39m 3       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 86.3 kB \u001b[90m│\u001b[39m 8.62 kB \u001b[90m│\u001b[39m 25.9 kB \u001b[90m│\u001b[39m 86.3 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 18    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n36 requests in 60.15s, 518 kB read\n15 errors (15 timeouts)\n\n\n----------------\n\n\n\nCLIENTS: *** 4 ***\n\nRunning 60s test @ http://192.168.2.131/\n4 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 29 ms \u001b[90m│\u001b[39m 76 ms \u001b[90m│\u001b[39m 137 ms \u001b[90m│\u001b[39m 137 ms \u001b[90m│\u001b[39m 86.55 ms \u001b[90m│\u001b[39m 35.16 ms \u001b[90m│\u001b[39m 137 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 4       \u001b[90m│\u001b[39m 0.4     \u001b[90m│\u001b[39m 1.21    \u001b[90m│\u001b[39m 4       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 17.5 kB \u001b[90m│\u001b[39m 1.75 kB \u001b[90m│\u001b[39m 5.25 kB \u001b[90m│\u001b[39m 17.5 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 24    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n48 requests in 60.13s, 105 kB read\n20 errors (20 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/api?foo=bar\n4 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg       \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 54 ms \u001b[90m│\u001b[39m 108 ms \u001b[90m│\u001b[39m 523 ms \u001b[90m│\u001b[39m 523 ms \u001b[90m│\u001b[39m 164.71 ms \u001b[90m│\u001b[39m 130.96 ms \u001b[90m│\u001b[39m 523 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min   \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 4     \u001b[90m│\u001b[39m 0.4    \u001b[90m│\u001b[39m 1.21  \u001b[90m│\u001b[39m 4     \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 696 B \u001b[90m│\u001b[39m 69.6 B \u001b[90m│\u001b[39m 209 B \u001b[90m│\u001b[39m 696 B \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 24    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n48 requests in 60.09s, 4.18 kB read\n20 errors (20 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/alien.png\n4 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg       \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 322 ms \u001b[90m│\u001b[39m 379 ms \u001b[90m│\u001b[39m 405 ms \u001b[90m│\u001b[39m 405 ms \u001b[90m│\u001b[39m 372.55 ms \u001b[90m│\u001b[39m 20.5 ms \u001b[90m│\u001b[39m 405 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 4      \u001b[90m│\u001b[39m 0.4     \u001b[90m│\u001b[39m 1.21    \u001b[90m│\u001b[39m 4      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 115 kB \u001b[90m│\u001b[39m 11.5 kB \u001b[90m│\u001b[39m 34.5 kB \u001b[90m│\u001b[39m 115 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 24    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n48 requests in 60.08s, 690 kB read\n20 errors (20 timeouts)\n\n\n----------------\n\n\n\nCLIENTS: *** 5 ***\n\nRunning 60s test @ http://192.168.2.131/\n5 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 36 ms \u001b[90m│\u001b[39m 104 ms \u001b[90m│\u001b[39m 148 ms \u001b[90m│\u001b[39m 148 ms \u001b[90m│\u001b[39m 94.7 ms \u001b[90m│\u001b[39m 35.9 ms \u001b[90m│\u001b[39m 148 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 5       \u001b[90m│\u001b[39m 0.5     \u001b[90m│\u001b[39m 1.5     \u001b[90m│\u001b[39m 5       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 21.9 kB \u001b[90m│\u001b[39m 2.19 kB \u001b[90m│\u001b[39m 6.57 kB \u001b[90m│\u001b[39m 21.9 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 30    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n60 requests in 60.05s, 131 kB read\n25 errors (25 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/api?foo=bar\n5 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg       \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 66 ms \u001b[90m│\u001b[39m 123 ms \u001b[90m│\u001b[39m 263 ms \u001b[90m│\u001b[39m 263 ms \u001b[90m│\u001b[39m 127.67 ms \u001b[90m│\u001b[39m 37.33 ms \u001b[90m│\u001b[39m 263 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min   \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 5     \u001b[90m│\u001b[39m 0.5  \u001b[90m│\u001b[39m 1.5   \u001b[90m│\u001b[39m 5     \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 870 B \u001b[90m│\u001b[39m 87 B \u001b[90m│\u001b[39m 261 B \u001b[90m│\u001b[39m 870 B \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 30    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n60 requests in 60.07s, 5.22 kB read\n25 errors (25 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/alien.png\n5 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg       \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 348 ms \u001b[90m│\u001b[39m 398 ms \u001b[90m│\u001b[39m 465 ms \u001b[90m│\u001b[39m 465 ms \u001b[90m│\u001b[39m 399.27 ms \u001b[90m│\u001b[39m 31.99 ms \u001b[90m│\u001b[39m 465 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 5      \u001b[90m│\u001b[39m 0.5     \u001b[90m│\u001b[39m 1.5     \u001b[90m│\u001b[39m 5      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 144 kB \u001b[90m│\u001b[39m 14.4 kB \u001b[90m│\u001b[39m 43.1 kB \u001b[90m│\u001b[39m 144 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 30    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n60 requests in 60.08s, 863 kB read\n25 errors (25 timeouts)\n\n\n----------------\n\n\n\nCLIENTS: *** 6 ***\n\nRunning 60s test @ http://192.168.2.131/\n6 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg       \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 34 ms \u001b[90m│\u001b[39m 111 ms \u001b[90m│\u001b[39m 188 ms \u001b[90m│\u001b[39m 188 ms \u001b[90m│\u001b[39m 113.25 ms \u001b[90m│\u001b[39m 41.29 ms \u001b[90m│\u001b[39m 188 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 6       \u001b[90m│\u001b[39m 0.6     \u001b[90m│\u001b[39m 1.81    \u001b[90m│\u001b[39m 6       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 26.3 kB \u001b[90m│\u001b[39m 2.63 kB \u001b[90m│\u001b[39m 7.88 kB \u001b[90m│\u001b[39m 26.3 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 36    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n72 requests in 60.07s, 158 kB read\n30 errors (30 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/api?foo=bar\n6 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg       \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 61 ms \u001b[90m│\u001b[39m 121 ms \u001b[90m│\u001b[39m 296 ms \u001b[90m│\u001b[39m 296 ms \u001b[90m│\u001b[39m 134.95 ms \u001b[90m│\u001b[39m 46.95 ms \u001b[90m│\u001b[39m 296 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 6       \u001b[90m│\u001b[39m 0.6   \u001b[90m│\u001b[39m 1.81  \u001b[90m│\u001b[39m 6       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 1.05 kB \u001b[90m│\u001b[39m 105 B \u001b[90m│\u001b[39m 315 B \u001b[90m│\u001b[39m 1.05 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 36    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n72 requests in 60.09s, 6.3 kB read\n30 errors (30 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/alien.png\n6 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg       \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 322 ms \u001b[90m│\u001b[39m 422 ms \u001b[90m│\u001b[39m 522 ms \u001b[90m│\u001b[39m 522 ms \u001b[90m│\u001b[39m 422.98 ms \u001b[90m│\u001b[39m 51.58 ms \u001b[90m│\u001b[39m 522 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 6      \u001b[90m│\u001b[39m 0.6     \u001b[90m│\u001b[39m 1.81    \u001b[90m│\u001b[39m 6      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 173 kB \u001b[90m│\u001b[39m 17.2 kB \u001b[90m│\u001b[39m 51.7 kB \u001b[90m│\u001b[39m 173 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 36    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n72 requests in 60.08s, 1.04 MB read\n30 errors (30 timeouts)\n\n\n----------------\n\n\n\nCLIENTS: *** 7 ***\n\nRunning 60s test @ http://192.168.2.131/\n7 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg       \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 60 ms \u001b[90m│\u001b[39m 129 ms \u001b[90m│\u001b[39m 220 ms \u001b[90m│\u001b[39m 280 ms \u001b[90m│\u001b[39m 127.81 ms \u001b[90m│\u001b[39m 51.08 ms \u001b[90m│\u001b[39m 280 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 7       \u001b[90m│\u001b[39m 0.7     \u001b[90m│\u001b[39m 2.1     \u001b[90m│\u001b[39m 7       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 30.7 kB \u001b[90m│\u001b[39m 3.06 kB \u001b[90m│\u001b[39m 9.19 kB \u001b[90m│\u001b[39m 30.6 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 42    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n84 requests in 60.08s, 184 kB read\n35 errors (35 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/api?foo=bar\n7 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg       \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 63 ms \u001b[90m│\u001b[39m 125 ms \u001b[90m│\u001b[39m 252 ms \u001b[90m│\u001b[39m 289 ms \u001b[90m│\u001b[39m 126.22 ms \u001b[90m│\u001b[39m 46.41 ms \u001b[90m│\u001b[39m 289 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 7       \u001b[90m│\u001b[39m 0.7   \u001b[90m│\u001b[39m 2.1   \u001b[90m│\u001b[39m 7       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 1.23 kB \u001b[90m│\u001b[39m 123 B \u001b[90m│\u001b[39m 368 B \u001b[90m│\u001b[39m 1.23 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 42    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n84 requests in 60.07s, 7.35 kB read\n35 errors (35 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/alien.png\n7 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 144 ms \u001b[90m│\u001b[39m 439 ms \u001b[90m│\u001b[39m 877 ms \u001b[90m│\u001b[39m 921 ms \u001b[90m│\u001b[39m 439.3 ms \u001b[90m│\u001b[39m 138.35 ms \u001b[90m│\u001b[39m 921 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 7      \u001b[90m│\u001b[39m 0.69    \u001b[90m│\u001b[39m 1.87    \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 201 kB \u001b[90m│\u001b[39m 19.6 kB \u001b[90m│\u001b[39m 53.7 kB \u001b[90m│\u001b[39m 28.8 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 41    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n83 requests in 60.07s, 1.18 MB read\n35 errors (35 timeouts)\n\n\n----------------\n\n\n\nCLIENTS: *** 8 ***\n\nRunning 60s test @ http://192.168.2.131/\n8 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 74 ms \u001b[90m│\u001b[39m 141 ms \u001b[90m│\u001b[39m 193 ms \u001b[90m│\u001b[39m 198 ms \u001b[90m│\u001b[39m 143 ms \u001b[90m│\u001b[39m 31.11 ms \u001b[90m│\u001b[39m 198 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min   \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 8     \u001b[90m│\u001b[39m 0.8    \u001b[90m│\u001b[39m 2.41    \u001b[90m│\u001b[39m 8     \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 35 kB \u001b[90m│\u001b[39m 3.5 kB \u001b[90m│\u001b[39m 10.5 kB \u001b[90m│\u001b[39m 35 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 48    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n96 requests in 60.08s, 210 kB read\n40 errors (40 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/api?foo=bar\n8 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 59 ms \u001b[90m│\u001b[39m 138 ms \u001b[90m│\u001b[39m 284 ms \u001b[90m│\u001b[39m 319 ms \u001b[90m│\u001b[39m 139.8 ms \u001b[90m│\u001b[39m 53.96 ms \u001b[90m│\u001b[39m 319 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min   \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 8      \u001b[90m│\u001b[39m 0.8   \u001b[90m│\u001b[39m 2.36  \u001b[90m│\u001b[39m 1     \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 1.4 kB \u001b[90m│\u001b[39m 140 B \u001b[90m│\u001b[39m 411 B \u001b[90m│\u001b[39m 175 B \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 48    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n96 requests in 60.07s, 8.4 kB read\n40 errors (40 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/alien.png\n8 connections\n1 workers\n\nnode:internal/event_target:1084\n  process.nextTick(() => { throw err; });\n                           ^\n\nTypeError: colorize is not a function\n    at /Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/printResult.js:46:31\n    at Array.forEach (<anonymous>)\n    at printResult (/Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/printResult.js:43:43)\n    at EventEmitter.<anonymous> (/Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/progressTracker.js:79:28)\n    at EventEmitter.emit (node:events:527:35)\n    at _cb (/Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/init.js:76:13)\n    at handleFinish (/Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/manager.js:41:5)\n    at Worker.<anonymous> (/Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/manager.js:78:13)\n    at Worker.emit (node:events:515:28)\n    at MessagePort.<anonymous> (node:internal/worker:263:53)\n\nNode.js v21.1.0\n\n\n----------------\n\n\n\nCLIENTS: *** 9 ***\n\nRunning 60s test @ http://192.168.2.131/\n9 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg       \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 31 ms \u001b[90m│\u001b[39m 116 ms \u001b[90m│\u001b[39m 206 ms \u001b[90m│\u001b[39m 210 ms \u001b[90m│\u001b[39m 109.58 ms \u001b[90m│\u001b[39m 45.11 ms \u001b[90m│\u001b[39m 210 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 9       \u001b[90m│\u001b[39m 0.9     \u001b[90m│\u001b[39m 2.7     \u001b[90m│\u001b[39m 9       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 39.4 kB \u001b[90m│\u001b[39m 3.94 kB \u001b[90m│\u001b[39m 11.8 kB \u001b[90m│\u001b[39m 39.4 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 54    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n108 requests in 60.08s, 236 kB read\n45 errors (45 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/api?foo=bar\n9 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg       \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 66 ms \u001b[90m│\u001b[39m 131 ms \u001b[90m│\u001b[39m 313 ms \u001b[90m│\u001b[39m 349 ms \u001b[90m│\u001b[39m 139.95 ms \u001b[90m│\u001b[39m 60.66 ms \u001b[90m│\u001b[39m 349 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 9       \u001b[90m│\u001b[39m 0.9   \u001b[90m│\u001b[39m 2.7   \u001b[90m│\u001b[39m 9       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 1.57 kB \u001b[90m│\u001b[39m 158 B \u001b[90m│\u001b[39m 473 B \u001b[90m│\u001b[39m 1.57 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 54    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n108 requests in 60.08s, 9.45 kB read\n45 errors (45 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/alien.png\n9 connections\n1 workers\n\nnode:internal/event_target:1084\n  process.nextTick(() => { throw err; });\n                           ^\n\nTypeError: colorize is not a function\n    at /Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/printResult.js:46:31\n    at Array.forEach (<anonymous>)\n    at printResult (/Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/printResult.js:43:43)\n    at EventEmitter.<anonymous> (/Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/progressTracker.js:79:28)\n    at EventEmitter.emit (node:events:527:35)\n    at _cb (/Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/init.js:76:13)\n    at handleFinish (/Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/manager.js:41:5)\n    at Worker.<anonymous> (/Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/manager.js:78:13)\n    at Worker.emit (node:events:515:28)\n    at MessagePort.<anonymous> (node:internal/worker:263:53)\n\nNode.js v21.1.0\n\n\n----------------\n\n\n\nCLIENTS: *** 10 ***\n\nRunning 60s test @ http://192.168.2.131/\n10 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg       \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 35 ms \u001b[90m│\u001b[39m 96 ms \u001b[90m│\u001b[39m 264 ms \u001b[90m│\u001b[39m 267 ms \u001b[90m│\u001b[39m 103.97 ms \u001b[90m│\u001b[39m 54.56 ms \u001b[90m│\u001b[39m 267 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 10      \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m 3       \u001b[90m│\u001b[39m 10      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 43.8 kB \u001b[90m│\u001b[39m 4.38 kB \u001b[90m│\u001b[39m 13.1 kB \u001b[90m│\u001b[39m 43.8 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 60    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n120 requests in 60.08s, 263 kB read\n50 errors (50 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/api?foo=bar\n10 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg       \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 64 ms \u001b[90m│\u001b[39m 144 ms \u001b[90m│\u001b[39m 411 ms \u001b[90m│\u001b[39m 437 ms \u001b[90m│\u001b[39m 156.64 ms \u001b[90m│\u001b[39m 80.67 ms \u001b[90m│\u001b[39m 437 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min   \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 10      \u001b[90m│\u001b[39m 1     \u001b[90m│\u001b[39m 2.83  \u001b[90m│\u001b[39m 1     \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 1.75 kB \u001b[90m│\u001b[39m 175 B \u001b[90m│\u001b[39m 495 B \u001b[90m│\u001b[39m 175 B \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 60    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n120 requests in 60.08s, 10.5 kB read\n50 errors (50 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/alien.png\n10 connections\n1 workers\n\nnode:internal/event_target:1084\n  process.nextTick(() => { throw err; });\n                           ^\n\nTypeError: colorize is not a function\n    at /Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/printResult.js:46:31\n    at Array.forEach (<anonymous>)\n    at printResult (/Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/printResult.js:43:43)\n    at EventEmitter.<anonymous> (/Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/progressTracker.js:79:28)\n    at EventEmitter.emit (node:events:527:35)\n    at _cb (/Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/init.js:76:13)\n    at handleFinish (/Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/manager.js:41:5)\n    at Worker.<anonymous> (/Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/manager.js:78:13)\n    at Worker.emit (node:events:515:28)\n    at MessagePort.<anonymous> (node:internal/worker:263:53)\n\nNode.js v21.1.0\n\n\n----------------\n\n\n\nCLIENTS: *** 15 ***\n\nRunning 60s test @ http://192.168.2.131/\n15 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 29 ms \u001b[90m│\u001b[39m 104 ms \u001b[90m│\u001b[39m 359 ms \u001b[90m│\u001b[39m 362 ms \u001b[90m│\u001b[39m 121.5 ms \u001b[90m│\u001b[39m 77.5 ms \u001b[90m│\u001b[39m 362 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 14      \u001b[90m│\u001b[39m 1.34    \u001b[90m│\u001b[39m 4.02    \u001b[90m│\u001b[39m 12      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 52.6 kB \u001b[90m│\u001b[39m 5.12 kB \u001b[90m│\u001b[39m 15.4 kB \u001b[90m│\u001b[39m 48.3 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 80    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n170 requests in 60.09s, 307 kB read\n75 errors (75 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/api?foo=bar\n15 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg       \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 91 ms \u001b[90m│\u001b[39m 148 ms \u001b[90m│\u001b[39m 505 ms \u001b[90m│\u001b[39m 574 ms \u001b[90m│\u001b[39m 174.38 ms \u001b[90m│\u001b[39m 100.31 ms \u001b[90m│\u001b[39m 574 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min   \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 15      \u001b[90m│\u001b[39m 1.5   \u001b[90m│\u001b[39m 4.06  \u001b[90m│\u001b[39m 1     \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 2.63 kB \u001b[90m│\u001b[39m 263 B \u001b[90m│\u001b[39m 710 B \u001b[90m│\u001b[39m 175 B \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 90    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n180 requests in 60.08s, 15.8 kB read\n75 errors (75 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/alien.png\n15 connections\n1 workers\n\nnode:internal/event_target:1084\n  process.nextTick(() => { throw err; });\n                           ^\n\nTypeError: colorize is not a function\n    at /Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/printResult.js:46:31\n    at Array.forEach (<anonymous>)\n    at printResult (/Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/printResult.js:43:43)\n    at EventEmitter.<anonymous> (/Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/progressTracker.js:79:28)\n    at EventEmitter.emit (node:events:527:35)\n    at _cb (/Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/init.js:76:13)\n    at handleFinish (/Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/manager.js:41:5)\n    at Worker.<anonymous> (/Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/manager.js:78:13)\n    at Worker.emit (node:events:515:28)\n    at MessagePort.<anonymous> (node:internal/worker:263:53)\n\nNode.js v21.1.0\n\n\n----------------\n\n\n\nCLIENTS: *** 20 ***\n\nRunning 60s test @ http://192.168.2.131/\n20 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg        \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 62 ms \u001b[90m│\u001b[39m 1134 ms \u001b[90m│\u001b[39m 6942 ms \u001b[90m│\u001b[39m 6976 ms \u001b[90m│\u001b[39m 1884.35 ms \u001b[90m│\u001b[39m 1805.12 ms \u001b[90m│\u001b[39m 6976 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 15      \u001b[90m│\u001b[39m 1.44    \u001b[90m│\u001b[39m 4.15    \u001b[90m│\u001b[39m 4       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 57.2 kB \u001b[90m│\u001b[39m 4.42 kB \u001b[90m│\u001b[39m 14.2 kB \u001b[90m│\u001b[39m 5.82 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 86    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n211 requests in 60.08s, 265 kB read\n105 errors (100 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/api?foo=bar\n20 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg       \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 62 ms \u001b[90m│\u001b[39m 232 ms \u001b[90m│\u001b[39m 4030 ms \u001b[90m│\u001b[39m 6972 ms \u001b[90m│\u001b[39m 586.75 ms \u001b[90m│\u001b[39m 1218.03 ms \u001b[90m│\u001b[39m 6972 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min   \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 11      \u001b[90m│\u001b[39m 1.39  \u001b[90m│\u001b[39m 3.08  \u001b[90m│\u001b[39m 1     \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 1.89 kB \u001b[90m│\u001b[39m 238 B \u001b[90m│\u001b[39m 529 B \u001b[90m│\u001b[39m 172 B \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 83    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n203 requests in 60.09s, 14.3 kB read\n100 errors (100 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/alien.png\n20 connections\n1 workers\n\nnode:internal/event_target:1084\n  process.nextTick(() => { throw err; });\n                           ^\n\nTypeError: colorize is not a function\n    at /Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/printResult.js:46:31\n    at Array.forEach (<anonymous>)\n    at printResult (/Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/printResult.js:43:43)\n    at EventEmitter.<anonymous> (/Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/progressTracker.js:79:28)\n    at EventEmitter.emit (node:events:527:35)\n    at _cb (/Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/init.js:76:13)\n    at handleFinish (/Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/manager.js:41:5)\n    at Worker.<anonymous> (/Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/manager.js:78:13)\n    at Worker.emit (node:events:515:28)\n    at MessagePort.<anonymous> (node:internal/worker:263:53)\n\nNode.js v21.1.0\n\n\n----------------\n\n"
  },
  {
    "path": "benchmark/results/espasync-websocket-loadtest.log",
    "content": "\n\nCLIENTS: *** 1 ***\n\n\nTarget URL:          ws://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  1\nAgent:               none\n\nCompleted requests:  4231\nTotal errors:        0\nTotal time:          60.002 s\nMean latency:        13.6 ms\nEffective rps:       71\n\nPercentage of requests served within a certain time\n  50%      10 ms\n  90%      16 ms\n  95%      24 ms\n  99%      81 ms\n 100%      280 ms (longest request)\n\n\nCLIENTS: *** 2 ***\n\n\nTarget URL:          ws://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  2\nAgent:               none\n\nCompleted requests:  5914\nTotal errors:        0\nTotal time:          60.001 s\nMean latency:        19.7 ms\nEffective rps:       99\n\nPercentage of requests served within a certain time\n  50%      15 ms\n  90%      26 ms\n  95%      67 ms\n  99%      86 ms\n 100%      109 ms (longest request)\n\n\nCLIENTS: *** 3 ***\n\n\nTarget URL:          ws://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  3\nAgent:               none\n\nCompleted requests:  8204\nTotal errors:        0\nTotal time:          60.003 s\nMean latency:        21.4 ms\nEffective rps:       137\n\nPercentage of requests served within a certain time\n  50%      17 ms\n  90%      29 ms\n  95%      68 ms\n  99%      87 ms\n 100%      104 ms (longest request)\n\n\nCLIENTS: *** 4 ***\n\n\nTarget URL:          ws://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  4\nAgent:               none\n\nCompleted requests:  9634\nTotal errors:        0\nTotal time:          60.004 s\nMean latency:        24.4 ms\nEffective rps:       161\n\nPercentage of requests served within a certain time\n  50%      19 ms\n  90%      33 ms\n  95%      73 ms\n  99%      91 ms\n 100%      145 ms (longest request)\n\n\nCLIENTS: *** 5 ***\n\n\nTarget URL:          ws://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  5\nAgent:               none\n\nCompleted requests:  10759\nTotal errors:        0\nTotal time:          60.003 s\nMean latency:        27.3 ms\nEffective rps:       179\n\nPercentage of requests served within a certain time\n  50%      22 ms\n  90%      39 ms\n  95%      76 ms\n  99%      95 ms\n 100%      117 ms (longest request)\n\n\nCLIENTS: *** 6 ***\n\n\nTarget URL:          ws://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  6\nAgent:               none\n\nCompleted requests:  11302\nTotal errors:        0\nTotal time:          60.004 s\nMean latency:        31.3 ms\nEffective rps:       188\n\nPercentage of requests served within a certain time\n  50%      26 ms\n  90%      58 ms\n  95%      81 ms\n  99%      100 ms\n 100%      122 ms (longest request)\n\n\nCLIENTS: *** 7 ***\n\n\nTarget URL:          ws://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  7\nAgent:               none\n\nCompleted requests:  12713\nTotal errors:        0\nTotal time:          60.003 s\nMean latency:        32.5 ms\nEffective rps:       212\n\nPercentage of requests served within a certain time\n  50%      27 ms\n  90%      52 ms\n  95%      81 ms\n  99%      99 ms\n 100%      125 ms (longest request)\n\n\nCLIENTS: *** 8 ***\n\n\nTarget URL:          ws://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  8\nRunning on cores:    2\nAgent:               none\n\nCompleted requests:  13157\nTotal errors:        0\nTotal time:          60.003 s\nMean latency:        35.9 ms\nEffective rps:       219\n\nPercentage of requests served within a certain time\n  50%      30 ms\n  90%      71 ms\n  95%      88 ms\n  99%      107 ms\n 100%      132 ms (longest request)\n\n\nCLIENTS: *** 10 ***\n\n\nTarget URL:          ws://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  10\nRunning on cores:    2\nAgent:               none\n\nCompleted requests:  13417\nTotal errors:        2\nTotal time:          60.001 s\nMean latency:        34.4 ms\nEffective rps:       224\n\nPercentage of requests served within a certain time\n  50%      30 ms\n  90%      53 ms\n  95%      81 ms\n  99%      101 ms\n 100%      124 ms (longest request)\n\n   -1:   2 errors\n\n\nCLIENTS: *** 16 ***\n\n\nTarget URL:          ws://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  16\nRunning on cores:    2\nAgent:               none\n\nCompleted requests:  12804\nTotal errors:        7\nTotal time:          60.001 s\nMean latency:        36.4 ms\nEffective rps:       213\n\nPercentage of requests served within a certain time\n  50%      30 ms\n  90%      70 ms\n  95%      86 ms\n  99%      106 ms\n 100%      135 ms (longest request)\n\n   -1:   7 errors\n\n\nCLIENTS: *** 20 ***\n\n\nTarget URL:          ws://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  20\nRunning on cores:    2\nAgent:               none\n\nCompleted requests:  8421\nTotal errors:        13\nTotal time:          60.003 s\nMean latency:        37.2 ms\nEffective rps:       140\n\nPercentage of requests served within a certain time\n  50%      20 ms\n  90%      50 ms\n  95%      77 ms\n  99%      105 ms\n 100%      9227 ms (longest request)\n\n   -1:   13 errors\n"
  },
  {
    "path": "benchmark/results/psychic-http-loadtest.log",
    "content": "\n\nCLIENTS: *** 1 ***\n\nRunning 60s test @ http://192.168.2.131/\n1 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 24 ms \u001b[90m│\u001b[39m 31 ms \u001b[90m│\u001b[39m 100 ms \u001b[90m│\u001b[39m 134 ms \u001b[90m│\u001b[39m 39.16 ms \u001b[90m│\u001b[39m 22.82 ms \u001b[90m│\u001b[39m 270 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 18      \u001b[90m│\u001b[39m 21      \u001b[90m│\u001b[39m 25     \u001b[90m│\u001b[39m 30     \u001b[90m│\u001b[39m 25.19  \u001b[90m│\u001b[39m 2.28    \u001b[90m│\u001b[39m 18      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 78.1 kB \u001b[90m│\u001b[39m 91.1 kB \u001b[90m│\u001b[39m 108 kB \u001b[90m│\u001b[39m 130 kB \u001b[90m│\u001b[39m 109 kB \u001b[90m│\u001b[39m 9.88 kB \u001b[90m│\u001b[39m 78.1 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 1511  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n2k requests in 60.05s, 6.55 MB read\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/api?foo=bar\n1 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 19 ms \u001b[90m│\u001b[39m 25 ms \u001b[90m│\u001b[39m 91 ms \u001b[90m│\u001b[39m 99 ms \u001b[90m│\u001b[39m 31.42 ms \u001b[90m│\u001b[39m 18.78 ms \u001b[90m│\u001b[39m 116 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 26      \u001b[90m│\u001b[39m 28      \u001b[90m│\u001b[39m 31      \u001b[90m│\u001b[39m 34      \u001b[90m│\u001b[39m 31.29   \u001b[90m│\u001b[39m 1.79  \u001b[90m│\u001b[39m 26      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 3.46 kB \u001b[90m│\u001b[39m 3.73 kB \u001b[90m│\u001b[39m 4.16 kB \u001b[90m│\u001b[39m 4.56 kB \u001b[90m│\u001b[39m 4.19 kB \u001b[90m│\u001b[39m 241 B \u001b[90m│\u001b[39m 3.46 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 1877  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n2k requests in 60.06s, 251 kB read\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/alien.png\n1 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg       \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 141 ms \u001b[90m│\u001b[39m 201 ms \u001b[90m│\u001b[39m 317 ms \u001b[90m│\u001b[39m 331 ms \u001b[90m│\u001b[39m 206.85 ms \u001b[90m│\u001b[39m 51.73 ms \u001b[90m│\u001b[39m 366 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 4      \u001b[90m│\u001b[39m 4      \u001b[90m│\u001b[39m 5      \u001b[90m│\u001b[39m 6      \u001b[90m│\u001b[39m 4.82   \u001b[90m│\u001b[39m 0.62    \u001b[90m│\u001b[39m 4      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 115 kB \u001b[90m│\u001b[39m 115 kB \u001b[90m│\u001b[39m 144 kB \u001b[90m│\u001b[39m 173 kB \u001b[90m│\u001b[39m 139 kB \u001b[90m│\u001b[39m 17.8 kB \u001b[90m│\u001b[39m 115 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 289   \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n290 requests in 60.07s, 8.32 MB read\n\n\n----------------\n\n\n\nCLIENTS: *** 2 ***\n\nRunning 60s test @ http://192.168.2.131/\n2 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 26 ms \u001b[90m│\u001b[39m 41 ms \u001b[90m│\u001b[39m 167 ms \u001b[90m│\u001b[39m 203 ms \u001b[90m│\u001b[39m 55.52 ms \u001b[90m│\u001b[39m 37.23 ms \u001b[90m│\u001b[39m 373 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 29     \u001b[90m│\u001b[39m 31     \u001b[90m│\u001b[39m 35     \u001b[90m│\u001b[39m 40     \u001b[90m│\u001b[39m 35.64  \u001b[90m│\u001b[39m 2.36    \u001b[90m│\u001b[39m 29     \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 126 kB \u001b[90m│\u001b[39m 135 kB \u001b[90m│\u001b[39m 152 kB \u001b[90m│\u001b[39m 174 kB \u001b[90m│\u001b[39m 155 kB \u001b[90m│\u001b[39m 10.2 kB \u001b[90m│\u001b[39m 126 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 2138  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n2k requests in 60.06s, 9.27 MB read\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/api?foo=bar\n2 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 25 ms \u001b[90m│\u001b[39m 35 ms \u001b[90m│\u001b[39m 103 ms \u001b[90m│\u001b[39m 112 ms \u001b[90m│\u001b[39m 43.19 ms \u001b[90m│\u001b[39m 21.44 ms \u001b[90m│\u001b[39m 142 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 40      \u001b[90m│\u001b[39m 40      \u001b[90m│\u001b[39m 46      \u001b[90m│\u001b[39m 50     \u001b[90m│\u001b[39m 45.7    \u001b[90m│\u001b[39m 2.76  \u001b[90m│\u001b[39m 40      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 5.36 kB \u001b[90m│\u001b[39m 5.36 kB \u001b[90m│\u001b[39m 6.17 kB \u001b[90m│\u001b[39m 6.7 kB \u001b[90m│\u001b[39m 6.12 kB \u001b[90m│\u001b[39m 370 B \u001b[90m│\u001b[39m 5.36 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 2742  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n3k requests in 60.06s, 367 kB read\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/alien.png\n2 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg       \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 188 ms \u001b[90m│\u001b[39m 322 ms \u001b[90m│\u001b[39m 475 ms \u001b[90m│\u001b[39m 507 ms \u001b[90m│\u001b[39m 324.51 ms \u001b[90m│\u001b[39m 70.51 ms \u001b[90m│\u001b[39m 535 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 5      \u001b[90m│\u001b[39m 5      \u001b[90m│\u001b[39m 6      \u001b[90m│\u001b[39m 7      \u001b[90m│\u001b[39m 6.15   \u001b[90m│\u001b[39m 0.63  \u001b[90m│\u001b[39m 5      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 144 kB \u001b[90m│\u001b[39m 144 kB \u001b[90m│\u001b[39m 173 kB \u001b[90m│\u001b[39m 201 kB \u001b[90m│\u001b[39m 177 kB \u001b[90m│\u001b[39m 18 kB \u001b[90m│\u001b[39m 144 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 369   \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n371 requests in 60.06s, 10.6 MB read\n\n\n----------------\n\n\n\nCLIENTS: *** 3 ***\n\nRunning 60s test @ http://192.168.2.131/\n3 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 31 ms \u001b[90m│\u001b[39m 54 ms \u001b[90m│\u001b[39m 185 ms \u001b[90m│\u001b[39m 212 ms \u001b[90m│\u001b[39m 68.63 ms \u001b[90m│\u001b[39m 39.36 ms \u001b[90m│\u001b[39m 386 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 38     \u001b[90m│\u001b[39m 39     \u001b[90m│\u001b[39m 43     \u001b[90m│\u001b[39m 47     \u001b[90m│\u001b[39m 43.32  \u001b[90m│\u001b[39m 2.31  \u001b[90m│\u001b[39m 38     \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 165 kB \u001b[90m│\u001b[39m 169 kB \u001b[90m│\u001b[39m 187 kB \u001b[90m│\u001b[39m 204 kB \u001b[90m│\u001b[39m 188 kB \u001b[90m│\u001b[39m 10 kB \u001b[90m│\u001b[39m 165 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 2599  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n3k requests in 60.06s, 11.3 MB read\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/api?foo=bar\n3 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 29 ms \u001b[90m│\u001b[39m 42 ms \u001b[90m│\u001b[39m 116 ms \u001b[90m│\u001b[39m 126 ms \u001b[90m│\u001b[39m 51.59 ms \u001b[90m│\u001b[39m 23.91 ms \u001b[90m│\u001b[39m 175 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 40      \u001b[90m│\u001b[39m 51      \u001b[90m│\u001b[39m 58      \u001b[90m│\u001b[39m 64      \u001b[90m│\u001b[39m 57.59   \u001b[90m│\u001b[39m 4.25  \u001b[90m│\u001b[39m 40      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 5.36 kB \u001b[90m│\u001b[39m 6.83 kB \u001b[90m│\u001b[39m 7.78 kB \u001b[90m│\u001b[39m 8.58 kB \u001b[90m│\u001b[39m 7.72 kB \u001b[90m│\u001b[39m 569 B \u001b[90m│\u001b[39m 5.36 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 3455  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n3k requests in 60.06s, 463 kB read\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/alien.png\n3 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg       \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 203 ms \u001b[90m│\u001b[39m 458 ms \u001b[90m│\u001b[39m 761 ms \u001b[90m│\u001b[39m 814 ms \u001b[90m│\u001b[39m 474.54 ms \u001b[90m│\u001b[39m 168.16 ms \u001b[90m│\u001b[39m 902 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 4      \u001b[90m│\u001b[39m 5      \u001b[90m│\u001b[39m 6      \u001b[90m│\u001b[39m 7      \u001b[90m│\u001b[39m 6.29   \u001b[90m│\u001b[39m 0.67  \u001b[90m│\u001b[39m 4      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 115 kB \u001b[90m│\u001b[39m 144 kB \u001b[90m│\u001b[39m 173 kB \u001b[90m│\u001b[39m 201 kB \u001b[90m│\u001b[39m 181 kB \u001b[90m│\u001b[39m 19 kB \u001b[90m│\u001b[39m 115 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 377   \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n380 requests in 60.06s, 10.9 MB read\n\n\n----------------\n\n\n\nCLIENTS: *** 4 ***\n\nRunning 60s test @ http://192.168.2.131/\n4 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 37 ms \u001b[90m│\u001b[39m 63 ms \u001b[90m│\u001b[39m 206 ms \u001b[90m│\u001b[39m 239 ms \u001b[90m│\u001b[39m 81.32 ms \u001b[90m│\u001b[39m 45.45 ms \u001b[90m│\u001b[39m 396 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 42     \u001b[90m│\u001b[39m 44     \u001b[90m│\u001b[39m 49     \u001b[90m│\u001b[39m 56     \u001b[90m│\u001b[39m 48.87  \u001b[90m│\u001b[39m 3.01  \u001b[90m│\u001b[39m 42     \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 182 kB \u001b[90m│\u001b[39m 191 kB \u001b[90m│\u001b[39m 213 kB \u001b[90m│\u001b[39m 243 kB \u001b[90m│\u001b[39m 212 kB \u001b[90m│\u001b[39m 13 kB \u001b[90m│\u001b[39m 182 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 2932  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n3k requests in 60.05s, 12.7 MB read\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/api?foo=bar\n4 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 33 ms \u001b[90m│\u001b[39m 50 ms \u001b[90m│\u001b[39m 123 ms \u001b[90m│\u001b[39m 131 ms \u001b[90m│\u001b[39m 58.29 ms \u001b[90m│\u001b[39m 23.99 ms \u001b[90m│\u001b[39m 159 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 59      \u001b[90m│\u001b[39m 59      \u001b[90m│\u001b[39m 68      \u001b[90m│\u001b[39m 78      \u001b[90m│\u001b[39m 68      \u001b[90m│\u001b[39m 4.3   \u001b[90m│\u001b[39m 59      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 7.91 kB \u001b[90m│\u001b[39m 7.91 kB \u001b[90m│\u001b[39m 9.12 kB \u001b[90m│\u001b[39m 10.5 kB \u001b[90m│\u001b[39m 9.11 kB \u001b[90m│\u001b[39m 576 B \u001b[90m│\u001b[39m 7.91 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 4080  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n4k requests in 60.05s, 547 kB read\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/alien.png\n4 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg       \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 326 ms \u001b[90m│\u001b[39m 534 ms \u001b[90m│\u001b[39m 1064 ms \u001b[90m│\u001b[39m 1141 ms \u001b[90m│\u001b[39m 635.61 ms \u001b[90m│\u001b[39m 238.71 ms \u001b[90m│\u001b[39m 1210 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 5      \u001b[90m│\u001b[39m 5      \u001b[90m│\u001b[39m 6      \u001b[90m│\u001b[39m 7      \u001b[90m│\u001b[39m 6.27   \u001b[90m│\u001b[39m 0.63    \u001b[90m│\u001b[39m 5      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 144 kB \u001b[90m│\u001b[39m 144 kB \u001b[90m│\u001b[39m 173 kB \u001b[90m│\u001b[39m 201 kB \u001b[90m│\u001b[39m 180 kB \u001b[90m│\u001b[39m 18.1 kB \u001b[90m│\u001b[39m 144 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 376   \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n380 requests in 60.05s, 10.8 MB read\n\n\n----------------\n\n\n\nCLIENTS: *** 5 ***\n\nRunning 60s test @ http://192.168.2.131/\n5 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 44 ms \u001b[90m│\u001b[39m 74 ms \u001b[90m│\u001b[39m 222 ms \u001b[90m│\u001b[39m 261 ms \u001b[90m│\u001b[39m 91.54 ms \u001b[90m│\u001b[39m 47.88 ms \u001b[90m│\u001b[39m 417 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 47     \u001b[90m│\u001b[39m 47     \u001b[90m│\u001b[39m 54     \u001b[90m│\u001b[39m 60     \u001b[90m│\u001b[39m 54.29  \u001b[90m│\u001b[39m 3.05    \u001b[90m│\u001b[39m 47     \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 204 kB \u001b[90m│\u001b[39m 204 kB \u001b[90m│\u001b[39m 234 kB \u001b[90m│\u001b[39m 260 kB \u001b[90m│\u001b[39m 235 kB \u001b[90m│\u001b[39m 13.2 kB \u001b[90m│\u001b[39m 204 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 3257  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n3k requests in 60.06s, 14.1 MB read\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/api?foo=bar\n5 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 36 ms \u001b[90m│\u001b[39m 57 ms \u001b[90m│\u001b[39m 126 ms \u001b[90m│\u001b[39m 138 ms \u001b[90m│\u001b[39m 64.99 ms \u001b[90m│\u001b[39m 24.42 ms \u001b[90m│\u001b[39m 195 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 64      \u001b[90m│\u001b[39m 69      \u001b[90m│\u001b[39m 76      \u001b[90m│\u001b[39m 84      \u001b[90m│\u001b[39m 76.32   \u001b[90m│\u001b[39m 3.97  \u001b[90m│\u001b[39m 64      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 8.58 kB \u001b[90m│\u001b[39m 9.25 kB \u001b[90m│\u001b[39m 10.2 kB \u001b[90m│\u001b[39m 11.3 kB \u001b[90m│\u001b[39m 10.2 kB \u001b[90m│\u001b[39m 532 B \u001b[90m│\u001b[39m 8.58 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 4579  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n5k requests in 60.06s, 614 kB read\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/alien.png\n5 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg       \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 439 ms \u001b[90m│\u001b[39m 652 ms \u001b[90m│\u001b[39m 1393 ms \u001b[90m│\u001b[39m 1458 ms \u001b[90m│\u001b[39m 780.62 ms \u001b[90m│\u001b[39m 290.11 ms \u001b[90m│\u001b[39m 2018 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 4      \u001b[90m│\u001b[39m 5      \u001b[90m│\u001b[39m 6      \u001b[90m│\u001b[39m 8      \u001b[90m│\u001b[39m 6.35   \u001b[90m│\u001b[39m 0.78    \u001b[90m│\u001b[39m 4      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 115 kB \u001b[90m│\u001b[39m 144 kB \u001b[90m│\u001b[39m 173 kB \u001b[90m│\u001b[39m 230 kB \u001b[90m│\u001b[39m 183 kB \u001b[90m│\u001b[39m 22.1 kB \u001b[90m│\u001b[39m 115 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 381   \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n386 requests in 60.06s, 11 MB read\n\n\n----------------\n\n\n\nCLIENTS: *** 6 ***\n\nRunning 60s test @ http://192.168.2.131/\n6 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg       \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 50 ms \u001b[90m│\u001b[39m 85 ms \u001b[90m│\u001b[39m 238 ms \u001b[90m│\u001b[39m 268 ms \u001b[90m│\u001b[39m 102.35 ms \u001b[90m│\u001b[39m 50.03 ms \u001b[90m│\u001b[39m 517 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 49     \u001b[90m│\u001b[39m 53     \u001b[90m│\u001b[39m 58     \u001b[90m│\u001b[39m 65     \u001b[90m│\u001b[39m 58.3   \u001b[90m│\u001b[39m 3.13    \u001b[90m│\u001b[39m 49     \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 213 kB \u001b[90m│\u001b[39m 230 kB \u001b[90m│\u001b[39m 252 kB \u001b[90m│\u001b[39m 282 kB \u001b[90m│\u001b[39m 253 kB \u001b[90m│\u001b[39m 13.6 kB \u001b[90m│\u001b[39m 213 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 3498  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n4k requests in 60.05s, 15.2 MB read\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/api?foo=bar\n6 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 41 ms \u001b[90m│\u001b[39m 64 ms \u001b[90m│\u001b[39m 138 ms \u001b[90m│\u001b[39m 151 ms \u001b[90m│\u001b[39m 74.53 ms \u001b[90m│\u001b[39m 27.06 ms \u001b[90m│\u001b[39m 286 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 71      \u001b[90m│\u001b[39m 71      \u001b[90m│\u001b[39m 80      \u001b[90m│\u001b[39m 90      \u001b[90m│\u001b[39m 79.92   \u001b[90m│\u001b[39m 4.07  \u001b[90m│\u001b[39m 71      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 9.59 kB \u001b[90m│\u001b[39m 9.59 kB \u001b[90m│\u001b[39m 10.8 kB \u001b[90m│\u001b[39m 12.2 kB \u001b[90m│\u001b[39m 10.8 kB \u001b[90m│\u001b[39m 548 B \u001b[90m│\u001b[39m 9.59 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 4795  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n5k requests in 60.06s, 647 kB read\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/alien.png\n6 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg       \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 579 ms \u001b[90m│\u001b[39m 840 ms \u001b[90m│\u001b[39m 1766 ms \u001b[90m│\u001b[39m 1816 ms \u001b[90m│\u001b[39m 973.38 ms \u001b[90m│\u001b[39m 355.3 ms \u001b[90m│\u001b[39m 2392 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 4      \u001b[90m│\u001b[39m 4      \u001b[90m│\u001b[39m 6      \u001b[90m│\u001b[39m 8      \u001b[90m│\u001b[39m 6.1    \u001b[90m│\u001b[39m 0.87  \u001b[90m│\u001b[39m 4      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 115 kB \u001b[90m│\u001b[39m 115 kB \u001b[90m│\u001b[39m 173 kB \u001b[90m│\u001b[39m 230 kB \u001b[90m│\u001b[39m 176 kB \u001b[90m│\u001b[39m 25 kB \u001b[90m│\u001b[39m 115 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 366   \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n372 requests in 60.06s, 10.5 MB read\n\n\n----------------\n\n\n\nCLIENTS: *** 7 ***\n\nRunning 60s test @ http://192.168.2.131/\n7 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 57 ms \u001b[90m│\u001b[39m 96 ms \u001b[90m│\u001b[39m 249 ms \u001b[90m│\u001b[39m 293 ms \u001b[90m│\u001b[39m 113.4 ms \u001b[90m│\u001b[39m 53.05 ms \u001b[90m│\u001b[39m 640 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 53     \u001b[90m│\u001b[39m 54     \u001b[90m│\u001b[39m 62     \u001b[90m│\u001b[39m 68     \u001b[90m│\u001b[39m 61.44  \u001b[90m│\u001b[39m 3.82    \u001b[90m│\u001b[39m 53     \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 230 kB \u001b[90m│\u001b[39m 234 kB \u001b[90m│\u001b[39m 269 kB \u001b[90m│\u001b[39m 295 kB \u001b[90m│\u001b[39m 266 kB \u001b[90m│\u001b[39m 16.6 kB \u001b[90m│\u001b[39m 230 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 3686  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n4k requests in 60.05s, 16 MB read\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/api?foo=bar\n7 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 45 ms \u001b[90m│\u001b[39m 69 ms \u001b[90m│\u001b[39m 145 ms \u001b[90m│\u001b[39m 154 ms \u001b[90m│\u001b[39m 79.11 ms \u001b[90m│\u001b[39m 27.06 ms \u001b[90m│\u001b[39m 274 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 78      \u001b[90m│\u001b[39m 80      \u001b[90m│\u001b[39m 89    \u001b[90m│\u001b[39m 99      \u001b[90m│\u001b[39m 87.9    \u001b[90m│\u001b[39m 4.78  \u001b[90m│\u001b[39m 78      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 10.5 kB \u001b[90m│\u001b[39m 10.8 kB \u001b[90m│\u001b[39m 12 kB \u001b[90m│\u001b[39m 13.4 kB \u001b[90m│\u001b[39m 11.9 kB \u001b[90m│\u001b[39m 644 B \u001b[90m│\u001b[39m 10.5 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 5274  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n5k requests in 60.07s, 712 kB read\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/alien.png\n7 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg        \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 671 ms \u001b[90m│\u001b[39m 952 ms \u001b[90m│\u001b[39m 1965 ms \u001b[90m│\u001b[39m 2059 ms \u001b[90m│\u001b[39m 1094.09 ms \u001b[90m│\u001b[39m 402.31 ms \u001b[90m│\u001b[39m 3654 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 5      \u001b[90m│\u001b[39m 5      \u001b[90m│\u001b[39m 6      \u001b[90m│\u001b[39m 8      \u001b[90m│\u001b[39m 6.34   \u001b[90m│\u001b[39m 0.79    \u001b[90m│\u001b[39m 5      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 144 kB \u001b[90m│\u001b[39m 144 kB \u001b[90m│\u001b[39m 173 kB \u001b[90m│\u001b[39m 230 kB \u001b[90m│\u001b[39m 182 kB \u001b[90m│\u001b[39m 22.7 kB \u001b[90m│\u001b[39m 144 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 380   \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n387 requests in 60.07s, 10.9 MB read\n\n\n----------------\n\n\n\nCLIENTS: *** 8 ***\n\nRunning 60s test @ http://192.168.2.131/\n8 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg       \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 56 ms \u001b[90m│\u001b[39m 95 ms \u001b[90m│\u001b[39m 243 ms \u001b[90m│\u001b[39m 275 ms \u001b[90m│\u001b[39m 110.53 ms \u001b[90m│\u001b[39m 52.27 ms \u001b[90m│\u001b[39m 1027 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 52     \u001b[90m│\u001b[39m 54     \u001b[90m│\u001b[39m 62     \u001b[90m│\u001b[39m 73     \u001b[90m│\u001b[39m 62.99  \u001b[90m│\u001b[39m 4.89    \u001b[90m│\u001b[39m 52     \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 226 kB \u001b[90m│\u001b[39m 234 kB \u001b[90m│\u001b[39m 269 kB \u001b[90m│\u001b[39m 317 kB \u001b[90m│\u001b[39m 273 kB \u001b[90m│\u001b[39m 21.2 kB \u001b[90m│\u001b[39m 226 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 3779  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n4k requests in 60.06s, 16.4 MB read\n6 errors (6 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/api?foo=bar\n8 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 45 ms \u001b[90m│\u001b[39m 70 ms \u001b[90m│\u001b[39m 146 ms \u001b[90m│\u001b[39m 156 ms \u001b[90m│\u001b[39m 80.9 ms \u001b[90m│\u001b[39m 28.68 ms \u001b[90m│\u001b[39m 308 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 77      \u001b[90m│\u001b[39m 77      \u001b[90m│\u001b[39m 86      \u001b[90m│\u001b[39m 95      \u001b[90m│\u001b[39m 85.92   \u001b[90m│\u001b[39m 4.89  \u001b[90m│\u001b[39m 77      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 10.4 kB \u001b[90m│\u001b[39m 10.4 kB \u001b[90m│\u001b[39m 11.6 kB \u001b[90m│\u001b[39m 12.8 kB \u001b[90m│\u001b[39m 11.6 kB \u001b[90m│\u001b[39m 659 B \u001b[90m│\u001b[39m 10.4 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 5155  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n5k requests in 60.07s, 696 kB read\n6 errors (6 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/alien.png\n8 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg        \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 699 ms \u001b[90m│\u001b[39m 979 ms \u001b[90m│\u001b[39m 2038 ms \u001b[90m│\u001b[39m 2128 ms \u001b[90m│\u001b[39m 1111.14 ms \u001b[90m│\u001b[39m 406.26 ms \u001b[90m│\u001b[39m 3506 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 5      \u001b[90m│\u001b[39m 5      \u001b[90m│\u001b[39m 6      \u001b[90m│\u001b[39m 7      \u001b[90m│\u001b[39m 6.25   \u001b[90m│\u001b[39m 0.6     \u001b[90m│\u001b[39m 5      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 144 kB \u001b[90m│\u001b[39m 144 kB \u001b[90m│\u001b[39m 173 kB \u001b[90m│\u001b[39m 201 kB \u001b[90m│\u001b[39m 180 kB \u001b[90m│\u001b[39m 17.1 kB \u001b[90m│\u001b[39m 144 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 375   \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n389 requests in 60.06s, 10.8 MB read\n6 errors (6 timeouts)\n\n\n----------------\n\n\n\nCLIENTS: *** 9 ***\n\nRunning 60s test @ http://192.168.2.131/\n9 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg       \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 57 ms \u001b[90m│\u001b[39m 96 ms \u001b[90m│\u001b[39m 249 ms \u001b[90m│\u001b[39m 277 ms \u001b[90m│\u001b[39m 112.81 ms \u001b[90m│\u001b[39m 51.23 ms \u001b[90m│\u001b[39m 626 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 52     \u001b[90m│\u001b[39m 57     \u001b[90m│\u001b[39m 61     \u001b[90m│\u001b[39m 68     \u001b[90m│\u001b[39m 61.7   \u001b[90m│\u001b[39m 3.18    \u001b[90m│\u001b[39m 52     \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 226 kB \u001b[90m│\u001b[39m 247 kB \u001b[90m│\u001b[39m 265 kB \u001b[90m│\u001b[39m 295 kB \u001b[90m│\u001b[39m 268 kB \u001b[90m│\u001b[39m 13.8 kB \u001b[90m│\u001b[39m 226 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 3702  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n4k requests in 60.06s, 16.1 MB read\n12 errors (12 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/api?foo=bar\n9 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 45 ms \u001b[90m│\u001b[39m 70 ms \u001b[90m│\u001b[39m 144 ms \u001b[90m│\u001b[39m 154 ms \u001b[90m│\u001b[39m 79.64 ms \u001b[90m│\u001b[39m 27.25 ms \u001b[90m│\u001b[39m 239 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 76      \u001b[90m│\u001b[39m 79      \u001b[90m│\u001b[39m 87      \u001b[90m│\u001b[39m 96    \u001b[90m│\u001b[39m 87.34   \u001b[90m│\u001b[39m 4.79  \u001b[90m│\u001b[39m 76      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 10.3 kB \u001b[90m│\u001b[39m 10.7 kB \u001b[90m│\u001b[39m 11.8 kB \u001b[90m│\u001b[39m 13 kB \u001b[90m│\u001b[39m 11.8 kB \u001b[90m│\u001b[39m 647 B \u001b[90m│\u001b[39m 10.3 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 5240  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n5k requests in 60.1s, 707 kB read\n12 errors (12 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/alien.png\n9 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg        \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 664 ms \u001b[90m│\u001b[39m 952 ms \u001b[90m│\u001b[39m 2001 ms \u001b[90m│\u001b[39m 2055 ms \u001b[90m│\u001b[39m 1092.56 ms \u001b[90m│\u001b[39m 399.94 ms \u001b[90m│\u001b[39m 3588 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 5      \u001b[90m│\u001b[39m 5      \u001b[90m│\u001b[39m 6      \u001b[90m│\u001b[39m 7      \u001b[90m│\u001b[39m 6.35   \u001b[90m│\u001b[39m 0.63  \u001b[90m│\u001b[39m 5      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 144 kB \u001b[90m│\u001b[39m 144 kB \u001b[90m│\u001b[39m 173 kB \u001b[90m│\u001b[39m 201 kB \u001b[90m│\u001b[39m 183 kB \u001b[90m│\u001b[39m 18 kB \u001b[90m│\u001b[39m 144 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 381   \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n402 requests in 60.06s, 11 MB read\n12 errors (12 timeouts)\n\n\n----------------\n\n\n\nCLIENTS: *** 10 ***\n\nRunning 60s test @ http://192.168.2.131/\n10 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg       \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 56 ms \u001b[90m│\u001b[39m 97 ms \u001b[90m│\u001b[39m 244 ms \u001b[90m│\u001b[39m 277 ms \u001b[90m│\u001b[39m 113.43 ms \u001b[90m│\u001b[39m 51.43 ms \u001b[90m│\u001b[39m 616 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 48     \u001b[90m│\u001b[39m 51     \u001b[90m│\u001b[39m 61     \u001b[90m│\u001b[39m 69     \u001b[90m│\u001b[39m 61.42  \u001b[90m│\u001b[39m 3.92  \u001b[90m│\u001b[39m 48     \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 208 kB \u001b[90m│\u001b[39m 221 kB \u001b[90m│\u001b[39m 265 kB \u001b[90m│\u001b[39m 300 kB \u001b[90m│\u001b[39m 266 kB \u001b[90m│\u001b[39m 17 kB \u001b[90m│\u001b[39m 208 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 3685  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n4k requests in 60.06s, 16 MB read\n18 errors (18 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/api?foo=bar\n10 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 45 ms \u001b[90m│\u001b[39m 71 ms \u001b[90m│\u001b[39m 147 ms \u001b[90m│\u001b[39m 154 ms \u001b[90m│\u001b[39m 81.57 ms \u001b[90m│\u001b[39m 28.91 ms \u001b[90m│\u001b[39m 335 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 75      \u001b[90m│\u001b[39m 76      \u001b[90m│\u001b[39m 86      \u001b[90m│\u001b[39m 92      \u001b[90m│\u001b[39m 85.32   \u001b[90m│\u001b[39m 4.46  \u001b[90m│\u001b[39m 75      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 10.1 kB \u001b[90m│\u001b[39m 10.3 kB \u001b[90m│\u001b[39m 11.6 kB \u001b[90m│\u001b[39m 12.4 kB \u001b[90m│\u001b[39m 11.5 kB \u001b[90m│\u001b[39m 601 B \u001b[90m│\u001b[39m 10.1 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 5119  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n5k requests in 60.06s, 691 kB read\n18 errors (18 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/alien.png\n10 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg        \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 705 ms \u001b[90m│\u001b[39m 940 ms \u001b[90m│\u001b[39m 1962 ms \u001b[90m│\u001b[39m 2052 ms \u001b[90m│\u001b[39m 1075.72 ms \u001b[90m│\u001b[39m 385.45 ms \u001b[90m│\u001b[39m 3313 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 5      \u001b[90m│\u001b[39m 5      \u001b[90m│\u001b[39m 6      \u001b[90m│\u001b[39m 7      \u001b[90m│\u001b[39m 6.45   \u001b[90m│\u001b[39m 0.65    \u001b[90m│\u001b[39m 5      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 144 kB \u001b[90m│\u001b[39m 144 kB \u001b[90m│\u001b[39m 173 kB \u001b[90m│\u001b[39m 201 kB \u001b[90m│\u001b[39m 186 kB \u001b[90m│\u001b[39m 18.5 kB \u001b[90m│\u001b[39m 144 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 387   \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n415 requests in 60.05s, 11.1 MB read\n18 errors (18 timeouts)\n\n\n----------------\n\n\n\nCLIENTS: *** 15 ***\n\nRunning 60s test @ http://192.168.2.131/\n15 connections\n1 workers\n\nnode:internal/event_target:1084\n  process.nextTick(() => { throw err; });\n                           ^\n\nTypeError: colorize is not a function\n    at /Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/printResult.js:46:31\n    at Array.forEach (<anonymous>)\n    at printResult (/Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/printResult.js:43:43)\n    at EventEmitter.<anonymous> (/Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/progressTracker.js:79:28)\n    at EventEmitter.emit (node:events:527:35)\n    at _cb (/Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/init.js:76:13)\n    at handleFinish (/Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/manager.js:41:5)\n    at Worker.<anonymous> (/Users/hoeken/.nvm/versions/node/v21.1.0/lib/node_modules/autocannon/lib/manager.js:78:13)\n    at Worker.emit (node:events:515:28)\n    at MessagePort.<anonymous> (node:internal/worker:263:53)\n\nNode.js v21.1.0\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/api?foo=bar\n15 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 44 ms \u001b[90m│\u001b[39m 69 ms \u001b[90m│\u001b[39m 158 ms \u001b[90m│\u001b[39m 318 ms \u001b[90m│\u001b[39m 82.99 ms \u001b[90m│\u001b[39m 44.17 ms \u001b[90m│\u001b[39m 1074 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 22      \u001b[90m│\u001b[39m 23     \u001b[90m│\u001b[39m 88      \u001b[90m│\u001b[39m 98      \u001b[90m│\u001b[39m 83.74   \u001b[90m│\u001b[39m 16.45   \u001b[90m│\u001b[39m 22      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 2.97 kB \u001b[90m│\u001b[39m 3.1 kB \u001b[90m│\u001b[39m 11.9 kB \u001b[90m│\u001b[39m 13.2 kB \u001b[90m│\u001b[39m 11.3 kB \u001b[90m│\u001b[39m 2.22 kB \u001b[90m│\u001b[39m 2.97 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 5024  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n5k requests in 60.06s, 678 kB read\n48 errors (48 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/alien.png\n15 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg        \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 665 ms \u001b[90m│\u001b[39m 954 ms \u001b[90m│\u001b[39m 1989 ms \u001b[90m│\u001b[39m 2105 ms \u001b[90m│\u001b[39m 1092.91 ms \u001b[90m│\u001b[39m 396.34 ms \u001b[90m│\u001b[39m 3476 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 5      \u001b[90m│\u001b[39m 5      \u001b[90m│\u001b[39m 6      \u001b[90m│\u001b[39m 7      \u001b[90m│\u001b[39m 6.35   \u001b[90m│\u001b[39m 0.66    \u001b[90m│\u001b[39m 5      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 144 kB \u001b[90m│\u001b[39m 144 kB \u001b[90m│\u001b[39m 173 kB \u001b[90m│\u001b[39m 201 kB \u001b[90m│\u001b[39m 183 kB \u001b[90m│\u001b[39m 18.8 kB \u001b[90m│\u001b[39m 144 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 381   \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n444 requests in 60.06s, 11 MB read\n48 errors (48 timeouts)\n\n\n----------------\n\n\n\nCLIENTS: *** 20 ***\n\nRunning 60s test @ http://192.168.2.131/\n20 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg       \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 57 ms \u001b[90m│\u001b[39m 97 ms \u001b[90m│\u001b[39m 255 ms \u001b[90m│\u001b[39m 322 ms \u001b[90m│\u001b[39m 114.69 ms \u001b[90m│\u001b[39m 55.79 ms \u001b[90m│\u001b[39m 683 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 26     \u001b[90m│\u001b[39m 48     \u001b[90m│\u001b[39m 61     \u001b[90m│\u001b[39m 67     \u001b[90m│\u001b[39m 60.75  \u001b[90m│\u001b[39m 5.8     \u001b[90m│\u001b[39m 26     \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 113 kB \u001b[90m│\u001b[39m 208 kB \u001b[90m│\u001b[39m 265 kB \u001b[90m│\u001b[39m 291 kB \u001b[90m│\u001b[39m 264 kB \u001b[90m│\u001b[39m 25.2 kB \u001b[90m│\u001b[39m 113 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 3645  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n4k requests in 60.05s, 15.8 MB read\n78 errors (78 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/api?foo=bar\n20 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 44 ms \u001b[90m│\u001b[39m 69 ms \u001b[90m│\u001b[39m 142 ms \u001b[90m│\u001b[39m 153 ms \u001b[90m│\u001b[39m 78.14 ms \u001b[90m│\u001b[39m 26.88 ms \u001b[90m│\u001b[39m 256 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 76      \u001b[90m│\u001b[39m 78      \u001b[90m│\u001b[39m 88      \u001b[90m│\u001b[39m 100     \u001b[90m│\u001b[39m 88.92 \u001b[90m│\u001b[39m 5.59  \u001b[90m│\u001b[39m 76      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 10.3 kB \u001b[90m│\u001b[39m 10.5 kB \u001b[90m│\u001b[39m 11.9 kB \u001b[90m│\u001b[39m 13.5 kB \u001b[90m│\u001b[39m 12 kB \u001b[90m│\u001b[39m 754 B \u001b[90m│\u001b[39m 10.3 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 5335  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n5k requests in 60.07s, 720 kB read\n78 errors (78 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/alien.png\n20 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg        \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 705 ms \u001b[90m│\u001b[39m 940 ms \u001b[90m│\u001b[39m 1991 ms \u001b[90m│\u001b[39m 2070 ms \u001b[90m│\u001b[39m 1085.97 ms \u001b[90m│\u001b[39m 389.59 ms \u001b[90m│\u001b[39m 3357 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 5      \u001b[90m│\u001b[39m 5      \u001b[90m│\u001b[39m 6      \u001b[90m│\u001b[39m 7      \u001b[90m│\u001b[39m 6.39   \u001b[90m│\u001b[39m 0.64    \u001b[90m│\u001b[39m 5      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 144 kB \u001b[90m│\u001b[39m 144 kB \u001b[90m│\u001b[39m 173 kB \u001b[90m│\u001b[39m 201 kB \u001b[90m│\u001b[39m 184 kB \u001b[90m│\u001b[39m 18.2 kB \u001b[90m│\u001b[39m 144 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 383   \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n481 requests in 60.06s, 11 MB read\n78 errors (78 timeouts)\n\n\n----------------\n\n"
  },
  {
    "path": "benchmark/results/psychic-ssl-http-loadtest.log",
    "content": "\n\nCLIENTS: *** 1 ***\n\nRunning 60s test @ https://192.168.2.131/\n1 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 33 ms \u001b[90m│\u001b[39m 40 ms \u001b[90m│\u001b[39m 139 ms \u001b[90m│\u001b[39m 157 ms \u001b[90m│\u001b[39m 51.6 ms \u001b[90m│\u001b[39m 58.1 ms \u001b[90m│\u001b[39m 1757 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 5       \u001b[90m│\u001b[39m 20      \u001b[90m│\u001b[39m 24     \u001b[90m│\u001b[39m 19.19   \u001b[90m│\u001b[39m 4.05    \u001b[90m│\u001b[39m 5       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 21.7 kB \u001b[90m│\u001b[39m 86.8 kB \u001b[90m│\u001b[39m 104 kB \u001b[90m│\u001b[39m 83.2 kB \u001b[90m│\u001b[39m 17.5 kB \u001b[90m│\u001b[39m 21.7 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 1151  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n1k requests in 60.07s, 4.99 MB read\n\n\n----------------\n\nRunning 60s test @ https://192.168.2.131/api?foo=bar\n1 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 21 ms \u001b[90m│\u001b[39m 27 ms \u001b[90m│\u001b[39m 89 ms \u001b[90m│\u001b[39m 100 ms \u001b[90m│\u001b[39m 32.17 ms \u001b[90m│\u001b[39m 43.71 ms \u001b[90m│\u001b[39m 1745 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 8       \u001b[90m│\u001b[39m 32      \u001b[90m│\u001b[39m 38      \u001b[90m│\u001b[39m 30.57  \u001b[90m│\u001b[39m 5.91  \u001b[90m│\u001b[39m 8       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 1.07 kB \u001b[90m│\u001b[39m 4.29 kB \u001b[90m│\u001b[39m 5.09 kB \u001b[90m│\u001b[39m 4.1 kB \u001b[90m│\u001b[39m 791 B \u001b[90m│\u001b[39m 1.07 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 1834  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n2k requests in 60.07s, 246 kB read\n\n\n----------------\n\nRunning 60s test @ https://192.168.2.131/alien.png\n1 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg       \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 216 ms \u001b[90m│\u001b[39m 252 ms \u001b[90m│\u001b[39m 400 ms \u001b[90m│\u001b[39m 408 ms \u001b[90m│\u001b[39m 281.55 ms \u001b[90m│\u001b[39m 122.23 ms \u001b[90m│\u001b[39m 1871 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m 4      \u001b[90m│\u001b[39m 5      \u001b[90m│\u001b[39m 3.54   \u001b[90m│\u001b[39m 0.83    \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 28.8 kB \u001b[90m│\u001b[39m 115 kB \u001b[90m│\u001b[39m 144 kB \u001b[90m│\u001b[39m 102 kB \u001b[90m│\u001b[39m 23.8 kB \u001b[90m│\u001b[39m 28.8 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 212   \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n213 requests in 60.07s, 6.1 MB read\n\n\n----------------\n\n\n\nCLIENTS: *** 2 ***\n\nRunning 60s test @ https://192.168.2.131/\n2 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 37 ms \u001b[90m│\u001b[39m 54 ms \u001b[90m│\u001b[39m 149 ms \u001b[90m│\u001b[39m 164 ms \u001b[90m│\u001b[39m 64.14 ms \u001b[90m│\u001b[39m 106.26 ms \u001b[90m│\u001b[39m 3230 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 33     \u001b[90m│\u001b[39m 36     \u001b[90m│\u001b[39m 30.92  \u001b[90m│\u001b[39m 7.43    \u001b[90m│\u001b[39m 27     \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 143 kB \u001b[90m│\u001b[39m 156 kB \u001b[90m│\u001b[39m 134 kB \u001b[90m│\u001b[39m 32.2 kB \u001b[90m│\u001b[39m 117 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 1855  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n2k requests in 60.06s, 8.05 MB read\n\n\n----------------\n\nRunning 60s test @ https://192.168.2.131/api?foo=bar\n2 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 27 ms \u001b[90m│\u001b[39m 38 ms \u001b[90m│\u001b[39m 95 ms \u001b[90m│\u001b[39m 106 ms \u001b[90m│\u001b[39m 44.65 ms \u001b[90m│\u001b[39m 87.8 ms \u001b[90m│\u001b[39m 3211 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 47      \u001b[90m│\u001b[39m 52      \u001b[90m│\u001b[39m 44.29   \u001b[90m│\u001b[39m 10.57   \u001b[90m│\u001b[39m 35      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 6.35 kB \u001b[90m│\u001b[39m 7.02 kB \u001b[90m│\u001b[39m 5.98 kB \u001b[90m│\u001b[39m 1.43 kB \u001b[90m│\u001b[39m 4.72 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 2657  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n3k requests in 60.07s, 359 kB read\n\n\n----------------\n\nRunning 60s test @ https://192.168.2.131/alien.png\n2 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg       \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 320 ms \u001b[90m│\u001b[39m 456 ms \u001b[90m│\u001b[39m 633 ms \u001b[90m│\u001b[39m 701 ms \u001b[90m│\u001b[39m 488.51 ms \u001b[90m│\u001b[39m 296.92 ms \u001b[90m│\u001b[39m 3820 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 4      \u001b[90m│\u001b[39m 5      \u001b[90m│\u001b[39m 4.09   \u001b[90m│\u001b[39m 1.09    \u001b[90m│\u001b[39m 3       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 115 kB \u001b[90m│\u001b[39m 144 kB \u001b[90m│\u001b[39m 118 kB \u001b[90m│\u001b[39m 31.2 kB \u001b[90m│\u001b[39m 86.3 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 245   \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n247 requests in 60.07s, 7.05 MB read\n\n\n----------------\n\n\n\nCLIENTS: *** 3 ***\n\nRunning 60s test @ https://192.168.2.131/\n3 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬──────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg        \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max      \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 1535 ms \u001b[90m│\u001b[39m 6477 ms \u001b[90m│\u001b[39m 14517 ms \u001b[90m│\u001b[39m 14517 ms \u001b[90m│\u001b[39m 6462.25 ms \u001b[90m│\u001b[39m 2849.18 ms \u001b[90m│\u001b[39m 14517 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴──────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m 0.6    \u001b[90m│\u001b[39m 0.53    \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 4.34 kB \u001b[90m│\u001b[39m 4.34 kB \u001b[90m│\u001b[39m 2.6 kB \u001b[90m│\u001b[39m 2.27 kB \u001b[90m│\u001b[39m 4.34 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 36    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n75 requests in 60.1s, 156 kB read\n5 errors (0 timeouts)\n\n\n----------------\n\nRunning 60s test @ https://192.168.2.131/api?foo=bar\n3 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg        \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 1517 ms \u001b[90m│\u001b[39m 1638 ms \u001b[90m│\u001b[39m 3675 ms \u001b[90m│\u001b[39m 3675 ms \u001b[90m│\u001b[39m 1697.95 ms \u001b[90m│\u001b[39m 343.44 ms \u001b[90m│\u001b[39m 3675 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min   \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 1     \u001b[90m│\u001b[39m 1     \u001b[90m│\u001b[39m 0.59   \u001b[90m│\u001b[39m 0.5    \u001b[90m│\u001b[39m 1     \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 135 B \u001b[90m│\u001b[39m 135 B \u001b[90m│\u001b[39m 78.8 B \u001b[90m│\u001b[39m 66.6 B \u001b[90m│\u001b[39m 135 B \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 35    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n73 requests in 60.11s, 4.72 kB read\n1 errors (0 timeouts)\n\n\n----------------\n\nRunning 60s test @ https://192.168.2.131/alien.png\n3 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬─────────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬──────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg         \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max      \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼─────────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 386 ms \u001b[90m│\u001b[39m 9117 ms \u001b[90m│\u001b[39m 50313 ms \u001b[90m│\u001b[39m 50313 ms \u001b[90m│\u001b[39m 12942.77 ms \u001b[90m│\u001b[39m 11833.9 ms \u001b[90m│\u001b[39m 50313 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴─────────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴──────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 3       \u001b[90m│\u001b[39m 0.57    \u001b[90m│\u001b[39m 0.7     \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 86.4 kB \u001b[90m│\u001b[39m 16.3 kB \u001b[90m│\u001b[39m 19.9 kB \u001b[90m│\u001b[39m 28.8 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 34    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n68 requests in 60.11s, 979 kB read\n28 errors (0 timeouts)\n\n\n----------------\n\n\n\nCLIENTS: *** 4 ***\n\nRunning 60s test @ https://192.168.2.131/\n4 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬─────────────\u001b[39m\u001b[90m┬─────────────\u001b[39m\u001b[90m┬──────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg         \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev       \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max      \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼─────────────\u001b[39m\u001b[90m┼─────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 1530 ms \u001b[90m│\u001b[39m 1686 ms \u001b[90m│\u001b[39m 40733 ms \u001b[90m│\u001b[39m 40733 ms \u001b[90m│\u001b[39m 10336.06 ms \u001b[90m│\u001b[39m 12608.67 ms \u001b[90m│\u001b[39m 40733 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴─────────────\u001b[39m\u001b[90m┴─────────────\u001b[39m\u001b[90m┴──────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m 0.6    \u001b[90m│\u001b[39m 0.53    \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 4.34 kB \u001b[90m│\u001b[39m 4.34 kB \u001b[90m│\u001b[39m 2.6 kB \u001b[90m│\u001b[39m 2.27 kB \u001b[90m│\u001b[39m 4.34 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 36    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n76 requests in 60.15s, 156 kB read\n11 errors (0 timeouts)\n\n\n----------------\n\nRunning 60s test @ https://192.168.2.131/api?foo=bar\n4 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg        \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 1495 ms \u001b[90m│\u001b[39m 1586 ms \u001b[90m│\u001b[39m 4490 ms \u001b[90m│\u001b[39m 4490 ms \u001b[90m│\u001b[39m 1673.35 ms \u001b[90m│\u001b[39m 485.3 ms \u001b[90m│\u001b[39m 4490 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min   \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 1     \u001b[90m│\u001b[39m 1     \u001b[90m│\u001b[39m 0.59   \u001b[90m│\u001b[39m 0.5    \u001b[90m│\u001b[39m 1     \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 135 B \u001b[90m│\u001b[39m 135 B \u001b[90m│\u001b[39m 78.8 B \u001b[90m│\u001b[39m 66.6 B \u001b[90m│\u001b[39m 135 B \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 35    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n74 requests in 60.15s, 4.72 kB read\n3 errors (0 timeouts)\n\n\n----------------\n\nRunning 60s test @ https://192.168.2.131/alien.png\n4 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬─────────────\u001b[39m\u001b[90m┬─────────────\u001b[39m\u001b[90m┬──────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg         \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev       \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max      \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼─────────────\u001b[39m\u001b[90m┼─────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 340 ms \u001b[90m│\u001b[39m 3642 ms \u001b[90m│\u001b[39m 49950 ms \u001b[90m│\u001b[39m 49950 ms \u001b[90m│\u001b[39m 13180.63 ms \u001b[90m│\u001b[39m 14189.21 ms \u001b[90m│\u001b[39m 49950 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴─────────────\u001b[39m\u001b[90m┴─────────────\u001b[39m\u001b[90m┴──────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m 2       \u001b[90m│\u001b[39m 0.59    \u001b[90m│\u001b[39m 0.65    \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 28.8 kB \u001b[90m│\u001b[39m 57.6 kB \u001b[90m│\u001b[39m 16.8 kB \u001b[90m│\u001b[39m 18.4 kB \u001b[90m│\u001b[39m 28.8 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 35    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n72 requests in 60.15s, 1.01 MB read\n30 errors (0 timeouts)\n\n\n----------------\n\n\n\nCLIENTS: *** 5 ***\n\nRunning 60s test @ https://192.168.2.131/\n5 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg        \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 1449 ms \u001b[90m│\u001b[39m 1597 ms \u001b[90m│\u001b[39m 4810 ms \u001b[90m│\u001b[39m 4810 ms \u001b[90m│\u001b[39m 1691.72 ms \u001b[90m│\u001b[39m 537.09 ms \u001b[90m│\u001b[39m 4810 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m 0.59    \u001b[90m│\u001b[39m 0.5     \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 4.34 kB \u001b[90m│\u001b[39m 4.34 kB \u001b[90m│\u001b[39m 2.53 kB \u001b[90m│\u001b[39m 2.14 kB \u001b[90m│\u001b[39m 4.34 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 35    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n75 requests in 60.13s, 152 kB read\n11 errors (0 timeouts)\n\n\n----------------\n\nRunning 60s test @ https://192.168.2.131/api?foo=bar\n5 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg        \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 1510 ms \u001b[90m│\u001b[39m 1584 ms \u001b[90m│\u001b[39m 4971 ms \u001b[90m│\u001b[39m 4971 ms \u001b[90m│\u001b[39m 1685.03 ms \u001b[90m│\u001b[39m 564.99 ms \u001b[90m│\u001b[39m 4971 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min   \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 1     \u001b[90m│\u001b[39m 1     \u001b[90m│\u001b[39m 0.59   \u001b[90m│\u001b[39m 0.5    \u001b[90m│\u001b[39m 1     \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 135 B \u001b[90m│\u001b[39m 135 B \u001b[90m│\u001b[39m 78.8 B \u001b[90m│\u001b[39m 66.6 B \u001b[90m│\u001b[39m 135 B \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 35    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n75 requests in 60.14s, 4.72 kB read\n1 errors (0 timeouts)\n\n\n----------------\n\nRunning 60s test @ https://192.168.2.131/alien.png\n5 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬──────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg        \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max      \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 409 ms \u001b[90m│\u001b[39m 5565 ms \u001b[90m│\u001b[39m 38132 ms \u001b[90m│\u001b[39m 38132 ms \u001b[90m│\u001b[39m 9430.76 ms \u001b[90m│\u001b[39m 9263.66 ms \u001b[90m│\u001b[39m 38132 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴──────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 2       \u001b[90m│\u001b[39m 0.56    \u001b[90m│\u001b[39m 0.62    \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 57.6 kB \u001b[90m│\u001b[39m 15.8 kB \u001b[90m│\u001b[39m 17.8 kB \u001b[90m│\u001b[39m 28.8 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 33    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n69 requests in 60.14s, 950 kB read\n29 errors (1 timeouts)\n\n\n----------------\n\n\n\nCLIENTS: *** 6 ***\n\nRunning 60s test @ https://192.168.2.131/\n6 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg        \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 1007 ms \u001b[90m│\u001b[39m 1603 ms \u001b[90m│\u001b[39m 5373 ms \u001b[90m│\u001b[39m 5373 ms \u001b[90m│\u001b[39m 1696.69 ms \u001b[90m│\u001b[39m 639.15 ms \u001b[90m│\u001b[39m 5373 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m 0.59    \u001b[90m│\u001b[39m 0.5     \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 4.34 kB \u001b[90m│\u001b[39m 4.34 kB \u001b[90m│\u001b[39m 2.53 kB \u001b[90m│\u001b[39m 2.14 kB \u001b[90m│\u001b[39m 4.34 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 35    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n76 requests in 60.14s, 152 kB read\n15 errors (2 timeouts)\n\n\n----------------\n\nRunning 60s test @ https://192.168.2.131/api?foo=bar\n6 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg        \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 976 ms \u001b[90m│\u001b[39m 1586 ms \u001b[90m│\u001b[39m 6118 ms \u001b[90m│\u001b[39m 6118 ms \u001b[90m│\u001b[39m 1683.15 ms \u001b[90m│\u001b[39m 773.87 ms \u001b[90m│\u001b[39m 6118 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min   \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 1     \u001b[90m│\u001b[39m 1     \u001b[90m│\u001b[39m 0.59   \u001b[90m│\u001b[39m 0.5    \u001b[90m│\u001b[39m 1     \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 135 B \u001b[90m│\u001b[39m 135 B \u001b[90m│\u001b[39m 78.8 B \u001b[90m│\u001b[39m 66.6 B \u001b[90m│\u001b[39m 135 B \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 35    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n76 requests in 60.14s, 4.72 kB read\n4 errors (2 timeouts)\n\n\n----------------\n\nRunning 60s test @ https://192.168.2.131/alien.png\n6 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬──────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg        \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max      \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 437 ms \u001b[90m│\u001b[39m 3543 ms \u001b[90m│\u001b[39m 18174 ms \u001b[90m│\u001b[39m 18174 ms \u001b[90m│\u001b[39m 4264.16 ms \u001b[90m│\u001b[39m 3629.94 ms \u001b[90m│\u001b[39m 18174 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴──────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m 0.54    \u001b[90m│\u001b[39m 0.6   \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 28.8 kB \u001b[90m│\u001b[39m 15.3 kB \u001b[90m│\u001b[39m 17 kB \u001b[90m│\u001b[39m 28.8 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 32    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n69 requests in 60.15s, 921 kB read\n30 errors (5 timeouts)\n\n\n----------------\n\n\n\nCLIENTS: *** 7 ***\n\nRunning 60s test @ https://192.168.2.131/\n7 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬──────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg        \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max      \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 979 ms \u001b[90m│\u001b[39m 1600 ms \u001b[90m│\u001b[39m 37778 ms \u001b[90m│\u001b[39m 37778 ms \u001b[90m│\u001b[39m 2654.48 ms \u001b[90m│\u001b[39m 5987.7 ms \u001b[90m│\u001b[39m 37778 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴──────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m 0.6    \u001b[90m│\u001b[39m 0.53    \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 4.34 kB \u001b[90m│\u001b[39m 4.34 kB \u001b[90m│\u001b[39m 2.6 kB \u001b[90m│\u001b[39m 2.27 kB \u001b[90m│\u001b[39m 4.34 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 36    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n80 requests in 60.1s, 156 kB read\n17 errors (7 timeouts)\n\n\n----------------\n\nRunning 60s test @ https://192.168.2.131/api?foo=bar\n7 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg        \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 928 ms \u001b[90m│\u001b[39m 1591 ms \u001b[90m│\u001b[39m 7128 ms \u001b[90m│\u001b[39m 7128 ms \u001b[90m│\u001b[39m 1648.53 ms \u001b[90m│\u001b[39m 955.92 ms \u001b[90m│\u001b[39m 7128 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min   \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 1     \u001b[90m│\u001b[39m 1     \u001b[90m│\u001b[39m 0.6  \u001b[90m│\u001b[39m 0.49   \u001b[90m│\u001b[39m 1     \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 135 B \u001b[90m│\u001b[39m 135 B \u001b[90m│\u001b[39m 81 B \u001b[90m│\u001b[39m 66.1 B \u001b[90m│\u001b[39m 135 B \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 36    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n79 requests in 60.09s, 4.86 kB read\n13 errors (8 timeouts)\n\n\n----------------\n\nRunning 60s test @ https://192.168.2.131/alien.png\n7 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬──────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg       \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max      \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 487 ms \u001b[90m│\u001b[39m 1740 ms \u001b[90m│\u001b[39m 24134 ms \u001b[90m│\u001b[39m 24134 ms \u001b[90m│\u001b[39m 3069.3 ms \u001b[90m│\u001b[39m 4835.41 ms \u001b[90m│\u001b[39m 24134 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴──────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m 0.4     \u001b[90m│\u001b[39m 0.53  \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 28.8 kB \u001b[90m│\u001b[39m 11.5 kB \u001b[90m│\u001b[39m 15 kB \u001b[90m│\u001b[39m 28.8 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 24    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n69 requests in 60.08s, 691 kB read\n37 errors (21 timeouts)\n\n\n----------------\n\n\n\nCLIENTS: *** 8 ***\n\nRunning 60s test @ https://192.168.2.131/\n8 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg        \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 892 ms \u001b[90m│\u001b[39m 1585 ms \u001b[90m│\u001b[39m 6973 ms \u001b[90m│\u001b[39m 6973 ms \u001b[90m│\u001b[39m 1613.52 ms \u001b[90m│\u001b[39m 927.38 ms \u001b[90m│\u001b[39m 6973 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m 0.62    \u001b[90m│\u001b[39m 0.49    \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 4.34 kB \u001b[90m│\u001b[39m 4.34 kB \u001b[90m│\u001b[39m 2.68 kB \u001b[90m│\u001b[39m 2.11 kB \u001b[90m│\u001b[39m 4.34 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 37    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n89 requests in 60.09s, 161 kB read\n25 errors (16 timeouts)\n\n\n----------------\n\nRunning 60s test @ https://192.168.2.131/api?foo=bar\n8 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg        \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 964 ms \u001b[90m│\u001b[39m 1593 ms \u001b[90m│\u001b[39m 7380 ms \u001b[90m│\u001b[39m 7380 ms \u001b[90m│\u001b[39m 1645.62 ms \u001b[90m│\u001b[39m 998.66 ms \u001b[90m│\u001b[39m 7380 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min   \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 1     \u001b[90m│\u001b[39m 1     \u001b[90m│\u001b[39m 0.6  \u001b[90m│\u001b[39m 0.53   \u001b[90m│\u001b[39m 1     \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 135 B \u001b[90m│\u001b[39m 135 B \u001b[90m│\u001b[39m 81 B \u001b[90m│\u001b[39m 70.6 B \u001b[90m│\u001b[39m 135 B \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 36    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n86 requests in 60.1s, 4.86 kB read\n14 errors (14 timeouts)\n\n\n----------------\n\nRunning 60s test @ https://192.168.2.131/alien.png\n8 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬──────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg        \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max      \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 341 ms \u001b[90m│\u001b[39m 4820 ms \u001b[90m│\u001b[39m 26999 ms \u001b[90m│\u001b[39m 26999 ms \u001b[90m│\u001b[39m 7220.49 ms \u001b[90m│\u001b[39m 6874.47 ms \u001b[90m│\u001b[39m 26999 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴──────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 3       \u001b[90m│\u001b[39m 0.56    \u001b[90m│\u001b[39m 0.67    \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 86.4 kB \u001b[90m│\u001b[39m 15.8 kB \u001b[90m│\u001b[39m 19.3 kB \u001b[90m│\u001b[39m 28.8 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 33    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n84 requests in 60.08s, 950 kB read\n41 errors (27 timeouts)\n\n\n----------------\n\n\n\nCLIENTS: *** 9 ***\n\nRunning 60s test @ https://192.168.2.131/\n9 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg        \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 960 ms \u001b[90m│\u001b[39m 1598 ms \u001b[90m│\u001b[39m 7751 ms \u001b[90m│\u001b[39m 7751 ms \u001b[90m│\u001b[39m 1665.89 ms \u001b[90m│\u001b[39m 1056.66 ms \u001b[90m│\u001b[39m 7751 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m 0.6    \u001b[90m│\u001b[39m 0.49    \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 4.34 kB \u001b[90m│\u001b[39m 4.34 kB \u001b[90m│\u001b[39m 2.6 kB \u001b[90m│\u001b[39m 2.13 kB \u001b[90m│\u001b[39m 4.34 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 36    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n93 requests in 60.1s, 156 kB read\n25 errors (21 timeouts)\n\n\n----------------\n\nRunning 60s test @ https://192.168.2.131/api?foo=bar\n9 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg        \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 933 ms \u001b[90m│\u001b[39m 1589 ms \u001b[90m│\u001b[39m 7703 ms \u001b[90m│\u001b[39m 7703 ms \u001b[90m│\u001b[39m 1649.14 ms \u001b[90m│\u001b[39m 1051.77 ms \u001b[90m│\u001b[39m 7703 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min   \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 1     \u001b[90m│\u001b[39m 1     \u001b[90m│\u001b[39m 0.6  \u001b[90m│\u001b[39m 0.49   \u001b[90m│\u001b[39m 1     \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 135 B \u001b[90m│\u001b[39m 135 B \u001b[90m│\u001b[39m 81 B \u001b[90m│\u001b[39m 66.1 B \u001b[90m│\u001b[39m 135 B \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 36    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n93 requests in 60.09s, 4.86 kB read\n21 errors (20 timeouts)\n\n\n----------------\n\nRunning 60s test @ https://192.168.2.131/alien.png\n9 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 1049 ms \u001b[90m│\u001b[39m 1783 ms \u001b[90m│\u001b[39m 7382 ms \u001b[90m│\u001b[39m 7382 ms \u001b[90m│\u001b[39m 1758 ms \u001b[90m│\u001b[39m 1027.58 ms \u001b[90m│\u001b[39m 7382 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m 0.57    \u001b[90m│\u001b[39m 0.5     \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 28.8 kB \u001b[90m│\u001b[39m 28.8 kB \u001b[90m│\u001b[39m 16.3 kB \u001b[90m│\u001b[39m 14.3 kB \u001b[90m│\u001b[39m 28.8 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 34    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n91 requests in 60.1s, 979 kB read\n48 errors (29 timeouts)\n\n\n----------------\n\n\n\nCLIENTS: *** 10 ***\n\nRunning 60s test @ https://192.168.2.131/\n10 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg        \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 979 ms \u001b[90m│\u001b[39m 1597 ms \u001b[90m│\u001b[39m 7548 ms \u001b[90m│\u001b[39m 7548 ms \u001b[90m│\u001b[39m 1660.23 ms \u001b[90m│\u001b[39m 1024.01 ms \u001b[90m│\u001b[39m 7548 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m 0.6    \u001b[90m│\u001b[39m 0.49    \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 4.34 kB \u001b[90m│\u001b[39m 4.34 kB \u001b[90m│\u001b[39m 2.6 kB \u001b[90m│\u001b[39m 2.13 kB \u001b[90m│\u001b[39m 4.34 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 36    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n100 requests in 60.09s, 156 kB read\n29 errors (26 timeouts)\n\n\n----------------\n\nRunning 60s test @ https://192.168.2.131/api?foo=bar\n10 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg        \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 976 ms \u001b[90m│\u001b[39m 1590 ms \u001b[90m│\u001b[39m 7480 ms \u001b[90m│\u001b[39m 7480 ms \u001b[90m│\u001b[39m 1628.95 ms \u001b[90m│\u001b[39m 1021.2 ms \u001b[90m│\u001b[39m 7480 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min   \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 1     \u001b[90m│\u001b[39m 1     \u001b[90m│\u001b[39m 0.6  \u001b[90m│\u001b[39m 0.49   \u001b[90m│\u001b[39m 1     \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 135 B \u001b[90m│\u001b[39m 135 B \u001b[90m│\u001b[39m 81 B \u001b[90m│\u001b[39m 66.1 B \u001b[90m│\u001b[39m 135 B \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 36    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n101 requests in 60.12s, 4.86 kB read\n28 errors (28 timeouts)\n\n\n----------------\n\nRunning 60s test @ https://192.168.2.131/alien.png\n10 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬──────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg        \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max      \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 585 ms \u001b[90m│\u001b[39m 5882 ms \u001b[90m│\u001b[39m 27503 ms \u001b[90m│\u001b[39m 27503 ms \u001b[90m│\u001b[39m 6338.82 ms \u001b[90m│\u001b[39m 6773.89 ms \u001b[90m│\u001b[39m 27503 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴──────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m 0.54    \u001b[90m│\u001b[39m 0.6   \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 28.8 kB \u001b[90m│\u001b[39m 15.3 kB \u001b[90m│\u001b[39m 17 kB \u001b[90m│\u001b[39m 28.8 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 32    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n97 requests in 60.14s, 921 kB read\n54 errors (38 timeouts)\n\n\n----------------\n\n\n\nCLIENTS: *** 15 ***\n\nRunning 60s test @ https://192.168.2.131/\n15 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg        \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 957 ms \u001b[90m│\u001b[39m 1601 ms \u001b[90m│\u001b[39m 7609 ms \u001b[90m│\u001b[39m 7609 ms \u001b[90m│\u001b[39m 1654.73 ms \u001b[90m│\u001b[39m 1034.04 ms \u001b[90m│\u001b[39m 7609 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m 0.6    \u001b[90m│\u001b[39m 0.49    \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 4.34 kB \u001b[90m│\u001b[39m 4.34 kB \u001b[90m│\u001b[39m 2.6 kB \u001b[90m│\u001b[39m 2.13 kB \u001b[90m│\u001b[39m 4.34 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 36    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n135 requests in 60.14s, 156 kB read\n64 errors (56 timeouts)\n\n\n----------------\n\nRunning 60s test @ https://192.168.2.131/api?foo=bar\n15 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg        \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 966 ms \u001b[90m│\u001b[39m 1576 ms \u001b[90m│\u001b[39m 7369 ms \u001b[90m│\u001b[39m 7369 ms \u001b[90m│\u001b[39m 1612.68 ms \u001b[90m│\u001b[39m 991.59 ms \u001b[90m│\u001b[39m 7369 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min   \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 1     \u001b[90m│\u001b[39m 1     \u001b[90m│\u001b[39m 0.62   \u001b[90m│\u001b[39m 0.49   \u001b[90m│\u001b[39m 1     \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 135 B \u001b[90m│\u001b[39m 135 B \u001b[90m│\u001b[39m 83.3 B \u001b[90m│\u001b[39m 65.6 B \u001b[90m│\u001b[39m 135 B \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 37    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n136 requests in 60.14s, 5 kB read\n61 errors (60 timeouts)\n\n\n----------------\n\nRunning 60s test @ https://192.168.2.131/alien.png\n15 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬──────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max      \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 300 ms \u001b[90m│\u001b[39m 7281 ms \u001b[90m│\u001b[39m 34953 ms \u001b[90m│\u001b[39m 34953 ms \u001b[90m│\u001b[39m 10153 ms \u001b[90m│\u001b[39m 9647.72 ms \u001b[90m│\u001b[39m 34953 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴──────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 3       \u001b[90m│\u001b[39m 0.52    \u001b[90m│\u001b[39m 0.68    \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 86.4 kB \u001b[90m│\u001b[39m 14.9 kB \u001b[90m│\u001b[39m 19.3 kB \u001b[90m│\u001b[39m 28.8 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 31    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n132 requests in 60.11s, 892 kB read\n84 errors (70 timeouts)\n\n\n----------------\n\n\n\nCLIENTS: *** 20 ***\n\nRunning 60s test @ https://192.168.2.131/\n20 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬──────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg        \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max      \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼──────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 944 ms \u001b[90m│\u001b[39m 1600 ms \u001b[90m│\u001b[39m 36783 ms \u001b[90m│\u001b[39m 36783 ms \u001b[90m│\u001b[39m 2881.21 ms \u001b[90m│\u001b[39m 6487.79 ms \u001b[90m│\u001b[39m 36783 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴──────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m 0.49   \u001b[90m│\u001b[39m 0.54    \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 4.34 kB \u001b[90m│\u001b[39m 2.1 kB \u001b[90m│\u001b[39m 2.31 kB \u001b[90m│\u001b[39m 4.34 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 29    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n165 requests in 60.1s, 126 kB read\n96 errors (92 timeouts)\n\n\n----------------\n\nRunning 60s test @ https://192.168.2.131/api?foo=bar\n20 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg        \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 931 ms \u001b[90m│\u001b[39m 1568 ms \u001b[90m│\u001b[39m 7097 ms \u001b[90m│\u001b[39m 7097 ms \u001b[90m│\u001b[39m 1637.53 ms \u001b[90m│\u001b[39m 950.49 ms \u001b[90m│\u001b[39m 7097 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min   \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 1     \u001b[90m│\u001b[39m 1     \u001b[90m│\u001b[39m 0.6  \u001b[90m│\u001b[39m 0.49   \u001b[90m│\u001b[39m 1     \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 135 B \u001b[90m│\u001b[39m 135 B \u001b[90m│\u001b[39m 81 B \u001b[90m│\u001b[39m 66.1 B \u001b[90m│\u001b[39m 135 B \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 36    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n170 requests in 60.12s, 4.86 kB read\n87 errors (85 timeouts)\n\n\n----------------\n\nRunning 60s test @ https://192.168.2.131/alien.png\n20 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg        \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 1116 ms \u001b[90m│\u001b[39m 1707 ms \u001b[90m│\u001b[39m 7481 ms \u001b[90m│\u001b[39m 7481 ms \u001b[90m│\u001b[39m 1754.83 ms \u001b[90m│\u001b[39m 1032.66 ms \u001b[90m│\u001b[39m 7481 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────\u001b[39m\u001b[90m┬──────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 0   \u001b[90m│\u001b[39m 0    \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m 0.57    \u001b[90m│\u001b[39m 0.5     \u001b[90m│\u001b[39m 1       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────\u001b[39m\u001b[90m┼──────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 0 B \u001b[90m│\u001b[39m 0 B  \u001b[90m│\u001b[39m 28.8 kB \u001b[90m│\u001b[39m 28.8 kB \u001b[90m│\u001b[39m 16.3 kB \u001b[90m│\u001b[39m 14.3 kB \u001b[90m│\u001b[39m 28.8 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────\u001b[39m\u001b[90m┴──────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 34    \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n168 requests in 60.09s, 979 kB read\n114 errors (95 timeouts)\n\n\n----------------\n\n"
  },
  {
    "path": "benchmark/results/psychic-ssl-websocket-loadtest.log",
    "content": "\n\nCLIENTS: *** 1 ***\n\n\nTarget URL:          wss://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  1\nAgent:               none\n\nCompleted requests:  2039\nTotal errors:        0\nTotal time:          60.002 s\nMean latency:        27.8 ms\nEffective rps:       34\n\nPercentage of requests served within a certain time\n  50%      24 ms\n  90%      34 ms\n  95%      62 ms\n  99%      97 ms\n 100%      109 ms (longest request)\n\n\nCLIENTS: *** 2 ***\n\n\nTarget URL:          wss://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  2\nAgent:               none\n\nCompleted requests:  2969\nTotal errors:        0\nTotal time:          60.003 s\nMean latency:        37.7 ms\nEffective rps:       49\n\nPercentage of requests served within a certain time\n  50%      32 ms\n  90%      52 ms\n  95%      92 ms\n  99%      110 ms\n 100%      126 ms (longest request)\n\n\nCLIENTS: *** 3 ***\n\n\nTarget URL:          wss://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  3\nAgent:               none\n\nCompleted requests:  2883\nTotal errors:        0\nTotal time:          60.003 s\nMean latency:        38.2 ms\nEffective rps:       48\n\nPercentage of requests served within a certain time\n  50%      32 ms\n  90%      52 ms\n  95%      86 ms\n  99%      109 ms\n 100%      1711 ms (longest request)\n\n\nCLIENTS: *** 4 ***\n\n\nTarget URL:          wss://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  4\nAgent:               none\n\nCompleted requests:  2858\nTotal errors:        0\nTotal time:          60.003 s\nMean latency:        37.9 ms\nEffective rps:       48\n\nPercentage of requests served within a certain time\n  50%      32 ms\n  90%      49 ms\n  95%      76 ms\n  99%      104 ms\n 100%      1740 ms (longest request)\n\n\nCLIENTS: *** 5 ***\n\n\nTarget URL:          wss://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  5\nAgent:               none\n\nCompleted requests:  2772\nTotal errors:        0\nTotal time:          60.003 s\nMean latency:        38.6 ms\nEffective rps:       46\n\nPercentage of requests served within a certain time\n  50%      32 ms\n  90%      49 ms\n  95%      79 ms\n  99%      106 ms\n 100%      1634 ms (longest request)\n\n\nCLIENTS: *** 6 ***\n\n\nTarget URL:          wss://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  6\nAgent:               none\n\nCompleted requests:  2722\nTotal errors:        0\nTotal time:          60.003 s\nMean latency:        38.7 ms\nEffective rps:       45\n\nPercentage of requests served within a certain time\n  50%      32 ms\n  90%      49 ms\n  95%      72 ms\n  99%      102 ms\n 100%      1694 ms (longest request)\n\n\nCLIENTS: *** 7 ***\n\n\nTarget URL:          wss://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  7\nAgent:               none\n\nCompleted requests:  2552\nTotal errors:        0\nTotal time:          60.003 s\nMean latency:        40.7 ms\nEffective rps:       43\n\nPercentage of requests served within a certain time\n  50%      32 ms\n  90%      52 ms\n  95%      86 ms\n  99%      112 ms\n 100%      1816 ms (longest request)\n\n\nCLIENTS: *** 8 ***\n\n\nTarget URL:          wss://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  8\nRunning on cores:    2\nAgent:               none\n\nCompleted requests:  2507\nTotal errors:        0\nTotal time:          60.005 s\nMean latency:        40.8 ms\nEffective rps:       42\n\nPercentage of requests served within a certain time\n  50%      32 ms\n  90%      50 ms\n  95%      80 ms\n  99%      112 ms\n 100%      1646 ms (longest request)\n\n\nCLIENTS: *** 10 ***\n\n\nTarget URL:          wss://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  10\nRunning on cores:    2\nAgent:               none\n\nCompleted requests:  2265\nTotal errors:        0\nTotal time:          60.008 s\nMean latency:        43.7 ms\nEffective rps:       38\n\nPercentage of requests served within a certain time\n  50%      33 ms\n  90%      52 ms\n  95%      79 ms\n  99%      114 ms\n 100%      1675 ms (longest request)\n\n\nCLIENTS: *** 16 ***\n\n\nTarget URL:          wss://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  16\nRunning on cores:    2\nAgent:               none\n\nCompleted requests:  1795\nTotal errors:        0\nTotal time:          60.003 s\nMean latency:        49.7 ms\nEffective rps:       30\n\nPercentage of requests served within a certain time\n  50%      33 ms\n  90%      51 ms\n  95%      77 ms\n  99%      112 ms\n 100%      1741 ms (longest request)\n\n\nCLIENTS: *** 20 ***\n\n\nTarget URL:          wss://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  20\nRunning on cores:    2\nAgent:               none\n\nCompleted requests:  1603\nTotal errors:        0\nTotal time:          60.004 s\nMean latency:        54.1 ms\nEffective rps:       27\n\nPercentage of requests served within a certain time\n  50%      33 ms\n  90%      60 ms\n  95%      94 ms\n  99%      133 ms\n 100%      1729 ms (longest request)\n"
  },
  {
    "path": "benchmark/results/psychic-v1.1-http-loadtest.log",
    "content": "\n\nCLIENTS: *** 1 ***\n\nRunning 60s test @ http://192.168.2.131/\n1 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 25 ms \u001b[90m│\u001b[39m 34 ms \u001b[90m│\u001b[39m 137 ms \u001b[90m│\u001b[39m 175 ms \u001b[90m│\u001b[39m 44.75 ms \u001b[90m│\u001b[39m 33.04 ms \u001b[90m│\u001b[39m 363 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 13      \u001b[90m│\u001b[39m 14      \u001b[90m│\u001b[39m 23      \u001b[90m│\u001b[39m 27     \u001b[90m│\u001b[39m 22.05   \u001b[90m│\u001b[39m 3.62    \u001b[90m│\u001b[39m 13      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 56.4 kB \u001b[90m│\u001b[39m 60.7 kB \u001b[90m│\u001b[39m 99.8 kB \u001b[90m│\u001b[39m 117 kB \u001b[90m│\u001b[39m 95.6 kB \u001b[90m│\u001b[39m 15.7 kB \u001b[90m│\u001b[39m 56.4 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 1323  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n1k requests in 60.06s, 5.74 MB read\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/api?foo=bar\n1 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 21 ms \u001b[90m│\u001b[39m 29 ms \u001b[90m│\u001b[39m 122 ms \u001b[90m│\u001b[39m 173 ms \u001b[90m│\u001b[39m 40.61 ms \u001b[90m│\u001b[39m 38.19 ms \u001b[90m│\u001b[39m 646 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min   \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 2     \u001b[90m│\u001b[39m 6     \u001b[90m│\u001b[39m 27      \u001b[90m│\u001b[39m 34      \u001b[90m│\u001b[39m 24.29   \u001b[90m│\u001b[39m 7.62    \u001b[90m│\u001b[39m 2     \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 268 B \u001b[90m│\u001b[39m 804 B \u001b[90m│\u001b[39m 3.62 kB \u001b[90m│\u001b[39m 4.56 kB \u001b[90m│\u001b[39m 3.25 kB \u001b[90m│\u001b[39m 1.02 kB \u001b[90m│\u001b[39m 268 B \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 1457  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n1k requests in 60.07s, 195 kB read\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/alien.png\n1 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg       \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 254 ms \u001b[90m│\u001b[39m 291 ms \u001b[90m│\u001b[39m 441 ms \u001b[90m│\u001b[39m 487 ms \u001b[90m│\u001b[39m 311.18 ms \u001b[90m│\u001b[39m 52.89 ms \u001b[90m│\u001b[39m 503 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 2       \u001b[90m│\u001b[39m 2       \u001b[90m│\u001b[39m 3       \u001b[90m│\u001b[39m 4      \u001b[90m│\u001b[39m 3.2     \u001b[90m│\u001b[39m 0.58    \u001b[90m│\u001b[39m 2       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 57.6 kB \u001b[90m│\u001b[39m 57.6 kB \u001b[90m│\u001b[39m 86.4 kB \u001b[90m│\u001b[39m 115 kB \u001b[90m│\u001b[39m 92.1 kB \u001b[90m│\u001b[39m 16.4 kB \u001b[90m│\u001b[39m 57.6 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 192   \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n193 requests in 60.07s, 5.53 MB read\n\n\n----------------\n\n\n\nCLIENTS: *** 2 ***\n\nRunning 60s test @ http://192.168.2.131/\n2 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 29 ms \u001b[90m│\u001b[39m 46 ms \u001b[90m│\u001b[39m 184 ms \u001b[90m│\u001b[39m 213 ms \u001b[90m│\u001b[39m 63.03 ms \u001b[90m│\u001b[39m 43.98 ms \u001b[90m│\u001b[39m 437 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 13      \u001b[90m│\u001b[39m 13      \u001b[90m│\u001b[39m 34     \u001b[90m│\u001b[39m 43     \u001b[90m│\u001b[39m 31.44  \u001b[90m│\u001b[39m 7.44    \u001b[90m│\u001b[39m 13      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 56.4 kB \u001b[90m│\u001b[39m 56.4 kB \u001b[90m│\u001b[39m 148 kB \u001b[90m│\u001b[39m 187 kB \u001b[90m│\u001b[39m 136 kB \u001b[90m│\u001b[39m 32.2 kB \u001b[90m│\u001b[39m 56.4 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 1886  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n2k requests in 60.07s, 8.18 MB read\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/api?foo=bar\n2 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 27 ms \u001b[90m│\u001b[39m 37 ms \u001b[90m│\u001b[39m 107 ms \u001b[90m│\u001b[39m 120 ms \u001b[90m│\u001b[39m 44.09 ms \u001b[90m│\u001b[39m 20.34 ms \u001b[90m│\u001b[39m 188 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 24      \u001b[90m│\u001b[39m 25      \u001b[90m│\u001b[39m 46      \u001b[90m│\u001b[39m 52      \u001b[90m│\u001b[39m 44.79 \u001b[90m│\u001b[39m 6.1   \u001b[90m│\u001b[39m 24      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 3.22 kB \u001b[90m│\u001b[39m 3.35 kB \u001b[90m│\u001b[39m 6.17 kB \u001b[90m│\u001b[39m 6.97 kB \u001b[90m│\u001b[39m 6 kB  \u001b[90m│\u001b[39m 817 B \u001b[90m│\u001b[39m 3.22 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 2687  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n3k requests in 60.06s, 360 kB read\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/alien.png\n2 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg       \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 375 ms \u001b[90m│\u001b[39m 552 ms \u001b[90m│\u001b[39m 759 ms \u001b[90m│\u001b[39m 848 ms \u001b[90m│\u001b[39m 556.76 ms \u001b[90m│\u001b[39m 95.75 ms \u001b[90m│\u001b[39m 875 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 3       \u001b[90m│\u001b[39m 3       \u001b[90m│\u001b[39m 4      \u001b[90m│\u001b[39m 4      \u001b[90m│\u001b[39m 3.59   \u001b[90m│\u001b[39m 0.53    \u001b[90m│\u001b[39m 3       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 86.4 kB \u001b[90m│\u001b[39m 86.4 kB \u001b[90m│\u001b[39m 115 kB \u001b[90m│\u001b[39m 115 kB \u001b[90m│\u001b[39m 103 kB \u001b[90m│\u001b[39m 15.1 kB \u001b[90m│\u001b[39m 86.3 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 215   \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n217 requests in 60.09s, 6.19 MB read\n\n\n----------------\n\n\n\nCLIENTS: *** 3 ***\n\nRunning 60s test @ http://192.168.2.131/\n3 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 36 ms \u001b[90m│\u001b[39m 56 ms \u001b[90m│\u001b[39m 167 ms \u001b[90m│\u001b[39m 193 ms \u001b[90m│\u001b[39m 67.22 ms \u001b[90m│\u001b[39m 33.6 ms \u001b[90m│\u001b[39m 343 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 32     \u001b[90m│\u001b[39m 34     \u001b[90m│\u001b[39m 45     \u001b[90m│\u001b[39m 52     \u001b[90m│\u001b[39m 44.25  \u001b[90m│\u001b[39m 4.31    \u001b[90m│\u001b[39m 32     \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 139 kB \u001b[90m│\u001b[39m 148 kB \u001b[90m│\u001b[39m 195 kB \u001b[90m│\u001b[39m 226 kB \u001b[90m│\u001b[39m 192 kB \u001b[90m│\u001b[39m 18.7 kB \u001b[90m│\u001b[39m 139 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 2655  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n3k requests in 60.08s, 11.5 MB read\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/api?foo=bar\n3 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 30 ms \u001b[90m│\u001b[39m 45 ms \u001b[90m│\u001b[39m 114 ms \u001b[90m│\u001b[39m 128 ms \u001b[90m│\u001b[39m 51.89 ms \u001b[90m│\u001b[39m 22.2 ms \u001b[90m│\u001b[39m 294 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 37      \u001b[90m│\u001b[39m 44     \u001b[90m│\u001b[39m 58      \u001b[90m│\u001b[39m 67      \u001b[90m│\u001b[39m 57.24   \u001b[90m│\u001b[39m 6.16  \u001b[90m│\u001b[39m 37      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 4.96 kB \u001b[90m│\u001b[39m 5.9 kB \u001b[90m│\u001b[39m 7.78 kB \u001b[90m│\u001b[39m 8.98 kB \u001b[90m│\u001b[39m 7.67 kB \u001b[90m│\u001b[39m 825 B \u001b[90m│\u001b[39m 4.96 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 3434  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n3k requests in 60.1s, 460 kB read\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/alien.png\n3 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg       \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 412 ms \u001b[90m│\u001b[39m 786 ms \u001b[90m│\u001b[39m 1293 ms \u001b[90m│\u001b[39m 1397 ms \u001b[90m│\u001b[39m 829.09 ms \u001b[90m│\u001b[39m 295.53 ms \u001b[90m│\u001b[39m 1412 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 2       \u001b[90m│\u001b[39m 3       \u001b[90m│\u001b[39m 4      \u001b[90m│\u001b[39m 4      \u001b[90m│\u001b[39m 3.59   \u001b[90m│\u001b[39m 0.53    \u001b[90m│\u001b[39m 2       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 57.6 kB \u001b[90m│\u001b[39m 86.4 kB \u001b[90m│\u001b[39m 115 kB \u001b[90m│\u001b[39m 115 kB \u001b[90m│\u001b[39m 103 kB \u001b[90m│\u001b[39m 15.1 kB \u001b[90m│\u001b[39m 57.6 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 215   \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n218 requests in 60.11s, 6.19 MB read\n\n\n----------------\n\n\n\nCLIENTS: *** 4 ***\n\nRunning 60s test @ http://192.168.2.131/\n4 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 41 ms \u001b[90m│\u001b[39m 65 ms \u001b[90m│\u001b[39m 189 ms \u001b[90m│\u001b[39m 221 ms \u001b[90m│\u001b[39m 79.49 ms \u001b[90m│\u001b[39m 39.69 ms \u001b[90m│\u001b[39m 385 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 41     \u001b[90m│\u001b[39m 41     \u001b[90m│\u001b[39m 51     \u001b[90m│\u001b[39m 56     \u001b[90m│\u001b[39m 50     \u001b[90m│\u001b[39m 4.07    \u001b[90m│\u001b[39m 41     \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 178 kB \u001b[90m│\u001b[39m 178 kB \u001b[90m│\u001b[39m 221 kB \u001b[90m│\u001b[39m 243 kB \u001b[90m│\u001b[39m 217 kB \u001b[90m│\u001b[39m 17.6 kB \u001b[90m│\u001b[39m 178 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 3000  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n3k requests in 60.1s, 13 MB read\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/api?foo=bar\n4 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 35 ms \u001b[90m│\u001b[39m 51 ms \u001b[90m│\u001b[39m 128 ms \u001b[90m│\u001b[39m 154 ms \u001b[90m│\u001b[39m 58.79 ms \u001b[90m│\u001b[39m 24.56 ms \u001b[90m│\u001b[39m 347 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 38      \u001b[90m│\u001b[39m 50     \u001b[90m│\u001b[39m 69      \u001b[90m│\u001b[39m 77      \u001b[90m│\u001b[39m 67.49   \u001b[90m│\u001b[39m 7.34  \u001b[90m│\u001b[39m 38      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 5.09 kB \u001b[90m│\u001b[39m 6.7 kB \u001b[90m│\u001b[39m 9.25 kB \u001b[90m│\u001b[39m 10.3 kB \u001b[90m│\u001b[39m 9.04 kB \u001b[90m│\u001b[39m 983 B \u001b[90m│\u001b[39m 5.09 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 4049  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n4k requests in 60.11s, 543 kB read\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/alien.png\n4 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg        \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 630 ms \u001b[90m│\u001b[39m 885 ms \u001b[90m│\u001b[39m 1840 ms \u001b[90m│\u001b[39m 1877 ms \u001b[90m│\u001b[39m 1082.82 ms \u001b[90m│\u001b[39m 406.47 ms \u001b[90m│\u001b[39m 2050 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 3       \u001b[90m│\u001b[39m 3       \u001b[90m│\u001b[39m 4      \u001b[90m│\u001b[39m 5      \u001b[90m│\u001b[39m 3.65   \u001b[90m│\u001b[39m 0.55    \u001b[90m│\u001b[39m 3       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 86.4 kB \u001b[90m│\u001b[39m 86.4 kB \u001b[90m│\u001b[39m 115 kB \u001b[90m│\u001b[39m 144 kB \u001b[90m│\u001b[39m 105 kB \u001b[90m│\u001b[39m 15.6 kB \u001b[90m│\u001b[39m 86.3 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 219   \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n223 requests in 60.08s, 6.3 MB read\n\n\n----------------\n\n\n\nCLIENTS: *** 5 ***\n\nRunning 60s test @ http://192.168.2.131/\n5 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 47 ms \u001b[90m│\u001b[39m 77 ms \u001b[90m│\u001b[39m 213 ms \u001b[90m│\u001b[39m 242 ms \u001b[90m│\u001b[39m 91.79 ms \u001b[90m│\u001b[39m 44.06 ms \u001b[90m│\u001b[39m 398 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 41     \u001b[90m│\u001b[39m 42     \u001b[90m│\u001b[39m 55     \u001b[90m│\u001b[39m 62     \u001b[90m│\u001b[39m 54.12  \u001b[90m│\u001b[39m 4.67    \u001b[90m│\u001b[39m 41     \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 178 kB \u001b[90m│\u001b[39m 182 kB \u001b[90m│\u001b[39m 239 kB \u001b[90m│\u001b[39m 269 kB \u001b[90m│\u001b[39m 235 kB \u001b[90m│\u001b[39m 20.2 kB \u001b[90m│\u001b[39m 178 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 3247  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n3k requests in 60.08s, 14.1 MB read\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/api?foo=bar\n5 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 39 ms \u001b[90m│\u001b[39m 60 ms \u001b[90m│\u001b[39m 126 ms \u001b[90m│\u001b[39m 141 ms \u001b[90m│\u001b[39m 65.76 ms \u001b[90m│\u001b[39m 21.03 ms \u001b[90m│\u001b[39m 172 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 53     \u001b[90m│\u001b[39m 58      \u001b[90m│\u001b[39m 76      \u001b[90m│\u001b[39m 86      \u001b[90m│\u001b[39m 75.34   \u001b[90m│\u001b[39m 7.04  \u001b[90m│\u001b[39m 53     \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 7.1 kB \u001b[90m│\u001b[39m 7.78 kB \u001b[90m│\u001b[39m 10.2 kB \u001b[90m│\u001b[39m 11.5 kB \u001b[90m│\u001b[39m 10.1 kB \u001b[90m│\u001b[39m 943 B \u001b[90m│\u001b[39m 7.1 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 4520  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n5k requests in 60.08s, 606 kB read\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/alien.png\n5 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg        \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 832 ms \u001b[90m│\u001b[39m 1125 ms \u001b[90m│\u001b[39m 2405 ms \u001b[90m│\u001b[39m 2530 ms \u001b[90m│\u001b[39m 1344.04 ms \u001b[90m│\u001b[39m 504.13 ms \u001b[90m│\u001b[39m 3485 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 2       \u001b[90m│\u001b[39m 3       \u001b[90m│\u001b[39m 4      \u001b[90m│\u001b[39m 5      \u001b[90m│\u001b[39m 3.69   \u001b[90m│\u001b[39m 0.57    \u001b[90m│\u001b[39m 2       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 57.6 kB \u001b[90m│\u001b[39m 86.4 kB \u001b[90m│\u001b[39m 115 kB \u001b[90m│\u001b[39m 144 kB \u001b[90m│\u001b[39m 106 kB \u001b[90m│\u001b[39m 16.2 kB \u001b[90m│\u001b[39m 57.6 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 221   \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n226 requests in 60.08s, 6.36 MB read\n\n\n----------------\n\n\n\nCLIENTS: *** 6 ***\n\nRunning 60s test @ http://192.168.2.131/\n6 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 51 ms \u001b[90m│\u001b[39m 84 ms \u001b[90m│\u001b[39m 214 ms \u001b[90m│\u001b[39m 249 ms \u001b[90m│\u001b[39m 98.05 ms \u001b[90m│\u001b[39m 44.48 ms \u001b[90m│\u001b[39m 553 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 40     \u001b[90m│\u001b[39m 50     \u001b[90m│\u001b[39m 62     \u001b[90m│\u001b[39m 66     \u001b[90m│\u001b[39m 60.87  \u001b[90m│\u001b[39m 4.59    \u001b[90m│\u001b[39m 40     \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 174 kB \u001b[90m│\u001b[39m 217 kB \u001b[90m│\u001b[39m 269 kB \u001b[90m│\u001b[39m 286 kB \u001b[90m│\u001b[39m 264 kB \u001b[90m│\u001b[39m 19.9 kB \u001b[90m│\u001b[39m 174 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 3652  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n4k requests in 60.09s, 15.8 MB read\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/api?foo=bar\n6 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 45 ms \u001b[90m│\u001b[39m 68 ms \u001b[90m│\u001b[39m 144 ms \u001b[90m│\u001b[39m 159 ms \u001b[90m│\u001b[39m 75.43 ms \u001b[90m│\u001b[39m 24.46 ms \u001b[90m│\u001b[39m 223 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 53      \u001b[90m│\u001b[39m 63      \u001b[90m│\u001b[39m 80      \u001b[90m│\u001b[39m 91      \u001b[90m│\u001b[39m 78.95   \u001b[90m│\u001b[39m 7.74    \u001b[90m│\u001b[39m 53      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 7.16 kB \u001b[90m│\u001b[39m 8.51 kB \u001b[90m│\u001b[39m 10.8 kB \u001b[90m│\u001b[39m 12.3 kB \u001b[90m│\u001b[39m 10.7 kB \u001b[90m│\u001b[39m 1.04 kB \u001b[90m│\u001b[39m 7.16 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 4737  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n5k requests in 60.08s, 639 kB read\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/alien.png\n6 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg        \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 893 ms \u001b[90m│\u001b[39m 1385 ms \u001b[90m│\u001b[39m 3045 ms \u001b[90m│\u001b[39m 3336 ms \u001b[90m│\u001b[39m 1630.97 ms \u001b[90m│\u001b[39m 621.58 ms \u001b[90m│\u001b[39m 4350 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 2       \u001b[90m│\u001b[39m 3       \u001b[90m│\u001b[39m 4      \u001b[90m│\u001b[39m 5      \u001b[90m│\u001b[39m 3.62   \u001b[90m│\u001b[39m 0.58    \u001b[90m│\u001b[39m 2       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 57.6 kB \u001b[90m│\u001b[39m 86.4 kB \u001b[90m│\u001b[39m 115 kB \u001b[90m│\u001b[39m 144 kB \u001b[90m│\u001b[39m 104 kB \u001b[90m│\u001b[39m 16.7 kB \u001b[90m│\u001b[39m 57.6 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 217   \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n223 requests in 60.1s, 6.25 MB read\n\n\n----------------\n\n\n\nCLIENTS: *** 7 ***\n\nRunning 60s test @ http://192.168.2.131/\n7 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg       \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 59 ms \u001b[90m│\u001b[39m 96 ms \u001b[90m│\u001b[39m 232 ms \u001b[90m│\u001b[39m 260 ms \u001b[90m│\u001b[39m 109.85 ms \u001b[90m│\u001b[39m 47.04 ms \u001b[90m│\u001b[39m 531 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 44     \u001b[90m│\u001b[39m 53     \u001b[90m│\u001b[39m 65     \u001b[90m│\u001b[39m 72     \u001b[90m│\u001b[39m 63.39  \u001b[90m│\u001b[39m 5.76  \u001b[90m│\u001b[39m 44     \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 191 kB \u001b[90m│\u001b[39m 230 kB \u001b[90m│\u001b[39m 282 kB \u001b[90m│\u001b[39m 313 kB \u001b[90m│\u001b[39m 275 kB \u001b[90m│\u001b[39m 25 kB \u001b[90m│\u001b[39m 191 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 3803  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n4k requests in 60.08s, 16.5 MB read\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/api?foo=bar\n7 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 48 ms \u001b[90m│\u001b[39m 75 ms \u001b[90m│\u001b[39m 139 ms \u001b[90m│\u001b[39m 152 ms \u001b[90m│\u001b[39m 80.37 ms \u001b[90m│\u001b[39m 22.69 ms \u001b[90m│\u001b[39m 291 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5% \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 52      \u001b[90m│\u001b[39m 67      \u001b[90m│\u001b[39m 88      \u001b[90m│\u001b[39m 96    \u001b[90m│\u001b[39m 86.59   \u001b[90m│\u001b[39m 7.62    \u001b[90m│\u001b[39m 52      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 7.02 kB \u001b[90m│\u001b[39m 9.05 kB \u001b[90m│\u001b[39m 11.9 kB \u001b[90m│\u001b[39m 13 kB \u001b[90m│\u001b[39m 11.7 kB \u001b[90m│\u001b[39m 1.03 kB \u001b[90m│\u001b[39m 7.02 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 5195  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n5k requests in 60.11s, 701 kB read\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/alien.png\n7 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg        \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 845 ms \u001b[90m│\u001b[39m 1642 ms \u001b[90m│\u001b[39m 3537 ms \u001b[90m│\u001b[39m 3656 ms \u001b[90m│\u001b[39m 1887.17 ms \u001b[90m│\u001b[39m 728.73 ms \u001b[90m│\u001b[39m 6130 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 3       \u001b[90m│\u001b[39m 3       \u001b[90m│\u001b[39m 4      \u001b[90m│\u001b[39m 4      \u001b[90m│\u001b[39m 3.64   \u001b[90m│\u001b[39m 0.52    \u001b[90m│\u001b[39m 3       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 86.4 kB \u001b[90m│\u001b[39m 86.4 kB \u001b[90m│\u001b[39m 115 kB \u001b[90m│\u001b[39m 115 kB \u001b[90m│\u001b[39m 105 kB \u001b[90m│\u001b[39m 14.8 kB \u001b[90m│\u001b[39m 86.3 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 218   \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n225 requests in 60.1s, 6.27 MB read\n\n\n----------------\n\n\n\nCLIENTS: *** 8 ***\n\nRunning 60s test @ http://192.168.2.131/\n8 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg       \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 58 ms \u001b[90m│\u001b[39m 96 ms \u001b[90m│\u001b[39m 225 ms \u001b[90m│\u001b[39m 256 ms \u001b[90m│\u001b[39m 108.89 ms \u001b[90m│\u001b[39m 45.19 ms \u001b[90m│\u001b[39m 571 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 51     \u001b[90m│\u001b[39m 54     \u001b[90m│\u001b[39m 65     \u001b[90m│\u001b[39m 70     \u001b[90m│\u001b[39m 63.92  \u001b[90m│\u001b[39m 4.63    \u001b[90m│\u001b[39m 51     \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 221 kB \u001b[90m│\u001b[39m 234 kB \u001b[90m│\u001b[39m 282 kB \u001b[90m│\u001b[39m 304 kB \u001b[90m│\u001b[39m 277 kB \u001b[90m│\u001b[39m 20.1 kB \u001b[90m│\u001b[39m 221 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 3835  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n4k requests in 60.07s, 16.6 MB read\n6 errors (6 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/api?foo=bar\n8 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 50 ms \u001b[90m│\u001b[39m 76 ms \u001b[90m│\u001b[39m 148 ms \u001b[90m│\u001b[39m 166 ms \u001b[90m│\u001b[39m 83.61 ms \u001b[90m│\u001b[39m 26.5 ms \u001b[90m│\u001b[39m 282 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 63      \u001b[90m│\u001b[39m 66      \u001b[90m│\u001b[39m 82      \u001b[90m│\u001b[39m 98      \u001b[90m│\u001b[39m 83.15   \u001b[90m│\u001b[39m 8.78    \u001b[90m│\u001b[39m 63      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 8.51 kB \u001b[90m│\u001b[39m 8.91 kB \u001b[90m│\u001b[39m 11.1 kB \u001b[90m│\u001b[39m 13.2 kB \u001b[90m│\u001b[39m 11.2 kB \u001b[90m│\u001b[39m 1.18 kB \u001b[90m│\u001b[39m 8.51 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 4989  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n5k requests in 60.08s, 674 kB read\n6 errors (6 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/alien.png\n8 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg       \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 806 ms \u001b[90m│\u001b[39m 1614 ms \u001b[90m│\u001b[39m 3526 ms \u001b[90m│\u001b[39m 3769 ms \u001b[90m│\u001b[39m 1851.3 ms \u001b[90m│\u001b[39m 712.64 ms \u001b[90m│\u001b[39m 5877 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 3       \u001b[90m│\u001b[39m 3       \u001b[90m│\u001b[39m 4      \u001b[90m│\u001b[39m 5      \u001b[90m│\u001b[39m 3.72   \u001b[90m│\u001b[39m 0.52    \u001b[90m│\u001b[39m 3       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 86.4 kB \u001b[90m│\u001b[39m 86.4 kB \u001b[90m│\u001b[39m 115 kB \u001b[90m│\u001b[39m 144 kB \u001b[90m│\u001b[39m 107 kB \u001b[90m│\u001b[39m 14.9 kB \u001b[90m│\u001b[39m 86.3 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 223   \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n237 requests in 60.09s, 6.42 MB read\n6 errors (6 timeouts)\n\n\n----------------\n\n\n\nCLIENTS: *** 9 ***\n\nRunning 60s test @ http://192.168.2.131/\n9 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg       \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 60 ms \u001b[90m│\u001b[39m 98 ms \u001b[90m│\u001b[39m 232 ms \u001b[90m│\u001b[39m 268 ms \u001b[90m│\u001b[39m 111.69 ms \u001b[90m│\u001b[39m 57.8 ms \u001b[90m│\u001b[39m 1065 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min   \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 3     \u001b[90m│\u001b[39m 54     \u001b[90m│\u001b[39m 63     \u001b[90m│\u001b[39m 72     \u001b[90m│\u001b[39m 62.37  \u001b[90m│\u001b[39m 8.98  \u001b[90m│\u001b[39m 3     \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 13 kB \u001b[90m│\u001b[39m 234 kB \u001b[90m│\u001b[39m 273 kB \u001b[90m│\u001b[39m 313 kB \u001b[90m│\u001b[39m 271 kB \u001b[90m│\u001b[39m 39 kB \u001b[90m│\u001b[39m 13 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 3742  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n4k requests in 60.07s, 16.2 MB read\n12 errors (12 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/api?foo=bar\n9 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 50 ms \u001b[90m│\u001b[39m 77 ms \u001b[90m│\u001b[39m 148 ms \u001b[90m│\u001b[39m 160 ms \u001b[90m│\u001b[39m 83.55 ms \u001b[90m│\u001b[39m 24.72 ms \u001b[90m│\u001b[39m 275 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 63      \u001b[90m│\u001b[39m 67      \u001b[90m│\u001b[39m 85      \u001b[90m│\u001b[39m 95      \u001b[90m│\u001b[39m 83.27   \u001b[90m│\u001b[39m 7.2   \u001b[90m│\u001b[39m 63      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 8.51 kB \u001b[90m│\u001b[39m 9.05 kB \u001b[90m│\u001b[39m 11.5 kB \u001b[90m│\u001b[39m 12.8 kB \u001b[90m│\u001b[39m 11.2 kB \u001b[90m│\u001b[39m 972 B \u001b[90m│\u001b[39m 8.51 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 4996  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n5k requests in 60.08s, 674 kB read\n12 errors (12 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/alien.png\n9 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg        \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 857 ms \u001b[90m│\u001b[39m 1631 ms \u001b[90m│\u001b[39m 3541 ms \u001b[90m│\u001b[39m 3814 ms \u001b[90m│\u001b[39m 1883.14 ms \u001b[90m│\u001b[39m 730.83 ms \u001b[90m│\u001b[39m 6021 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 3       \u001b[90m│\u001b[39m 3       \u001b[90m│\u001b[39m 4      \u001b[90m│\u001b[39m 4      \u001b[90m│\u001b[39m 3.67   \u001b[90m│\u001b[39m 0.48    \u001b[90m│\u001b[39m 3       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 86.4 kB \u001b[90m│\u001b[39m 86.4 kB \u001b[90m│\u001b[39m 115 kB \u001b[90m│\u001b[39m 115 kB \u001b[90m│\u001b[39m 106 kB \u001b[90m│\u001b[39m 13.5 kB \u001b[90m│\u001b[39m 86.3 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 220   \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n241 requests in 60.08s, 6.33 MB read\n12 errors (12 timeouts)\n\n\n----------------\n\n\n\nCLIENTS: *** 10 ***\n\nRunning 60s test @ http://192.168.2.131/\n10 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg       \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 59 ms \u001b[90m│\u001b[39m 95 ms \u001b[90m│\u001b[39m 235 ms \u001b[90m│\u001b[39m 276 ms \u001b[90m│\u001b[39m 111.77 ms \u001b[90m│\u001b[39m 57.35 ms \u001b[90m│\u001b[39m 1010 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 17      \u001b[90m│\u001b[39m 47     \u001b[90m│\u001b[39m 64     \u001b[90m│\u001b[39m 70     \u001b[90m│\u001b[39m 62.32  \u001b[90m│\u001b[39m 8.14    \u001b[90m│\u001b[39m 17      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 73.8 kB \u001b[90m│\u001b[39m 204 kB \u001b[90m│\u001b[39m 278 kB \u001b[90m│\u001b[39m 304 kB \u001b[90m│\u001b[39m 270 kB \u001b[90m│\u001b[39m 35.3 kB \u001b[90m│\u001b[39m 73.7 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 3739  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n4k requests in 60.08s, 16.2 MB read\n18 errors (18 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/api?foo=bar\n10 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 49 ms \u001b[90m│\u001b[39m 82 ms \u001b[90m│\u001b[39m 179 ms \u001b[90m│\u001b[39m 209 ms \u001b[90m│\u001b[39m 91.77 ms \u001b[90m│\u001b[39m 33.92 ms \u001b[90m│\u001b[39m 312 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 46      \u001b[90m│\u001b[39m 48      \u001b[90m│\u001b[39m 76      \u001b[90m│\u001b[39m 92      \u001b[90m│\u001b[39m 75.85   \u001b[90m│\u001b[39m 11.6    \u001b[90m│\u001b[39m 46      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 6.21 kB \u001b[90m│\u001b[39m 6.48 kB \u001b[90m│\u001b[39m 10.3 kB \u001b[90m│\u001b[39m 12.4 kB \u001b[90m│\u001b[39m 10.2 kB \u001b[90m│\u001b[39m 1.57 kB \u001b[90m│\u001b[39m 6.21 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 4551  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n5k requests in 60.07s, 614 kB read\n18 errors (18 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/alien.png\n10 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg        \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 1062 ms \u001b[90m│\u001b[39m 1673 ms \u001b[90m│\u001b[39m 3588 ms \u001b[90m│\u001b[39m 3643 ms \u001b[90m│\u001b[39m 1903.02 ms \u001b[90m│\u001b[39m 693.11 ms \u001b[90m│\u001b[39m 5495 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 2       \u001b[90m│\u001b[39m 2       \u001b[90m│\u001b[39m 4      \u001b[90m│\u001b[39m 5      \u001b[90m│\u001b[39m 3.6    \u001b[90m│\u001b[39m 0.64    \u001b[90m│\u001b[39m 2       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 57.6 kB \u001b[90m│\u001b[39m 57.6 kB \u001b[90m│\u001b[39m 115 kB \u001b[90m│\u001b[39m 144 kB \u001b[90m│\u001b[39m 104 kB \u001b[90m│\u001b[39m 18.3 kB \u001b[90m│\u001b[39m 57.6 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 216   \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n244 requests in 60.08s, 6.22 MB read\n18 errors (18 timeouts)\n\n\n----------------\n\n\n\nCLIENTS: *** 15 ***\n\nRunning 60s test @ http://192.168.2.131/\n15 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg       \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 62 ms \u001b[90m│\u001b[39m 103 ms \u001b[90m│\u001b[39m 252 ms \u001b[90m│\u001b[39m 297 ms \u001b[90m│\u001b[39m 119.53 ms \u001b[90m│\u001b[39m 58.1 ms \u001b[90m│\u001b[39m 1050 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 22      \u001b[90m│\u001b[39m 41     \u001b[90m│\u001b[39m 60     \u001b[90m│\u001b[39m 70     \u001b[90m│\u001b[39m 58.27  \u001b[90m│\u001b[39m 8.6     \u001b[90m│\u001b[39m 22      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 95.5 kB \u001b[90m│\u001b[39m 178 kB \u001b[90m│\u001b[39m 260 kB \u001b[90m│\u001b[39m 304 kB \u001b[90m│\u001b[39m 253 kB \u001b[90m│\u001b[39m 37.3 kB \u001b[90m│\u001b[39m 95.4 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 3496  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n4k requests in 60.06s, 15.2 MB read\n48 errors (48 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/api?foo=bar\n15 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 49 ms \u001b[90m│\u001b[39m 75 ms \u001b[90m│\u001b[39m 151 ms \u001b[90m│\u001b[39m 164 ms \u001b[90m│\u001b[39m 82.32 ms \u001b[90m│\u001b[39m 25.95 ms \u001b[90m│\u001b[39m 313 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 61      \u001b[90m│\u001b[39m 66      \u001b[90m│\u001b[39m 85      \u001b[90m│\u001b[39m 99      \u001b[90m│\u001b[39m 84.52   \u001b[90m│\u001b[39m 8.42    \u001b[90m│\u001b[39m 61      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 8.24 kB \u001b[90m│\u001b[39m 8.91 kB \u001b[90m│\u001b[39m 11.5 kB \u001b[90m│\u001b[39m 13.4 kB \u001b[90m│\u001b[39m 11.4 kB \u001b[90m│\u001b[39m 1.14 kB \u001b[90m│\u001b[39m 8.23 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 5071  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n5k requests in 60.07s, 685 kB read\n48 errors (48 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/alien.png\n15 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg        \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 801 ms \u001b[90m│\u001b[39m 1709 ms \u001b[90m│\u001b[39m 3676 ms \u001b[90m│\u001b[39m 3762 ms \u001b[90m│\u001b[39m 1929.08 ms \u001b[90m│\u001b[39m 744.64 ms \u001b[90m│\u001b[39m 5846 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 2       \u001b[90m│\u001b[39m 3       \u001b[90m│\u001b[39m 4      \u001b[90m│\u001b[39m 5      \u001b[90m│\u001b[39m 3.57   \u001b[90m│\u001b[39m 0.59    \u001b[90m│\u001b[39m 2       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 57.6 kB \u001b[90m│\u001b[39m 86.4 kB \u001b[90m│\u001b[39m 115 kB \u001b[90m│\u001b[39m 144 kB \u001b[90m│\u001b[39m 103 kB \u001b[90m│\u001b[39m 16.9 kB \u001b[90m│\u001b[39m 57.6 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 214   \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n277 requests in 60.09s, 6.16 MB read\n48 errors (48 timeouts)\n\n\n----------------\n\n\n\nCLIENTS: *** 20 ***\n\nRunning 60s test @ http://192.168.2.131/\n20 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg       \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 60 ms \u001b[90m│\u001b[39m 97 ms \u001b[90m│\u001b[39m 232 ms \u001b[90m│\u001b[39m 267 ms \u001b[90m│\u001b[39m 112.02 ms \u001b[90m│\u001b[39m 53.32 ms \u001b[90m│\u001b[39m 1054 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 21      \u001b[90m│\u001b[39m 52     \u001b[90m│\u001b[39m 63     \u001b[90m│\u001b[39m 69     \u001b[90m│\u001b[39m 62.12  \u001b[90m│\u001b[39m 6.59    \u001b[90m│\u001b[39m 21      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 91.1 kB \u001b[90m│\u001b[39m 226 kB \u001b[90m│\u001b[39m 273 kB \u001b[90m│\u001b[39m 300 kB \u001b[90m│\u001b[39m 269 kB \u001b[90m│\u001b[39m 28.6 kB \u001b[90m│\u001b[39m 91.1 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 3727  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n4k requests in 60.1s, 16.2 MB read\n78 errors (78 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/api?foo=bar\n20 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬───────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬──────────\u001b[39m\u001b[90m┬────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max    \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼───────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼──────────\u001b[39m\u001b[90m┼────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 49 ms \u001b[90m│\u001b[39m 78 ms \u001b[90m│\u001b[39m 164 ms \u001b[90m│\u001b[39m 178 ms \u001b[90m│\u001b[39m 87.8 ms \u001b[90m│\u001b[39m 35.83 ms \u001b[90m│\u001b[39m 658 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴───────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴──────────\u001b[39m\u001b[90m┴────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 35      \u001b[90m│\u001b[39m 55      \u001b[90m│\u001b[39m 81      \u001b[90m│\u001b[39m 95      \u001b[90m│\u001b[39m 79.27   \u001b[90m│\u001b[39m 10.5    \u001b[90m│\u001b[39m 35      \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 4.73 kB \u001b[90m│\u001b[39m 7.43 kB \u001b[90m│\u001b[39m 10.9 kB \u001b[90m│\u001b[39m 12.8 kB \u001b[90m│\u001b[39m 10.7 kB \u001b[90m│\u001b[39m 1.42 kB \u001b[90m│\u001b[39m 4.72 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 4756  \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n5k requests in 60.07s, 642 kB read\n78 errors (78 timeouts)\n\n\n----------------\n\nRunning 60s test @ http://192.168.2.131/alien.png\n20 connections\n1 workers\n\n\n\u001b[90m┌─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────────\u001b[39m\u001b[90m┬───────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 99%     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg        \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev     \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Max     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────────\u001b[39m\u001b[90m┼───────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Latency \u001b[90m│\u001b[39m 806 ms \u001b[90m│\u001b[39m 1613 ms \u001b[90m│\u001b[39m 3348 ms \u001b[90m│\u001b[39m 4009 ms \u001b[90m│\u001b[39m 1854.07 ms \u001b[90m│\u001b[39m 733.32 ms \u001b[90m│\u001b[39m 6606 ms \u001b[90m│\u001b[39m\n\u001b[90m└─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────────\u001b[39m\u001b[90m┴───────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌───────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬────────\u001b[39m\u001b[90m┬─────────\u001b[39m\u001b[90m┬─────────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Stat      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 1%      \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 2.5%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 50%    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m 97.5%  \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Avg    \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Stdev   \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Min     \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Req/Sec   \u001b[90m│\u001b[39m 2       \u001b[90m│\u001b[39m 3       \u001b[90m│\u001b[39m 4      \u001b[90m│\u001b[39m 5      \u001b[90m│\u001b[39m 3.7    \u001b[90m│\u001b[39m 0.62    \u001b[90m│\u001b[39m 2       \u001b[90m│\u001b[39m\n\u001b[90m├───────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼────────\u001b[39m\u001b[90m┼─────────\u001b[39m\u001b[90m┼─────────┤\u001b[39m\n\u001b[90m│\u001b[39m Bytes/Sec \u001b[90m│\u001b[39m 57.6 kB \u001b[90m│\u001b[39m 86.4 kB \u001b[90m│\u001b[39m 115 kB \u001b[90m│\u001b[39m 144 kB \u001b[90m│\u001b[39m 106 kB \u001b[90m│\u001b[39m 17.7 kB \u001b[90m│\u001b[39m 57.6 kB \u001b[90m│\u001b[39m\n\u001b[90m└───────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴────────\u001b[39m\u001b[90m┴─────────\u001b[39m\u001b[90m┴─────────┘\u001b[39m\n\u001b[90m┌──────\u001b[39m\u001b[90m┬───────┐\u001b[39m\n\u001b[90m│\u001b[39m\u001b[31m Code \u001b[39m\u001b[90m│\u001b[39m\u001b[31m Count \u001b[39m\u001b[90m│\u001b[39m\n\u001b[90m├──────\u001b[39m\u001b[90m┼───────┤\u001b[39m\n\u001b[90m│\u001b[39m 200  \u001b[90m│\u001b[39m 222   \u001b[90m│\u001b[39m\n\u001b[90m└──────\u001b[39m\u001b[90m┴───────┘\u001b[39m\n\nReq/Bytes counts sampled once per second.\n# of samples: 60\n\n320 requests in 60.05s, 6.39 MB read\n78 errors (78 timeouts)\n\n\n----------------\n\n"
  },
  {
    "path": "benchmark/results/psychic-v1.1-websocket-loadtest.log",
    "content": "\n\nCLIENTS: *** 1 ***\n\n\nTarget URL:          ws://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  1\nAgent:               none\n\nCompleted requests:  1972\nTotal errors:        0\nTotal time:          60.003 s\nMean latency:        29.8 ms\nEffective rps:       33\n\nPercentage of requests served within a certain time\n  50%      25 ms\n  90%      40 ms\n  95%      66 ms\n  99%      96 ms\n 100%      147 ms (longest request)\n\n\nCLIENTS: *** 2 ***\n\n\nTarget URL:          ws://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  2\nAgent:               none\n\nCompleted requests:  3144\nTotal errors:        0\nTotal time:          60.003 s\nMean latency:        37.6 ms\nEffective rps:       52\n\nPercentage of requests served within a certain time\n  50%      32 ms\n  90%      58 ms\n  95%      82 ms\n  99%      114 ms\n 100%      160 ms (longest request)\n\n\nCLIENTS: *** 3 ***\n\n\nTarget URL:          ws://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  3\nAgent:               none\n\nCompleted requests:  4113\nTotal errors:        0\nTotal time:          60.005 s\nMean latency:        43.2 ms\nEffective rps:       69\n\nPercentage of requests served within a certain time\n  50%      38 ms\n  90%      63 ms\n  95%      88 ms\n  99%      119 ms\n 100%      339 ms (longest request)\n\n\nCLIENTS: *** 4 ***\n\n\nTarget URL:          ws://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  4\nAgent:               none\n\nCompleted requests:  4902\nTotal errors:        0\nTotal time:          60.004 s\nMean latency:        48.3 ms\nEffective rps:       82\n\nPercentage of requests served within a certain time\n  50%      42 ms\n  90%      74 ms\n  95%      97 ms\n  99%      125 ms\n 100%      217 ms (longest request)\n\n\nCLIENTS: *** 5 ***\n\n\nTarget URL:          ws://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  5\nAgent:               none\n\nCompleted requests:  5522\nTotal errors:        0\nTotal time:          60.003 s\nMean latency:        53.7 ms\nEffective rps:       92\n\nPercentage of requests served within a certain time\n  50%      48 ms\n  90%      81 ms\n  95%      102 ms\n  99%      122 ms\n 100%      324 ms (longest request)\n\n\nCLIENTS: *** 6 ***\n\n\nTarget URL:          ws://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  6\nAgent:               none\n\nCompleted requests:  5808\nTotal errors:        0\nTotal time:          60.004 s\nMean latency:        61.4 ms\nEffective rps:       97\n\nPercentage of requests served within a certain time\n  50%      54 ms\n  90%      94 ms\n  95%      117 ms\n  99%      142 ms\n 100%      348 ms (longest request)\n\n\nCLIENTS: *** 7 ***\n\n\nTarget URL:          ws://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  7\nAgent:               none\n\nCompleted requests:  6478\nTotal errors:        0\nTotal time:          60.006 s\nMean latency:        64.1 ms\nEffective rps:       108\n\nPercentage of requests served within a certain time\n  50%      59 ms\n  90%      94 ms\n  95%      110 ms\n  99%      137 ms\n 100%      195 ms (longest request)\n\n\nCLIENTS: *** 8 ***\n\n\nTarget URL:          ws://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  8\nRunning on cores:    2\nAgent:               none\n\nCompleted requests:  6124\nTotal errors:        0\nTotal time:          60.004 s\nMean latency:        67.8 ms\nEffective rps:       102\n\nPercentage of requests served within a certain time\n  50%      59 ms\n  90%      107 ms\n  95%      131 ms\n  99%      173 ms\n 100%      260 ms (longest request)\n\n\nCLIENTS: *** 10 ***\n\n\nTarget URL:          ws://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  10\nRunning on cores:    2\nAgent:               none\n\nCompleted requests:  5640\nTotal errors:        0\nTotal time:          60.004 s\nMean latency:        73.7 ms\nEffective rps:       94\n\nPercentage of requests served within a certain time\n  50%      61 ms\n  90%      120 ms\n  95%      140 ms\n  99%      240 ms\n 100%      780 ms (longest request)\n\n\nCLIENTS: *** 16 ***\n\n\nTarget URL:          ws://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  16\nRunning on cores:    2\nAgent:               none\n\nCompleted requests:  5809\nTotal errors:        0\nTotal time:          60.006 s\nMean latency:        71.6 ms\nEffective rps:       97\n\nPercentage of requests served within a certain time\n  50%      64 ms\n  90%      111 ms\n  95%      130 ms\n  99%      162 ms\n 100%      226 ms (longest request)\n\n\nCLIENTS: *** 20 ***\n\n\nTarget URL:          ws://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  20\nRunning on cores:    2\nAgent:               none\n\nCompleted requests:  5590\nTotal errors:        0\nTotal time:          60.003 s\nMean latency:        74.4 ms\nEffective rps:       93\n\nPercentage of requests served within a certain time\n  50%      61 ms\n  90%      122 ms\n  95%      151 ms\n  99%      247 ms\n 100%      513 ms (longest request)\n"
  },
  {
    "path": "benchmark/results/psychic-websocket-loadtest.log",
    "content": "\n\nCLIENTS: *** 1 ***\n\n\nTarget URL:          ws://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  1\nAgent:               none\n\nCompleted requests:  2304\nTotal errors:        0\nTotal time:          60.002 s\nMean latency:        25.5 ms\nEffective rps:       38\n\nPercentage of requests served within a certain time\n  50%      22 ms\n  90%      32 ms\n  95%      58 ms\n  99%      92 ms\n 100%      105 ms (longest request)\n\n\nCLIENTS: *** 2 ***\n\n\nTarget URL:          ws://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  2\nAgent:               none\n\nCompleted requests:  3647\nTotal errors:        0\nTotal time:          60.002 s\nMean latency:        32.3 ms\nEffective rps:       61\n\nPercentage of requests served within a certain time\n  50%      28 ms\n  90%      43 ms\n  95%      67 ms\n  99%      93 ms\n 100%      135 ms (longest request)\n\n\nCLIENTS: *** 3 ***\n\n\nTarget URL:          ws://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  3\nAgent:               none\n\nCompleted requests:  4629\nTotal errors:        0\nTotal time:          60.004 s\nMean latency:        38.3 ms\nEffective rps:       77\n\nPercentage of requests served within a certain time\n  50%      34 ms\n  90%      51 ms\n  95%      79 ms\n  99%      110 ms\n 100%      152 ms (longest request)\n\n\nCLIENTS: *** 4 ***\n\n\nTarget URL:          ws://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  4\nAgent:               none\n\nCompleted requests:  5290\nTotal errors:        0\nTotal time:          60.003 s\nMean latency:        44.7 ms\nEffective rps:       88\n\nPercentage of requests served within a certain time\n  50%      40 ms\n  90%      67 ms\n  95%      92 ms\n  99%      115 ms\n 100%      159 ms (longest request)\n\n\nCLIENTS: *** 5 ***\n\n\nTarget URL:          ws://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  5\nAgent:               none\n\nCompleted requests:  5935\nTotal errors:        0\nTotal time:          60.002 s\nMean latency:        50 ms\nEffective rps:       99\n\nPercentage of requests served within a certain time\n  50%      45 ms\n  90%      74 ms\n  95%      97 ms\n  99%      123 ms\n 100%      172 ms (longest request)\n\n\nCLIENTS: *** 6 ***\n\n\nTarget URL:          ws://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  6\nAgent:               none\n\nCompleted requests:  6533\nTotal errors:        0\nTotal time:          60.003 s\nMean latency:        54.5 ms\nEffective rps:       109\n\nPercentage of requests served within a certain time\n  50%      49 ms\n  90%      78 ms\n  95%      101 ms\n  99%      129 ms\n 100%      170 ms (longest request)\n\n\nCLIENTS: *** 7 ***\n\n\nTarget URL:          ws://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  7\nAgent:               none\n\nCompleted requests:  7086\nTotal errors:        0\nTotal time:          60.004 s\nMean latency:        58.6 ms\nEffective rps:       118\n\nPercentage of requests served within a certain time\n  50%      54 ms\n  90%      85 ms\n  95%      107 ms\n  99%      130 ms\n 100%      184 ms (longest request)\n\n\nCLIENTS: *** 8 ***\n\n\nTarget URL:          ws://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  8\nRunning on cores:    2\nAgent:               none\n\nCompleted requests:  6994\nTotal errors:        0\nTotal time:          60.004 s\nMean latency:        59.3 ms\nEffective rps:       117\n\nPercentage of requests served within a certain time\n  50%      54 ms\n  90%      88 ms\n  95%      109 ms\n  99%      134 ms\n 100%      176 ms (longest request)\n\n\nCLIENTS: *** 10 ***\n\n\nTarget URL:          ws://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  10\nRunning on cores:    2\nAgent:               none\n\nCompleted requests:  7197\nTotal errors:        0\nTotal time:          60.004 s\nMean latency:        57.7 ms\nEffective rps:       120\n\nPercentage of requests served within a certain time\n  50%      53 ms\n  90%      83 ms\n  95%      98 ms\n  99%      123 ms\n 100%      176 ms (longest request)\n\n\nCLIENTS: *** 16 ***\n\n\nTarget URL:          ws://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  16\nRunning on cores:    2\nAgent:               none\n\nCompleted requests:  7173\nTotal errors:        0\nTotal time:          60.002 s\nMean latency:        57.9 ms\nEffective rps:       120\n\nPercentage of requests served within a certain time\n  50%      53 ms\n  90%      83 ms\n  95%      100 ms\n  99%      123 ms\n 100%      156 ms (longest request)\n\n\nCLIENTS: *** 20 ***\n\n\nTarget URL:          ws://192.168.2.131/ws\nMax time (s):        60\nConcurrent clients:  20\nRunning on cores:    2\nAgent:               none\n\nCompleted requests:  6883\nTotal errors:        0\nTotal time:          60.002 s\nMean latency:        60.4 ms\nEffective rps:       115\n\nPercentage of requests served within a certain time\n  50%      55 ms\n  90%      92 ms\n  95%      111 ms\n  99%      138 ms\n 100%      175 ms (longest request)\n"
  },
  {
    "path": "benchmark/websocket-client-test.js",
    "content": "#!/usr/bin/env node\n//stress test the client open/close for websockets\n\nconst WebSocket = require('ws');\n\nconst uri = 'ws://psychic.local/ws';\n\nasync function websocketClient() {\n  console.log(`Starting test`);\n  for (let i = 0; i < 1000000; i++) {\n    const ws = new WebSocket(uri);\n\n    if (i % 100 == 0)\n      console.log(`Count: ${i}`);\n\n    ws.on('open', () => {\n      //console.log(`Connected`);\n    });\n\n    ws.on('message', (message) => {\n      //console.log(`Message: ${message}`);\n      ws.close();\n    });\n\n    ws.on('error', (error) => {\n      console.error(`Error: ${error.message}`);\n    });\n\n    await new Promise((resolve) => {\n      ws.on('close', () => {\n        resolve();\n      });\n    });\n  }\n}\n\nwebsocketClient();"
  },
  {
    "path": "component.mk",
    "content": "COMPONENT_ADD_INCLUDEDIRS := src\nCOMPONENT_SRCDIRS := src\nCXXFLAGS += -fno-rtti\n"
  },
  {
    "path": "examples/esp-idf/.gitignore",
    "content": "build/\nsdkconfig\nsdkconfig.old\ncomponents/\nmanaged_components/\ndependencies.lock\nmain/_secret.h\n"
  },
  {
    "path": "examples/esp-idf/CMakeLists.txt",
    "content": "# The following lines of boilerplate have to be in your project's\n# CMakeLists in this exact order for cmake to work correctly\ncmake_minimum_required(VERSION 3.5)\ninclude($ENV{IDF_PATH}/tools/cmake/project.cmake)\n\nif(DEFINED ENV{HTTP_PATH})\n  set(HTTP_PATH $ENV{HTTP_PATH})\nelse()\n  #these both work\n  set(HTTP_PATH \"../../\")\n  #set(HTTP_PATH ${CMAKE_CURRENT_LIST_DIR}/../../../)\n\n  #this does not work for me...\n  #set(HTTP_PATH ${CMAKE_CURRENT_LIST_DIR}/../../../PsychicHttp)\nendif(DEFINED ENV{HTTP_PATH})\n\nset(EXTRA_COMPONENT_DIRS ${HTTP_PATH})\nif(${IDF_VERSION_MAJOR} LESS \"5\")\n  include_directories(\"managed_components/joltwallet__littlefs/include\")\nendif()\n\nproject(PsychicHttp_IDF)\n"
  },
  {
    "path": "examples/esp-idf/README.md",
    "content": "# PsychicHttp - ESP IDF Example\n*  Download and install [ESP IDF 4.4.7](https://github.com/espressif/esp-idf/releases/tag/v4.4.7) (or later version)\n*  Clone the project: ```git clone --recursive git@github.com:hoeken/PsychicHttp.git```\n*  Run build command: ```cd PsychicHttp/examples/esp-idf``` and then ```idf.py build```\n*  Flash the LittleFS filesystem: ```esptool.py write_flash --flash_mode dio --flash_freq 40m --flash_size 4MB 0x317000 build/littlefs.bin```\n*  Flash the app firmware: ```idf.py flash monitor``` and visit the IP address shown in the console with a web browser.\n*  Learn more about [Arduino as ESP-IDF Component](https://docs.espressif.com/projects/arduino-esp32/en/latest/esp-idf_component.html)\n"
  },
  {
    "path": "examples/esp-idf/data/custom.txt",
    "content": "Custom text file."
  },
  {
    "path": "examples/esp-idf/data/server.crt",
    "content": "-----BEGIN CERTIFICATE-----\nMIIDKzCCAhOgAwIBAgIUBxM3WJf2bP12kAfqhmhhjZWv0ukwDQYJKoZIhvcNAQEL\nBQAwJTEjMCEGA1UEAwwaRVNQMzIgSFRUUFMgc2VydmVyIGV4YW1wbGUwHhcNMTgx\nMDE3MTEzMjU3WhcNMjgxMDE0MTEzMjU3WjAlMSMwIQYDVQQDDBpFU1AzMiBIVFRQ\nUyBzZXJ2ZXIgZXhhbXBsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB\nALBint6nP77RCQcmKgwPtTsGK0uClxg+LwKJ3WXuye3oqnnjqJCwMEneXzGdG09T\nsA0SyNPwrEgebLCH80an3gWU4pHDdqGHfJQa2jBL290e/5L5MB+6PTs2NKcojK/k\nqcZkn58MWXhDW1NpAnJtjVniK2Ksvr/YIYSbyD+JiEs0MGxEx+kOl9d7hRHJaIzd\nGF/vO2pl295v1qXekAlkgNMtYIVAjUy9CMpqaQBCQRL+BmPSJRkXBsYk8GPnieS4\nsUsp53DsNvCCtWDT6fd9D1v+BB6nDk/FCPKhtjYOwOAZlX4wWNSZpRNr5dfrxKsb\njAn4PCuR2akdF4G8WLUeDWECAwEAAaNTMFEwHQYDVR0OBBYEFMnmdJKOEepXrHI/\nivM6mVqJgAX8MB8GA1UdIwQYMBaAFMnmdJKOEepXrHI/ivM6mVqJgAX8MA8GA1Ud\nEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBADiXIGEkSsN0SLSfCF1VNWO3\nemBurfOcDq4EGEaxRKAU0814VEmU87btIDx80+z5Dbf+GGHCPrY7odIkxGNn0DJY\nW1WcF+DOcbiWoUN6DTkAML0SMnp8aGj9ffx3x+qoggT+vGdWVVA4pgwqZT7Ybntx\nbkzcNFW0sqmCv4IN1t4w6L0A87ZwsNwVpre/j6uyBw7s8YoJHDLRFT6g7qgn0tcN\nZufhNISvgWCVJQy/SZjNBHSpnIdCUSJAeTY2mkM4sGxY0Widk8LnjydxZUSxC3Nl\nhb6pnMh3jRq4h0+5CZielA4/a+TdrNPv/qok67ot/XJdY3qHCCd8O2b14OVq9jo=\n-----END CERTIFICATE-----"
  },
  {
    "path": "examples/esp-idf/data/server.key",
    "content": "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCwYp7epz++0QkH\nJioMD7U7BitLgpcYPi8Cid1l7snt6Kp546iQsDBJ3l8xnRtPU7ANEsjT8KxIHmyw\nh/NGp94FlOKRw3ahh3yUGtowS9vdHv+S+TAfuj07NjSnKIyv5KnGZJ+fDFl4Q1tT\naQJybY1Z4itirL6/2CGEm8g/iYhLNDBsRMfpDpfXe4URyWiM3Rhf7ztqZdveb9al\n3pAJZIDTLWCFQI1MvQjKamkAQkES/gZj0iUZFwbGJPBj54nkuLFLKedw7DbwgrVg\n0+n3fQ9b/gQepw5PxQjyobY2DsDgGZV+MFjUmaUTa+XX68SrG4wJ+DwrkdmpHReB\nvFi1Hg1hAgMBAAECggEAaTCnZkl/7qBjLexIryC/CBBJyaJ70W1kQ7NMYfniWwui\nf0aRxJgOdD81rjTvkINsPp+xPRQO6oOadjzdjImYEuQTqrJTEUnntbu924eh+2D9\nMf2CAanj0mglRnscS9mmljZ0KzoGMX6Z/EhnuS40WiJTlWlH6MlQU/FDnwC6U34y\nJKy6/jGryfsx+kGU/NRvKSru6JYJWt5v7sOrymHWD62IT59h3blOiP8GMtYKeQlX\n49om9Mo1VTIFASY3lrxmexbY+6FG8YO+tfIe0tTAiGrkb9Pz6tYbaj9FjEWOv4Vc\n+3VMBUVdGJjgqvE8fx+/+mHo4Rg69BUPfPSrpEg7sQKBgQDlL85G04VZgrNZgOx6\npTlCCl/NkfNb1OYa0BELqWINoWaWQHnm6lX8YjrUjwRpBF5s7mFhguFjUjp/NW6D\n0EEg5BmO0ePJ3dLKSeOA7gMo7y7kAcD/YGToqAaGljkBI+IAWK5Su5yldrECTQKG\nYnMKyQ1MWUfCYEwHtPvFvE5aPwKBgQDFBWXekpxHIvt/B41Cl/TftAzE7/f58JjV\nMFo/JCh9TDcH6N5TMTRS1/iQrv5M6kJSSrHnq8pqDXOwfHLwxetpk9tr937VRzoL\nCuG1Ar7c1AO6ujNnAEmUVC2DppL/ck5mRPWK/kgLwZSaNcZf8sydRgphsW1ogJin\n7g0nGbFwXwKBgQCPoZY07Pr1TeP4g8OwWTu5F6dSvdU2CAbtZthH5q98u1n/cAj1\nnoak1Srpa3foGMTUn9CHu+5kwHPIpUPNeAZZBpq91uxa5pnkDMp3UrLIRJ2uZyr8\n4PxcknEEh8DR5hsM/IbDcrCJQglM19ZtQeW3LKkY4BsIxjDf45ymH407IQKBgE/g\nUl6cPfOxQRlNLH4VMVgInSyyxWx1mODFy7DRrgCuh5kTVh+QUVBM8x9lcwAn8V9/\nnQT55wR8E603pznqY/jX0xvAqZE6YVPcw4kpZcwNwL1RhEl8GliikBlRzUL3SsW3\nq30AfqEViHPE3XpE66PPo6Hb1ymJCVr77iUuC3wtAoGBAIBrOGunv1qZMfqmwAY2\nlxlzRgxgSiaev0lTNxDzZkmU/u3dgdTwJ5DDANqPwJc6b8SGYTp9rQ0mbgVHnhIB\njcJQBQkTfq6Z0H6OoTVi7dPs3ibQJFrtkoyvYAbyk36quBmNRjVh6rc8468bhXYr\nv/t+MeGJP/0Zw8v/X2CFll96\n-----END PRIVATE KEY-----"
  },
  {
    "path": "examples/esp-idf/data/www/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n    <head>\n        <meta charset=\"UTF-8\">\n        <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n        <title>PsychicHTTP Demo</title>\n        <link rel=\"icon\" href=\"./favicon.ico\" type=\"image/x-icon\">\n    </head>\n    <body>\n        <main>\n            <h1>Basic Request Examples</h1>\n            <ul>\n                <li><a href=\"/api?foo=bar\">API Call</a></li>\n                <li><a href=\"/redirect\">Redirection</a></li>\n                <li><a href=\"/auth-digest\">Authentication (Digest)</a></li>\n                <li><a href=\"/auth-basic\">Authentication (Basic)</a></li>\n                <li><a href=\"/cookies\">Cookies Demo</a></li>\n                <li><a href=\"/404\">404</a></li>\n            </ul>\n\n            <h1>Static Serving</h1>\n            <p>\n                <a href=\"/alien.png\"><img width=\"60\" src=\"/alien.png\"></a>\n                <a href=\"/img/request_flow.png\"><img width=\"60\" src=\"/img/request_flow.png\"></a>\n            </p>\n            <p><a href=\"/myfile.txt\">Text File</a></p>\n\n            <h1>Simple POST Form</h1>\n            <form action=\"/post\" method=\"post\">\n                <label for=\"param1\">Parameter 1:</label>\n                <input type=\"text\" id=\"param1\" name=\"param1\" value=\"Parameter 1\">            \n                <br>\n                <label for=\"param2\">Parameter 2:</label>\n                <input type=\"text\" id=\"param2\" name=\"param2\" value=\"Parameter 2\">            \n                <br>\n                <input type=\"submit\" value=\"Submit\">\n            </form>            \n\n            <h1>Basic File Upload</h1>\n            <table border=\"0\">\n                <tr>\n                    <td>\n                        <label for=\"newfile\">Upload a file</label>\n                    </td>\n                    <td colspan=\"2\">\n                        <input id=\"newfile\" type=\"file\" onchange=\"setpath()\" style=\"width:100%;\">\n                    </td>\n                </tr>\n                <tr>\n                    <td>\n                        <label for=\"filepath\">Set path on server</label>\n                    </td>\n                    <td>\n                        <input id=\"filepath\" type=\"text\" style=\"width:100%;\">\n                    </td>\n                </tr>\n                <tr>\n                    <td>\n                        <button id=\"upload\" type=\"button\" onclick=\"upload()\">Upload</button>\n                    </td>\n                </tr>\n            </table>\n            <script>\n            function setpath() {\n                var default_path = document.getElementById(\"newfile\").files[0].name;\n                document.getElementById(\"filepath\").value = default_path;\n            }\n            function upload() {\n                var filePath = document.getElementById(\"filepath\").value;\n                var upload_path = \"/upload/\" + filePath;\n                var fileInput = document.getElementById(\"newfile\").files;\n\n                /* Max size of an individual file. Make sure this\n                * value is same as that set in file_server.c */\n                var MAX_FILE_SIZE = 2048*1024;\n                var MAX_FILE_SIZE_STR = \"2MB\";\n\n                if (fileInput.length == 0) {\n                    alert(\"No file selected!\");\n                } else if (filePath.length == 0) {\n                    alert(\"File path on server is not set!\");\n                } else if (filePath.indexOf(' ') >= 0) {\n                    alert(\"File path on server cannot have spaces!\");\n                } else if (filePath[filePath.length-1] == '/') {\n                    alert(\"File name not specified after path!\");\n                } else if (fileInput[0].size > 200*1024) {\n                    alert(\"File size must be less than 200KB!\");\n                } else {\n                    document.getElementById(\"newfile\").disabled = true;\n                    document.getElementById(\"filepath\").disabled = true;\n                    document.getElementById(\"upload\").disabled = true;\n\n                    var file = fileInput[0];\n                    var xhttp = new XMLHttpRequest();\n                    xhttp.onreadystatechange = function() {\n                        if (xhttp.readyState == 4) {\n                            if (xhttp.status == 200) {\n                                document.open();\n                                document.write(xhttp.responseText);\n                                document.close();\n                            } else if (xhttp.status == 0) {\n                                alert(\"Server closed the connection abruptly!\");\n                                location.reload()\n                            } else {\n                                alert(xhttp.status + \" Error!\\n\" + xhttp.responseText);\n                                location.reload()\n                            }\n                        }\n                    };\n                    xhttp.open(\"POST\", upload_path, true);\n                    xhttp.send(file);\n                }\n            }\n            </script>\n\n            <h1>Multipart POST Form</h1>\n            <form action=\"/multipart\" method=\"post\" enctype=\"multipart/form-data\">\n                <label for=\"param1\">Parameter 1:</label>\n                <input type=\"text\" id=\"param1\" name=\"param1\" value=\"Parameter 1\">            \n                <br>\n\n                <label for=\"param2\">Parameter 2:</label>\n                <input type=\"text\" id=\"param2\" name=\"param2\" value=\"Parameter 2\">            \n                <br>\n\n                <label for=\"file-upload\">File Upload:</label>\n                <input type=\"file\" id=\"file-upload\" name=\"file_upload\" accept=\".txt, .html, .pdf, .png, .jpg, .gif\" required>\n                <br>\n            \n                <input type=\"submit\" value=\"Upload File\">\n            </form>\n\n            <h1>Websocket Demo</h1>\n            <input type=\"text\" id=\"message_input\" placeholder=\"Type your message\">\n            <button onclick=\"sendMessage()\">Send Message</button>\n            <button onclick=\"websocketConnect()\">Connect</button>\n            <div>\n                <textarea id=\"websocket_output\" style=\"width: 50%; height: 250px;\"></textarea>\n            </div>\n\n            <script>\n                let socket;\n                const outputText = document.getElementById('websocket_output');\n                const messageInput = document.getElementById('message_input');\n\n                function websocketConnect()\n                {\n                    // Create a WebSocket connection\n                    socket = new WebSocket('ws://' + window.location.host + '/ws');\n            \n                    // Event handler for when the WebSocket connection is open\n                    socket.addEventListener('open', (event) => {\n                        outputText.value += `[socket] connection opened!\\n`;\n                        outputText.scrollTop = outputText.scrollHeight;\n                    });\n            \n                    // Event handler for when a message is received from the WebSocket server\n                    socket.addEventListener('message', (event) => {\n                        // Echo the received message into the output div\n                        let data = event.data.trim();\n                        outputText.value += `[received] ${data}\\n`;\n                        outputText.scrollTop = outputText.scrollHeight;\n                    });\n            \n                    // Event handler for when an error occurs with the WebSocket connection\n                    socket.addEventListener('error', (event) => {\n                        let data = event.data.trim();\n                        outputText.value += `[error] ${event.data}\\n`;\n                        outputText.scrollTop = outputText.scrollHeight;\n                    });\n            \n                    // Event handler for when the WebSocket connection is closed\n                    socket.addEventListener('close', (event) => {\n                        outputText.value += `[socket] connection opened!\\n`;\n                    });\n                }\n        \n                // Function to send a message to the WebSocket server\n                function sendMessage() {\n                    if (socket.readyState == WebSocket.OPEN) {\n                        const message = messageInput.value.trim();\n                        if (message) {\n                            socket.send(message);\n                            messageInput.value = ''; // Clear the input field after sending the message\n                            outputText.value += `[sent] ${message}\\n`;\n                            outputText.scrollTop = outputText.scrollHeight;\n                        }\n                    }\n                    else\n                    {\n                        outputText.value += `[error] Not Connected\\n`;\n                        outputText.scrollTop = outputText.scrollHeight;\n                    }\n                }\n            </script>\n\n            <h1>EventSource Demo</h1>\n            <button onclick=\"eventSourceConnect()\">Connect</button>\n            <div>\n                <textarea id=\"eventsource_output\" style=\"width: 50%; height: 250px;\"></textarea>\n            </div>\n\n            <script>\n                const dataElement = document.getElementById('eventsource_output');\n\n                function eventSourceConnect()\n                {\n                    const eventSource = new EventSource('/events');\n            \n                    eventSource.onopen = () => {\n                        dataElement.value += `[connected]\\n`;\n                        dataElement.scrollTop = dataElement.scrollHeight;\n                    };\n\n                    eventSource.addEventListener('millis', (event) => {\n                        let data = event.data.trim()\n                        dataElement.value += `[millis] ${data}\\n`;\n                        dataElement.scrollTop = dataElement.scrollHeight;\n                    });\n\n                    eventSource.onmessage = (event) => {\n                        let data = event.data.trim()\n                        dataElement.value += `[message] ${data}\\n`;\n                        dataElement.scrollTop = dataElement.scrollHeight;\n                    };\n                \n                    eventSource.onerror = (error) => {\n                        dataElement.value += `[error] ${error}\\n`;\n                        dataElement.scrollTop = dataElement.scrollHeight;\n                        eventSource.close();\n                    };\n                }\n              </script>\n        </main>\n    </body>\n</html>"
  },
  {
    "path": "examples/esp-idf/data/www/text.txt",
    "content": "Test File.\n"
  },
  {
    "path": "examples/esp-idf/data/www-ap/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n    <head>\n        <meta charset=\"UTF-8\">\n        <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n        <title>PsychicHTTP SoftAP Demo</title>\n        <link rel=\"icon\" href=\"./favicon.ico\" type=\"image/x-icon\">\n    </head>\n    <body>\n        <main>\n            <h1>SoftAP Demo</h1>\n            <p>You are connected to the ESP in SoftAP mode.</p>\n        </main>\n    </body>\n</html>"
  },
  {
    "path": "examples/esp-idf/include/README",
    "content": "\nThis directory is intended for project header files.\n\nA header file is a file containing C declarations and macro definitions\nto be shared between several project source files. You request the use of a\nheader file in your project source file (C, C++, etc) located in `src` folder\nby including it, with the C preprocessing directive `#include'.\n\n```src/main.c\n\n#include \"header.h\"\n\nint main (void)\n{\n ...\n}\n```\n\nIncluding a header file produces the same results as copying the header file\ninto each source file that needs it. Such copying would be time-consuming\nand error-prone. With a header file, the related declarations appear\nin only one place. If they need to be changed, they can be changed in one\nplace, and programs that include the header file will automatically use the\nnew version when next recompiled. The header file eliminates the labor of\nfinding and changing all the copies as well as the risk that a failure to\nfind one copy will result in inconsistencies within a program.\n\nIn C, the usual convention is to give header files names that end with `.h'.\nIt is most portable to use only letters, digits, dashes, and underscores in\nheader file names, and at most one dot.\n\nRead more about using header files in official GCC documentation:\n\n* Include Syntax\n* Include Operation\n* Once-Only Headers\n* Computed Includes\n\nhttps://gcc.gnu.org/onlinedocs/cpp/Header-Files.html\n"
  },
  {
    "path": "examples/esp-idf/lib/README",
    "content": "\nThis directory is intended for project specific (private) libraries.\nPlatformIO will compile them to static libraries and link into executable file.\n\nThe source code of each library should be placed in a an own separate directory\n(\"lib/your_library_name/[here are source files]\").\n\nFor example, see a structure of the following two libraries `Foo` and `Bar`:\n\n|--lib\n|  |\n|  |--Bar\n|  |  |--docs\n|  |  |--examples\n|  |  |--src\n|  |     |- Bar.c\n|  |     |- Bar.h\n|  |  |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html\n|  |\n|  |--Foo\n|  |  |- Foo.c\n|  |  |- Foo.h\n|  |\n|  |- README --> THIS FILE\n|\n|- platformio.ini\n|--src\n   |- main.c\n\nand a contents of `src/main.c`:\n```\n#include <Foo.h>\n#include <Bar.h>\n\nint main (void)\n{\n  ...\n}\n\n```\n\nPlatformIO Library Dependency Finder will find automatically dependent\nlibraries scanning project source files.\n\nMore information about PlatformIO Library Dependency Finder\n- https://docs.platformio.org/page/librarymanager/ldf.html\n"
  },
  {
    "path": "examples/esp-idf/main/CMakeLists.txt",
    "content": "# This file was automatically generated for projects\n# without default 'CMakeLists.txt' file.\n\nidf_component_register(\n    SRCS \"main.cpp\"\n    INCLUDE_DIRS \".\")\n\nlittlefs_create_partition_image(littlefs ${project_dir}/data FLASH_IN_PROJECT)\n"
  },
  {
    "path": "examples/esp-idf/main/idf_component.yml",
    "content": "dependencies:\n  joltwallet/littlefs: ^1.16.4\n"
  },
  {
    "path": "examples/esp-idf/main/main.cpp",
    "content": "/*\n  PsychicHTTP Server Example\n\n  This example code is in the Public Domain (or CC0 licensed, at your option.)\n\n  Unless required by applicable law or agreed to in writing, this\n  software is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n  CONDITIONS OF ANY KIND, either express or implied.\n*/\n\n/**********************************************************************************************\n * Note: this demo relies on various files to be uploaded on the LittleFS partition\n * Follow instructions here: https://randomnerdtutorials.com/esp32-littlefs-arduino-ide/\n **********************************************************************************************/\n\n#include \"_secret.h\"\n#include <Arduino.h>\n#include <ArduinoJson.h>\n#include <ESPmDNS.h>\n#include <LittleFS.h>\n#include <PsychicHttp.h>\n#include <WiFi.h>\n#include <esp_sntp.h>\n\n// set CONFIG_ESP_HTTPS_SERVER_ENABLE=y in menuconfig to enable SSL\n#ifdef CONFIG_ESP_HTTPS_SERVER_ENABLE\n  #include <PsychicHttpsServer.h>\n#endif\n\n#ifndef WIFI_SSID\n  #error \"You need to enter your wifi credentials. Rename secret.h to _secret.h and enter your credentials there.\"\n#endif\n\n// Enter your WIFI credentials in secret.h\nconst char* ssid = WIFI_SSID;\nconst char* password = WIFI_PASS;\n\n// Set your SoftAP credentials\nconst char* softap_ssid = \"PsychicHttp\";\nconst char* softap_password = \"\";\nIPAddress softap_ip(10, 0, 0, 1);\n\n// credentials for the /auth-basic and /auth-digest examples\nconst char* app_user = \"admin\";\nconst char* app_pass = \"admin\";\nconst char* app_name = \"Your App\";\n\nLoggingMiddleware loggingMiddleware;\nAuthenticationMiddleware basicAuth;\nAuthenticationMiddleware digestAuth;\n\n// hostname for mdns (psychic.local)\nconst char* local_hostname = \"psychic\";\n\n// set CONFIG_ESP_HTTPS_SERVER_ENABLE=y in menuconfig to enable ssl\n#ifdef CONFIG_ESP_HTTPS_SERVER_ENABLE\nbool app_enable_ssl = true;\nString server_cert;\nString server_key;\n#endif\n\n// our main server object\n#ifdef CONFIG_ESP_HTTPS_SERVER_ENABLE\nPsychicHttpsServer server;\n#else\nPsychicHttpServer server;\n#endif\nPsychicWebSocketHandler websocketHandler;\nPsychicEventSource eventSource;\nCorsMiddleware corsMiddleware;\n\n// NTP server stuff\nconst char* ntpServer1 = \"pool.ntp.org\";\nconst char* ntpServer2 = \"time.nist.gov\";\nconst long gmtOffset_sec = 0;\nconst int daylightOffset_sec = 0;\nstruct tm timeinfo;\n\n// Callback function (gets called when time adjusts via NTP)\nvoid timeAvailable(struct timeval* t)\n{\n  if (!getLocalTime(&timeinfo)) {\n    Serial.println(\"Failed to obtain time\");\n    return;\n  }\n\n  Serial.print(\"NTP update: \");\n  char buffer[40];\n  strftime(buffer, 40, \"%FT%T%z\", &timeinfo);\n  Serial.println(buffer);\n}\n\nbool connectToWifi()\n{\n  // WiFi.mode(WIFI_AP);     // ap only mode\n  // WiFi.mode(WIFI_STA); // client only mode\n  WiFi.mode(WIFI_AP_STA); // ap and client\n\n  // Configure SoftAP\n  // dual client and AP mode\n  WiFi.softAPConfig(softap_ip, softap_ip, IPAddress(255, 255, 255, 0)); // subnet FF FF FF 00\n  WiFi.softAP(softap_ssid, softap_password);\n  IPAddress myIP = WiFi.softAPIP();\n  Serial.print(\"SoftAP IP Address: \");\n  Serial.println(myIP);\n\n  Serial.println();\n  Serial.print(\"[WiFi] Connecting to \");\n  Serial.println(ssid);\n\n  WiFi.begin(ssid, password);\n  // Auto reconnect is set true as default\n  // To set auto connect off, use the following function\n  // WiFi.setAutoReconnect(false);\n\n  // Will try for about 10 seconds (20x 500ms)\n  int tryDelay = 500;\n  int numberOfTries = 20;\n\n  // Wait for the WiFi event\n  while (true) {\n    switch (WiFi.status()) {\n      case WL_NO_SSID_AVAIL:\n        Serial.println(\"[WiFi] SSID not found\");\n        break;\n      case WL_CONNECT_FAILED:\n        Serial.print(\"[WiFi] Failed - WiFi not connected! Reason: \");\n        return false;\n        break;\n      case WL_CONNECTION_LOST:\n        Serial.println(\"[WiFi] Connection was lost\");\n        break;\n      case WL_SCAN_COMPLETED:\n        Serial.println(\"[WiFi] Scan is completed\");\n        break;\n      case WL_DISCONNECTED:\n        Serial.println(\"[WiFi] WiFi is disconnected\");\n        break;\n      case WL_CONNECTED:\n        Serial.println(\"[WiFi] WiFi is connected!\");\n        Serial.print(\"[WiFi] IP address: \");\n        Serial.println(WiFi.localIP());\n        return true;\n        break;\n      default:\n        Serial.print(\"[WiFi] WiFi Status: \");\n        Serial.println(WiFi.status());\n        break;\n    }\n    delay(tryDelay);\n\n    if (numberOfTries <= 0) {\n      Serial.print(\"[WiFi] Failed to connect to WiFi!\");\n      // Use disconnect function to force stop trying to connect\n      WiFi.disconnect();\n      return false;\n    } else {\n      numberOfTries--;\n    }\n  }\n\n  return false;\n}\n\nvoid setup()\n{\n  esp_log_level_set(PH_TAG, ESP_LOG_DEBUG);\n  esp_log_level_set(\"httpd_uri\", ESP_LOG_DEBUG);\n\n  Serial.begin(115200);\n  delay(10);\n\n  Serial.printf(\"ESP-IDF Version: %s\\n\", esp_get_idf_version());\n#ifdef ESP_ARDUINO_VERSION_STR\n  Serial.printf(\"Arduino Version: %s\\n\", ESP_ARDUINO_VERSION_STR);\n#else\n  Serial.printf(\"Arduino Version: %d.%d.%d\\n\", ESP_ARDUINO_VERSION_MAJOR, ESP_ARDUINO_VERSION_MINOR, ESP_ARDUINO_VERSION_PATCH);\n#endif\n  Serial.printf(\"PsychicHttp Version: %s\\n\", PSYCHIC_VERSION_STR);\n\n  // We start by connecting to a WiFi network\n  // To debug, please enable Core Debug Level to Verbose\n  if (connectToWifi()) {\n    // Setup our NTP to get the current time.\n    sntp_set_time_sync_notification_cb(timeAvailable);\n    sntp_servermode_dhcp(1); // (optional)\n    configTime(gmtOffset_sec, daylightOffset_sec, ntpServer1, ntpServer2);\n\n    // set up our esp32 to listen on the psychic.local domain\n    if (MDNS.begin(local_hostname))\n      MDNS.addService(\"http\", \"tcp\", 80);\n    else\n      Serial.println(\"Error starting mDNS\");\n\n    if (!LittleFS.begin(false, \"/spiffs\", 5, \"littlefs\")) {\n      Serial.println(\"LittleFS Mount Failed. Upload filesystem image first.\");\n      return;\n    }\n\n#ifdef CONFIG_ESP_HTTPS_SERVER_ENABLE\n    // look up our keys?\n    if (app_enable_ssl) {\n      File fp = LittleFS.open(\"/server.crt\");\n      if (fp) {\n        server_cert = fp.readString();\n\n        // Serial.println(\"Server Cert:\");\n        // Serial.println(server_cert);\n      } else {\n        Serial.println(\"server.pem not found, SSL not available\");\n        app_enable_ssl = false;\n      }\n      fp.close();\n\n      File fp2 = LittleFS.open(\"/server.key\");\n      if (fp2) {\n        server_key = fp2.readString();\n\n        // Serial.println(\"Server Key:\");\n        // Serial.println(server_key);\n      } else {\n        Serial.println(\"server.key not found, SSL not available\");\n        app_enable_ssl = false;\n      }\n      fp2.close();\n    }\n\n    // do we want secure or not?\n    if (app_enable_ssl) {\n      server.setCertificate(server_cert.c_str(), server_key.c_str());\n\n      // this creates a 2nd server listening on port 80 and redirects all requests HTTPS\n      PsychicHttpServer* redirectServer = new PsychicHttpServer();\n      redirectServer->config.ctrl_port = 20424; // just a random port different from the default one\n      redirectServer->config.stack_size = 4096; // we dont need a large stack size for this.\n      redirectServer->onNotFound([](PsychicRequest* request, PsychicResponse* response) {\n        String url = \"https://\" + request->host() + request->url();\n        return response->redirect(url.c_str()); });\n      redirectServer->start();\n    }\n#endif\n\n    DefaultHeaders::Instance().addHeader(\"Server\", \"PsychicHttp\");\n\n    loggingMiddleware.setOutput(Serial);\n\n    basicAuth.setUsername(app_user);\n    basicAuth.setPassword(app_pass);\n    basicAuth.setRealm(app_name);\n    basicAuth.setAuthMethod(HTTPAuthMethod::BASIC_AUTH);\n    basicAuth.setAuthFailureMessage(\"You must log in.\");\n\n    digestAuth.setUsername(app_user);\n    digestAuth.setPassword(app_pass);\n    digestAuth.setRealm(app_name);\n    digestAuth.setAuthMethod(HTTPAuthMethod::DIGEST_AUTH);\n    digestAuth.setAuthFailureMessage(\"You must log in.\");\n\n    // corsMiddleware.setAllowCredentials(true);\n    // corsMiddleware.setOrigin(\"http://www.example.com,https://www.example.com,http://api.example.com,https://api.example.com\");\n    // corsMiddleware.setHeaders(\"Origin,X-Requested-With,Content-Type,Accept,Content-Type,Authorization,X-Access-Token\");\n\n    server.addMiddleware(&loggingMiddleware);\n    // this will send CORS headers on every HTTP_OPTIONS request that contains the Origin: header\n    server.addMiddleware(&corsMiddleware);\n\n    // rewrites!\n    server.rewrite(\"/rewrite\", \"/api?foo=rewrite\");\n\n    // serve static files from LittleFS/www on / only to clients on same wifi network\n    // this is where our /index.html file lives\n    //  curl -i http://psychic.local/\n    server.serveStatic(\"/\", LittleFS, \"/www/\")\n      ->setCacheControl(\"max-age=60\")\n      ->addFilter(ON_STA_FILTER);\n\n    // serve static files from LittleFS/www-ap on / only to clients on SoftAP\n    // this is where our /index.html file lives\n    server.serveStatic(\"/\", LittleFS, \"/www-ap/\")->addFilter(ON_AP_FILTER);\n\n    // serve static files from LittleFS/img on /img\n    // it's more efficient to serve everything from a single www directory, but this is also possible.\n    //  curl -i http://psychic.local/img/request_flow.png\n    server.serveStatic(\"/img\", LittleFS, \"/img/\");\n\n    // you can also serve single files\n    //  curl -i http://psychic.local/myfile.txt\n    server.serveStatic(\"/myfile.txt\", LittleFS, \"/custom.txt\");\n\n    // example callback everytime a connection is opened\n    server.onOpen([](PsychicClient* client) { Serial.printf(\"[http] connection #%u connected from %s\\n\", client->socket(), client->remoteIP().toString().c_str()); });\n\n    // example callback everytime a connection is closed\n    server.onClose([](PsychicClient* client) { Serial.printf(\"[http] connection #%u closed\\n\", client->socket()); });\n\n    // api - json message passed in as post body\n    //  curl -i -X POST -H \"Content-Type: application/json\" -d '{\"foo\":\"bar\"}' http://psychic.local/api\n    server.on(\"/api\", HTTP_POST, [](PsychicRequest* request, PsychicResponse* resp, JsonVariant& json) {\n      JsonObject input = json.as<JsonObject>();\n\n      // create our response json\n      PsychicJsonResponse response(resp);\n      JsonObject output = response.getRoot();\n\n      output[\"msg\"] = \"status\";\n      output[\"status\"] = \"success\";\n      output[\"millis\"] = millis();\n      output[\"method\"] = request->methodStr();\n\n      // work with some params\n      if (input.containsKey(\"foo\")) {\n        String foo = input[\"foo\"];\n        output[\"foo\"] = foo;\n      }\n\n      return response.send();\n    });\n\n    // ip - get info about the client\n    //  curl -i http://psychic.local/ip\n    server.on(\"/ip\", HTTP_GET, [](PsychicRequest* request, PsychicResponse* response) {\n      String output = \"Your IP is: \" + request->client()->remoteIP().toString();\n      return response->send(output.c_str());\n    });\n\n    // client connect/disconnect to a url\n    //  curl -i http://psychic.local/handler\n    PsychicWebHandler* connectionHandler = new PsychicWebHandler();\n    connectionHandler->onRequest([](PsychicRequest* request, PsychicResponse* response) { return response->send(\"OK\"); });\n    connectionHandler->onOpen([](PsychicClient* client) { Serial.printf(\"[handler] connection #%u connected from %s\\n\", client->socket(), client->remoteIP().toString().c_str()); });\n    connectionHandler->onClose([](PsychicClient* client) { Serial.printf(\"[handler] connection #%u closed\\n\", client->socket()); });\n\n    // add it to our server\n    server.on(\"/handler\", connectionHandler);\n\n    // api - parameters passed in via query eg. /api?foo=bar\n    //  curl -i 'http://psychic.local/api?foo=bar'\n    server.on(\"/api\", HTTP_GET, [](PsychicRequest* request, PsychicResponse* resp) {\n      // create our response json\n      PsychicJsonResponse response = PsychicJsonResponse(resp);\n      JsonObject output = response.getRoot();\n\n      output[\"msg\"] = \"status\";\n      output[\"status\"] = \"success\";\n      output[\"millis\"] = millis();\n      output[\"method\"] = request->methodStr();\n\n      // work with some params\n      if (request->hasParam(\"foo\")) {\n        String foo = request->getParam(\"foo\")->value();\n        output[\"foo\"] = foo;\n      }\n\n      return response.send();\n    });\n\n    // curl -i -X GET 'http://psychic.local/any'\n    // curl -i -X POST 'http://psychic.local/any'\n    server.on(\"/any\", HTTP_ANY, [](PsychicRequest* request, PsychicResponse* resp) {\n      // create our response json\n      PsychicJsonResponse response = PsychicJsonResponse(resp);\n      JsonObject output = response.getRoot();\n\n      output[\"msg\"] = \"status\";\n      output[\"status\"] = \"success\";\n      output[\"millis\"] = millis();\n      output[\"method\"] = request->methodStr();\n\n      return response.send();\n    });\n\n    // curl -i 'http://psychic.local/simple'\n    server.on(\"/simple\", HTTP_GET, [](PsychicRequest* request, PsychicResponse* response) {\n            return response->send(\"Simple\");\n          })\n      ->setURIMatchFunction(MATCH_SIMPLE);\n\n#ifdef PSY_ENABLE_REGEX\n    // curl -i 'http://psychic.local/regex/23'\n    // curl -i 'http://psychic.local/regex/4223'\n    server.on(\"^/regex/([\\\\d]+)/?$\", HTTP_GET, [](PsychicRequest* request, PsychicResponse* response) {\n            // look up our regex matches\n            std::smatch matches;\n            if (request->getRegexMatches(matches)) {\n              String output;\n              output += \"Matches: \" + String(matches.size()) + \"<br/>\\n\";\n              output += \"Matched URI: \" + String(matches.str(0).c_str()) + \"<br/>\\n\";\n              output += \"Match 1: \" + String(matches.str(1).c_str()) + \"<br/>\\n\";\n\n              return response->send(output.c_str());\n            } else\n              return response->send(\"No regex match.\");\n          })\n      ->setURIMatchFunction(MATCH_REGEX);\n#endif\n\n    // JsonResponse example\n    //  curl -i http://psychic.local/json\n    server.on(\"/json\", HTTP_GET, [](PsychicRequest* request, PsychicResponse* response) {\n      PsychicJsonResponse jsonResponse = PsychicJsonResponse(response);\n\n      char key[16];\n      char value[32];\n      JsonObject root = jsonResponse.getRoot();\n      for (int i = 0; i < 100; i++) {\n        sprintf(key, \"key%d\", i);\n        sprintf(value, \"value is %d\", i);\n        root[key] = value;\n      }\n\n      return jsonResponse.send();\n    });\n\n    // how to redirect a request\n    //  curl -i  http://psychic.local/redirect\n    server.on(\"/redirect\", HTTP_GET, [](PsychicRequest* request, PsychicResponse* response) { return response->redirect(\"/alien.png\"); });\n\n    // how to do basic auth\n    //  curl -i --user admin:admin http://psychic.local/auth-basic\n    server.on(\"/auth-basic\", HTTP_GET, [](PsychicRequest* request, PsychicResponse* response) {\n            return response->send(\"Auth Basic Success!\");\n          })\n      ->addMiddleware(&basicAuth);\n\n    // how to do digest auth\n    //  curl -i --user admin:admin http://psychic.local/auth-digest\n    server.on(\"/auth-digest\", HTTP_GET, [](PsychicRequest* request, PsychicResponse* response) {\n            return response->send(\"Auth Digest Success!\");\n          })\n      ->addMiddleware(&digestAuth);\n\n    // example of getting / setting cookies\n    //  curl -i -b cookie.txt -c cookie.txt http://psychic.local/cookies\n    server.on(\"/cookies\", HTTP_GET, [](PsychicRequest* request, PsychicResponse* response) {\n      int counter = 0;\n      char cookie[14];\n      size_t size = sizeof(cookie);\n      if (request->getCookie(\"counter\", cookie, &size) == ESP_OK) {\n        // value is null-terminated.\n        counter = std::stoi(cookie);\n        counter++;\n      }\n      sprintf(cookie, \"%d\", counter);\n\n      response->setCookie(\"counter\", cookie);\n      response->setContent(cookie);\n      return response->send();\n    });\n\n    // example of getting POST variables\n    //  curl -i -d \"param1=value1&param2=value2\" -X POST http://psychic.local/post\n    //  curl -F \"param1=value1\" -F \"param2=value2\" -X POST http://psychic.local/post\n    server.on(\"/post\", HTTP_POST, [](PsychicRequest* request, PsychicResponse* response) {\n      String output;\n      output += \"Param 1: \" + request->getParam(\"param1\")->value() + \"<br/>\\n\";\n      output += \"Param 2: \" + request->getParam(\"param2\")->value() + \"<br/>\\n\";\n\n      return response->send(output.c_str());\n    });\n\n    // you can set up a custom 404 handler.\n    //  curl -i http://psychic.local/404\n    server.onNotFound([](PsychicRequest* request, PsychicResponse* response) { return response->send(404, \"text/html\", \"Custom 404 Handler\"); });\n\n    // handle a very basic upload as post body\n    PsychicUploadHandler* uploadHandler = new PsychicUploadHandler();\n    uploadHandler->onUpload([](PsychicRequest* request, const String& filename, uint64_t index, uint8_t* data, size_t len, bool last) {\n      static File file;\n      String path = \"/www/\" + filename;\n\n      Serial.printf(\"Writing %d/%d bytes to: %s\\n\", (int)index + (int)len, request->contentLength(), path.c_str());\n\n      if (last)\n        Serial.printf(\"%s is finished. Total bytes: %llu\\n\", path.c_str(), (uint64_t)index + (uint64_t)len);\n\n      if (!index)\n        file = LittleFS.open(path, FILE_WRITE);\n\n      if (!file) {\n        Serial.println(\"Failed to open file\");\n        return ESP_FAIL;\n      }\n\n      if (!file.write(data, len)) {\n        Serial.println(\"Write failed\");\n        return ESP_FAIL;\n      }\n\n      if (last)\n        file.close();\n\n      return ESP_OK;\n    });\n\n    // gets called after upload has been handled\n    uploadHandler->onRequest([](PsychicRequest* request, PsychicResponse* response) {\n      String url = \"/\" + request->getFilename();\n      String output = \"<a href=\\\"\" + url + \"\\\">\" + url + \"</a>\";\n\n      return response->send(output.c_str());\n    });\n\n    // wildcard basic file upload - POST to /upload/filename.ext\n    //  use http://psychic.local/ to test\n    server.on(\"/upload/*\", HTTP_POST, uploadHandler);\n\n    // a little bit more complicated multipart form\n    PsychicUploadHandler* multipartHandler = new PsychicUploadHandler();\n    multipartHandler->onUpload([](PsychicRequest* request, const String& filename, uint64_t index, uint8_t* data, size_t len, bool last) {\n      static File file;\n      String path = \"/www/\" + filename;\n\n      // some progress over serial.\n      Serial.printf(\"Writing %d bytes to: %s @ index %llu\\n\", (int)len, path.c_str(), index);\n      if (last)\n        Serial.printf(\"%s is finished. Total bytes: %llu\\n\", path.c_str(), (uint64_t)index + (uint64_t)len);\n\n      if (!index)\n        file = LittleFS.open(path, FILE_WRITE);\n\n      if (!file) {\n        Serial.println(\"Failed to open file\");\n        return ESP_FAIL;\n      }\n\n      if (!file.write(data, len)) {\n        Serial.println(\"Write failed\");\n        return ESP_FAIL;\n      }\n\n      if (last)\n        file.close();\n\n      return ESP_OK;\n    });\n\n    // gets called after upload has been handled\n    multipartHandler->onRequest([](PsychicRequest* request, PsychicResponse* response) {\n      String output;\n      if (request->hasParam(\"file_upload\")) {\n        PsychicWebParameter* file = request->getParam(\"file_upload\");\n\n        String url = \"/\" + file->value();\n        output += \"<a href=\\\"\" + url + \"\\\">\" + url + \"</a><br/>\\n\";\n        output += \"Bytes: \" + String(file->size()) + \"<br/>\\n\";\n      }\n\n      if (request->hasParam(\"param1\"))\n        output += \"Param 1: \" + request->getParam(\"param1\")->value() + \"<br/>\\n\";\n      if (request->hasParam(\"param2\"))\n        output += \"Param 2: \" + request->getParam(\"param2\")->value() + \"<br/>\\n\";\n\n      return response->send(output.c_str());\n    });\n\n    // wildcard basic file upload - POST to /upload/filename.ext\n    //  use http://psychic.local/ to test\n    // just multipart data: curl -F \"param1=multi\" -F \"param2=part\" http://psychic.local/multipart\n    server.on(\"/multipart\", HTTP_POST, multipartHandler);\n\n    // form only multipart handler\n    // curl -F \"param1=multi\" -F \"param2=part\" http://psychic.local/multipart-data\n    PsychicUploadHandler* multipartFormHandler = new PsychicUploadHandler();\n    multipartFormHandler->onRequest([](PsychicRequest* request, PsychicResponse* response) {\n      String output;\n      if (request->hasParam(\"param1\"))\n        output += \"Param 1: \" + request->getParam(\"param1\")->value() + \"<br/>\\n\";\n      if (request->hasParam(\"param2\"))\n        output += \"Param 2: \" + request->getParam(\"param2\")->value() + \"<br/>\\n\";\n\n      return response->send(output.c_str());\n    });\n    server.on(\"/multipart-data\", HTTP_POST, multipartFormHandler);\n\n    // a websocket echo server\n    //  npm install -g wscat\n    // Plaintext: wscat -c ws://psychic.local/ws\n    // SSL: wscat -n -c wss://psychic.local/ws\n    websocketHandler.onOpen([](PsychicWebSocketClient* client) {\n      Serial.printf(\"[socket] connection #%u connected from %s\\n\", client->socket(), client->remoteIP().toString().c_str());\n      client->sendMessage(\"Hello!\");\n    });\n    websocketHandler.onFrame([](PsychicWebSocketRequest* request, httpd_ws_frame* frame) {\n      // Serial.printf(\"[socket] #%d sent: %s\\n\", request->client()->socket(), String((char*)frame->payload, frame->len).c_str());\n      return request->reply(frame);\n    });\n    websocketHandler.onClose([](PsychicWebSocketClient* client) { Serial.printf(\"[socket] connection #%u closed\\n\", client->socket()); });\n    server.on(\"/ws\", &websocketHandler);\n\n    // EventSource server\n    //  curl -i -N http://psychic.local/events\n    eventSource.onOpen([](PsychicEventSourceClient* client) {\n      Serial.printf(\"[eventsource] connection #%u connected from %s\\n\", client->socket(), client->remoteIP().toString().c_str());\n      client->send(\"Hello user!\", NULL, millis(), 1000);\n    });\n    eventSource.onClose([](PsychicEventSourceClient* client) { Serial.printf(\"[eventsource] connection #%u closed\\n\", client->socket()); });\n    server.on(\"/events\", &eventSource);\n\n    // example of using POST data inside the filter\n    // works: curl -F \"secret=password\" http://psychic.local/post-filter\n    // 404:   curl -F \"foo=bar\" http://psychic.local/post-filter\n    server.on(\"/post-filter\", HTTP_POST, [](PsychicRequest* request, PsychicResponse* response) {\n            String output;\n            output += \"Secret: \" + request->getParam(\"secret\")->value() + \"<br/>\\n\";\n\n            return response->send(output.c_str());\n          })\n      ->addFilter([](PsychicRequest* request) {\n        request->loadParams();\n        return request->hasParam(\"secret\");\n      });\n\n    server.begin();\n  }\n}\n\nunsigned long lastUpdate = 0;\nchar output[60];\n\nvoid loop()\n{\n  if (millis() - lastUpdate > 1000) {\n    sprintf(output, \"Millis: %lu\\n\", millis());\n    websocketHandler.sendAll(output);\n\n    sprintf(output, \"%lu\", millis());\n    eventSource.send(output, \"millis\", millis(), 0);\n\n    lastUpdate = millis();\n  }\n  vTaskDelay(1 / portTICK_PERIOD_MS); // Feed WDT\n}\n"
  },
  {
    "path": "examples/esp-idf/main/secret.h",
    "content": "#define WIFI_SSID \"Your_SSID\"\n#define WIFI_PASS \"Your_PASS\""
  },
  {
    "path": "examples/esp-idf/partitions_custom.csv",
    "content": "# Name,   Type, SubType,  Offset,   Size,  Flags\nnvs, data, nvs, 0x11000, 0xC000\notadata, data, ota, 0x1D000, 0x2000\nphy_init, data, phy, 0x1F000, 0x1000\napp0, app, ota_0, 0x20000, 0x177000\napp1, app, ota_1, 0x1A0000, 0x177000\nlittlefs, data, spiffs, 0x317000, 0xE1000"
  },
  {
    "path": "examples/esp-idf/sdkconfig.defaults",
    "content": "CONFIG_AUTOSTART_ARDUINO=y\n# CONFIG_WS2812_LED_ENABLE is not set\nCONFIG_FREERTOS_HZ=1000\n\nCONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y\nCONFIG_COMPILER_OPTIMIZATION_SIZE=y\n\n#\n# Serial flasher config\n#\nCONFIG_ESPTOOLPY_FLASHMODE_QIO=y\nCONFIG_ESPTOOLPY_FLASHSIZE_4MB=y\nCONFIG_ESPTOOLPY_FLASHSIZE=\"4MB\"\n\n#\n# Partition Table\n#\nCONFIG_PARTITION_TABLE_CUSTOM=y\nCONFIG_PARTITION_TABLE_CUSTOM_FILENAME=\"partitions_custom.csv\"\n#CONFIG_PARTITION_TABLE_FILENAME=\"partitions_custom.csv\"\n#CONFIG_PARTITION_TABLE_OFFSET=0xE000\nCONFIG_PARTITION_TABLE_MD5=y\n\n#\n# ESP HTTPS OTA\n#\nCONFIG_ESP_HTTPS_OTA_DECRYPT_CB=y\nCONFIG_ESP_HTTPS_OTA_ALLOW_HTTP=y\n# end of ESP HTTPS OTA\n\n\n#\n# ESP HTTP client\n#\nCONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y\nCONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH=y\nCONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH=y\n# end of ESP HTTP client\n\n#\n# HTTP Server\n#\nCONFIG_HTTPD_MAX_REQ_HDR_LEN=1024\nCONFIG_HTTPD_MAX_URI_LEN=512\nCONFIG_HTTPD_ERR_RESP_NO_DELAY=y\nCONFIG_HTTPD_PURGE_BUF_LEN=32\n# CONFIG_HTTPD_LOG_PURGE_DATA is not set\nCONFIG_HTTPD_WS_SUPPORT=y\n# end of HTTP Server\n\n#\n# ESP HTTPS server\n#\nCONFIG_ESP_HTTPS_SERVER_ENABLE=n\n# end of ESP HTTPS server\n\n\n#\n# TLS Key Exchange Methods\n#\n# 2 option require for arduino Arduino\nCONFIG_MBEDTLS_PSK_MODES=y\nCONFIG_MBEDTLS_KEY_EXCHANGE_PSK=y\n\n"
  },
  {
    "path": "examples/platformio/.gitignore",
    "content": ".pio\n.vscode/\n.vscode/.browse.c_cpp.db*\n.vscode/c_cpp_properties.json\n.vscode/launch.json\n.vscode/ipch\nsrc/_secret.h\n"
  },
  {
    "path": "examples/platformio/data/custom.txt",
    "content": "Custom text file."
  },
  {
    "path": "examples/platformio/data/server.crt",
    "content": "-----BEGIN CERTIFICATE-----\nMIIDKzCCAhOgAwIBAgIUBxM3WJf2bP12kAfqhmhhjZWv0ukwDQYJKoZIhvcNAQEL\nBQAwJTEjMCEGA1UEAwwaRVNQMzIgSFRUUFMgc2VydmVyIGV4YW1wbGUwHhcNMTgx\nMDE3MTEzMjU3WhcNMjgxMDE0MTEzMjU3WjAlMSMwIQYDVQQDDBpFU1AzMiBIVFRQ\nUyBzZXJ2ZXIgZXhhbXBsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB\nALBint6nP77RCQcmKgwPtTsGK0uClxg+LwKJ3WXuye3oqnnjqJCwMEneXzGdG09T\nsA0SyNPwrEgebLCH80an3gWU4pHDdqGHfJQa2jBL290e/5L5MB+6PTs2NKcojK/k\nqcZkn58MWXhDW1NpAnJtjVniK2Ksvr/YIYSbyD+JiEs0MGxEx+kOl9d7hRHJaIzd\nGF/vO2pl295v1qXekAlkgNMtYIVAjUy9CMpqaQBCQRL+BmPSJRkXBsYk8GPnieS4\nsUsp53DsNvCCtWDT6fd9D1v+BB6nDk/FCPKhtjYOwOAZlX4wWNSZpRNr5dfrxKsb\njAn4PCuR2akdF4G8WLUeDWECAwEAAaNTMFEwHQYDVR0OBBYEFMnmdJKOEepXrHI/\nivM6mVqJgAX8MB8GA1UdIwQYMBaAFMnmdJKOEepXrHI/ivM6mVqJgAX8MA8GA1Ud\nEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBADiXIGEkSsN0SLSfCF1VNWO3\nemBurfOcDq4EGEaxRKAU0814VEmU87btIDx80+z5Dbf+GGHCPrY7odIkxGNn0DJY\nW1WcF+DOcbiWoUN6DTkAML0SMnp8aGj9ffx3x+qoggT+vGdWVVA4pgwqZT7Ybntx\nbkzcNFW0sqmCv4IN1t4w6L0A87ZwsNwVpre/j6uyBw7s8YoJHDLRFT6g7qgn0tcN\nZufhNISvgWCVJQy/SZjNBHSpnIdCUSJAeTY2mkM4sGxY0Widk8LnjydxZUSxC3Nl\nhb6pnMh3jRq4h0+5CZielA4/a+TdrNPv/qok67ot/XJdY3qHCCd8O2b14OVq9jo=\n-----END CERTIFICATE-----"
  },
  {
    "path": "examples/platformio/data/server.key",
    "content": "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCwYp7epz++0QkH\nJioMD7U7BitLgpcYPi8Cid1l7snt6Kp546iQsDBJ3l8xnRtPU7ANEsjT8KxIHmyw\nh/NGp94FlOKRw3ahh3yUGtowS9vdHv+S+TAfuj07NjSnKIyv5KnGZJ+fDFl4Q1tT\naQJybY1Z4itirL6/2CGEm8g/iYhLNDBsRMfpDpfXe4URyWiM3Rhf7ztqZdveb9al\n3pAJZIDTLWCFQI1MvQjKamkAQkES/gZj0iUZFwbGJPBj54nkuLFLKedw7DbwgrVg\n0+n3fQ9b/gQepw5PxQjyobY2DsDgGZV+MFjUmaUTa+XX68SrG4wJ+DwrkdmpHReB\nvFi1Hg1hAgMBAAECggEAaTCnZkl/7qBjLexIryC/CBBJyaJ70W1kQ7NMYfniWwui\nf0aRxJgOdD81rjTvkINsPp+xPRQO6oOadjzdjImYEuQTqrJTEUnntbu924eh+2D9\nMf2CAanj0mglRnscS9mmljZ0KzoGMX6Z/EhnuS40WiJTlWlH6MlQU/FDnwC6U34y\nJKy6/jGryfsx+kGU/NRvKSru6JYJWt5v7sOrymHWD62IT59h3blOiP8GMtYKeQlX\n49om9Mo1VTIFASY3lrxmexbY+6FG8YO+tfIe0tTAiGrkb9Pz6tYbaj9FjEWOv4Vc\n+3VMBUVdGJjgqvE8fx+/+mHo4Rg69BUPfPSrpEg7sQKBgQDlL85G04VZgrNZgOx6\npTlCCl/NkfNb1OYa0BELqWINoWaWQHnm6lX8YjrUjwRpBF5s7mFhguFjUjp/NW6D\n0EEg5BmO0ePJ3dLKSeOA7gMo7y7kAcD/YGToqAaGljkBI+IAWK5Su5yldrECTQKG\nYnMKyQ1MWUfCYEwHtPvFvE5aPwKBgQDFBWXekpxHIvt/B41Cl/TftAzE7/f58JjV\nMFo/JCh9TDcH6N5TMTRS1/iQrv5M6kJSSrHnq8pqDXOwfHLwxetpk9tr937VRzoL\nCuG1Ar7c1AO6ujNnAEmUVC2DppL/ck5mRPWK/kgLwZSaNcZf8sydRgphsW1ogJin\n7g0nGbFwXwKBgQCPoZY07Pr1TeP4g8OwWTu5F6dSvdU2CAbtZthH5q98u1n/cAj1\nnoak1Srpa3foGMTUn9CHu+5kwHPIpUPNeAZZBpq91uxa5pnkDMp3UrLIRJ2uZyr8\n4PxcknEEh8DR5hsM/IbDcrCJQglM19ZtQeW3LKkY4BsIxjDf45ymH407IQKBgE/g\nUl6cPfOxQRlNLH4VMVgInSyyxWx1mODFy7DRrgCuh5kTVh+QUVBM8x9lcwAn8V9/\nnQT55wR8E603pznqY/jX0xvAqZE6YVPcw4kpZcwNwL1RhEl8GliikBlRzUL3SsW3\nq30AfqEViHPE3XpE66PPo6Hb1ymJCVr77iUuC3wtAoGBAIBrOGunv1qZMfqmwAY2\nlxlzRgxgSiaev0lTNxDzZkmU/u3dgdTwJ5DDANqPwJc6b8SGYTp9rQ0mbgVHnhIB\njcJQBQkTfq6Z0H6OoTVi7dPs3ibQJFrtkoyvYAbyk36quBmNRjVh6rc8468bhXYr\nv/t+MeGJP/0Zw8v/X2CFll96\n-----END PRIVATE KEY-----"
  },
  {
    "path": "examples/platformio/data/www/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>PsychicHTTP Demo</title>\n    <link rel=\"icon\" href=\"./favicon.ico\" type=\"image/x-icon\">\n</head>\n\n<body>\n    <main>\n        <h1>Basic Request Examples</h1>\n        <ul>\n            <li><a href=\"/api?foo=bar\">API Call</a></li>\n            <li><a href=\"/redirect\">Redirection</a></li>\n            <li><a href=\"/auth-digest\">Authentication (Digest)</a></li>\n            <li><a href=\"/auth-basic\">Authentication (Basic)</a></li>\n            <li><a href=\"/cookies\">Cookies Demo</a></li>\n            <li><a href=\"/404\">404</a></li>\n        </ul>\n\n        <h1>Utilities</h1>\n        <ul>\n            <li><a href=\"/websocket-test.html\">WebSocket Tester</a></li>\n        </ul>\n\n        <h1>Static Serving</h1>\n        <p>\n            <a href=\"/alien.png\"><img width=\"60\" src=\"/alien.png\"></a>\n            <a href=\"/img/request_flow.png\"><img width=\"60\" src=\"/img/request_flow.png\"></a>\n        </p>\n        <p><a href=\"/myfile.txt\">Text File</a></p>\n\n        <h1>Simple POST Form</h1>\n        <form action=\"/post\" method=\"post\">\n            <label for=\"param1\">Parameter 1:</label>\n            <input type=\"text\" id=\"param1\" name=\"param1\" value=\"Parameter 1\">\n            <br>\n            <label for=\"param2\">Parameter 2:</label>\n            <input type=\"text\" id=\"param2\" name=\"param2\" value=\"Parameter 2\">\n            <br>\n            <input type=\"submit\" value=\"Submit\">\n        </form>\n\n        <h1>Basic File Upload</h1>\n        <table border=\"0\">\n            <tr>\n                <td>\n                    <label for=\"newfile\">Upload a file</label>\n                </td>\n                <td colspan=\"2\">\n                    <input id=\"newfile\" type=\"file\" onchange=\"setpath()\" style=\"width:100%;\">\n                </td>\n            </tr>\n            <tr>\n                <td>\n                    <label for=\"filepath\">Set path on server</label>\n                </td>\n                <td>\n                    <input id=\"filepath\" type=\"text\" style=\"width:100%;\">\n                </td>\n            </tr>\n            <tr>\n                <td>\n                    <button id=\"upload\" type=\"button\" onclick=\"upload()\">Upload</button>\n                </td>\n            </tr>\n        </table>\n        <script>\n            function setpath() {\n                var default_path = document.getElementById(\"newfile\").files[0].name;\n                document.getElementById(\"filepath\").value = default_path;\n            }\n            function upload() {\n                var filePath = document.getElementById(\"filepath\").value;\n                var upload_path = \"/upload/\" + filePath;\n                var fileInput = document.getElementById(\"newfile\").files;\n\n                /* Max size of an individual file. Make sure this\n                * value is same as that set in file_server.c */\n                var MAX_FILE_SIZE = 2048 * 1024;\n                var MAX_FILE_SIZE_STR = \"2MB\";\n\n                if (fileInput.length == 0) {\n                    alert(\"No file selected!\");\n                } else if (filePath.length == 0) {\n                    alert(\"File path on server is not set!\");\n                } else if (filePath.indexOf(' ') >= 0) {\n                    alert(\"File path on server cannot have spaces!\");\n                } else if (filePath[filePath.length - 1] == '/') {\n                    alert(\"File name not specified after path!\");\n                } else if (fileInput[0].size > 200 * 1024) {\n                    alert(\"File size must be less than 200KB!\");\n                } else {\n                    document.getElementById(\"newfile\").disabled = true;\n                    document.getElementById(\"filepath\").disabled = true;\n                    document.getElementById(\"upload\").disabled = true;\n\n                    var file = fileInput[0];\n                    var xhttp = new XMLHttpRequest();\n                    xhttp.onreadystatechange = function () {\n                        if (xhttp.readyState == 4) {\n                            if (xhttp.status == 200) {\n                                document.open();\n                                document.write(xhttp.responseText);\n                                document.close();\n                            } else if (xhttp.status == 0) {\n                                alert(\"Server closed the connection abruptly!\");\n                                location.reload()\n                            } else {\n                                alert(xhttp.status + \" Error!\\n\" + xhttp.responseText);\n                                location.reload()\n                            }\n                        }\n                    };\n                    xhttp.open(\"POST\", upload_path, true);\n                    xhttp.send(file);\n                }\n            }\n        </script>\n\n        <h1>Multipart POST Form</h1>\n        <form action=\"/multipart\" method=\"post\" enctype=\"multipart/form-data\">\n            <label for=\"param1\">Parameter 1:</label>\n            <input type=\"text\" id=\"param1\" name=\"param1\" value=\"Parameter 1\">\n            <br>\n\n            <label for=\"param2\">Parameter 2:</label>\n            <input type=\"text\" id=\"param2\" name=\"param2\" value=\"Parameter 2\">\n            <br>\n\n            <label for=\"file-upload\">File Upload:</label>\n            <input type=\"file\" id=\"file-upload\" name=\"file_upload\" accept=\".txt, .html, .pdf, .png, .jpg, .gif\"\n                required>\n            <br>\n\n            <input type=\"submit\" value=\"Upload File\">\n        </form>\n\n        <h1>Websocket Demo</h1>\n        <input type=\"text\" id=\"message_input\" placeholder=\"Type your message\">\n        <button onclick=\"sendMessage()\">Send Message</button>\n        <button onclick=\"websocketConnect()\">Connect</button>\n        <div>\n            <textarea id=\"websocket_output\" style=\"width: 50%; height: 250px;\"></textarea>\n        </div>\n\n        <script>\n            let socket;\n            const outputText = document.getElementById('websocket_output');\n            const messageInput = document.getElementById('message_input');\n\n            function websocketConnect() {\n                // Create a WebSocket connection\n                socket = new WebSocket((location.protocol === \"https:\" ? \"wss://\" : \"ws://\") + window.location.host + \"/ws\");\n\n                // Event handler for when the WebSocket connection is open\n                socket.addEventListener('open', (event) => {\n                    outputText.value += `[socket] connection opened!\\n`;\n                    outputText.scrollTop = outputText.scrollHeight;\n                });\n\n                // Event handler for when a message is received from the WebSocket server\n                socket.addEventListener('message', (event) => {\n                    // Echo the received message into the output div\n                    let data = event.data.trim();\n                    outputText.value += `[received] ${data}\\n`;\n                    outputText.scrollTop = outputText.scrollHeight;\n                });\n\n                // Event handler for when an error occurs with the WebSocket connection\n                socket.addEventListener('error', (event) => {\n                    let data = event.data.trim();\n                    outputText.value += `[error] ${event.data}\\n`;\n                    outputText.scrollTop = outputText.scrollHeight;\n                });\n\n                // Event handler for when the WebSocket connection is closed\n                socket.addEventListener('close', (event) => {\n                    outputText.value += `[socket] connection closed!\\n`;\n                });\n            }\n\n            // Function to send a message to the WebSocket server\n            function sendMessage() {\n                if (socket.readyState == WebSocket.OPEN) {\n                    const message = messageInput.value.trim();\n                    if (message) {\n                        socket.send(message);\n                        messageInput.value = ''; // Clear the input field after sending the message\n                        outputText.value += `[sent] ${message}\\n`;\n                        outputText.scrollTop = outputText.scrollHeight;\n                    }\n                }\n                else {\n                    outputText.value += `[error] Not Connected\\n`;\n                    outputText.scrollTop = outputText.scrollHeight;\n                }\n            }\n        </script>\n\n        <h1>EventSource Demo</h1>\n        <button onclick=\"eventSourceConnect()\">Connect</button>\n        <div>\n            <textarea id=\"eventsource_output\" style=\"width: 50%; height: 250px;\"></textarea>\n        </div>\n\n        <script>\n            const dataElement = document.getElementById('eventsource_output');\n\n            function eventSourceConnect() {\n                const eventSource = new EventSource('/events');\n\n                eventSource.onopen = () => {\n                    dataElement.value += `[connected]\\n`;\n                    dataElement.scrollTop = dataElement.scrollHeight;\n                };\n\n                eventSource.addEventListener('millis', (event) => {\n                    let data = event.data.trim()\n                    dataElement.value += `[millis] ${data}\\n`;\n                    dataElement.scrollTop = dataElement.scrollHeight;\n                });\n\n                eventSource.onmessage = (event) => {\n                    let data = event.data.trim()\n                    dataElement.value += `[message] ${data}\\n`;\n                    dataElement.scrollTop = dataElement.scrollHeight;\n                };\n\n                eventSource.onerror = (error) => {\n                    dataElement.value += `[error] ${error}\\n`;\n                    dataElement.scrollTop = dataElement.scrollHeight;\n                    eventSource.close();\n                };\n            }\n        </script>\n    </main>\n</body>\n\n</html>"
  },
  {
    "path": "examples/platformio/data/www/text.txt",
    "content": "Test File.\n"
  },
  {
    "path": "examples/platformio/data/www/websocket-test.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n\t<meta charset=\"UTF-8\">\n\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n\t<title>WebSocket Message Rate Test</title>\n</head>\n\n<body>\n\t<h1>WebSocket Message Rate Test</h1>\n\t<p>Time Remaining: <span id=\"time_remaining\">0</span></p>\n\t<p>Messages Count: <span id=\"message_count\">0</span></p>\n\t<p>Messages per second: <span id=\"rate\">0</span></p>\n\t<label for=\"duration\">Test Duration (seconds):</label>\n\t<input type=\"number\" id=\"duration\" value=\"30\" min=\"1\">\n\t<p>\n\t\t<button id=\"startTestSmall\">Start Test (256b json)</button>\n\t\t<button id=\"startTestBig\">Start Test (2k json)</button>\n\t</p>\n\t<p id=\"status\"></p>\n\n\t<script>\n\t\tlet ws;\n\t\tlet messageCount = 0;\n\t\tlet startTime;\n\t\tlet endTime;\n\t\tlet testRunning = false;\n\t\tlet smallPayload = { \"user\": { \"id\": 123456789, \"name\": \"JohnDoe\", \"email\": \"johndoe@example.com\", \"preferences\": { \"theme\": \"dark\", \"notifications\": { \"email\": true, \"sms\": false }, \"language\": \"en\" } } };\n\t\tlet bigPayload = { \"user\": { \"id\": 123456789, \"name\": \"JohnDoe\", \"email\": \"johndoe@example.com\", \"preferences\": { \"theme\": \"dark\", \"notifications\": { \"email\": true, \"sms\": false }, \"language\": \"en\", \"options\": { \"option1\": \"value1\", \"option2\": \"value2\", \"option3\": \"value3\", \"option4\": \"value4\", \"option5\": \"value5\", \"option6\": \"value6\", \"option7\": \"value7\", \"option8\": \"value8\", \"option9\": \"value9\", \"option10\": \"value10\", \"option11\": \"value11\", \"option12\": \"value12\", \"option13\": \"value13\", \"option14\": \"value14\", \"option15\": \"value15\", \"option16\": \"value16\", \"option17\": \"value17\", \"option18\": \"value18\", \"option19\": \"value19\", \"option20\": \"value20\", \"option21\": \"value21\", \"option22\": \"value22\", \"option23\": \"value23\", \"option24\": \"value24\", \"option25\": \"value25\", \"option26\": \"value26\", \"option27\": \"value27\", \"option28\": \"value28\", \"option29\": \"value29\", \"option30\": \"value30\", \"option31\": \"value31\", \"option32\": \"value32\", \"option33\": \"value33\", \"option34\": \"value34\", \"option35\": \"value35\", \"option36\": \"value36\", \"option37\": \"value37\", \"option38\": \"value38\", \"option39\": \"value39\", \"option40\": \"value40\", \"option41\": \"value41\", \"option42\": \"value42\", \"option43\": \"value43\", \"option44\": \"value44\", \"option45\": \"value45\", \"option46\": \"value46\", \"option47\": \"value47\", \"option48\": \"value48\", \"option49\": \"value49\", \"option50\": \"value50\", \"option51\": \"value51\", \"option52\": \"value52\", \"option53\": \"value53\", \"option54\": \"value54\", \"option55\": \"value55\", \"option56\": \"value56\", \"option57\": \"value57\", \"option58\": \"value58\", \"option59\": \"value59\", \"option60\": \"value60\", \"option61\": \"value61\", \"option62\": \"value62\", \"option63\": \"value63\", \"option64\": \"value64\", \"option65\": \"value65\", \"option66\": \"value66\", \"option67\": \"value67\", \"option68\": \"value68\", \"option69\": \"value69\", \"option70\": \"value70\", \"option71\": \"value71\", \"option72\": \"value72\", \"option73\": \"value73\", \"option74\": \"value74\", \"option75\": \"value75\", \"option76\": \"value76\", \"option77\": \"value77\", \"option78\": \"value78\", \"option79\": \"value79\", \"option80\": \"value80\", \"option81\": \"value81\", \"option82\": \"value82\", \"option83\": \"value83\", \"option84\": \"value84\", \"option85\": \"value85\", \"option86\": \"value86\", \"option87\": \"value87\", \"option88\": \"value88\", \"option89\": \"value89\", \"option90\": \"value90\", \"option91\": \"value91\", \"option92\": \"value92\", \"option93\": \"value93\", \"option94\": \"value94\", \"option95\": \"value95\", \"option96\": \"value96\", \"option97\": \"value97\", \"option98\": \"value98\", \"option99\": \"value99\", \"option100\": \"value100\", \"option101\": \"value101\", \"option102\": \"value102\", \"option103\": \"value103\", \"option104\": \"value104\", \"option105\": \"value105\", \"option106\": \"value106\", \"option107\": \"value107\", \"option108\": \"value108\", \"option109\": \"value109\", \"option110\": \"value110\", \"option111\": \"value111\", \"option112\": \"value112\", \"option113\": \"value113\", \"option114\": \"value114\", \"option115\": \"value115\", \"option116\": \"value116\", \"option117\": \"value117\", \"option118\": \"value118\", \"option119\": \"value119\", \"option120\": \"value120\" } } } };\n\t\tlet payload;\n\n\t\t// Function to update the message rate\n\t\tfunction updateRate(force = false) {\n\t\t\tconst currentTime = Date.now();\n\t\t\tconst elapsedTime = (currentTime - startTime) / 1000; // in seconds\n\t\t\tlet remainingTime = (endTime - currentTime) / 1000; // in seconds\n\t\t\tremainingTime = Math.max(0, remainingTime);\n\t\t\tconst rate = messageCount / elapsedTime;\n\n\t\t\tif (rate) {\n\t\t\t\tdocument.getElementById('rate').innerText = rate.toFixed(2);\n\t\t\t\tdocument.getElementById('message_count').innerText = messageCount;\n\t\t\t\tdocument.getElementById('time_remaining').innerText = remainingTime.toFixed(2);\n\t\t\t}\n\n\t\t\tif (testRunning)\n\t\t\t\tsetTimeout(updateRate, 25);\n\t\t}\n\n\t\tfunction startTestSmall() {\n\t\t\tpayload = smallPayload;\n\t\t\tstartTest();\n\t\t}\n\n\t\tfunction startTestBig() {\n\t\t\tpayload = bigPayload;\n\t\t\tstartTest();\n\t\t}\n\n\t\t// Function to start the WebSocket connection and the test\n\t\tfunction startTest() {\n\t\t\tif (testRunning) return;\n\n\t\t\tconsole.log(\"Payload length: \" + JSON.stringify(payload).length);\n\n\t\t\tdocument.getElementById('startTestSmall').disabled = true;\n\t\t\tdocument.getElementById('startTestBig').disabled = true;\n\n\t\t\tdocument.getElementById('status').innerText = 'Connecting';\n\n\t\t\tconst durationInput = document.getElementById('duration').value;\n\t\t\tconst testDuration = parseInt(durationInput) * 1000 || 60000; // default to 60 seconds if invalid\n\n\t\t\t// Determine the WebSocket protocol based on the current protocol\n\t\t\tconst protocol = window.location.protocol === 'https:' ? 'wss://' : 'ws://';\n\t\t\tws = new WebSocket(`${protocol}${window.location.host}/ws`);\n\n\t\t\tws.onopen = function () {\n\t\t\t\tdocument.getElementById('status').innerText = 'Connected';\n\t\t\t\tstartTime = Date.now();\n\t\t\t\tendTime = startTime + testDuration;\n\t\t\t\tmessageCount = 0;\n\t\t\t\ttestRunning = true;\n\t\t\t\tsendAndReceiveMessage();\n\n\t\t\t\tupdateRate();\n\t\t\t};\n\n\t\t\tws.onmessage = function (event) {\n\t\t\t\ttry {\n\t\t\t\t\tconst parsedData = JSON.parse(event.data);\n\n\t\t\t\t\tif (parsedData.user) {\n\t\t\t\t\t\tmessageCount++;\n\t\t\t\t\t\tif (testRunning) {\n\t\t\t\t\t\t\tsendAndReceiveMessage();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} catch (err) { }\n\t\t\t};\n\n\t\t\tws.onerror = function (error) {\n\t\t\t\tdocument.getElementById('status').innerText = 'Error: ' + error.message;\n\t\t\t};\n\n\t\t\tws.onclose = function () {\n\t\t\t\t//document.getElementById('status').innerText = 'Connection Closed';\n\t\t\t};\n\t\t}\n\n\t\t// Function to send a message and wait for the response\n\t\tfunction sendAndReceiveMessage() {\n\t\t\tif (Date.now() >= endTime) {\n\t\t\t\ttestRunning = false;\n\t\t\t\tdocument.getElementById('startTestSmall').disabled = false;\n\t\t\t\tdocument.getElementById('startTestBig').disabled = false;\n\t\t\t\tif (ws.readyState === WebSocket.OPEN) {\n\t\t\t\t\tws.close();\n\t\t\t\t}\n\t\t\t\tdocument.getElementById('status').innerText = 'Test Finished';\n\t\t\t\tupdateRate(true);\n\t\t\t} else {\n\t\t\t\tif (ws.readyState === WebSocket.OPEN) {\n\t\t\t\t\tws.send(JSON.stringify(payload));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tdocument.getElementById('startTestSmall').addEventListener('click', startTestSmall);\n\t\tdocument.getElementById('startTestBig').addEventListener('click', startTestBig);\n\t</script>\n</body>\n\n</html>"
  },
  {
    "path": "examples/platformio/data/www-ap/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n    <head>\n        <meta charset=\"UTF-8\">\n        <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n        <title>PsychicHTTP SoftAP Demo</title>\n        <link rel=\"icon\" href=\"./favicon.ico\" type=\"image/x-icon\">\n    </head>\n    <body>\n        <main>\n            <h1>SoftAP Demo</h1>\n            <p>You are connected to the ESP in SoftAP mode.</p>\n        </main>\n    </body>\n</html>"
  },
  {
    "path": "examples/platformio/platformio.ini",
    "content": "; PlatformIO Project Configuration File\n;\n;   Build options: build flags, source filter\n;   Upload options: custom upload port, speed and extra flags\n;   Library options: dependencies, extra library storages\n;   Advanced options: extra scripting\n;\n; Please visit documentation for the other options and examples\n; https://docs.platformio.org/page/projectconf.html\n\n[env]\nplatform = espressif32\nframework = arduino\nboard = esp32-s3-devkitc-1\nupload_port = /dev/ttyACM0\nmonitor_port = /dev/ttyACM1\nmonitor_speed = 115200\nmonitor_filters = esp32_exception_decoder\nlib_deps = \n    ; hoeken/PsychicHttp\n    ; PIO is not able to consider installed project in CI\n    ;../..\nboard_build.filesystem = littlefs\nbuild_flags =\n    -Wall\n    -Wextra\n\n[env:arduino2]\nplatform = espressif32@6.8.1\n\n[env:arduino2-ssl]\nplatform = espressif32@6.8.1\nbuild_flags = -D PSY_ENABLE_SSL\n\n[env:arduino2-regex]\nplatform = espressif32@6.8.1\nbuild_flags = -D PSY_ENABLE_REGEX\n\n[env:arduino3]\nplatform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.05/platform-espressif32.zip\n\n[env:arduino3-ssl]\nplatform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.05/platform-espressif32.zip\nbuild_flags = -D PSY_ENABLE_SSL\n\n[env:arduino3-regex]\nplatform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.05/platform-espressif32.zip\nbuild_flags = -D PSY_ENABLE_REGEX\n\n[env:waveshare-4-3-touchscreen]\nlib_deps = ${env.lib_deps}\n            https://github.com/esp-arduino-libs/ESP32_IO_Expander\nbuild_flags =\n  -D PSY_ENABLE_SDCARD\n  -D WAVESHARE_43_TOUCH\n"
  },
  {
    "path": "examples/platformio/src/main.cpp",
    "content": "/*\n  PsychicHTTP Server Example\n\n  This example code is in the Public Domain (or CC0 licensed, at your option.)\n\n  Unless required by applicable law or agreed to in writing, this\n  software is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n  CONDITIONS OF ANY KIND, either express or implied.\n*/\n\n/**********************************************************************************************\n * Note: this demo relies on various files to be uploaded on the LittleFS partition\n * PlatformIO -> Build Filesystem Image and then PlatformIO -> Upload Filesystem Image\n **********************************************************************************************/\n\n#include \"_secret.h\"\n#include <Arduino.h>\n#include <ArduinoJson.h>\n#include <ESPmDNS.h>\n#include <LittleFS.h>\n#include <PsychicHttp.h>\n#include <WiFi.h>\n#include <esp_sntp.h>\n\n// #define this to enable SD card support\n#ifdef PSY_ENABLE_SDCARD\n\n  #ifdef WAVESHARE_43_TOUCH\n    #include <ESP_IOExpander_Library.h>\n    // Extend IO Pin define\n    #define TP_RST  1\n    #define LCD_BL  2\n    #define LCD_RST 3\n    #define SD_CS   4\n    #define USB_SEL 5\n\n    // I2C Pin define\n    #define I2C_MASTER_NUM    I2C_NUM_0\n    #define I2C_MASTER_SDA_IO 8\n    #define I2C_MASTER_SCL_IO 9\n\n    #define SD_MOSI 11\n    #define SD_CLK  12\n    #define SD_MISO 13\n    #define SD_SS   -1\n  #else\n    #define SD_MOSI 11\n    #define SD_CLK  12\n    #define SD_MISO 13\n    #define SD_SS   5\n  #endif\n\n  #include <FS.h>\n  #include <SD.h>\n  #include <SPI.h>\n#endif\n\n// #define this to enable SSL at build (or switch to the 'ssl' build target in vscode)\n#ifdef PSY_ENABLE_SSL\n  #include <PsychicHttpsServer.h>\n#endif\n\n// debugging library\n#ifdef PSY_DEVMODE\n  #include <ArduinoTrace.h>\n#endif\n\n#ifndef WIFI_SSID\n  #error \"You need to enter your wifi credentials. Rename secret.h to _secret.h and enter your credentials there.\"\n#endif\n\n// Enter your WIFI credentials in secret.h\nconst char* ssid = WIFI_SSID;\nconst char* password = WIFI_PASS;\n\n// Set your SoftAP credentials\nconst char* softap_ssid = \"PsychicHttp\";\nconst char* softap_password = \"\";\nIPAddress softap_ip(10, 0, 0, 1);\n\n// credentials for the /auth-basic and /auth-digest examples\nconst char* app_user = \"admin\";\nconst char* app_pass = \"admin\";\nconst char* app_name = \"Your App\";\n\nLoggingMiddleware loggingMiddleware;\nAuthenticationMiddleware basicAuth;\nAuthenticationMiddleware digestAuth;\n\n// hostname for mdns (psychic.local)\nconst char* local_hostname = \"psychic\";\n\n// #define PSY_ENABLE_SSL to enable ssl\n#ifdef PSY_ENABLE_SSL\nbool app_enable_ssl = true;\nString server_cert;\nString server_key;\n#endif\n\n// our main server object\n#ifdef PSY_ENABLE_SSL\nPsychicHttpsServer server;\n#else\nPsychicHttpServer server;\n#endif\nPsychicWebSocketHandler websocketHandler;\nPsychicEventSource eventSource;\nCorsMiddleware corsMiddleware;\n\n// NTP server stuff\nconst char* ntpServer1 = \"pool.ntp.org\";\nconst char* ntpServer2 = \"time.nist.gov\";\nconst long gmtOffset_sec = 0;\nconst int daylightOffset_sec = 0;\nstruct tm timeinfo;\n\n// Callback function (gets called when time adjusts via NTP)\nvoid timeAvailable(struct timeval* t)\n{\n  if (!getLocalTime(&timeinfo)) {\n    Serial.println(\"Failed to obtain time\");\n    return;\n  }\n\n  Serial.print(\"NTP update: \");\n  char buffer[40];\n  strftime(buffer, 40, \"%FT%T%z\", &timeinfo);\n  Serial.println(buffer);\n}\n\nbool connectToWifi()\n{\n  // WiFi.mode(WIFI_AP);     // ap only mode\n  // WiFi.mode(WIFI_STA); // client only mode\n  WiFi.mode(WIFI_AP_STA); // ap and client\n\n  // Configure SoftAP\n  // dual client and AP mode\n  WiFi.softAPConfig(softap_ip, softap_ip, IPAddress(255, 255, 255, 0)); // subnet FF FF FF 00\n  WiFi.softAP(softap_ssid, softap_password);\n  IPAddress myIP = WiFi.softAPIP();\n  Serial.print(\"SoftAP IP Address: \");\n  Serial.println(myIP);\n\n  Serial.println();\n  Serial.print(\"[WiFi] Connecting to \");\n  Serial.println(ssid);\n\n  WiFi.begin(ssid, password);\n  // Auto reconnect is set true as default\n  // To set auto connect off, use the following function\n  // WiFi.setAutoReconnect(false);\n\n  // Will try for about 10 seconds (20x 500ms)\n  int tryDelay = 500;\n  int numberOfTries = 20;\n\n  // Wait for the WiFi event\n  while (true) {\n    switch (WiFi.status()) {\n      case WL_NO_SSID_AVAIL:\n        Serial.println(\"[WiFi] SSID not found\");\n        break;\n      case WL_CONNECT_FAILED:\n        Serial.print(\"[WiFi] Failed - WiFi not connected! Reason: \");\n        return false;\n        break;\n      case WL_CONNECTION_LOST:\n        Serial.println(\"[WiFi] Connection was lost\");\n        break;\n      case WL_SCAN_COMPLETED:\n        Serial.println(\"[WiFi] Scan is completed\");\n        break;\n      case WL_DISCONNECTED:\n        Serial.println(\"[WiFi] WiFi is disconnected\");\n        break;\n      case WL_CONNECTED:\n        Serial.println(\"[WiFi] WiFi is connected!\");\n        Serial.print(\"[WiFi] IP address: \");\n        Serial.println(WiFi.localIP());\n        return true;\n        break;\n      default:\n        Serial.print(\"[WiFi] WiFi Status: \");\n        Serial.println(WiFi.status());\n        break;\n    }\n    delay(tryDelay);\n\n    if (numberOfTries <= 0) {\n      Serial.print(\"[WiFi] Failed to connect to WiFi!\");\n      // Use disconnect function to force stop trying to connect\n      WiFi.disconnect();\n      return false;\n    } else {\n      numberOfTries--;\n    }\n  }\n\n  return false;\n}\n\n#ifdef PSY_ENABLE_SDCARD\nbool setupSDCard()\n{\n  #ifdef WAVESHARE_43_TOUCH\n  ESP_IOExpander* expander = new ESP_IOExpander_CH422G((i2c_port_t)I2C_MASTER_NUM, ESP_IO_EXPANDER_I2C_CH422G_ADDRESS_000, I2C_MASTER_SCL_IO, I2C_MASTER_SDA_IO);\n  expander->init();\n  expander->begin();\n  expander->multiPinMode(TP_RST | LCD_BL | LCD_RST | SD_CS | USB_SEL, OUTPUT);\n  expander->multiDigitalWrite(TP_RST | LCD_BL | LCD_RST, HIGH);\n\n  // use extend GPIO for SD card\n  expander->digitalWrite(SD_CS, LOW);\n  SPI.setHwCs(false);\n  #endif\n\n  SPI.begin(SD_CLK, SD_MISO, SD_MOSI, SD_SS);\n  if (!SD.begin()) {\n    Serial.println(\"SD Card Mount Failed\");\n    return false;\n  }\n  uint8_t cardType = SD.cardType();\n\n  if (cardType == CARD_NONE) {\n    Serial.println(\"No SD card attached\");\n    return false;\n  }\n\n  Serial.print(\"SD Card Type: \");\n  if (cardType == CARD_MMC) {\n    Serial.println(\"MMC\");\n  } else if (cardType == CARD_SD) {\n    Serial.println(\"SDSC\");\n  } else if (cardType == CARD_SDHC) {\n    Serial.println(\"SDHC\");\n  } else {\n    Serial.println(\"UNKNOWN\");\n  }\n\n  uint64_t cardSize = SD.cardSize() / (1024 * 1024);\n  Serial.printf(\"SD Card Size: %lluMB\\n\", cardSize);\n  Serial.printf(\"Total space: %lluMB\\n\", SD.totalBytes() / (1024 * 1024));\n  Serial.printf(\"Used space: %lluMB\\n\", SD.usedBytes() / (1024 * 1024));\n\n  return true;\n}\n#endif\n\nvoid setup()\n{\n  esp_log_level_set(PH_TAG, ESP_LOG_DEBUG);\n  esp_log_level_set(\"httpd_uri\", ESP_LOG_DEBUG);\n\n  Serial.begin(115200);\n  delay(10);\n\n  Serial.printf(\"ESP-IDF Version: %s\\n\", esp_get_idf_version());\n\n#ifdef ESP_ARDUINO_VERSION_STR\n  Serial.printf(\"Arduino Version: %s\\n\", ESP_ARDUINO_VERSION_STR);\n#else\n  Serial.printf(\"Arduino Version: %d.%d.%d\\n\", ESP_ARDUINO_VERSION_MAJOR, ESP_ARDUINO_VERSION_MINOR, ESP_ARDUINO_VERSION_PATCH);\n#endif\n  Serial.printf(\"PsychicHttp Version: %s\\n\", PSYCHIC_VERSION_STR);\n\n  // We start by connecting to a WiFi network\n  // To debug, please enable Core Debug Level to Verbose\n  if (connectToWifi()) {\n    // Setup our NTP to get the current time.\n    sntp_set_time_sync_notification_cb(timeAvailable);\n    sntp_servermode_dhcp(1); // (optional)\n    configTime(gmtOffset_sec, daylightOffset_sec, ntpServer1, ntpServer2);\n\n    // set up our esp32 to listen on the psychic.local domain\n    if (MDNS.begin(local_hostname))\n      MDNS.addService(\"http\", \"tcp\", 80);\n    else\n      Serial.println(\"Error starting mDNS\");\n\n    if (!LittleFS.begin()) {\n      Serial.println(\"LittleFS Mount Failed. Do Platform -> Build Filesystem Image and Platform -> Upload Filesystem Image from VSCode\");\n      return;\n    }\n\n#ifdef PSY_ENABLE_SSL\n    // look up our keys?\n    if (app_enable_ssl) {\n      File fp = LittleFS.open(\"/server.crt\");\n      if (fp) {\n        server_cert = fp.readString();\n\n        // Serial.println(\"Server Cert:\");\n        // Serial.println(server_cert);\n      } else {\n        Serial.println(\"server.pem not found, SSL not available\");\n        app_enable_ssl = false;\n      }\n      fp.close();\n\n      File fp2 = LittleFS.open(\"/server.key\");\n      if (fp2) {\n        server_key = fp2.readString();\n\n        // Serial.println(\"Server Key:\");\n        // Serial.println(server_key);\n      } else {\n        Serial.println(\"server.key not found, SSL not available\");\n        app_enable_ssl = false;\n      }\n      fp2.close();\n    }\n\n    // do we want secure or not?\n    if (app_enable_ssl) {\n      server.setCertificate(server_cert.c_str(), server_key.c_str());\n\n      // this creates a 2nd server listening on port 80 and redirects all requests HTTPS\n      PsychicHttpServer* redirectServer = new PsychicHttpServer();\n      redirectServer->config.ctrl_port = 20424; // just a random port different from the default one\n      redirectServer->config.stack_size = 4096; // we dont need a large stack size for this.\n      redirectServer->onNotFound([](PsychicRequest* request, PsychicResponse* response) {\n        String url = \"https://\" + request->host() + request->url();\n        return response->redirect(url.c_str()); });\n      redirectServer->start();\n    }\n#endif\n\n    DefaultHeaders::Instance().addHeader(\"Server\", \"PsychicHttp\");\n\n    loggingMiddleware.setOutput(Serial);\n\n    basicAuth.setUsername(app_user);\n    basicAuth.setPassword(app_pass);\n    basicAuth.setRealm(app_name);\n    basicAuth.setAuthMethod(HTTPAuthMethod::BASIC_AUTH);\n    basicAuth.setAuthFailureMessage(\"You must log in.\");\n\n    digestAuth.setUsername(app_user);\n    digestAuth.setPassword(app_pass);\n    digestAuth.setRealm(app_name);\n    digestAuth.setAuthMethod(HTTPAuthMethod::DIGEST_AUTH);\n    digestAuth.setAuthFailureMessage(\"You must log in.\");\n\n    // corsMiddleware.setAllowCredentials(true);\n    // corsMiddleware.setOrigin(\"http://www.example.com,https://www.example.com,http://api.example.com,https://api.example.com\");\n    // corsMiddleware.setHeaders(\"Origin,X-Requested-With,Content-Type,Accept,Content-Type,Authorization,X-Access-Token\");\n\n    server.addMiddleware(&loggingMiddleware);\n    // this will send CORS headers on every HTTP_OPTIONS request that contains the Origin: header\n    server.addMiddleware(&corsMiddleware);\n\n    // rewrites!\n    server.rewrite(\"/rewrite\", \"/api?foo=rewrite\");\n\n    // serve static files from LittleFS/www on / only to clients on same wifi network\n    // this is where our /index.html file lives\n    //  curl -i http://psychic.local/\n    server.serveStatic(\"/\", LittleFS, \"/www/\")\n      ->setCacheControl(\"max-age=60\")\n      ->addFilter(ON_STA_FILTER);\n\n    // serve static files from LittleFS/www-ap on / only to clients on SoftAP\n    // this is where our /index.html file lives\n    server.serveStatic(\"/\", LittleFS, \"/www-ap/\")->addFilter(ON_AP_FILTER);\n\n    // serve static files from LittleFS/img on /img\n    // it's more efficient to serve everything from a single www directory, but this is also possible.\n    //  curl -i http://psychic.local/img/request_flow.png\n    server.serveStatic(\"/img\", LittleFS, \"/img/\");\n\n#ifdef PSY_ENABLE_SDCARD\n    // if we detect an SD card, serve all files from sd:/ on http://psychic.local/sd\n    if (setupSDCard())\n      server.serveStatic(\"/sd\", SD, \"/\");\n#endif\n\n    // you can also serve single files\n    //  curl -i http://psychic.local/myfile.txt\n    server.serveStatic(\"/myfile.txt\", LittleFS, \"/custom.txt\");\n\n    // example callback everytime a connection is opened\n    server.onOpen([](PsychicClient* client) { Serial.printf(\"[http] connection #%u connected from %s\\n\", client->socket(), client->remoteIP().toString().c_str()); });\n\n    // example callback everytime a connection is closed\n    server.onClose([](PsychicClient* client) { Serial.printf(\"[http] connection #%u closed\\n\", client->socket()); });\n\n    // api - json message passed in as post body\n    //  curl -i -X POST -H \"Content-Type: application/json\" -d '{\"foo\":\"bar\"}' http://psychic.local/api\n    server.on(\"/api\", HTTP_POST, [](PsychicRequest* request, PsychicResponse* resp, JsonVariant& json) {\n      JsonObject input = json.as<JsonObject>();\n\n      // create our response json\n      PsychicJsonResponse response(resp);\n      JsonObject output = response.getRoot();\n\n      output[\"msg\"] = \"status\";\n      output[\"status\"] = \"success\";\n      output[\"millis\"] = millis();\n      output[\"method\"] = request->methodStr();\n\n      // work with some params\n      if (input.containsKey(\"foo\")) {\n        String foo = input[\"foo\"];\n        output[\"foo\"] = foo;\n      }\n\n      return response.send();\n    });\n\n    // ip - get info about the client\n    //  curl -i http://psychic.local/ip\n    server.on(\"/ip\", HTTP_GET, [](PsychicRequest* request, PsychicResponse* response) {\n      String output = \"Your IP is: \" + request->client()->remoteIP().toString();\n      return response->send(output.c_str());\n    });\n\n    // client connect/disconnect to a url\n    //  curl -i http://psychic.local/handler\n    PsychicWebHandler* connectionHandler = new PsychicWebHandler();\n    connectionHandler->onRequest([](PsychicRequest* request, PsychicResponse* response) { return response->send(\"OK\"); });\n    connectionHandler->onOpen([](PsychicClient* client) { Serial.printf(\"[handler] connection #%u connected from %s\\n\", client->socket(), client->remoteIP().toString().c_str()); });\n    connectionHandler->onClose([](PsychicClient* client) { Serial.printf(\"[handler] connection #%u closed\\n\", client->socket()); });\n\n    // add it to our server\n    server.on(\"/handler\", connectionHandler);\n\n    // api - parameters passed in via query eg. /api?foo=bar\n    //  curl -i 'http://psychic.local/api?foo=bar'\n    server.on(\"/api\", HTTP_GET, [](PsychicRequest* request, PsychicResponse* resp) {\n      // create our response json\n      PsychicJsonResponse response = PsychicJsonResponse(resp);\n      JsonObject output = response.getRoot();\n\n      output[\"msg\"] = \"status\";\n      output[\"status\"] = \"success\";\n      output[\"millis\"] = millis();\n      output[\"method\"] = request->methodStr();\n\n      // work with some params\n      if (request->hasParam(\"foo\")) {\n        String foo = request->getParam(\"foo\")->value();\n        output[\"foo\"] = foo;\n      }\n\n      return response.send();\n    });\n\n    // curl -i -X GET 'http://psychic.local/any'\n    // curl -i -X POST 'http://psychic.local/any'\n    server.on(\"/any\", HTTP_ANY, [](PsychicRequest* request, PsychicResponse* resp) {\n      // create our response json\n      PsychicJsonResponse response = PsychicJsonResponse(resp);\n      JsonObject output = response.getRoot();\n\n      output[\"msg\"] = \"status\";\n      output[\"status\"] = \"success\";\n      output[\"millis\"] = millis();\n      output[\"method\"] = request->methodStr();\n\n      return response.send();\n    });\n\n    // curl -i 'http://psychic.local/simple'\n    server.on(\"/simple\", HTTP_GET, [](PsychicRequest* request, PsychicResponse* response) {\n            return response->send(\"Simple\");\n          })\n      ->setURIMatchFunction(MATCH_SIMPLE);\n\n#ifdef PSY_ENABLE_REGEX\n    // curl -i 'http://psychic.local/regex/23'\n    // curl -i 'http://psychic.local/regex/4223'\n    server.on(\"^/regex/([\\\\d]+)/?$\", HTTP_GET, [](PsychicRequest* request, PsychicResponse* response) {\n            // look up our regex matches\n            std::smatch matches;\n            if (request->getRegexMatches(matches)) {\n              String output;\n              output += \"Matches: \" + String(matches.size()) + \"<br/>\\n\";\n              output += \"Matched URI: \" + String(matches.str(0).c_str()) + \"<br/>\\n\";\n              output += \"Match 1: \" + String(matches.str(1).c_str()) + \"<br/>\\n\";\n\n              return response->send(output.c_str());\n            } else\n              return response->send(\"No regex match.\");\n          })\n      ->setURIMatchFunction(MATCH_REGEX);\n#endif\n\n    // JsonResponse example\n    //  curl -i http://psychic.local/json\n    server.on(\"/json\", HTTP_GET, [](PsychicRequest* request, PsychicResponse* response) {\n      PsychicJsonResponse jsonResponse = PsychicJsonResponse(response);\n\n      char key[16];\n      char value[32];\n      JsonObject root = jsonResponse.getRoot();\n      for (int i = 0; i < 100; i++) {\n        sprintf(key, \"key%d\", i);\n        sprintf(value, \"value is %d\", i);\n        root[key] = value;\n      }\n\n      return jsonResponse.send();\n    });\n\n    // how to redirect a request\n    //  curl -i  http://psychic.local/redirect\n    server.on(\"/redirect\", HTTP_GET, [](PsychicRequest* request, PsychicResponse* response) { return response->redirect(\"/alien.png\"); });\n\n    // how to do basic auth\n    //  curl -i --user admin:admin http://psychic.local/auth-basic\n    server.on(\"/auth-basic\", HTTP_GET, [](PsychicRequest* request, PsychicResponse* response) {\n            return response->send(\"Auth Basic Success!\");\n          })\n      ->addMiddleware(&basicAuth);\n\n    // how to do digest auth\n    //  curl -i --user admin:admin http://psychic.local/auth-digest\n    server.on(\"/auth-digest\", HTTP_GET, [](PsychicRequest* request, PsychicResponse* response) {\n            return response->send(\"Auth Digest Success!\");\n          })\n      ->addMiddleware(&digestAuth);\n\n    // example of getting / setting cookies\n    //  curl -i -b cookie.txt -c cookie.txt http://psychic.local/cookies\n    server.on(\"/cookies\", HTTP_GET, [](PsychicRequest* request, PsychicResponse* response) {\n      int counter = 0;\n      char cookie[14];\n      size_t size = sizeof(cookie);\n      if (request->getCookie(\"counter\", cookie, &size) == ESP_OK) {\n        // value is null-terminated.\n        counter = std::stoi(cookie);\n        counter++;\n      }\n      sprintf(cookie, \"%d\", counter);\n\n      response->setCookie(\"counter\", cookie);\n      response->setContent(cookie);\n      return response->send();\n    });\n\n    // example of getting POST variables\n    //  curl -i -d \"param1=value1&param2=value2\" -X POST http://psychic.local/post\n    //  curl -F \"param1=value1\" -F \"param2=value2\" -X POST http://psychic.local/post\n    server.on(\"/post\", HTTP_POST, [](PsychicRequest* request, PsychicResponse* response) {\n      String output;\n      output += \"Param 1: \" + request->getParam(\"param1\")->value() + \"<br/>\\n\";\n      output += \"Param 2: \" + request->getParam(\"param2\")->value() + \"<br/>\\n\";\n\n      return response->send(output.c_str());\n    });\n\n    // you can set up a custom 404 handler.\n    //  curl -i http://psychic.local/404\n    server.onNotFound([](PsychicRequest* request, PsychicResponse* response) { return response->send(404, \"text/html\", \"Custom 404 Handler\"); });\n\n    // handle a very basic upload as post body\n    PsychicUploadHandler* uploadHandler = new PsychicUploadHandler();\n    uploadHandler->onUpload([](PsychicRequest* request, const String& filename, uint64_t index, uint8_t* data, size_t len, bool last) {\n      static File file;\n      String path = \"/www/\" + filename;\n\n      Serial.printf(\"Writing %d/%d bytes to: %s\\n\", (int)index + (int)len, request->contentLength(), path.c_str());\n\n      if (last)\n        Serial.printf(\"%s is finished. Total bytes: %llu\\n\", path.c_str(), (uint64_t)index + (uint64_t)len);\n\n      if (!index)\n        file = LittleFS.open(path, FILE_WRITE);\n\n      if (!file) {\n        Serial.println(\"Failed to open file\");\n        return ESP_FAIL;\n      }\n\n      if (!file.write(data, len)) {\n        Serial.println(\"Write failed\");\n        return ESP_FAIL;\n      }\n\n      if (last)\n        file.close();\n\n      return ESP_OK;\n    });\n\n    // gets called after upload has been handled\n    uploadHandler->onRequest([](PsychicRequest* request, PsychicResponse* response) {\n      String url = \"/\" + request->getFilename();\n      String output = \"<a href=\\\"\" + url + \"\\\">\" + url + \"</a>\";\n\n      return response->send(output.c_str());\n    });\n\n    // wildcard basic file upload - POST to /upload/filename.ext\n    //  use http://psychic.local/ to test\n    server.on(\"/upload/*\", HTTP_POST, uploadHandler);\n\n    // a little bit more complicated multipart form\n    PsychicUploadHandler* multipartHandler = new PsychicUploadHandler();\n    multipartHandler->onUpload([](PsychicRequest* request, const String& filename, uint64_t index, uint8_t* data, size_t len, bool last) {\n      static File file;\n      String path = \"/www/\" + filename;\n\n      // some progress over serial.\n      Serial.printf(\"Writing %d bytes to: %s @ index %llu\\n\", (int)len, path.c_str(), index);\n      if (last)\n        Serial.printf(\"%s is finished. Total bytes: %llu\\n\", path.c_str(), (uint64_t)index + (uint64_t)len);\n\n      if (!index)\n        file = LittleFS.open(path, FILE_WRITE);\n\n      if (!file) {\n        Serial.println(\"Failed to open file\");\n        return ESP_FAIL;\n      }\n\n      if (!file.write(data, len)) {\n        Serial.println(\"Write failed\");\n        return ESP_FAIL;\n      }\n\n      if (last)\n        file.close();\n\n      return ESP_OK;\n    });\n\n    // gets called after upload has been handled\n    multipartHandler->onRequest([](PsychicRequest* request, PsychicResponse* response) {\n      String output;\n      if (request->hasParam(\"file_upload\")) {\n        PsychicWebParameter* file = request->getParam(\"file_upload\");\n\n        String url = \"/\" + file->value();\n        output += \"<a href=\\\"\" + url + \"\\\">\" + url + \"</a><br/>\\n\";\n        output += \"Bytes: \" + String(file->size()) + \"<br/>\\n\";\n      }\n\n      if (request->hasParam(\"param1\"))\n        output += \"Param 1: \" + request->getParam(\"param1\")->value() + \"<br/>\\n\";\n      if (request->hasParam(\"param2\"))\n        output += \"Param 2: \" + request->getParam(\"param2\")->value() + \"<br/>\\n\";\n\n      return response->send(output.c_str());\n    });\n\n    // wildcard basic file upload - POST to /upload/filename.ext\n    //  use http://psychic.local/ to test\n    // just multipart data: curl -F \"param1=multi\" -F \"param2=part\" http://psychic.local/multipart\n    server.on(\"/multipart\", HTTP_POST, multipartHandler);\n\n    // form only multipart handler\n    // curl -F \"param1=multi\" -F \"param2=part\" http://psychic.local/multipart-data\n    PsychicUploadHandler* multipartFormHandler = new PsychicUploadHandler();\n    multipartFormHandler->onRequest([](PsychicRequest* request, PsychicResponse* response) {\n      String output;\n      if (request->hasParam(\"param1\"))\n        output += \"Param 1: \" + request->getParam(\"param1\")->value() + \"<br/>\\n\";\n      if (request->hasParam(\"param2\"))\n        output += \"Param 2: \" + request->getParam(\"param2\")->value() + \"<br/>\\n\";\n\n      return response->send(output.c_str());\n    });\n    server.on(\"/multipart-data\", HTTP_POST, multipartFormHandler);\n\n    // a websocket echo server\n    //  npm install -g wscat\n    // Plaintext: wscat -c ws://psychic.local/ws\n    // SSL: wscat -n -c wss://psychic.local/ws\n    websocketHandler.onOpen([](PsychicWebSocketClient* client) {\n      Serial.printf(\"[socket] connection #%u connected from %s\\n\", client->socket(), client->remoteIP().toString().c_str());\n      client->sendMessage(\"Hello!\");\n    });\n    websocketHandler.onFrame([](PsychicWebSocketRequest* request, httpd_ws_frame* frame) {\n      // Serial.printf(\"[socket] #%d sent: %s\\n\", request->client()->socket(), String((char*)frame->payload, frame->len).c_str());\n      return request->reply(frame);\n    });\n    websocketHandler.onClose([](PsychicWebSocketClient* client) { Serial.printf(\"[socket] connection #%u closed\\n\", client->socket()); });\n    server.on(\"/ws\", &websocketHandler);\n\n    // EventSource server\n    //  curl -i -N http://psychic.local/events\n    eventSource.onOpen([](PsychicEventSourceClient* client) {\n      Serial.printf(\"[eventsource] connection #%u connected from %s\\n\", client->socket(), client->remoteIP().toString().c_str());\n      client->send(\"Hello user!\", NULL, millis(), 1000);\n    });\n    eventSource.onClose([](PsychicEventSourceClient* client) { Serial.printf(\"[eventsource] connection #%u closed\\n\", client->socket()); });\n    server.on(\"/events\", &eventSource);\n\n    // example of using POST data inside the filter\n    // works: curl -F \"secret=password\" http://psychic.local/post-filter\n    // 404:   curl -F \"foo=bar\" http://psychic.local/post-filter\n    server.on(\"/post-filter\", HTTP_POST, [](PsychicRequest* request, PsychicResponse* response) {\n            String output;\n            output += \"Secret: \" + request->getParam(\"secret\")->value() + \"<br/>\\n\";\n\n            return response->send(output.c_str());\n          })\n      ->addFilter([](PsychicRequest* request) {\n        request->loadParams();\n        return request->hasParam(\"secret\");\n      });\n\n    server.begin();\n  }\n}\n\nunsigned long lastUpdate = 0;\nchar output[60];\n\nvoid loop()\n{\n  if (millis() - lastUpdate > 1000) {\n    sprintf(output, \"Millis: %lu\\n\", millis());\n    websocketHandler.sendAll(output);\n\n    sprintf(output, \"%lu\", millis());\n    eventSource.send(output, \"millis\", millis(), 0);\n\n    lastUpdate = millis();\n  }\n\n  // just some dev code to test that starting / stopping the server works okay.\n  // delay(5000);\n  // Serial.println(\"Stopping Server\");\n  // server.stop();\n  // delay(5000);\n  // Serial.println(\"Starting Server\");\n  // server.start();\n}"
  },
  {
    "path": "examples/platformio/src/secret.h",
    "content": "#define WIFI_SSID \"Your_SSID\"\n#define WIFI_PASS \"Your_PASS\""
  },
  {
    "path": "examples/websockets/.gitignore",
    "content": ".pio\n.vscode/\n.vscode/.browse.c_cpp.db*\n.vscode/c_cpp_properties.json\n.vscode/launch.json\n.vscode/ipch\nsrc/_secret.h\nlib/PsychicHttp/"
  },
  {
    "path": "examples/websockets/data/www/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n    <head>\n        <meta charset=\"UTF-8\">\n        <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n        <title>PsychicHTTP Websocket Demo</title>\n        <link rel=\"icon\" href=\"./favicon.ico\" type=\"image/x-icon\">\n    </head>\n    <body>\n        <main>\n            <h1>Websocket Demo</h1>\n            <input type=\"text\" id=\"message_input\" placeholder=\"Type your message\">\n            <button onclick=\"sendMessage()\">Send Message</button>\n            <button onclick=\"websocketConnect()\">Connect</button>\n            <div>\n                <textarea id=\"websocket_output\" style=\"width: 50%; height: 250px;\"></textarea>\n            </div>\n\n            <script>\n                let socket;\n                const outputText = document.getElementById('websocket_output');\n                const messageInput = document.getElementById('message_input');\n\n                function websocketConnect()\n                {\n                    // Create a WebSocket connection\n                    socket = new WebSocket('ws://' + window.location.host + '/ws');\n            \n                    // Event handler for when the WebSocket connection is open\n                    socket.addEventListener('open', (event) => {\n                        outputText.value += `[socket] connection opened!\\n`;\n                        outputText.scrollTop = outputText.scrollHeight;\n                    });\n            \n                    // Event handler for when a message is received from the WebSocket server\n                    socket.addEventListener('message', (event) => {\n                        // Echo the received message into the output div\n                        let data = event.data.trim();\n                        outputText.value += `[received] ${data}\\n`;\n                        outputText.scrollTop = outputText.scrollHeight;\n                    });\n            \n                    // Event handler for when an error occurs with the WebSocket connection\n                    socket.addEventListener('error', (event) => {\n                        let data = event.data.trim();\n                        outputText.value += `[error] ${event.data}\\n`;\n                        outputText.scrollTop = outputText.scrollHeight;\n                    });\n            \n                    // Event handler for when the WebSocket connection is closed\n                    socket.addEventListener('close', (event) => {\n                        outputText.value += `[socket] connection closed!\\n`;\n                    });\n                }\n        \n                // Function to send a message to the WebSocket server\n                function sendMessage() {\n                    if (socket.readyState == WebSocket.OPEN) {\n                        const message = messageInput.value.trim();\n                        if (message) {\n                            socket.send(message);\n                            messageInput.value = ''; // Clear the input field after sending the message\n                            outputText.value += `[sent] ${message}\\n`;\n                            outputText.scrollTop = outputText.scrollHeight;\n                        }\n                    }\n                    else\n                    {\n                        outputText.value += `[error] Not Connected\\n`;\n                        outputText.scrollTop = outputText.scrollHeight;\n                    }\n                }\n            </script>\n        </main>\n    </body>\n</html>"
  },
  {
    "path": "examples/websockets/include/README",
    "content": "\nThis directory is intended for project header files.\n\nA header file is a file containing C declarations and macro definitions\nto be shared between several project source files. You request the use of a\nheader file in your project source file (C, C++, etc) located in `src` folder\nby including it, with the C preprocessing directive `#include'.\n\n```src/main.c\n\n#include \"header.h\"\n\nint main (void)\n{\n ...\n}\n```\n\nIncluding a header file produces the same results as copying the header file\ninto each source file that needs it. Such copying would be time-consuming\nand error-prone. With a header file, the related declarations appear\nin only one place. If they need to be changed, they can be changed in one\nplace, and programs that include the header file will automatically use the\nnew version when next recompiled. The header file eliminates the labor of\nfinding and changing all the copies as well as the risk that a failure to\nfind one copy will result in inconsistencies within a program.\n\nIn C, the usual convention is to give header files names that end with `.h'.\nIt is most portable to use only letters, digits, dashes, and underscores in\nheader file names, and at most one dot.\n\nRead more about using header files in official GCC documentation:\n\n* Include Syntax\n* Include Operation\n* Once-Only Headers\n* Computed Includes\n\nhttps://gcc.gnu.org/onlinedocs/cpp/Header-Files.html\n"
  },
  {
    "path": "examples/websockets/lib/README",
    "content": "\nThis directory is intended for project specific (private) libraries.\nPlatformIO will compile them to static libraries and link into executable file.\n\nThe source code of each library should be placed in a an own separate directory\n(\"lib/your_library_name/[here are source files]\").\n\nFor example, see a structure of the following two libraries `Foo` and `Bar`:\n\n|--lib\n|  |\n|  |--Bar\n|  |  |--docs\n|  |  |--examples\n|  |  |--src\n|  |     |- Bar.c\n|  |     |- Bar.h\n|  |  |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html\n|  |\n|  |--Foo\n|  |  |- Foo.c\n|  |  |- Foo.h\n|  |\n|  |- README --> THIS FILE\n|\n|- platformio.ini\n|--src\n   |- main.c\n\nand a contents of `src/main.c`:\n```\n#include <Foo.h>\n#include <Bar.h>\n\nint main (void)\n{\n  ...\n}\n\n```\n\nPlatformIO Library Dependency Finder will find automatically dependent\nlibraries scanning project source files.\n\nMore information about PlatformIO Library Dependency Finder\n- https://docs.platformio.org/page/librarymanager/ldf.html\n"
  },
  {
    "path": "examples/websockets/platformio.ini",
    "content": "; PlatformIO Project Configuration File\n;\n;   Build options: build flags, source filter\n;   Upload options: custom upload port, speed and extra flags\n;   Library options: dependencies, extra library storages\n;   Advanced options: extra scripting\n;\n; Please visit documentation for the other options and examples\n; https://docs.platformio.org/page/projectconf.html\n\n[env]\nplatform = espressif32\nframework = arduino\nboard = esp32dev\nmonitor_speed = 115200\nmonitor_filters = esp32_exception_decoder\nlib_deps = \n    ; devmode: with this disabled make a symlink from platformio/lib to the PsychicHttp directory\n    ;hoeken/PsychicHttp\n    bblanchon/ArduinoJson\nboard_build.filesystem = littlefs\n\n[env:default]\nbuild_flags =\n    -D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_WARN"
  },
  {
    "path": "examples/websockets/src/main.cpp",
    "content": "/*\n  PsychicHTTP Server Example\n\n  This example code is in the Public Domain (or CC0 licensed, at your option.)\n\n  Unless required by applicable law or agreed to in writing, this\n  software is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n  CONDITIONS OF ANY KIND, either express or implied.\n*/\n\n/**********************************************************************************************\n * Note: this demo relies on various files to be uploaded on the LittleFS partition\n * PlatformIO -> Build Filesystem Image and then PlatformIO -> Upload Filesystem Image\n **********************************************************************************************/\n\n#include \"_secret.h\"\n#include <Arduino.h>\n#include <ArduinoJson.h>\n#include <ESPmDNS.h>\n#include <LittleFS.h>\n#include <PsychicHttp.h>\n#include <WiFi.h>\n#include <esp_sntp.h>\n#include <freertos/queue.h>\n\n#ifndef WIFI_SSID\n  #error \"You need to enter your wifi credentials. Rename secret.h to _secret.h and enter your credentials there.\"\n#endif\n\n// Enter your WIFI credentials in secret.h\nconst char* ssid = WIFI_SSID;\nconst char* password = WIFI_PASS;\n\n// hostname for mdns (psychic.local)\nconst char* local_hostname = \"psychic\";\n\nPsychicHttpServer server;\nPsychicWebSocketHandler websocketHandler;\n\ntypedef struct\n{\n    int socket;\n    char* buffer;\n    size_t len;\n} WebsocketMessage;\n\nQueueHandle_t wsMessages;\n\nbool connectToWifi()\n{\n  Serial.print(\"[WiFi] Connecting to \");\n  Serial.println(ssid);\n\n  // setup our wifi\n  WiFi.mode(WIFI_STA);\n  WiFi.begin(ssid, password);\n\n  // Will try for about 10 seconds (20x 500ms)\n  int tryDelay = 500;\n  int numberOfTries = 20;\n\n  // Wait for the WiFi event\n  while (true)\n  {\n    switch (WiFi.status())\n    {\n      case WL_NO_SSID_AVAIL:\n        Serial.println(\"[WiFi] SSID not found\");\n        break;\n      case WL_CONNECT_FAILED:\n        Serial.print(\"[WiFi] Failed - WiFi not connected! Reason: \");\n        return false;\n        break;\n      case WL_CONNECTION_LOST:\n        Serial.println(\"[WiFi] Connection was lost\");\n        break;\n      case WL_SCAN_COMPLETED:\n        Serial.println(\"[WiFi] Scan is completed\");\n        break;\n      case WL_DISCONNECTED:\n        Serial.println(\"[WiFi] WiFi is disconnected\");\n        break;\n      case WL_CONNECTED:\n        Serial.println(\"[WiFi] WiFi is connected!\");\n        Serial.print(\"[WiFi] IP address: \");\n        Serial.println(WiFi.localIP());\n        return true;\n        break;\n      default:\n        Serial.print(\"[WiFi] WiFi Status: \");\n        Serial.println(WiFi.status());\n        break;\n    }\n    delay(tryDelay);\n\n    if (numberOfTries <= 0)\n    {\n      Serial.print(\"[WiFi] Failed to connect to WiFi!\");\n      // Use disconnect function to force stop trying to connect\n      WiFi.disconnect();\n      return false;\n    }\n    else\n    {\n      numberOfTries--;\n    }\n  }\n\n  return false;\n}\n\nvoid setup()\n{\n  Serial.begin(115200);\n  delay(10);\n\n  // prepare our message queue of 10 messages\n  wsMessages = xQueueCreate(10, sizeof(WebsocketMessage));\n  if (wsMessages == 0)\n    Serial.printf(\"Failed to create queue= %p\\n\", wsMessages);\n\n  // We start by connecting to a WiFi network\n  // To debug, please enable Core Debug Level to Verbose\n  if (connectToWifi())\n  {\n    // set up our esp32 to listen on the local_hostname.local domain\n    if (!MDNS.begin(local_hostname))\n    {\n      Serial.println(\"Error starting mDNS\");\n      return;\n    }\n    MDNS.addService(\"http\", \"tcp\", 80);\n\n    if (!LittleFS.begin())\n    {\n      Serial.println(\"LittleFS Mount Failed. Do Platform -> Build Filesystem Image and Platform -> Upload Filesystem Image from VSCode\");\n      return;\n    }\n\n    // this is where our /index.html file lives\n    //  curl -i http://psychic.local/\n    server.serveStatic(\"/\", LittleFS, \"/www/\");\n\n    // a websocket echo server\n    //  npm install -g wscat\n    //  wscat -c ws://psychic.local/ws\n    websocketHandler.onOpen([](PsychicWebSocketClient* client)\n                            {\n      Serial.printf(\"[socket] connection #%u connected from %s\\n\", client->socket(), client->remoteIP().toString().c_str());\n      client->sendMessage(\"Hello!\"); });\n    websocketHandler.onFrame([](PsychicWebSocketRequest* request, httpd_ws_frame* frame)\n                             {\n      Serial.printf(\"[socket] #%d sent: %s\\n\", request->client()->socket(), (char *)frame->payload);\n\n      //we are allocating memory here, and the worker will free it\n      WebsocketMessage wm;\n      wm.socket = request->client()->socket();\n      wm.len = frame->len;\n      wm.buffer = (char *)malloc(frame->len);\n\n      //did we flame out?\n      if (wm.buffer == NULL)\n      {\n        Serial.printf(\"Queue message: unable to allocate %d bytes\\n\", frame->len);\n        return ESP_FAIL;    \n      }\n\n      //okay, copy it over\n      memcpy(wm.buffer, frame->payload, frame->len); \n\n      //try to throw it in our queue\n      if (xQueueSend(wsMessages, &wm, 1) != pdTRUE)\n      {\n        Serial.printf(\"[socket] queue full #%d\\n\", wm.socket);\n\n        //free the memory... no worker to do it for us.\n        free(wm.buffer);\n      }\n\n      //send a throttle message if we're full\n      if (!uxQueueSpacesAvailable(wsMessages))\n        return request->reply(\"Queue Full\");\n\n      return ESP_OK; });\n    websocketHandler.onClose([](PsychicWebSocketClient* client)\n                             { Serial.printf(\"[socket] connection #%u closed from %s\\n\", client->socket(), client->remoteIP().toString().c_str()); });\n    server.on(\"/ws\", &websocketHandler);\n  }\n}\n\nunsigned long lastUpdate = 0;\nchar output[60];\n\nvoid loop()\n{\n  // process our websockets outside the callback.\n  WebsocketMessage message;\n  while (xQueueReceive(wsMessages, &message, 0) == pdTRUE)\n  {\n    // make sure our client is still good.\n    PsychicWebSocketClient* client = websocketHandler.getClient(message.socket);\n    if (client == NULL)\n    {\n      Serial.printf(\"[socket] client #%d bad, bailing\\n\", message.socket);\n      return;\n    }\n\n    // echo it back to the client.\n    // alternatively, this is where you would deserialize a json message, parse it, and generate a response if needed\n    client->sendMessage(HTTPD_WS_TYPE_TEXT, message.buffer, message.len);\n\n    // make sure to release our memory!\n    free(message.buffer);\n  }\n\n  // send a periodic update to all clients\n  if (millis() - lastUpdate > 2000)\n  {\n    sprintf(output, \"Millis: %lu\\n\", millis());\n    websocketHandler.sendAll(output);\n\n    lastUpdate = millis();\n  }\n}"
  },
  {
    "path": "examples/websockets/src/secret.h",
    "content": "#define WIFI_SSID \"Your_SSID\"\n#define WIFI_PASS \"Your_PASS\""
  },
  {
    "path": "examples/websockets/test/README",
    "content": "\nThis directory is intended for PlatformIO Test Runner and project tests.\n\nUnit Testing is a software testing method by which individual units of\nsource code, sets of one or more MCU program modules together with associated\ncontrol data, usage procedures, and operating procedures, are tested to\ndetermine whether they are fit for use. Unit testing finds problems early\nin the development cycle.\n\nMore information about PlatformIO Unit Testing:\n- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html\n"
  },
  {
    "path": "idf_component.yml",
    "content": "## IDF Component Manager Manifest File\nversion: \"2.2.0\"\nlicense: \"MIT\"\ndescription: \"Asyncronous Webserver library for ESP32 + Arduino framework\"\nurl: \"https://github.com/hoeken/PsychicHttp\"\nrepository: \"https://github.com/hoeken/PsychicHttp\"\ndocumentation: \"https://github.com/hoeken/PsychicHttp\"\ntags:\n  - webserver\n  - websocket\n  - http\n  - https\n\ndependencies:\n  bblanchon/arduinojson: ^7.3.0\n  espressif/arduino-esp32:\n    matches:\n      - if: \"idf_version ^4\"\n        version: \"^2\"\n      - if: \"idf_version ^5.1\"\n        version: \"^3.0\"\n      - if: \"idf_version ^5.4\"\n        version: \"3.2.0\"\n"
  },
  {
    "path": "library.json",
    "content": "{\n  \"name\": \"PsychicHttp\",\n  \"version\": \"2.2.0\",\n  \"description\": \"Arduino style wrapper around ESP-IDF HTTP library. HTTP server with SSL + websockets. Works on esp32 and probably esp8266\",\n  \"keywords\": \"network,http,https,tcp,ssl,tls,websocket,espasyncwebserver\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/hoeken/PsychicHttp\"\n  },\n  \"authors\": [\n    {\n      \"name\": \"Zach Hoeken\",\n      \"email\": \"hoeken@gmail.com\",\n      \"maintainer\": true\n    }\n  ],\n  \"license\": \"MIT\",\n  \"examples\": [\n    {\n      \"name\": \"platformio\",\n      \"base\": \"examples/platformio\",\n      \"files\": [\n        \"src/main.cpp\"\n      ]\n    }\n  ],\n  \"frameworks\": \"arduino\",\n  \"platforms\": \"espressif32\",\n  \"dependencies\": [\n    {\n      \"owner\": \"bblanchon\",\n      \"name\": \"ArduinoJson\",\n      \"version\": \"^7.0.4\"\n    }\n  ],\n  \"export\": {\n    \"include\": [\n      \"examples/platformio\",\n      \"src\",\n      \"library.json\",\n      \"library.properties\",\n      \"LICENSE\",\n      \"README.md\"\n    ]\n  }\n}"
  },
  {
    "path": "library.properties",
    "content": "name=PsychicHttp\nversion=2.2.0\nauthor=Zach Hoeken <hoeken@gmail.com>\nmaintainer=Zach Hoeken <hoeken@gmail.com>\nsentence=PsychicHttp is a robust webserver that supports http/https + websockets.\nparagraph=This library is based on the ESP-IDF HTTP Server library which is asynchronous, does http / https+ssl and supports websockets.\ncategory=Communication\narchitectures=esp32\nurl=https://github.com/hoeken/PsychicHttp\nincludes=PsychicHttp.h\ndepends=ArduinoJson"
  },
  {
    "path": "middleware.md",
    "content": "# PsychicHandler\n\n- [x] create addMiddleware()\n- [x] create runMiddleware()\n- [ ] move all the handler::canHandle() stuff into filter();\n  - [ ] canHandle should be declared static\n\n# PsychicEndpoint\n\n- [ ] convert setAuthentication() to add AuthMiddleware instead.\n\n## PsychicHttpServer\n\n- [ ] add _chain\n- [ ] create addMiddleware()\n- [ ] create runMiddleware()\n- [ ] create removeMiddleware(name)\n- [ ] _filters -> _middleware\n- [ ] destructor / cleanup\n\n# PsychicRequest\n\n- [ ] add _response pointer to PsychicRequest, created in constructor\n- [ ] request->beginReply() should return existing _response pointer\n- [ ] requestAuthentication() -> should move to response?\n\n# PsychicResponse\n\n- how do we have extended classes when we have a pre-declared base PsychicResponse object?\n  - the delegation style is really ugly and causes problems with inheritance\n"
  },
  {
    "path": "partitions-4MB.csv",
    "content": "# Name   ,Type ,SubType  ,Offset ,Size  ,Flags\nnvs      ,data ,nvs      ,36K    ,20K   ,\notadata  ,data ,ota      ,56K    ,8K    ,\napp0     ,app  ,ota_0    ,64K    ,1856K  ,\napp1     ,app  ,ota_1    ,1920K  ,1856K ,\nspiffs   ,data ,spiffs   ,3776K  ,256K   ,\ncoredump ,data ,coredump ,4032K  ,64K   ,\n"
  },
  {
    "path": "platformio.ini",
    "content": "; PlatformIO Project Configuration File\n;\n;   Build options: build flags, source filter\n;   Upload options: custom upload port, speed and extra flags\n;   Library options: dependencies, extra library storages\n;   Advanced options: extra scripting\n;\n; Please visit documentation for the other options and examples\n; https://docs.platformio.org/page/projectconf.html\n[platformio]\nlib_dir = .\nsrc_dir = examples/platformio/src\ndata_dir = examples/platformio/data\n\n; src_dir = examples/websockets/src\n; data_dir = examples/websockets/data\n\n; src_dir = examples/arduino\n; data_dir = examples/arduino/data\n\n; src_dir = examples/arduino/arduino_captive_portal\n; data_dir = examples/arduino/arduino_captive_portal/data\n\n; src_dir = examples/arduino/arduino_ota\n; data_dir = examples/arduino/arduino_ota/data\n\n[env]\nplatform = espressif32\nframework = arduino\nboard = esp32-s3-devkitc-1\nmonitor_speed = 115200\nmonitor_filters = esp32_exception_decoder\nboard_upload.flash_size = 8MB\nboard_build.partitions = default_8MB.csv\nboard_build.filesystem = littlefs\nlib_deps = \n    bblanchon/ArduinoJson\nlib_ignore =\n    examples\nbuild_flags =\n    -Wall\n    -Wextra\n    -Og\n    -D CONFIG_ARDUHAL_LOG_COLORS\n    -D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_VERBOSE\n\n[env:arduino2]\nplatform = espressif32@6.8.1\n\n[env:arduino2-ssl]\nplatform = espressif32@6.8.1\nbuild_flags = -DPSY_ENABLE_SSL\n\n[env:arduino2-regex]\nplatform = espressif32@6.8.1\nbuild_flags = -DPSY_ENABLE_REGEX\n\n[env:arduino3]\nplatform = https://github.com/pioarduino/platform-espressif32/releases/download/stable/platform-espressif32.zip\n\n[env:arduino3-ssl]\nplatform = https://github.com/pioarduino/platform-espressif32/releases/download/stable/platform-espressif32.zip\nbuild_flags = -DPSY_ENABLE_SSL\n\n[env:arduino3-regex]\nplatform = https://github.com/pioarduino/platform-espressif32/releases/download/stable/platform-espressif32.zip\nbuild_flags = -D PSY_ENABLE_REGEX\n\n[env:pioarduino-c6]\nplatform = https://github.com/pioarduino/platform-espressif32/releases/download/stable/platform-espressif32.zip\nboard = esp32-c6-devkitc-1\n\n[env:mathieu]\nplatform = https://github.com/pioarduino/platform-espressif32/releases/download/stable/platform-espressif32.zip\nboard = esp32dev\nlib_deps = ${env.lib_deps}\n    ; bblanchon/ArduinoTrace@^1.2.0\nbuild_flags = ${env.build_flags}\n    ; -D PSY_DEVMODE\n    ; -D PSY_ENABLE_REGEX\n    -D PSY_ENABLE_SSL\n\n[env:hoeken]\nplatform = https://github.com/pioarduino/platform-espressif32/releases/download/stable/platform-espressif32.zip\nboard = esp32-s3-devkitc-1\nlib_deps = ${env.lib_deps}\n    bblanchon/ArduinoTrace@^1.2.0\nbuild_flags = ${env.build_flags}\n    -D PSY_DEVMODE\n\n[env:ci]\nplatform = ${sysenv.PIO_PLATFORM}\nboard = ${sysenv.PIO_BOARD}"
  },
  {
    "path": "request flow.drawio",
    "content": "<mxfile host=\"Electron\" modified=\"2023-12-09T15:02:09.427Z\" agent=\"5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/20.8.10 Chrome/106.0.5249.199 Electron/21.3.5 Safari/537.36\" etag=\"cOtONeHkqmkM2fyBsENB\" version=\"20.8.10\" type=\"device\" pages=\"2\"><diagram id=\"C5RBs43oDa-KdzZeNtuy\" name=\"Request Flow\">7Vxbd5s4EP41Pmf3wTkgAcaPza3Zbq/bbNM+yiAbNhi5ICd2f/0KIxmQFIypsZ1jpw+1hBCS5pv5ZgaJHryaLt4maBZ8ID6OesDwFz143QPANIDD/stqlnnNwIJ5xSQJfd6oqPga/sLiTl47D32cVhpSQiIazqqVHolj7NFKHUoS8lxtNiZR9akzNMFKxVcPRWrtQ+jTIK91waCov8PhJBBPNp1hfmWKRGM+kzRAPnkuVcGbHrxKCKH5r+niCkfZ4ol1efhr+RC9f3TevvuS/kT/Xv59//FbP+/sdptb1lNIcExbd+0/B97S/uJ9MrxvX76P0/f9+Gff5MvwhKI5XzA+WboUK5iQeezjrBezBy+fg5DirzPkZVefGWZYXUCnEb+8XiSDFcYkphwRbL3ZRXZbGE9Y0c6uhlF0RSKSrB4Dx3b2j99Vqs//srtpQh5x6Yqz+mNXGq4PX8cnnFC8KKGDr9dbTKaYJkvWRFwVIObYN21efi6QZA95XVBCkevwSsTRO1n3XUiI/eBC0gvsevkufbie3t/Yd9blDfz0bvHQ70NzG4EZVeH8hyldcoGgOSWsiiQ0IBMSo+g9ITPeriQ3Myvj2H+TqSIrjyLiPeZVt2E29NUzWIm3d9eCEtqmoCJCIxxdIu9xshqoEGhMYpx15TP15XMpBndT1LKHsYX8nnV2YYvij/VAWOF6USktRWkR0tJtrPSDDy/7XdyUFcQ9KUUJFXPnI9wObSmZJx6uUUEuP/agCaZ1kueQyhaoFrwJjhANn6r2TwdEfutnErKJrEEPbFgBPRyCahf5jPhdZYOzoSPbkDrKp6x0tNKL9XwaqYpWAODkNaU9UrXtoIpUbTtn10BtajHrRl2Cwd39/WdW8w/+Occp/T2+KwOAzfFyEqE0XRuPWulK/Ocj7I49Lc95Lh6Nu+Q5t6qpQGhqiedMoOE5awc0p52CpQjtB3MiT0x92xLdjtXeaaj2ptlQ7znq+sYFgIZbQV7f5N53WxITTch4nOJ6foKGdVB+shWMfyQKxDej5FUrQTdQ3YhA4c8b+wObVTWxljHYK9gcBWw3sT/jY/yAqBdkELpVTWxApqN52iLwu0XTMMpme4ejJ0xDD2noEkXhJGYFj8kfJ3o0rYNGpyjdr9DLaEINI8dj4Glp1HdGjt1puDiUPGdnoNKooQsXu6JRU40WP6dLLwi9OxT7EVvxs/MjOz+2uUfnRxvpaaR2it5Pi3B9/x6TXoCamH5XLpMNoC25TPtjMcuQWAxILNY2N2ANm9EhwydalpqtGCzVTErQrmSSLRfUj0um6Wp79iMfQVturoVLSd9XjJyxHnAiBqDLEbPUzoSuoOqgaWaH41Ga/ScM+Zm7f4sFZP9sr9ytR4WauLjGYzSPMrgWztvJ87cle12udWE3ZHC7K9mp+YvTi+0KMq5QccHMOyHjjXlzoUdHGBRam4LCpnQKZTo1O4su9Wus5jLOHuur8lib5vZbeKyOpST5Duix2m1VTNJVW3Z9d+Sx2rIqH6XHqqaTPuJnVnGV7+IISax1SA/jnBwyJSS/WXEbJhdAZ26luuMjxQmb0QWJP81wnAkRRdGImcFjkZ9vY9e3dPJzwQh2ugMEwqrpAoODJ4eGivxUx7KgRS9b9dCriqbKw4K2zBJpFRS2iba69O0205bm3VQt6jfSVnlnj0as9m8y1xpWktEWsNqalVw5ISN11LHjB9QgtUQBzJREJH3hxcLJc4Fra1IMe+UCoIapQZ5OYmSwEp2af1qTxQvXBXnUef8nwx6Sb+ZCt2lqQnZTdydzNVQ7Xf4AmrCnVlOOlD9Mw2ob1khGadgwEb8rAhG7GktwvA3jMA2OxXyMXQ/rCWPk2pa9PSjbE8YQNCSMzpxPCGoIg0cPPaC8o0hn2AvHzIoAwzvTw4v0MBCm+HDyVd25kyAH7cZstyE3CKU4Fm4wq6hybPNiWP5rSRTWVt3ujja0smmA0y6Tzes3HK9ub2ibHHV7vapNIZcVq+5kROcHHuTMrt0yGJc7GkCwV6VQXSnGdRQnf/yZ0fI5Bte4VPY+87H6E3iK0DwU55s6znJ7UW4OPLTcVE+YcUnAph16iJ5FVyO6g6ucmvVK8qNAbwoJhiTOZHgc0sMmi1IGOukNnQFE+4xRtNKzzD1K70TzV03PjtYh/kgjlIHV0uFSAmi5o44dLleBYp4N4ScLzwZEY/4HB2du9QVqgtMZiVN8kTLLcZaaRmpu00MR3fnJanRzULu/r+1adfZ8o90fHrfdbxtoy9sdlY52tRdLvPYRzg//FMJL45LbD7bcuzXY8d4tvSKpkcvpKpKhKlLtEY1j1ST56HJTTbLEkQaxed6W7PeONMmxqs8RX815aVxyewjr28vnfKT2HWnSkb0tOagmNd6Of9ya5LTXJAmBg272B8uaIcqvW5PUlIw4p0zprFf6VotxGzFlkrWMebW0qldVl5m/Vin717xKOcSW+cihh6I3/MI09P3VGxed21/VXuVzZ8q30PiIre10r7nbDiTh6T7kAsUOj7I2we3ddlYsvn2XA6H4giC8+R8=</diagram><diagram name=\"Standard Handlers\" id=\"NiY0WBS-fA4Nieu9lBZ8\">7Vtbc5s4FP41ntk+tGMQAvyYOLdNp9NOvTttn3ZkkDGNQA7It/z6FUayBcK3xNhMA34I5+iCdL5P5xwJ0gH9aHGfoMn4C/Ux6Zhdf9EBNx3TNLqmzf9kmmWucSyQK4Ik9EWljWIQvmDZUminoY/TQkVGKWHhpKj0aBxjjxV0KEnovFhtREnxqRMUYE0x8BDRtT9Cn41zrWs6G/0DDoOxfLJh9/KSCMnKYibpGPl0rqjAbQf0E0pZfhct+phkxpN2ue69/J493t0Yzy/92Xf/3v3nKviYd3Z3TJP1FBIcs9N2beZdzxCZCnuJubKlNGBCp7GPs06MDriej0OGBxPkZaVzThmuG7OIiOK1jbpcGNGYCUJwc/NC3iyMAy7CrDQkpE8JTVaPASOY/UQrRZ9fWWuW0CeslNiri5dEdIaGq+FmQ0hwGr6oMmWIKTInOFZl7IeqKHioaA60vkBphhOGFwr3BBr3mEaYJUteRZTyueVNxMoCUBBtvuEpsIVurHDUcoQSibURrPve4M9vBAWOoENPo8MPPHxAsU9w8jZiKFwwuE2uA4LSVPAkR1auTp1GRaL4CLsjr5IQnouHozoRc7sFxCwANcQMswqxugCTA1AQE3Clq2HxUZndPiJkiLynVIOQz5uVFnDBqDGNcQkBoUIkDGIuetzEnBvgOrNiyN3ulSiIQt/PHlNJjA11yn4CVjoRMWKrNmANWFyKbsVS7Dk6sOAEwBqfH8jEnz7+9yv4m4HH5+gruhe+XMWVxt/x8xSn7K8PjVmKELu+VbUUXXMIVr65LsQsGcDlUrQOXIpmXYgZGmIaTDj2r7KUJls3mdFDr4hMcVlwiyXLn6rwKxM+QSneLNTCm6WUFiH7KYMbv1dacWnTKBNkm+NgSuk08fD+OMJQEmC2w2YCC+wXcjgddAVUWIGp1CWYIBbOiplfFdDiCd9oyKercKrk3iEsdpHPW7RSU61yR3axI2Bbn3rqVew2N5PW7YqFayO8nph6jseD+oB6T5i1oX1baLfNM4b2SthARQT4OsFx6/4r3L/dvbT7tyrguktQhFu8qvA6NHOuDS89caZxn9C0xasSL/vSeNnvM73aFdH3pldWs9IroxhiofHa9Ao4uzuqOaFymkLF42i1ly6gWXTpljIy60R0sctp/Ra6cADRUqk2ySqkh/NbDnjruMr1jUJ9fpOP4KTcdf9Q7sJ3wl2zodx1zsBd/XT63wmhyG93sdt2sevIeLFdrORJe5B5YKYNL3+Q+U5PMnf5nL3xR/K8KQGodJQJwYmOMi3rNUeZbw1HcviHhiMIzxCODLPCteURqfVsVZ7t4md0hn5IdyHPdpzN93sfs1nep3sq71Pe6dvnSX+P9jfn2LoZ+pHl7YzzZ5DHsKY4nOZkv845P8+ohkw/tWxf4mwNEM6h79zqCxD68Uj7VmAHYBd/K2Dq28s/JKLbjY7ozqs/jQBbKFRzRHfgcRHdAWeI6GZjdtqnZq/7TthbTmybwt63HcdycfNZe159888B4PZ/</diagram></mxfile>"
  },
  {
    "path": "src/ChunkPrinter.cpp",
    "content": "\n#include \"ChunkPrinter.h\"\n\nChunkPrinter::ChunkPrinter(PsychicResponse* response, uint8_t* buffer, size_t len) : _response(response),\n                                                                                     _buffer(buffer),\n                                                                                     _length(len),\n                                                                                     _pos(0)\n{\n}\n\nChunkPrinter::~ChunkPrinter()\n{\n  flush();\n}\n\nsize_t ChunkPrinter::write(uint8_t c)\n{\n  esp_err_t err;\n\n  // if we're full, send a chunk\n  if (_pos == _length)\n  {\n    _pos = 0;\n    err = _response->sendChunk(_buffer, _length);\n\n    if (err != ESP_OK)\n      return 0;\n  }\n\n  _buffer[_pos] = c;\n  _pos++;\n  return 1;\n}\n\nsize_t ChunkPrinter::write(const uint8_t* buffer, size_t size)\n{\n  size_t written = 0;\n\n  while (written < size)\n  {\n    size_t space = _length - _pos;\n    size_t blockSize = std::min(space, size - written);\n\n    memcpy(_buffer + _pos, buffer + written, blockSize);\n    _pos += blockSize;\n\n    if (_pos == _length)\n    {\n      _pos = 0;\n\n      if (_response->sendChunk(_buffer, _length) != ESP_OK)\n        return written;\n    }\n    written += blockSize; // Update if sent correctly.\n  }\n  return written;\n}\n\nvoid ChunkPrinter::flush()\n{\n  if (_pos)\n  {\n    _response->sendChunk(_buffer, _pos);\n    _pos = 0;\n  }\n}\n\nsize_t ChunkPrinter::copyFrom(Stream& stream)\n{\n  size_t count = 0;\n\n  while (stream.available())\n  {\n\n    if (_pos == _length)\n    {\n      _response->sendChunk(_buffer, _length);\n      _pos = 0;\n    }\n\n    size_t readBytes = stream.readBytes(_buffer + _pos, _length - _pos);\n    _pos += readBytes;\n    count += readBytes;\n  }\n  return count;\n}"
  },
  {
    "path": "src/ChunkPrinter.h",
    "content": "#ifndef ChunkPrinter_h\n#define ChunkPrinter_h\n\n#include \"PsychicResponse.h\"\n#include <Print.h>\n\nclass ChunkPrinter : public Print\n{\n  private:\n    PsychicResponse* _response;\n    uint8_t* _buffer;\n    size_t _length;\n    size_t _pos;\n\n  public:\n    ChunkPrinter(PsychicResponse* response, uint8_t* buffer, size_t len);\n    ~ChunkPrinter();\n\n    size_t write(uint8_t c) override;\n    size_t write(const uint8_t* buffer, size_t size) override;\n\n    size_t copyFrom(Stream& stream);\n\n    void flush() override;\n};\n\n#endif"
  },
  {
    "path": "src/MultipartProcessor.cpp",
    "content": "#include \"MultipartProcessor.h\"\n#include \"PsychicRequest.h\"\n\nenum\n{\n  EXPECT_BOUNDARY,\n  PARSE_HEADERS,\n  WAIT_FOR_RETURN1,\n  EXPECT_FEED1,\n  EXPECT_DASH1,\n  EXPECT_DASH2,\n  BOUNDARY_OR_DATA,\n  DASH3_OR_RETURN2,\n  EXPECT_FEED2,\n  PARSING_FINISHED,\n  PARSE_ERROR\n};\n\nMultipartProcessor::MultipartProcessor(PsychicRequest* request, PsychicUploadCallback uploadCallback) : _request(request),\n                                                                                                        _uploadCallback(uploadCallback),\n                                                                                                        _temp(),\n                                                                                                        _parsedLength(0),\n                                                                                                        _multiParseState(EXPECT_BOUNDARY),\n                                                                                                        _boundaryPosition(0),\n                                                                                                        _itemStartIndex(0),\n                                                                                                        _itemSize(0),\n                                                                                                        _itemName(),\n                                                                                                        _itemFilename(),\n                                                                                                        _itemType(),\n                                                                                                        _itemValue(),\n                                                                                                        _itemBuffer(0),\n                                                                                                        _itemBufferIndex(0),\n                                                                                                        _itemIsFile(false)\n{\n}\nMultipartProcessor::~MultipartProcessor() {}\n\nesp_err_t MultipartProcessor::process()\n{\n  esp_err_t err = ESP_OK;\n\n  _parsedLength = 0;\n\n  String value = _request->header(\"Content-Type\");\n  if (value.startsWith(\"multipart/\"))\n  {\n    _boundary = value.substring(value.indexOf('=') + 1);\n    _boundary.replace(\"\\\"\", \"\");\n  }\n  else\n  {\n    ESP_LOGE(PH_TAG, \"No multipart boundary found.\");\n    return ESP_ERR_HTTPD_INVALID_REQ;\n  }\n\n  char* buf = (char*)malloc(FILE_CHUNK_SIZE);\n  int received;\n  unsigned long index = 0;\n\n  /* Content length of the request gives the size of the file being uploaded */\n  int remaining = _request->contentLength();\n\n  while (remaining > 0)\n  {\n#ifdef ENABLE_ASYNC\n    httpd_sess_update_lru_counter(request->server()->server, request->client()->socket());\n#endif\n\n    /* Receive the file part by part into a buffer */\n    if ((received = httpd_req_recv(_request->request(), buf, min(remaining, FILE_CHUNK_SIZE))) <= 0)\n    {\n      /* Retry if timeout occurred */\n      if (received == HTTPD_SOCK_ERR_TIMEOUT)\n        continue;\n      // bail if we got an error\n      else if (received == HTTPD_SOCK_ERR_FAIL)\n      {\n        ESP_LOGE(PH_TAG, \"Socket error\");\n        err = ESP_FAIL;\n        break;\n      }\n    }\n\n    // parse it 1 byte at a time.\n    for (int i = 0; i < received; i++)\n    {\n      /* Keep track of remaining size of the file left to be uploaded */\n      remaining--;\n      index++;\n\n      // send it to our parser\n      _parseMultipartPostByte(buf[i], !remaining);\n      _parsedLength++;\n    }\n  }\n\n  // dont forget to free our buffer\n  free(buf);\n\n  return err;\n}\n\nesp_err_t MultipartProcessor::process(const char* body)\n{\n  esp_err_t err = ESP_OK;\n  _parsedLength = 0;\n\n  String value = _request->header(\"Content-Type\");\n  if (value.startsWith(\"multipart/\"))\n  {\n    _boundary = value.substring(value.indexOf('=') + 1);\n    _boundary.replace(\"\\\"\", \"\");\n  }\n  else\n  {\n    ESP_LOGE(PH_TAG, \"No multipart boundary found.\");\n    return ESP_ERR_HTTPD_INVALID_REQ;\n  }\n\n  // loop over the whole string\n  unsigned int size = strlen(body);\n  for (unsigned i = 0; i < size; i++)\n  {\n    // send it to our parser\n    _parseMultipartPostByte(body[i], i == size - 1);\n    _parsedLength++;\n  }\n\n  return err;\n}\n\nvoid MultipartProcessor::_handleUploadByte(uint8_t data, bool last)\n{\n  _itemBuffer[_itemBufferIndex++] = data;\n\n  if (last || _itemBufferIndex == FILE_CHUNK_SIZE)\n  {\n    if (_uploadCallback)\n      _uploadCallback(_request, _itemFilename, _itemSize - _itemBufferIndex, _itemBuffer, _itemBufferIndex, last);\n\n    _itemBufferIndex = 0;\n  }\n}\n\n#define itemWriteByte(b)          \\\n  do                              \\\n  {                               \\\n    _itemSize++;                  \\\n    if (_itemIsFile)              \\\n      _handleUploadByte(b, last); \\\n    else                          \\\n      _itemValue += (char)(b);    \\\n  } while (0)\n\nvoid MultipartProcessor::_parseMultipartPostByte(uint8_t data, bool last)\n{\n  if (_multiParseState == PARSE_ERROR)\n  {\n    // not sure we can end up with an error during buffer fill, but jsut to be safe\n    if (_itemBuffer != NULL)\n    {\n      free(_itemBuffer);\n      _itemBuffer = NULL;\n    }\n\n    return;\n  }\n\n  if (!_parsedLength)\n  {\n    _multiParseState = EXPECT_BOUNDARY;\n    _temp = String();\n    _itemName = String();\n    _itemFilename = String();\n    _itemType = String();\n  }\n\n  if (_multiParseState == WAIT_FOR_RETURN1)\n  {\n    if (data != '\\r')\n    {\n      itemWriteByte(data);\n    }\n    else\n    {\n      _multiParseState = EXPECT_FEED1;\n    }\n  }\n  else if (_multiParseState == EXPECT_BOUNDARY)\n  {\n    if (_parsedLength < 2 && data != '-')\n    {\n      ESP_LOGE(PH_TAG, \"Multipart: No boundary\");\n      _multiParseState = PARSE_ERROR;\n      return;\n    }\n    else if (_parsedLength - 2 < _boundary.length() && _boundary.c_str()[_parsedLength - 2] != data)\n    {\n      ESP_LOGE(PH_TAG, \"Multipart: Multipart malformed\");\n      _multiParseState = PARSE_ERROR;\n      return;\n    }\n    else if (_parsedLength - 2 == _boundary.length() && data != '\\r')\n    {\n      ESP_LOGE(PH_TAG, \"Multipart: Multipart missing carriage return\");\n      _multiParseState = PARSE_ERROR;\n      return;\n    }\n    else if (_parsedLength - 3 == _boundary.length())\n    {\n      if (data != '\\n')\n      {\n        ESP_LOGE(PH_TAG, \"Multipart: Multipart missing newline\");\n        _multiParseState = PARSE_ERROR;\n        return;\n      }\n      _multiParseState = PARSE_HEADERS;\n      _itemIsFile = false;\n    }\n  }\n  else if (_multiParseState == PARSE_HEADERS)\n  {\n    if ((char)data != '\\r' && (char)data != '\\n')\n      _temp += (char)data;\n    if ((char)data == '\\n')\n    {\n      if (_temp.length())\n      {\n        if (_temp.length() > 12 && _temp.substring(0, 12).equalsIgnoreCase(\"Content-Type\"))\n        {\n          _itemType = _temp.substring(14);\n          _itemIsFile = true;\n        }\n        else if (_temp.length() > 19 && _temp.substring(0, 19).equalsIgnoreCase(\"Content-Disposition\"))\n        {\n          _temp = _temp.substring(_temp.indexOf(';') + 2);\n          while (_temp.indexOf(';') > 0)\n          {\n            String name = _temp.substring(0, _temp.indexOf('='));\n            String nameVal = _temp.substring(_temp.indexOf('=') + 2, _temp.indexOf(';') - 1);\n            if (name == \"name\")\n            {\n              _itemName = nameVal;\n            }\n            else if (name == \"filename\")\n            {\n              _itemFilename = nameVal;\n              _itemIsFile = true;\n            }\n            _temp = _temp.substring(_temp.indexOf(';') + 2);\n          }\n          String name = _temp.substring(0, _temp.indexOf('='));\n          String nameVal = _temp.substring(_temp.indexOf('=') + 2, _temp.length() - 1);\n          if (name == \"name\")\n          {\n            _itemName = nameVal;\n          }\n          else if (name == \"filename\")\n          {\n            _itemFilename = nameVal;\n            _itemIsFile = true;\n          }\n        }\n        _temp = String();\n      }\n      else\n      {\n        _multiParseState = WAIT_FOR_RETURN1;\n        // value starts from here\n        _itemSize = 0;\n        _itemStartIndex = _parsedLength;\n        _itemValue = String();\n        if (_itemIsFile)\n        {\n          if (_itemBuffer)\n            free(_itemBuffer);\n          _itemBuffer = (uint8_t*)malloc(FILE_CHUNK_SIZE);\n          if (_itemBuffer == NULL)\n          {\n            ESP_LOGE(PH_TAG, \"Multipart: Failed to allocate buffer\");\n            _multiParseState = PARSE_ERROR;\n            return;\n          }\n          _itemBufferIndex = 0;\n        }\n      }\n    }\n  }\n  else if (_multiParseState == EXPECT_FEED1)\n  {\n    if (data != '\\n')\n    {\n      _multiParseState = WAIT_FOR_RETURN1;\n      itemWriteByte('\\r');\n      _parseMultipartPostByte(data, last);\n    }\n    else\n    {\n      _multiParseState = EXPECT_DASH1;\n    }\n  }\n  else if (_multiParseState == EXPECT_DASH1)\n  {\n    if (data != '-')\n    {\n      _multiParseState = WAIT_FOR_RETURN1;\n      itemWriteByte('\\r');\n      itemWriteByte('\\n');\n      _parseMultipartPostByte(data, last);\n    }\n    else\n    {\n      _multiParseState = EXPECT_DASH2;\n    }\n  }\n  else if (_multiParseState == EXPECT_DASH2)\n  {\n    if (data != '-')\n    {\n      _multiParseState = WAIT_FOR_RETURN1;\n      itemWriteByte('\\r');\n      itemWriteByte('\\n');\n      itemWriteByte('-');\n      _parseMultipartPostByte(data, last);\n    }\n    else\n    {\n      _multiParseState = BOUNDARY_OR_DATA;\n      _boundaryPosition = 0;\n    }\n  }\n  else if (_multiParseState == BOUNDARY_OR_DATA)\n  {\n    if (_boundaryPosition < _boundary.length() && _boundary.c_str()[_boundaryPosition] != data)\n    {\n      _multiParseState = WAIT_FOR_RETURN1;\n      itemWriteByte('\\r');\n      itemWriteByte('\\n');\n      itemWriteByte('-');\n      itemWriteByte('-');\n      uint8_t i;\n      for (i = 0; i < _boundaryPosition; i++)\n        itemWriteByte(_boundary.c_str()[i]);\n      _parseMultipartPostByte(data, last);\n    }\n    else if (_boundaryPosition == _boundary.length() - 1)\n    {\n      _multiParseState = DASH3_OR_RETURN2;\n      if (!_itemIsFile)\n      {\n        // External - Add parameter!\n        _request->addParam(_itemName, _itemValue);\n      }\n      else\n      {\n        if (_itemSize)\n        {\n          if (_uploadCallback)\n          {\n            _uploadCallback(_request, _itemFilename, _itemSize - _itemBufferIndex, _itemBuffer, _itemBufferIndex, true);\n          }\n          _itemBufferIndex = 0;\n\n          // External - Add parameter!\n          _request->addParam(new PsychicWebParameter(_itemName, _itemFilename, true, true, _itemSize));\n        }\n        free(_itemBuffer);\n        _itemBuffer = NULL;\n      }\n    }\n    else\n    {\n      _boundaryPosition++;\n    }\n  }\n  else if (_multiParseState == DASH3_OR_RETURN2)\n  {\n    if (data == '-' && (_request->contentLength() - _parsedLength - 4) != 0)\n    {\n      ESP_LOGE(PH_TAG, \"ERROR: The parser got to the end of the POST but is expecting more bytes!\");\n      _multiParseState = PARSE_ERROR;\n      return;\n    }\n    if (data == '\\r')\n    {\n      _multiParseState = EXPECT_FEED2;\n    }\n    else if (data == '-' && _request->contentLength() == (_parsedLength + 4))\n    {\n      _multiParseState = PARSING_FINISHED;\n    }\n    else\n    {\n      _multiParseState = WAIT_FOR_RETURN1;\n      itemWriteByte('\\r');\n      itemWriteByte('\\n');\n      itemWriteByte('-');\n      itemWriteByte('-');\n      uint8_t i;\n      for (i = 0; i < _boundary.length(); i++)\n        itemWriteByte(_boundary.c_str()[i]);\n      _parseMultipartPostByte(data, last);\n    }\n  }\n  else if (_multiParseState == EXPECT_FEED2)\n  {\n    if (data == '\\n')\n    {\n      _multiParseState = PARSE_HEADERS;\n      _itemIsFile = false;\n    }\n    else\n    {\n      _multiParseState = WAIT_FOR_RETURN1;\n      itemWriteByte('\\r');\n      itemWriteByte('\\n');\n      itemWriteByte('-');\n      itemWriteByte('-');\n      uint8_t i;\n      for (i = 0; i < _boundary.length(); i++)\n        itemWriteByte(_boundary.c_str()[i]);\n      itemWriteByte('\\r');\n      _parseMultipartPostByte(data, last);\n    }\n  }\n}"
  },
  {
    "path": "src/MultipartProcessor.h",
    "content": "#ifndef MULTIPART_PROCESSOR_H\n#define MULTIPART_PROCESSOR_H\n\n#include \"PsychicCore.h\"\n\n/*\n * MultipartProcessor - handle parsing and processing a multipart form.\n * */\n\nclass MultipartProcessor\n{\n  protected:\n    PsychicRequest* _request;\n    PsychicUploadCallback _uploadCallback;\n\n    String _temp;\n    size_t _parsedLength;\n    uint8_t _multiParseState;\n    String _boundary;\n    uint8_t _boundaryPosition;\n    size_t _itemStartIndex;\n    size_t _itemSize;\n    String _itemName;\n    String _itemFilename;\n    String _itemType;\n    String _itemValue;\n    uint8_t* _itemBuffer;\n    size_t _itemBufferIndex;\n    bool _itemIsFile;\n\n    void _handleUploadByte(uint8_t data, bool last);\n    void _parseMultipartPostByte(uint8_t data, bool last);\n\n  public:\n    MultipartProcessor(PsychicRequest* request, PsychicUploadCallback uploadCallback = nullptr);\n    ~MultipartProcessor();\n\n    esp_err_t process();\n    esp_err_t process(const char* body);\n};\n\n#endif"
  },
  {
    "path": "src/PsychicClient.cpp",
    "content": "#include \"PsychicClient.h\"\n#include \"PsychicHttpServer.h\"\n#include <lwip/sockets.h>\n\nPsychicClient::PsychicClient(httpd_handle_t server, int socket) : _server(server),\n                                                                  _socket(socket),\n                                                                  _friend(NULL),\n                                                                  isNew(false)\n{\n}\n\nPsychicClient::~PsychicClient()\n{\n}\n\nhttpd_handle_t PsychicClient::server()\n{\n  return _server;\n}\n\nint PsychicClient::socket()\n{\n  return _socket;\n}\n\n// I'm not sure this is entirely safe to call.  I was having issues with race conditions when highly loaded using this.\nesp_err_t PsychicClient::close()\n{\n  esp_err_t err = httpd_sess_trigger_close(_server, _socket);\n  // PsychicHttpServer::closeCallback(_server, _socket); // call this immediately so the client is taken off the list.\n\n  return err;\n}\n\nIPAddress PsychicClient::localIP()\n{\n  IPAddress address(0, 0, 0, 0);\n\n  char ipstr[INET6_ADDRSTRLEN];\n  struct sockaddr_in6 addr; // esp_http_server uses IPv6 addressing\n  socklen_t addr_size = sizeof(addr);\n\n  if (getsockname(_socket, (struct sockaddr*)&addr, &addr_size) < 0) {\n    ESP_LOGE(PH_TAG, \"Error getting client IP\");\n    return address;\n  }\n\n  // Convert to IPv4 string\n  inet_ntop(AF_INET, &addr.sin6_addr.un.u32_addr[3], ipstr, sizeof(ipstr));\n  // ESP_LOGD(PH_TAG, \"Client Local IP => %s\", ipstr);\n  address.fromString(ipstr);\n\n  return address;\n}\n\nuint16_t PsychicClient::localPort() const\n{\n  struct sockaddr_storage addr;\n  socklen_t len = sizeof addr;\n  getsockname(_socket, (struct sockaddr*)&addr, &len);\n  struct sockaddr_in* s = (struct sockaddr_in*)&addr;\n  return ntohs(s->sin_port);\n}\n\nIPAddress PsychicClient::remoteIP()\n{\n  IPAddress address(0, 0, 0, 0);\n\n  char ipstr[INET6_ADDRSTRLEN];\n  struct sockaddr_in6 addr; // esp_http_server uses IPv6 addressing\n  socklen_t addr_size = sizeof(addr);\n\n  if (getpeername(_socket, (struct sockaddr*)&addr, &addr_size) < 0) {\n    ESP_LOGE(PH_TAG, \"Error getting client IP\");\n    return address;\n  }\n\n  // Convert to IPv4 string\n  inet_ntop(AF_INET, &addr.sin6_addr.un.u32_addr[3], ipstr, sizeof(ipstr));\n  // ESP_LOGD(PH_TAG, \"Client Remote IP => %s\", ipstr);\n  address.fromString(ipstr);\n\n  return address;\n}\n\nuint16_t PsychicClient::remotePort() const\n{\n  struct sockaddr_storage addr;\n  socklen_t len = sizeof addr;\n  getpeername(_socket, (struct sockaddr*)&addr, &len);\n  struct sockaddr_in* s = (struct sockaddr_in*)&addr;\n  return ntohs(s->sin_port);\n}\n"
  },
  {
    "path": "src/PsychicClient.h",
    "content": "#ifndef PsychicClient_h\n#define PsychicClient_h\n\n#include \"PsychicCore.h\"\n\n/*\n * PsychicClient :: Generic wrapper around the ESP-IDF socket\n */\n\nclass PsychicClient\n{\n\n  protected:\n    httpd_handle_t _server;\n    int _socket;\n\n  public:\n    PsychicClient(httpd_handle_t server, int socket);\n    ~PsychicClient();\n\n    // no idea if this is the right way to do it or not, but lets see.\n    // pointer to our derived class (eg. PsychicWebSocketConnection)\n    void* _friend;\n\n    bool isNew = false;\n\n    bool operator==(PsychicClient& rhs) const { return _socket == rhs.socket(); }\n\n    httpd_handle_t server();\n    int socket();\n    esp_err_t close();\n\n    IPAddress localIP();\n    uint16_t localPort() const;\n    IPAddress remoteIP();\n    uint16_t remotePort() const;\n};\n\n#endif"
  },
  {
    "path": "src/PsychicCore.h",
    "content": "#ifndef PsychicCore_h\n#define PsychicCore_h\n\n#define PH_TAG \"psychic\"\n\n#ifndef FILE_CHUNK_SIZE\n  #define FILE_CHUNK_SIZE 8 * 1024\n#endif\n\n#ifndef STREAM_CHUNK_SIZE\n  #define STREAM_CHUNK_SIZE 1024\n#endif\n\n#ifndef MAX_UPLOAD_SIZE\n  #define MAX_UPLOAD_SIZE (2048 * 1024) // 2MB\n#endif\n\n#ifndef MAX_REQUEST_BODY_SIZE\n  #define MAX_REQUEST_BODY_SIZE (16 * 1024) // 16K\n#endif\n\n#ifdef ARDUINO\n  #include <Arduino.h>\n#endif\n\n#include \"FS.h\"\n#include \"MD5Builder.h\"\n#include \"UrlEncode.h\"\n#include \"esp_random.h\"\n#include <ArduinoJson.h>\n#include <esp_http_server.h>\n#include <libb64/cencode.h>\n#include <list>\n#include <map>\n\n#ifdef PSY_DEVMODE\n  #include \"ArduinoTrace.h\"\n#endif\n\nenum HTTPAuthMethod {\n  BASIC_AUTH,\n  DIGEST_AUTH\n};\n\nString urlDecode(const char* encoded);\n\nclass PsychicHttpServer;\nclass PsychicRequest;\nclass PsychicResponse;\nclass PsychicWebSocketRequest;\nclass PsychicClient;\n\n// filter function definition\ntypedef std::function<bool(PsychicRequest* request)> PsychicRequestFilterFunction;\n\n// middleware function definition\ntypedef std::function<esp_err_t()> PsychicMiddlewareNext;\ntypedef std::function<esp_err_t(PsychicRequest* request, PsychicResponse* response, PsychicMiddlewareNext next)> PsychicMiddlewareCallback;\n\n// client connect callback\ntypedef std::function<void(PsychicClient* client)> PsychicClientCallback;\n\n// callback definitions\ntypedef std::function<esp_err_t(PsychicRequest* request, PsychicResponse* response)> PsychicHttpRequestCallback;\ntypedef std::function<esp_err_t(PsychicRequest* request, PsychicResponse* response, JsonVariant& json)> PsychicJsonRequestCallback;\ntypedef std::function<esp_err_t(PsychicRequest* request, const String& filename, uint64_t index, uint8_t* data, size_t len, bool final)> PsychicUploadCallback;\n\nstruct HTTPHeader {\n    String field;\n    String value;\n};\n\nclass DefaultHeaders\n{\n    std::list<HTTPHeader> _headers;\n\n  public:\n    DefaultHeaders() {}\n\n    void addHeader(const String& field, const String& value)\n    {\n      _headers.push_back({field, value});\n    }\n\n    void addHeader(const char* field, const char* value)\n    {\n      _headers.push_back({field, value});\n    }\n\n    const std::list<HTTPHeader>& getHeaders() { return _headers; }\n\n    // delete the copy constructor, singleton class\n    DefaultHeaders(DefaultHeaders const&) = delete;\n    DefaultHeaders& operator=(DefaultHeaders const&) = delete;\n\n    // single static class interface\n    static DefaultHeaders& Instance()\n    {\n      static DefaultHeaders instance;\n      return instance;\n    }\n};\n\n#endif // PsychicCore_h"
  },
  {
    "path": "src/PsychicEndpoint.cpp",
    "content": "#include \"PsychicEndpoint.h\"\n#include \"PsychicHttpServer.h\"\n\nPsychicEndpoint::PsychicEndpoint() : _server(NULL),\n                                     _uri(\"\"),\n                                     _method(HTTP_GET),\n                                     _handler(NULL)\n{\n}\n\nPsychicEndpoint::PsychicEndpoint(PsychicHttpServer* server, int method, const char* uri) : _server(server),\n                                                                                           _uri(uri),\n                                                                                           _method(method),\n                                                                                           _handler(NULL)\n{\n}\n\nPsychicEndpoint::~PsychicEndpoint()\n{\n  delete _handler;\n}\n\nPsychicEndpoint* PsychicEndpoint::setHandler(PsychicHandler* handler)\n{\n  // clean up old / default handler\n  if (_handler != NULL)\n    delete _handler;\n\n  // get our new pointer\n  _handler = handler;\n\n  // keep a pointer to the server\n  _handler->_server = _server;\n\n  return this;\n}\n\nPsychicHandler* PsychicEndpoint::handler()\n{\n  return _handler;\n}\n\nString PsychicEndpoint::uri()\n{\n  return _uri;\n}\n\nesp_err_t PsychicEndpoint::requestCallback(httpd_req_t* req)\n{\n#ifdef ENABLE_ASYNC\n  if (is_on_async_worker_thread() == false) {\n    if (submit_async_req(req, PsychicEndpoint::requestCallback) == ESP_OK) {\n      return ESP_OK;\n    } else {\n      httpd_resp_set_status(req, \"503 Busy\");\n      httpd_resp_sendstr(req, \"No workers available. Server busy.</div>\");\n      return ESP_OK;\n    }\n  }\n#endif\n\n  PsychicEndpoint* self = (PsychicEndpoint*)req->user_ctx;\n  PsychicRequest request(self->_server, req);\n\n  esp_err_t err = self->process(&request);\n\n  if (err == HTTPD_404_NOT_FOUND)\n    return PsychicHttpServer::requestHandler(req);\n\n  if (err == ESP_ERR_HTTPD_INVALID_REQ)\n    return request.response()->error(HTTPD_500_INTERNAL_SERVER_ERROR, \"No handler registered.\");\n\n  return err;\n}\n\nbool PsychicEndpoint::matches(const char* uri)\n{\n  // we only want to match the path, no GET strings\n  char* ptr;\n  size_t position = 0;\n\n  // look for a ? and set our path length to that,\n  ptr = strchr(uri, '?');\n  if (ptr != NULL)\n    position = (size_t)(int)(ptr - uri);\n  // or use the whole uri if not found\n  else\n    position = strlen(uri);\n\n  // do we have a per-endpoint match function\n  if (this->getURIMatchFunction() != NULL) {\n    // ESP_LOGD(PH_TAG, \"Match? %s == %s (%d)\", _uri.c_str(), uri, position);\n    return this->getURIMatchFunction()(_uri.c_str(), uri, (size_t)position);\n  }\n  // do we have a global match function\n  if (_server->getURIMatchFunction() != NULL) {\n    // ESP_LOGD(PH_TAG, \"Match? %s == %s (%d)\", _uri.c_str(), uri, position);\n    return _server->getURIMatchFunction()(_uri.c_str(), uri, (size_t)position);\n  } else {\n    ESP_LOGE(PH_TAG, \"No uri matching function set\");\n    return false;\n  }\n}\n\nhttpd_uri_match_func_t PsychicEndpoint::getURIMatchFunction()\n{\n  return _uri_match_fn;\n}\n\nvoid PsychicEndpoint::setURIMatchFunction(httpd_uri_match_func_t match_fn)\n{\n  _uri_match_fn = match_fn;\n}\n\nPsychicEndpoint* PsychicEndpoint::addFilter(PsychicRequestFilterFunction fn)\n{\n  _handler->addFilter(fn);\n  return this;\n}\n\nPsychicEndpoint* PsychicEndpoint::addMiddleware(PsychicMiddleware* middleware)\n{\n  _handler->addMiddleware(middleware);\n  return this;\n}\n\nPsychicEndpoint* PsychicEndpoint::addMiddleware(PsychicMiddlewareCallback fn)\n{\n  _handler->addMiddleware(fn);\n  return this;\n}\n\nvoid PsychicEndpoint::removeMiddleware(PsychicMiddleware* middleware)\n{\n  _handler->removeMiddleware(middleware);\n}\n\nesp_err_t PsychicEndpoint::process(PsychicRequest* request)\n{\n  esp_err_t ret = ESP_ERR_HTTPD_INVALID_REQ;\n  if (_handler != NULL)\n    ret = _handler->process(request);\n  ESP_LOGD(PH_TAG, \"Endpoint %s processed %s: %s\", _uri.c_str(), request->uri().c_str(), esp_err_to_name(ret));\n  return ret;\n}\n"
  },
  {
    "path": "src/PsychicEndpoint.h",
    "content": "#ifndef PsychicEndpoint_h\n#define PsychicEndpoint_h\n\n#include \"PsychicCore.h\"\n\nclass PsychicHandler;\nclass PsychicMiddleware;\n\n#ifdef ENABLE_ASYNC\n  #include \"async_worker.h\"\n#endif\n\nclass PsychicEndpoint\n{\n    friend PsychicHttpServer;\n\n  private:\n    PsychicHttpServer* _server;\n    String _uri;\n    int _method;\n    PsychicHandler* _handler;\n    httpd_uri_match_func_t _uri_match_fn = nullptr; // use this change the endpoint matching function.\n\n  public:\n    PsychicEndpoint();\n    PsychicEndpoint(PsychicHttpServer* server, int method, const char* uri);\n    ~PsychicEndpoint();\n\n    PsychicEndpoint* setHandler(PsychicHandler* handler);\n    PsychicHandler* handler();\n\n    httpd_uri_match_func_t getURIMatchFunction();\n    void setURIMatchFunction(httpd_uri_match_func_t match_fn);\n\n    bool matches(const char* uri);\n\n    // called to process this endpoint with its middleware chain\n    esp_err_t process(PsychicRequest* request);\n\n    PsychicEndpoint* addFilter(PsychicRequestFilterFunction fn);\n\n    PsychicEndpoint* addMiddleware(PsychicMiddleware* middleware);\n    PsychicEndpoint* addMiddleware(PsychicMiddlewareCallback fn);\n    void removeMiddleware(PsychicMiddleware* middleware);\n\n    String uri();\n\n    static esp_err_t requestCallback(httpd_req_t* req);\n};\n\n#endif // PsychicEndpoint_h"
  },
  {
    "path": "src/PsychicEventSource.cpp",
    "content": "/*\n  Asynchronous WebServer library for Espressif MCUs\n\n  Copyright (c) 2016 Hristo Gochkov. All rights reserved.\n\n  This library is free software; you can redistribute it and/or\n  modify it under the terms of the GNU Lesser General Public\n  License as published by the Free Software Foundation; either\n  version 2.1 of the License, or (at your option) any later version.\n\n  This library is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n  Lesser General Public License for more details.\n\n  You should have received a copy of the GNU Lesser General Public\n  License along with this library; if not, write to the Free Software\n  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\n*/\n\n#include \"PsychicEventSource.h\"\n#include \"esp_log.h\"\n#include <vector>\n\n/*****************************************/\n// PsychicEventSource - Handler\n/*****************************************/\n\nPsychicEventSource::PsychicEventSource() : PsychicHandler(),\n                                           _onOpen(nullptr),\n                                           _onClose(nullptr)\n{\n}\n\nPsychicEventSource::~PsychicEventSource()\n{\n}\n\nPsychicEventSourceClient* PsychicEventSource::getClient(int socket)\n{\n  PsychicClient* client = PsychicHandler::getClient(socket);\n\n  if (client == nullptr)\n    return nullptr;\n\n  return (PsychicEventSourceClient*)client->_friend;\n}\n\nPsychicEventSourceClient* PsychicEventSource::getClient(PsychicClient* client)\n{\n  return getClient(client->socket());\n}\n\nesp_err_t PsychicEventSource::handleRequest(PsychicRequest* request, PsychicResponse* resp)\n{\n  // start our open ended HTTP response\n  PsychicEventSourceResponse response(resp);\n  response.addHeader(\"Content-Type\", \"text/event-stream\");\n  response.addHeader(\"Cache-Control\", \"no-cache\");\n  response.addHeader(\"Connection\", \"keep-alive\");\n  esp_err_t err = response.send();\n\n  // lookup our client\n  PsychicClient* client = checkForNewClient(request->client());\n  if (client->isNew) {\n    // did we get our last id?\n    if (request->hasHeader(\"Last-Event-ID\")) {\n      PsychicEventSourceClient* buddy = getClient(client);\n      buddy->_lastId = atoi(request->header(\"Last-Event-ID\").c_str());\n    }\n\n    // let our handler know.\n    openCallback(client);\n  }\n\n  return err;\n}\n\nPsychicEventSource* PsychicEventSource::onOpen(PsychicEventSourceClientCallback fn)\n{\n  _onOpen = fn;\n  return this;\n}\n\nPsychicEventSource* PsychicEventSource::onClose(PsychicEventSourceClientCallback fn)\n{\n  _onClose = fn;\n  return this;\n}\n\nvoid PsychicEventSource::addClient(PsychicClient* client)\n{\n  client->_friend = new PsychicEventSourceClient(client);\n  PsychicHandler::addClient(client);\n}\n\nvoid PsychicEventSource::removeClient(PsychicClient* client)\n{\n  auto buddy = static_cast<PsychicEventSourceClient*>(client->_friend);\n  if (buddy) {\n    delete buddy;\n    client->_friend = nullptr;\n  }\n  PsychicHandler::removeClient(client);\n}\n\nvoid PsychicEventSource::openCallback(PsychicClient* client)\n{\n  PsychicEventSourceClient* buddy = getClient(client);\n  if (buddy == nullptr) {\n    return;\n  }\n\n  if (_onOpen != nullptr)\n    _onOpen(buddy);\n}\n\nvoid PsychicEventSource::closeCallback(PsychicClient* client)\n{\n  PsychicEventSourceClient* buddy = getClient(client);\n  if (buddy == nullptr) {\n    return;\n  }\n\n  if (_onClose != nullptr)\n    _onClose(getClient(buddy));\n}\n\n/**\n * @brief Sends an event to all connected clients.\n * * This function now safely handles client disconnections.\n * It iterates through all clients, attempts to send the event, and collects\n * any clients for whom the send fails. It then properly removes these\n * disconnected clients after the loop, preventing a crash from using a stale handle.\n */\nvoid PsychicEventSource::send(const char* message, const char* event, uint32_t id, uint32_t reconnect)\n{\n  String ev = generateEventMessage(message, event, id, reconnect);\n  std::vector<PsychicClient*> clientsToRemove;\n\n  // First, iterate and send, collecting disconnected clients\n  for (PsychicClient* c : _clients) {\n    if (!((PsychicEventSourceClient*)c->_friend)->sendEvent(ev.c_str())) {\n      clientsToRemove.push_back(c);\n    }\n  }\n\n  // Second, iterate through the disconnected clients and clean them up\n  for (PsychicClient* c : clientsToRemove) {\n    closeCallback(c); // Let the user application know\n    removeClient(c);  // Remove from handler and clean up memory\n  }\n}\n\n/*****************************************/\n// PsychicEventSourceClient\n/*****************************************/\n\nPsychicEventSourceClient::PsychicEventSourceClient(PsychicClient* client) : PsychicClient(client->server(), client->socket()),\n                                                                            _lastId(0)\n{\n}\n\nPsychicEventSourceClient::~PsychicEventSourceClient()\n{\n}\n\n/**\n * @brief Returns a boolean indicating send success.\n */\nbool PsychicEventSourceClient::send(const char* message, const char* event, uint32_t id, uint32_t reconnect)\n{\n  String ev = generateEventMessage(message, event, id, reconnect);\n  return sendEvent(ev.c_str());\n}\n\n/**\n * @brief Sends data and returns true on success, false on failure.\n * This prevents a crash by detecting if the underlying socket is closed.\n */\nbool PsychicEventSourceClient::sendEvent(const char* event)\n{\n  int result;\n  do {\n    result = httpd_socket_send(this->server(), this->socket(), event, strlen(event), 0);\n  } while (result == HTTPD_SOCK_ERR_TIMEOUT);\n\n  if (result < 0) {\n    ESP_LOGD(PH_TAG, \"sendEvent to socket %d failed. Client likely disconnected.\", this->socket());\n    return false;\n  }\n  return true;\n}\n\n/*****************************************/\n// PsychicEventSourceResponse\n/*****************************************/\n\nPsychicEventSourceResponse::PsychicEventSourceResponse(PsychicResponse* response) : PsychicResponseDelegate(response)\n{\n}\n\nesp_err_t PsychicEventSourceResponse::send()\n{\n  // build our main header\n  String out = String();\n  out.concat(\"HTTP/1.1 200 OK\\r\\n\");\n\n  // now do our individual headers\n  for (auto& header : _response->headers())\n    out.concat(header.field + \": \" + header.value + \"\\r\\n\");\n\n  // separator\n  out.concat(\"\\r\\n\");\n\n  int result;\n  do {\n    result = httpd_send(request(), out.c_str(), out.length());\n  } while (result == HTTPD_SOCK_ERR_TIMEOUT);\n\n  if (result < 0)\n    ESP_LOGE(PH_TAG, \"EventSource send failed with %s\", esp_err_to_name(result));\n\n  if (result > 0)\n    return ESP_OK;\n  else\n    return ESP_ERR_HTTPD_RESP_SEND;\n}\n\n/*****************************************/\n// Event Message Generator\n/*****************************************/\n\nString generateEventMessage(const char* message, const char* event, uint32_t id, uint32_t reconnect)\n{\n  String ev = \"\";\n\n  if (reconnect) {\n    ev += \"retry: \";\n    ev += String(reconnect);\n    ev += \"\\r\\n\";\n  }\n\n  if (id) {\n    ev += \"id: \";\n    ev += String(id);\n    ev += \"\\r\\n\";\n  }\n\n  if (event != NULL) {\n    ev += \"event: \";\n    ev += String(event);\n    ev += \"\\r\\n\";\n  }\n\n  if (message != NULL) {\n    ev += \"data: \";\n    ev += String(message);\n    ev += \"\\r\\n\";\n  }\n  ev += \"\\r\\n\";\n\n  return ev;\n}\n"
  },
  {
    "path": "src/PsychicEventSource.h",
    "content": "/*\n  Asynchronous WebServer library for Espressif MCUs\n\n  Copyright (c) 2016 Hristo Gochkov. All rights reserved.\n\n  This library is free software; you can redistribute it and/or\n  modify it under the terms of the GNU Lesser General Public\n  License as published by the Free Software Foundation; either\n  version 2.1 of the License, or (at your option) any later version.\n\n  This library is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n  Lesser General Public License for more details.\n\n  You should have received a copy of the GNU Lesser General Public\n  License along with this library; if not, write to the Free Software\n  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\n*/\n#ifndef PsychicEventSource_H_\n#define PsychicEventSource_H_\n\n#include \"PsychicClient.h\"\n#include \"PsychicCore.h\"\n#include \"PsychicHandler.h\"\n#include \"PsychicResponse.h\"\n#include <functional>\n\nclass PsychicEventSource;\nclass PsychicEventSourceResponse;\nclass PsychicEventSourceClient;\nclass PsychicResponse;\n\ntypedef std::function<void(PsychicEventSourceClient* client)> PsychicEventSourceClientCallback;\n\ntypedef struct {\n    httpd_handle_t handle;\n    int socket;\n    char* event;\n    size_t len;\n    transfer_complete_cb callback;\n    void* arg;\n} async_event_transfer_t;\n\nclass PsychicEventSourceClient : public PsychicClient\n{\n    friend PsychicEventSource;\n\n  protected:\n    uint32_t _lastId;\n    esp_err_t _sendEventAsync(httpd_handle_t handle, int socket, const char* event, size_t len);\n    static void _sendEventWorkCallback(void* arg);\n    static void _sendEventSentCallback(esp_err_t err, int socket, void* arg);\n\n  public:\n    PsychicEventSourceClient(PsychicClient* client);\n    ~PsychicEventSourceClient();\n\n    uint32_t lastId() const { return _lastId; }\n    bool send(const char *message, const char *event=nullptr, uint32_t id=0, uint32_t reconnect=0);\n    bool sendEvent(const char *event);\n};\n\nclass PsychicEventSource : public PsychicHandler\n{\n  private:\n    PsychicEventSourceClientCallback _onOpen;\n    PsychicEventSourceClientCallback _onClose;\n\n  public:\n    PsychicEventSource();\n    ~PsychicEventSource();\n\n    PsychicEventSourceClient* getClient(int socket) override;\n    PsychicEventSourceClient* getClient(PsychicClient* client) override;\n    void addClient(PsychicClient* client) override;\n    void removeClient(PsychicClient* client) override;\n    void openCallback(PsychicClient* client) override;\n    void closeCallback(PsychicClient* client) override;\n\n    PsychicEventSource* onOpen(PsychicEventSourceClientCallback fn);\n    PsychicEventSource* onClose(PsychicEventSourceClientCallback fn);\n\n    esp_err_t handleRequest(PsychicRequest* request, PsychicResponse* response) override final;\n\n    void send(const char *message, const char *event=nullptr, uint32_t id=0, uint32_t reconnect=0);\n};\n\nclass PsychicEventSourceResponse : public PsychicResponseDelegate\n{\n  public:\n    PsychicEventSourceResponse(PsychicResponse* response);\n    esp_err_t send();\n};\n\nString generateEventMessage(const char* message, const char* event, uint32_t id, uint32_t reconnect);\n\n#endif /* PsychicEventSource_H_ */"
  },
  {
    "path": "src/PsychicFileResponse.cpp",
    "content": "#include \"PsychicFileResponse.h\"\n#include \"PsychicRequest.h\"\n#include \"PsychicResponse.h\"\n#include <http_status.h>\n\nPsychicFileResponse::PsychicFileResponse(PsychicResponse* response, FS& fs, const String& path, const String& contentType, bool download) : PsychicResponseDelegate(response)\n{\n  //_code = 200;\n  String _path(path);\n\n  if (!download && !fs.exists(_path) && fs.exists(_path + \".gz\")) {\n    _path = _path + \".gz\";\n    addHeader(\"Content-Encoding\", \"gzip\");\n  }\n\n  _content = fs.open(_path, \"r\");\n  setContentLength(_content.size());\n\n  if (contentType == \"\")\n    _setContentTypeFromPath(path);\n  else\n    setContentType(contentType.c_str());\n\n  int filenameStart = path.lastIndexOf('/') + 1;\n  char buf[26 + path.length() - filenameStart];\n  char* filename = (char*)path.c_str() + filenameStart;\n\n  if (download) {\n    // set filename and force download\n    snprintf(buf, sizeof(buf), \"attachment; filename=\\\"%s\\\"\", filename);\n  } else {\n    // set filename and force rendering\n    snprintf(buf, sizeof(buf), \"inline; filename=\\\"%s\\\"\", filename);\n  }\n  addHeader(\"Content-Disposition\", buf);\n}\n\nPsychicFileResponse::PsychicFileResponse(PsychicResponse* response, File content, const String& path, const String& contentType, bool download) : PsychicResponseDelegate(response)\n{\n  String _path(path);\n\n  if (!download && String(content.name()).endsWith(\".gz\") && !path.endsWith(\".gz\")) {\n    addHeader(\"Content-Encoding\", \"gzip\");\n  }\n\n  _content = content;\n  setContentLength(_content.size());\n\n  if (contentType == \"\")\n    _setContentTypeFromPath(path);\n  else\n    setContentType(contentType.c_str());\n\n  int filenameStart = path.lastIndexOf('/') + 1;\n  char buf[26 + path.length() - filenameStart];\n  char* filename = (char*)path.c_str() + filenameStart;\n\n  if (download) {\n    snprintf(buf, sizeof(buf), \"attachment; filename=\\\"%s\\\"\", filename);\n  } else {\n    snprintf(buf, sizeof(buf), \"inline; filename=\\\"%s\\\"\", filename);\n  }\n  addHeader(\"Content-Disposition\", buf);\n}\n\nPsychicFileResponse::~PsychicFileResponse()\n{\n  if (_content)\n    _content.close();\n}\n\nvoid PsychicFileResponse::_setContentTypeFromPath(const String& path)\n{\n  const char* _contentType;\n\n  if (path.endsWith(\".html\"))\n    _contentType = \"text/html\";\n  else if (path.endsWith(\".htm\"))\n    _contentType = \"text/html\";\n  else if (path.endsWith(\".css\"))\n    _contentType = \"text/css\";\n  else if (path.endsWith(\".json\"))\n    _contentType = \"application/json\";\n  else if (path.endsWith(\".js\"))\n    _contentType = \"application/javascript\";\n  else if (path.endsWith(\".png\"))\n    _contentType = \"image/png\";\n  else if (path.endsWith(\".gif\"))\n    _contentType = \"image/gif\";\n  else if (path.endsWith(\".jpg\"))\n    _contentType = \"image/jpeg\";\n  else if (path.endsWith(\".ico\"))\n    _contentType = \"image/x-icon\";\n  else if (path.endsWith(\".svg\"))\n    _contentType = \"image/svg+xml\";\n  else if (path.endsWith(\".eot\"))\n    _contentType = \"font/eot\";\n  else if (path.endsWith(\".woff\"))\n    _contentType = \"font/woff\";\n  else if (path.endsWith(\".woff2\"))\n    _contentType = \"font/woff2\";\n  else if (path.endsWith(\".ttf\"))\n    _contentType = \"font/ttf\";\n  else if (path.endsWith(\".xml\"))\n    _contentType = \"text/xml\";\n  else if (path.endsWith(\".pdf\"))\n    _contentType = \"application/pdf\";\n  else if (path.endsWith(\".zip\"))\n    _contentType = \"application/zip\";\n  else if (path.endsWith(\".gz\"))\n    _contentType = \"application/x-gzip\";\n  else\n    _contentType = \"text/plain\";\n\n  setContentType(_contentType);\n}\n\nesp_err_t PsychicFileResponse::send()\n{\n  esp_err_t err = ESP_OK;\n\n  // just send small files directly\n  size_t size = getContentLength();\n  if (size < FILE_CHUNK_SIZE) {\n    uint8_t* buffer = (uint8_t*)malloc(size);\n    if (buffer == NULL && size > 0) {\n      ESP_LOGE(PH_TAG, \"Unable to allocate %zu bytes to send chunk\", size);\n      httpd_resp_send_err(request(), HTTPD_500_INTERNAL_SERVER_ERROR, \"Unable to allocate memory.\");\n      return ESP_FAIL;\n    }\n\n    size_t readSize = _content.readBytes((char*)buffer, size);\n\n    setContent(buffer, readSize);\n    err = _response->send();\n\n    free(buffer);\n  } else {\n    /* Retrieve the pointer to scratch buffer for temporary storage */\n    char* chunk = (char*)malloc(FILE_CHUNK_SIZE);\n    if (chunk == NULL) {\n      ESP_LOGE(PH_TAG, \"Unable to allocate %zu bytes to send chunk\", (size_t)FILE_CHUNK_SIZE);\n      httpd_resp_send_err(request(), HTTPD_500_INTERNAL_SERVER_ERROR, \"Unable to allocate memory.\");\n      return ESP_FAIL;\n    }\n\n    // now the headers\n    sendHeaders();\n\n    size_t chunksize;\n    do {\n      /* Read file in chunks into the scratch buffer */\n      chunksize = _content.readBytes(chunk, FILE_CHUNK_SIZE);\n      if (chunksize > 0) {\n        err = sendChunk((uint8_t*)chunk, chunksize);\n        if (err != ESP_OK)\n          break;\n      }\n\n      /* Keep looping till the whole file is sent */\n    } while (chunksize != 0);\n\n    // keep track of our memory\n    free(chunk);\n\n    if (err == ESP_OK) {\n      ESP_LOGD(PH_TAG, \"File sending complete\");\n      finishChunking();\n    }\n  }\n\n  return err;\n}\n"
  },
  {
    "path": "src/PsychicFileResponse.h",
    "content": "#ifndef PsychicFileResponse_h\n#define PsychicFileResponse_h\n\n#include \"PsychicCore.h\"\n#include \"PsychicResponse.h\"\n\nclass PsychicRequest;\n\nclass PsychicFileResponse : public PsychicResponseDelegate\n{\n    using File = fs::File;\n    using FS = fs::FS;\n\n  protected:\n    File _content;\n    void _setContentTypeFromPath(const String& path);\n\n  public:\n    PsychicFileResponse(PsychicResponse* response, FS& fs, const String& path, const String& contentType = String(), bool download = false);\n    PsychicFileResponse(PsychicResponse* response, File content, const String& path, const String& contentType = String(), bool download = false);\n    ~PsychicFileResponse();\n    esp_err_t send();\n};\n\n#endif // PsychicFileResponse_h"
  },
  {
    "path": "src/PsychicHandler.cpp",
    "content": "#include \"PsychicHandler.h\"\n\nPsychicHandler::PsychicHandler()\n{\n}\n\nPsychicHandler::~PsychicHandler()\n{\n  delete _chain;\n  // actual PsychicClient deletion handled by PsychicServer\n  // for (PsychicClient *client : _clients)\n  //   delete(client);\n  _clients.clear();\n}\n\nPsychicHandler* PsychicHandler::addFilter(PsychicRequestFilterFunction fn)\n{\n  _filters.push_back(fn);\n  return this;\n}\n\nbool PsychicHandler::filter(PsychicRequest* request)\n{\n  // run through our filter chain.\n  for (auto& filter : _filters) {\n    if (!filter(request)) {\n      ESP_LOGD(PH_TAG, \"Request %s refused by filter from handler\", request->uri().c_str());\n      return false;\n    }\n  }\n  return true;\n}\n\nvoid PsychicHandler::setSubprotocol(const String& subprotocol)\n{\n  this->_subprotocol = subprotocol;\n}\nconst char* PsychicHandler::getSubprotocol() const\n{\n  return _subprotocol.c_str();\n}\n\nPsychicClient* PsychicHandler::checkForNewClient(PsychicClient* client)\n{\n  PsychicClient* c = PsychicHandler::getClient(client);\n  if (c == NULL) {\n    c = client;\n    addClient(c);\n    c->isNew = true;\n  } else\n    c->isNew = false;\n\n  return c;\n}\n\nvoid PsychicHandler::checkForClosedClient(PsychicClient* client)\n{\n  if (hasClient(client)) {\n    closeCallback(client);\n    removeClient(client);\n  }\n}\n\nvoid PsychicHandler::addClient(PsychicClient* client)\n{\n  _clients.push_back(client);\n}\n\nvoid PsychicHandler::removeClient(PsychicClient* client)\n{\n  _clients.remove(client);\n}\n\nPsychicClient* PsychicHandler::getClient(int socket)\n{\n  // make sure the server has it too.\n  if (!_server->hasClient(socket))\n    return NULL;\n\n  // what about us?\n  for (PsychicClient* client : _clients)\n    if (client->socket() == socket)\n      return client;\n\n  // nothing found.\n  return NULL;\n}\n\nPsychicClient* PsychicHandler::getClient(PsychicClient* client)\n{\n  return PsychicHandler::getClient(client->socket());\n}\n\nbool PsychicHandler::hasClient(PsychicClient* socket)\n{\n  return PsychicHandler::getClient(socket) != NULL;\n}\n\nconst std::list<PsychicClient*>& PsychicHandler::getClientList()\n{\n  return _clients;\n}\n\nPsychicHandler* PsychicHandler::addMiddleware(PsychicMiddleware* middleware)\n{\n  if (!_chain) {\n    _chain = new PsychicMiddlewareChain();\n  }\n  _chain->addMiddleware(middleware);\n  return this;\n}\n\nPsychicHandler* PsychicHandler::addMiddleware(PsychicMiddlewareCallback fn)\n{\n  if (!_chain) {\n    _chain = new PsychicMiddlewareChain();\n  }\n  _chain->addMiddleware(fn);\n  return this;\n}\n\nvoid PsychicHandler::removeMiddleware(PsychicMiddleware* middleware)\n{\n  if (_chain) {\n    _chain->removeMiddleware(middleware);\n  }\n}\n\nesp_err_t PsychicHandler::process(PsychicRequest* request)\n{\n  if (!filter(request)) {\n    return HTTPD_404_NOT_FOUND;\n  }\n\n  if (!canHandle(request)) {\n    ESP_LOGD(PH_TAG, \"Request %s refused by handler\", request->uri().c_str());\n    return HTTPD_404_NOT_FOUND;\n  }\n\n  if (_chain) {\n    return _chain->runChain(request, [this, request]() {\n      return handleRequest(request, request->response());\n    });\n\n  } else {\n    return handleRequest(request, request->response());\n  }\n}"
  },
  {
    "path": "src/PsychicHandler.h",
    "content": "#ifndef PsychicHandler_h\n#define PsychicHandler_h\n\n#include \"PsychicCore.h\"\n#include \"PsychicRequest.h\"\n\nclass PsychicEndpoint;\nclass PsychicHttpServer;\nclass PsychicMiddleware;\nclass PsychicMiddlewareChain;\n\n/*\n * HANDLER :: Can be attached to any endpoint or as a generic request handler.\n */\n\nclass PsychicHandler\n{\n    friend PsychicEndpoint;\n\n  protected:\n    PsychicHttpServer* _server = nullptr;\n    PsychicMiddlewareChain* _chain = nullptr;\n    std::list<PsychicRequestFilterFunction> _filters;\n\n    String _subprotocol;\n\n    std::list<PsychicClient*> _clients;\n\n  public:\n    PsychicHandler();\n    virtual ~PsychicHandler();\n\n    virtual bool isWebSocket() { return false; };\n\n    void setSubprotocol(const String& subprotocol);\n    const char* getSubprotocol() const;\n\n    PsychicClient* checkForNewClient(PsychicClient* client);\n    void checkForClosedClient(PsychicClient* client);\n\n    virtual void addClient(PsychicClient* client);\n    virtual void removeClient(PsychicClient* client);\n    virtual PsychicClient* getClient(int socket);\n    virtual PsychicClient* getClient(PsychicClient* client);\n    virtual void openCallback(PsychicClient* client) {};\n    virtual void closeCallback(PsychicClient* client) {};\n\n    bool hasClient(PsychicClient* client);\n    int count() { return _clients.size(); };\n    const std::list<PsychicClient*>& getClientList();\n\n    // called to process this handler with its middleware chain and filers\n    esp_err_t process(PsychicRequest* request);\n\n    //bool filter(PsychicRequest* request);\n    PsychicHandler* addFilter(PsychicRequestFilterFunction fn);\n    bool filter(PsychicRequest* request);\n\n    PsychicHandler* addMiddleware(PsychicMiddleware* middleware);\n    PsychicHandler* addMiddleware(PsychicMiddlewareCallback fn);\n    void removeMiddleware(PsychicMiddleware *middleware);\n\n    // derived classes must implement these functions\n    virtual bool canHandle(PsychicRequest* request) { return true; };\n    virtual esp_err_t handleRequest(PsychicRequest* request, PsychicResponse* response) { return HTTPD_404_NOT_FOUND; };\n};\n\n#endif"
  },
  {
    "path": "src/PsychicHttp.h",
    "content": "#ifndef PsychicHttp_h\n#define PsychicHttp_h\n\n// #define ENABLE_ASYNC // This is something added in ESP-IDF 5.1.x where each request can be handled in its own thread\n\n#include \"PsychicEndpoint.h\"\n#include \"PsychicEventSource.h\"\n#include \"PsychicFileResponse.h\"\n#include \"PsychicHandler.h\"\n#include \"PsychicHttpServer.h\"\n#include \"PsychicJson.h\"\n#include \"PsychicMiddleware.h\"\n#include \"PsychicMiddlewareChain.h\"\n#include \"PsychicMiddlewares.h\"\n#include \"PsychicRequest.h\"\n#include \"PsychicResponse.h\"\n#include \"PsychicStaticFileHandler.h\"\n#include \"PsychicStreamResponse.h\"\n#include \"PsychicUploadHandler.h\"\n#include \"PsychicVersion.h\"\n#include \"PsychicWebSocket.h\"\n#include <http_status.h>\n\n#ifdef ENABLE_ASYNC\n  #include \"async_worker.h\"\n#endif\n\n// debugging library\n#ifdef PSY_USE_ARDUINO_TRACE\n  #include <ArduinoTrace.h>\n#endif\n\n#endif /* PsychicHttp_h */"
  },
  {
    "path": "src/PsychicHttpServer.cpp",
    "content": "#include \"PsychicHttpServer.h\"\n#include \"PsychicEndpoint.h\"\n#include \"PsychicHandler.h\"\n#include \"PsychicJson.h\"\n#include \"PsychicStaticFileHandler.h\"\n#include \"PsychicWebHandler.h\"\n#include \"PsychicWebSocket.h\"\n#include \"esp_idf_version.h\"\n#include \"esp_netif.h\"\n\n#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)\n  #define esp_netif_next_compat(n) esp_netif_next_unsafe(n)\n#else\n  #define esp_netif_next_compat(n) esp_netif_next(n)\n#endif\n\nPsychicHttpServer::PsychicHttpServer(uint16_t port)\n{\n  maxRequestBodySize = MAX_REQUEST_BODY_SIZE;\n  maxUploadSize = MAX_UPLOAD_SIZE;\n\n  defaultEndpoint = new PsychicEndpoint(this, HTTP_GET, \"\");\n  onNotFound(PsychicHttpServer::defaultNotFoundHandler);\n\n  // for a regular server\n  config = HTTPD_DEFAULT_CONFIG();\n  config.open_fn = PsychicHttpServer::openCallback;\n  config.close_fn = PsychicHttpServer::closeCallback;\n  config.global_user_ctx = this;\n  config.global_user_ctx_free_fn = PsychicHttpServer::destroy;\n  config.uri_match_fn = MATCH_WILDCARD; // new internal endpoint matching - do not change this!!!\n  config.stack_size = 8192;             // file I/O via VFS/LittleFS needs a deep call chain\n\n  // our internal matching function for endpoints\n  _uri_match_fn = MATCH_WILDCARD; // use this change the endpoint matching function.\n\n#ifdef ENABLE_ASYNC\n  // It is advisable that httpd_config_t->max_open_sockets > MAX_ASYNC_REQUESTS\n  // Why? This leaves at least one socket still available to handle\n  // quick synchronous requests. Otherwise, all the sockets will\n  // get taken by the long async handlers, and your server will no\n  // longer be responsive.\n  config.max_open_sockets = ASYNC_WORKER_COUNT + 1;\n  config.lru_purge_enable = true;\n#endif\n\n  setPort(port);\n}\n\nPsychicHttpServer::~PsychicHttpServer()\n{\n  _esp_idf_endpoints.clear();\n\n  for (auto* client : _clients)\n    delete (client);\n  _clients.clear();\n\n  for (auto* endpoint : _endpoints)\n    delete (endpoint);\n  _endpoints.clear();\n\n  for (auto* handler : _handlers)\n    delete (handler);\n  _handlers.clear();\n\n  for (auto* rewrite : _rewrites)\n    delete (rewrite);\n  _rewrites.clear();\n\n  delete defaultEndpoint;\n  delete _chain;\n}\n\nvoid PsychicHttpServer::destroy(void* ctx)\n{\n  // do not release any resource for PsychicHttpServer in order to be able to restart it after stopping\n}\n\nvoid PsychicHttpServer::setPort(uint16_t port)\n{\n  this->config.server_port = port;\n}\n\nuint16_t PsychicHttpServer::getPort()\n{\n  return this->config.server_port;\n}\n\nstatic bool _netif_is_connected(esp_netif_t* netif)\n{\n  if (!esp_netif_is_netif_up(netif))\n    return false;\n  esp_netif_ip_info_t ip;\n  if (esp_netif_get_ip_info(netif, &ip) != ESP_OK)\n    return false;\n  return ip.ip.addr != 0 && (ip.ip.addr & 0xFF) != 127;\n}\n\nbool PsychicHttpServer::isConnected()\n{\n  for (esp_netif_t* netif = esp_netif_next_compat(nullptr); netif != nullptr; netif = esp_netif_next_compat(netif))\n    if (_netif_is_connected(netif))\n      return true;\n  return false;\n}\n\nesp_err_t PsychicHttpServer::start()\n{\n  if (_running)\n    return ESP_OK;\n\n  // starting without network will crash us\n  if (!isConnected()) {\n    ESP_LOGE(PH_TAG, \"Server start failed - no network interface available.\");\n    return ESP_FAIL;\n  }\n\n  esp_err_t ret;\n\n#ifdef ENABLE_ASYNC\n  // start workers\n  start_async_req_workers();\n#endif\n\n  // one URI handler for each http_method\n  config.max_uri_handlers = supported_methods.size() + _esp_idf_endpoints.size();\n\n  // fire it up.\n  ret = _startServer();\n  if (ret != ESP_OK) {\n    ESP_LOGE(PH_TAG, \"Server start failed (%s)\", esp_err_to_name(ret));\n    return ret;\n  }\n\n  // some handlers (aka websockets) need actual endpoints in esp-idf http_server\n  for (auto& endpoint : _esp_idf_endpoints) {\n    ESP_LOGD(PH_TAG, \"Adding endpoint %s | %s\", endpoint.uri, http_method_str((http_method)endpoint.method));\n\n    // Register endpoint with ESP-IDF server\n    esp_err_t ret = httpd_register_uri_handler(this->server, &endpoint);\n    if (ret != ESP_OK)\n      ESP_LOGE(PH_TAG, \"Add endpoint failed (%s)\", esp_err_to_name(ret));\n  }\n\n  // Register a handler for each http_method method - it will match all requests with that URI/method\n  for (auto& method : supported_methods) {\n    ESP_LOGD(PH_TAG, \"Adding %s meta endpoint\", http_method_str((http_method)method));\n\n    httpd_uri_t my_uri;\n    my_uri.uri = \"*\";\n    my_uri.method = method;\n    my_uri.handler = PsychicHttpServer::requestHandler;\n    my_uri.is_websocket = false;\n    my_uri.supported_subprotocol = \"\";\n\n    // Register endpoint with ESP-IDF server\n    esp_err_t ret = httpd_register_uri_handler(this->server, &my_uri);\n    if (ret != ESP_OK)\n      ESP_LOGE(PH_TAG, \"Add endpoint failed (%s)\", esp_err_to_name(ret));\n  }\n\n  // Register handler\n  ret = httpd_register_err_handler(server, HTTPD_404_NOT_FOUND, PsychicHttpServer::notFoundHandler);\n  if (ret != ESP_OK)\n    ESP_LOGE(PH_TAG, \"Add 404 handler failed (%s)\", esp_err_to_name(ret));\n\n  ESP_LOGI(PH_TAG, \"Server started on port %\" PRIu16, getPort());\n\n  _running = true;\n  return ret;\n}\n\nesp_err_t PsychicHttpServer::_startServer()\n{\n  return httpd_start(&this->server, &this->config);\n}\n\nesp_err_t PsychicHttpServer::stop()\n{\n  if (!_running)\n    return ESP_OK;\n\n  // some handlers (aka websockets) need actual endpoints in esp-idf http_server\n  for (auto& endpoint : _esp_idf_endpoints) {\n    ESP_LOGD(PH_TAG, \"Removing endpoint %s | %s\", endpoint.uri, http_method_str((http_method)endpoint.method));\n\n    // Unregister endpoint with ESP-IDF server\n    esp_err_t ret = httpd_unregister_uri_handler(this->server, endpoint.uri, endpoint.method);\n    if (ret != ESP_OK)\n      ESP_LOGE(PH_TAG, \"Removal of endpoint failed (%s)\", esp_err_to_name(ret));\n  }\n\n  // Unregister a handler for each http_method method - it will match all requests with that URI/method\n  for (auto& method : supported_methods) {\n    ESP_LOGD(PH_TAG, \"Removing %s meta endpoint\", http_method_str((http_method)method));\n\n    // Unregister endpoint with ESP-IDF server\n    esp_err_t ret = httpd_unregister_uri_handler(this->server, \"*\", method);\n    if (ret != ESP_OK)\n      ESP_LOGE(PH_TAG, \"Removal of endpoint failed (%s)\", esp_err_to_name(ret));\n  }\n\n  esp_err_t ret = _stopServer();\n  if (ret != ESP_OK) {\n    ESP_LOGE(PH_TAG, \"Server stop failed (%s)\", esp_err_to_name(ret));\n    return ret;\n  }\n\n  ESP_LOGI(PH_TAG, \"Server stopped\");\n  _running = false;\n  return ret;\n}\n\nesp_err_t PsychicHttpServer::_stopServer()\n{\n  return httpd_stop(this->server);\n}\n\nvoid PsychicHttpServer::reset()\n{\n  if (_running)\n    stop();\n\n  for (auto* client : _clients)\n    delete (client);\n  _clients.clear();\n\n  for (auto* endpoint : _endpoints)\n    delete (endpoint);\n  _endpoints.clear();\n\n  for (auto* handler : _handlers)\n    delete (handler);\n  _handlers.clear();\n\n  for (auto* rewrite : _rewrites)\n    delete (rewrite);\n  _rewrites.clear();\n\n  _esp_idf_endpoints.clear();\n\n  delete _chain;\n  _chain = nullptr;\n\n  onNotFound(PsychicHttpServer::defaultNotFoundHandler);\n  _onOpen = nullptr;\n  _onClose = nullptr;\n}\n\nesp_err_t PsychicHttpServer::restart()\n{\n  esp_err_t ret = ESP_OK;\n\n  if (_running) {\n    ret = stop();\n    if (ret != ESP_OK)\n      return ret;\n  }\n\n  return start();\n}\n\nhttpd_uri_match_func_t PsychicHttpServer::getURIMatchFunction()\n{\n  return _uri_match_fn;\n}\n\nvoid PsychicHttpServer::setURIMatchFunction(httpd_uri_match_func_t match_fn)\n{\n  _uri_match_fn = match_fn;\n}\n\nPsychicHandler* PsychicHttpServer::addHandler(PsychicHandler* handler)\n{\n  _handlers.push_back(handler);\n  return handler;\n}\n\nvoid PsychicHttpServer::removeHandler(PsychicHandler* handler)\n{\n  _handlers.remove(handler);\n  delete handler;\n}\n\nPsychicRewrite* PsychicHttpServer::addRewrite(PsychicRewrite* rewrite)\n{\n  _rewrites.push_back(rewrite);\n  return rewrite;\n}\n\nvoid PsychicHttpServer::removeRewrite(PsychicRewrite* rewrite)\n{\n  _rewrites.remove(rewrite);\n  delete rewrite;\n}\n\nPsychicRewrite* PsychicHttpServer::rewrite(const char* from, const char* to)\n{\n  return addRewrite(new PsychicRewrite(from, to));\n}\n\nPsychicEndpoint* PsychicHttpServer::on(const char* uri)\n{\n  return on(uri, HTTP_GET);\n}\n\nPsychicEndpoint* PsychicHttpServer::on(const char* uri, int method)\n{\n  PsychicWebHandler* handler = new PsychicWebHandler();\n\n  return on(uri, method, handler);\n}\n\nPsychicEndpoint* PsychicHttpServer::on(const char* uri, PsychicHandler* handler)\n{\n  return on(uri, HTTP_GET, handler);\n}\n\nPsychicEndpoint* PsychicHttpServer::on(const char* uri, int method, PsychicHandler* handler)\n{\n  // make our endpoint\n  PsychicEndpoint* endpoint = new PsychicEndpoint(this, method, uri);\n\n  // set our handler\n  endpoint->setHandler(handler);\n\n  // websockets need a real endpoint in esp-idf\n  if (handler->isWebSocket()) {\n    if (_running)\n      ESP_LOGW(PH_TAG, \"WebSocket handler for '%s' registered after server started — it will not work. Call server.on() before server.start().\", uri);\n    // URI handler structure\n    httpd_uri_t my_uri;\n    my_uri.uri = uri;\n    my_uri.method = HTTP_GET;\n    my_uri.handler = PsychicEndpoint::requestCallback;\n    my_uri.user_ctx = endpoint;\n    my_uri.is_websocket = handler->isWebSocket();\n    my_uri.supported_subprotocol = handler->getSubprotocol();\n\n    // save it to our 'real' handlers for later.\n    _esp_idf_endpoints.push_back(my_uri);\n  }\n\n  // if this is a method we haven't added yet, do it.\n  if (method != HTTP_ANY) {\n    if (!(std::find(supported_methods.begin(), supported_methods.end(), (http_method)method) != supported_methods.end())) {\n      ESP_LOGD(PH_TAG, \"Adding %s to server.supported_methods\", http_method_str((http_method)method));\n      supported_methods.push_back((http_method)method);\n    }\n  }\n\n  // add it to our meta endpoints\n  _endpoints.push_back(endpoint);\n\n  return endpoint;\n}\n\nPsychicEndpoint* PsychicHttpServer::on(const char* uri, PsychicHttpRequestCallback fn)\n{\n  return on(uri, HTTP_GET, fn);\n}\n\nPsychicEndpoint* PsychicHttpServer::on(const char* uri, int method, PsychicHttpRequestCallback fn)\n{\n  // these basic requests need a basic web handler\n  PsychicWebHandler* handler = new PsychicWebHandler();\n  handler->onRequest(fn);\n\n  return on(uri, method, handler);\n}\n\nPsychicEndpoint* PsychicHttpServer::on(const char* uri, PsychicJsonRequestCallback fn)\n{\n  return on(uri, HTTP_GET, fn);\n}\n\nPsychicEndpoint* PsychicHttpServer::on(const char* uri, int method, PsychicJsonRequestCallback fn)\n{\n  // these basic requests need a basic web handler\n  PsychicJsonHandler* handler = new PsychicJsonHandler();\n  handler->onRequest(fn);\n\n  return on(uri, method, handler);\n}\n\nbool PsychicHttpServer::removeEndpoint(const char* uri, int method)\n{\n  for (auto* endpoint : _endpoints) {\n    if (endpoint->uri().equals(uri) && method == endpoint->_method)\n      return removeEndpoint(endpoint);\n  }\n  return false;\n}\n\nbool PsychicHttpServer::removeEndpoint(PsychicEndpoint* endpoint)\n{\n  // unregister any ESP-IDF native handler (e.g. WebSocket) for this endpoint\n  for (auto it = _esp_idf_endpoints.begin(); it != _esp_idf_endpoints.end();) {\n    if (endpoint->uri().equals(it->uri) && endpoint->_method == (int)it->method) {\n      ESP_LOGD(PH_TAG, \"Unregistering endpoint %s | %s\", it->uri, http_method_str((http_method)it->method));\n      if (_running) {\n        esp_err_t ret = httpd_unregister_uri_handler(this->server, it->uri, it->method);\n        if (ret != ESP_OK)\n          ESP_LOGE(PH_TAG, \"Remove endpoint failed (%s)\", esp_err_to_name(ret));\n      }\n      it = _esp_idf_endpoints.erase(it);\n    } else {\n      ++it;\n    }\n  }\n  _endpoints.remove(endpoint);\n  delete endpoint;\n  return true;\n}\n\nPsychicHttpServer* PsychicHttpServer::addFilter(PsychicRequestFilterFunction fn)\n{\n  _filters.push_back(fn);\n\n  return this;\n}\n\nbool PsychicHttpServer::_filter(PsychicRequest* request)\n{\n  // run through our filter chain.\n  for (auto& filter : _filters) {\n    if (!filter(request))\n      return false;\n  }\n\n  return true;\n}\n\nPsychicHttpServer* PsychicHttpServer::addMiddleware(PsychicMiddleware* middleware)\n{\n  if (!_chain) {\n    _chain = new PsychicMiddlewareChain();\n  }\n  _chain->addMiddleware(middleware);\n  return this;\n}\n\nPsychicHttpServer* PsychicHttpServer::addMiddleware(PsychicMiddlewareCallback fn)\n{\n  if (!_chain) {\n    _chain = new PsychicMiddlewareChain();\n  }\n  _chain->addMiddleware(fn);\n  return this;\n}\n\nvoid PsychicHttpServer::removeMiddleware(PsychicMiddleware* middleware)\n{\n  if (_chain) {\n    _chain->removeMiddleware(middleware);\n  }\n}\n\nvoid PsychicHttpServer::onNotFound(PsychicHttpRequestCallback fn)\n{\n  PsychicWebHandler* handler = new PsychicWebHandler();\n  handler->onRequest(fn == nullptr ? PsychicHttpServer::defaultNotFoundHandler : fn);\n\n  this->defaultEndpoint->setHandler(handler);\n}\n\nbool PsychicHttpServer::_rewriteRequest(PsychicRequest* request)\n{\n  for (auto* r : _rewrites) {\n    if (r->match(request)) {\n      request->_setUri(r->toUrl().c_str());\n      return true;\n    }\n  }\n\n  return false;\n}\n\nesp_err_t PsychicHttpServer::requestHandler(httpd_req_t* req)\n{\n  PsychicHttpServer* server = (PsychicHttpServer*)httpd_get_global_user_ctx(req->handle);\n  PsychicRequest request(server, req);\n\n  // process any URL rewrites\n  server->_rewriteRequest(&request);\n\n  // run it through our global server filter list\n  if (!server->_filter(&request)) {\n    ESP_LOGD(PH_TAG, \"Request %s refused by global filter\", request.uri().c_str());\n    return request.response()->send(400);\n  }\n\n  // then runs the request through the filter chain\n  esp_err_t ret;\n  if (server->_chain) {\n    ret = server->_chain->runChain(&request, [server, &request]() {\n      return server->_process(&request);\n    });\n  } else {\n    ret = server->_process(&request);\n  }\n  ESP_LOGD(PH_TAG, \"Request %s processed by global middleware: %s\", request.uri().c_str(), esp_err_to_name(ret));\n\n  if (ret == HTTPD_404_NOT_FOUND) {\n    return PsychicHttpServer::notFoundHandler(req, HTTPD_404_NOT_FOUND);\n  }\n\n  return ret;\n}\n\nesp_err_t PsychicHttpServer::_process(PsychicRequest* request)\n{\n  // loop through our endpoints and see if anyone wants it.\n  for (auto* endpoint : _endpoints) {\n    if (endpoint->matches(request->uri().c_str())) {\n      if (endpoint->_method == request->method() || endpoint->_method == HTTP_ANY) {\n        request->setEndpoint(endpoint);\n        return endpoint->process(request);\n      }\n    }\n  }\n\n  // loop through our global handlers and see if anyone wants it\n  for (auto* handler : _handlers) {\n    esp_err_t ret = handler->process(request);\n    if (ret != HTTPD_404_NOT_FOUND)\n      return ret;\n  }\n\n  return HTTPD_404_NOT_FOUND;\n}\n\nesp_err_t PsychicHttpServer::notFoundHandler(httpd_req_t* req, httpd_err_code_t err)\n{\n  PsychicHttpServer* server = (PsychicHttpServer*)httpd_get_global_user_ctx(req->handle);\n  PsychicRequest request(server, req);\n\n  // pull up our default handler / endpoint\n  PsychicHandler* handler = server->defaultEndpoint->handler();\n  if (!handler)\n    return request.response()->send(404);\n\n  esp_err_t ret = handler->process(&request);\n  if (ret != HTTPD_404_NOT_FOUND)\n    return ret;\n\n  // not sure how we got this far.\n  return request.response()->send(404);\n}\n\nesp_err_t PsychicHttpServer::defaultNotFoundHandler(PsychicRequest* request, PsychicResponse* response)\n{\n  return response->send(404, \"text/html\", \"That URI does not exist.\");\n}\n\nvoid PsychicHttpServer::onOpen(PsychicClientCallback handler)\n{\n  this->_onOpen = handler;\n}\n\nesp_err_t PsychicHttpServer::openCallback(httpd_handle_t hd, int sockfd)\n{\n  ESP_LOGD(PH_TAG, \"New client connected %d\", sockfd);\n\n  // get our global server reference\n  PsychicHttpServer* server = (PsychicHttpServer*)httpd_get_global_user_ctx(hd);\n\n  // lookup our client\n  PsychicClient* client = server->getClient(sockfd);\n  if (client == NULL) {\n    client = new PsychicClient(hd, sockfd);\n    server->addClient(client);\n  }\n\n  // user callback\n  if (server->_onOpen != NULL)\n    server->_onOpen(client);\n\n  return ESP_OK;\n}\n\nvoid PsychicHttpServer::onClose(PsychicClientCallback handler)\n{\n  this->_onClose = handler;\n}\n\nvoid PsychicHttpServer::closeCallback(httpd_handle_t hd, int sockfd)\n{\n  ESP_LOGD(PH_TAG, \"Client disconnected %d\", sockfd);\n\n  PsychicHttpServer* server = (PsychicHttpServer*)httpd_get_global_user_ctx(hd);\n\n  // lookup our client\n  PsychicClient* client = server->getClient(sockfd);\n  if (client != NULL) {\n    // give our handlers a chance to handle a disconnect first\n    for (PsychicEndpoint* endpoint : server->_endpoints) {\n      PsychicHandler* handler = endpoint->handler();\n      if (handler != nullptr)\n        handler->checkForClosedClient(client);\n    }\n\n    // do we have a callback attached?\n    if (server->_onClose != NULL)\n      server->_onClose(client);\n\n    // remove it from our list\n    server->removeClient(client);\n  } else\n    ESP_LOGE(PH_TAG, \"No client record %d\", sockfd);\n\n  // finally close it out.\n  close(sockfd);\n}\n\nPsychicStaticFileHandler* PsychicHttpServer::serveStatic(const char* uri, fs::FS& fs, const char* path, const char* cache_control)\n{\n  PsychicStaticFileHandler* handler = new PsychicStaticFileHandler(uri, fs, path, cache_control);\n  this->addHandler(handler);\n\n  return handler;\n}\n\nvoid PsychicHttpServer::addClient(PsychicClient* client)\n{\n  _clients.push_back(client);\n}\n\nvoid PsychicHttpServer::removeClient(PsychicClient* client)\n{\n  _clients.remove(client);\n  delete client;\n}\n\nPsychicClient* PsychicHttpServer::getClient(int socket)\n{\n  for (PsychicClient* client : _clients)\n    if (client->socket() == socket)\n      return client;\n\n  return NULL;\n}\n\nPsychicClient* PsychicHttpServer::getClient(httpd_req_t* req)\n{\n  return getClient(httpd_req_to_sockfd(req));\n}\n\nbool PsychicHttpServer::hasClient(int socket)\n{\n  return getClient(socket) != NULL;\n}\n\nconst std::list<PsychicClient*>& PsychicHttpServer::getClientList()\n{\n  return _clients;\n}\n\nstatic esp_netif_t* _find_netif_by_ip(const IPAddress& addr)\n{\n  for (esp_netif_t* netif = esp_netif_next_compat(nullptr); netif != nullptr; netif = esp_netif_next_compat(netif)) {\n    esp_netif_ip_info_t ip;\n    if (esp_netif_get_ip_info(netif, &ip) != ESP_OK)\n      continue;\n    if (IPAddress(ip.ip.addr) == addr)\n      return netif;\n  }\n  return nullptr;\n}\n\nbool ON_STA_FILTER(PsychicRequest* request)\n{\n  esp_netif_t* netif = _find_netif_by_ip(request->client()->localIP());\n  if (netif == nullptr)\n    return false;\n  return !(esp_netif_get_flags(netif) & ESP_NETIF_DHCP_SERVER);\n}\n\nbool ON_AP_FILTER(PsychicRequest* request)\n{\n  esp_netif_t* netif = _find_netif_by_ip(request->client()->localIP());\n  if (netif == nullptr)\n    return false;\n  return (esp_netif_get_flags(netif) & ESP_NETIF_DHCP_SERVER) != 0;\n}\n\nString urlDecode(const char* encoded)\n{\n  size_t length = strlen(encoded);\n  char* decoded = (char*)malloc(length + 1);\n  if (!decoded) {\n    return \"\";\n  }\n\n  size_t i, j = 0;\n  for (i = 0; i < length; ++i) {\n    if (encoded[i] == '%' && i + 2 < length && isxdigit(encoded[i + 1]) && isxdigit(encoded[i + 2])) {\n      // Valid percent-encoded sequence\n      int hex;\n      sscanf(encoded + i + 1, \"%2x\", &hex);\n      decoded[j++] = (char)hex;\n      i += 2; // Skip the two hexadecimal characters\n    } else if (encoded[i] == '+') {\n      // Convert '+' to space\n      decoded[j++] = ' ';\n    } else {\n      // Copy other characters as they are\n      decoded[j++] = encoded[i];\n    }\n  }\n\n  decoded[j] = '\\0'; // Null-terminate the decoded string\n\n  String output(decoded);\n  free(decoded);\n\n  return output;\n}\n\nbool psychic_uri_match_simple(const char* uri1, const char* uri2, size_t len2)\n{\n  return strlen(uri1) == len2 &&           // First match lengths\n         (strncmp(uri1, uri2, len2) == 0); // Then match actual URIs\n}\n\n#ifdef PSY_ENABLE_REGEX\nbool psychic_uri_match_regex(const char* uri1, const char* uri2, size_t len2)\n{\n  try {\n    std::regex pattern(uri1);\n    std::smatch matches;\n    std::string s(uri2, len2);\n    return std::regex_search(s, matches, pattern);\n  } catch (const std::regex_error& e) {\n    ESP_LOGE(PH_TAG, \"Invalid regex pattern '%s': %s\", uri1, e.what());\n    return false;\n  }\n}\n#endif"
  },
  {
    "path": "src/PsychicHttpServer.h",
    "content": "#ifndef PsychicHttpServer_h\n#define PsychicHttpServer_h\n\n#include \"PsychicClient.h\"\n#include \"PsychicCore.h\"\n#include \"PsychicHandler.h\"\n#include \"PsychicMiddleware.h\"\n#include \"PsychicMiddlewareChain.h\"\n#include \"PsychicRewrite.h\"\n\n#ifdef PSY_ENABLE_REGEX\n  #include <regex>\n#endif\n\n#ifndef HTTP_ANY\n  #define HTTP_ANY INT_MAX\n#endif\n\nclass PsychicEndpoint;\nclass PsychicHandler;\nclass PsychicStaticFileHandler;\n\nclass PsychicHttpServer\n{\n  protected:\n    std::list<httpd_uri_t> _esp_idf_endpoints;\n    std::list<PsychicEndpoint*> _endpoints;\n    std::list<PsychicHandler*> _handlers;\n    std::list<PsychicClient*> _clients;\n    std::list<PsychicRewrite*> _rewrites;\n    std::list<PsychicRequestFilterFunction> _filters;\n\n    PsychicClientCallback _onOpen = nullptr;\n    PsychicClientCallback _onClose = nullptr;\n    PsychicMiddlewareChain* _chain = nullptr;\n\n    esp_err_t _start();\n    virtual esp_err_t _startServer();\n    virtual esp_err_t _stopServer();\n    bool _running = false;\n    httpd_uri_match_func_t _uri_match_fn = nullptr;\n\n    bool _rewriteRequest(PsychicRequest* request);\n    esp_err_t _process(PsychicRequest* request);\n    bool _filter(PsychicRequest* request);\n\n  public:\n    PsychicHttpServer(uint16_t port = 80);\n    virtual ~PsychicHttpServer();\n\n    // what methods to support\n    std::list<http_method> supported_methods = {\n      HTTP_GET,\n      HTTP_POST,\n      HTTP_DELETE,\n      HTTP_HEAD,\n      HTTP_PUT,\n      HTTP_OPTIONS};\n\n    // esp-idf specific stuff\n    httpd_handle_t server;\n    httpd_config_t config;\n\n    // some limits on what we will accept\n    unsigned long maxUploadSize;\n    unsigned long maxRequestBodySize;\n\n    PsychicEndpoint* defaultEndpoint;\n\n    static void destroy(void* ctx);\n\n    virtual void setPort(uint16_t port);\n    virtual uint16_t getPort();\n\n    // stub functions to allow us to use a pointer to PsychicHttpServer that is really a PsychicHttpsServer\n    // for runtime selection of ssl or no ssl\n    virtual void setCertificate(const char* cert, const char* private_key) {}\n    virtual void setCertificate(const uint8_t* cert, size_t cert_size, const uint8_t* private_key, size_t private_key_size) {}\n\n    bool isConnected();\n    bool isRunning() { return _running; }\n    esp_err_t begin() { return start(); }\n    esp_err_t end() { return stop(); }\n    esp_err_t start();\n    esp_err_t stop();\n    esp_err_t restart();\n    void reset();\n\n    httpd_uri_match_func_t getURIMatchFunction();\n    void setURIMatchFunction(httpd_uri_match_func_t match_fn);\n\n    PsychicRewrite* addRewrite(PsychicRewrite* rewrite);\n    void removeRewrite(PsychicRewrite* rewrite);\n    PsychicRewrite* rewrite(const char* from, const char* to);\n\n    PsychicHandler* addHandler(PsychicHandler* handler);\n    void removeHandler(PsychicHandler* handler);\n\n    void addClient(PsychicClient* client);\n    void removeClient(PsychicClient* client);\n    PsychicClient* getClient(int socket);\n    PsychicClient* getClient(httpd_req_t* req);\n    bool hasClient(int socket);\n    int count() { return _clients.size(); };\n    const std::list<PsychicClient*>& getClientList();\n\n    PsychicEndpoint* on(const char* uri);\n    PsychicEndpoint* on(const char* uri, int method);\n    PsychicEndpoint* on(const char* uri, PsychicHandler* handler);\n    PsychicEndpoint* on(const char* uri, int method, PsychicHandler* handler);\n    PsychicEndpoint* on(const char* uri, PsychicHttpRequestCallback onRequest);\n    PsychicEndpoint* on(const char* uri, int method, PsychicHttpRequestCallback onRequest);\n    PsychicEndpoint* on(const char* uri, PsychicJsonRequestCallback onRequest);\n    PsychicEndpoint* on(const char* uri, int method, PsychicJsonRequestCallback onRequest);\n\n    bool removeEndpoint(const char* uri, int method);\n    bool removeEndpoint(PsychicEndpoint* endpoint);\n\n    PsychicHttpServer* addFilter(PsychicRequestFilterFunction fn);\n\n    PsychicHttpServer* addMiddleware(PsychicMiddleware* middleware);\n    PsychicHttpServer* addMiddleware(PsychicMiddlewareCallback fn);\n    void removeMiddleware(PsychicMiddleware* middleware);\n\n    static esp_err_t requestHandler(httpd_req_t* req);\n    static esp_err_t notFoundHandler(httpd_req_t* req, httpd_err_code_t err);\n    static esp_err_t defaultNotFoundHandler(PsychicRequest* request, PsychicResponse* response);\n    static esp_err_t openCallback(httpd_handle_t hd, int sockfd);\n    static void closeCallback(httpd_handle_t hd, int sockfd);\n\n    void onNotFound(PsychicHttpRequestCallback fn);\n    void onOpen(PsychicClientCallback handler);\n    void onClose(PsychicClientCallback handler);\n\n    PsychicStaticFileHandler* serveStatic(const char* uri, fs::FS& fs, const char* path, const char* cache_control = NULL);\n};\n\nbool ON_STA_FILTER(PsychicRequest* request);\nbool ON_AP_FILTER(PsychicRequest* request);\n\n// URI matching functions\nbool psychic_uri_match_simple(const char* uri1, const char* uri2, size_t len2);\n#define MATCH_SIMPLE   psychic_uri_match_simple\n#define MATCH_WILDCARD httpd_uri_match_wildcard\n\n#ifdef PSY_ENABLE_REGEX\nbool psychic_uri_match_regex(const char* uri1, const char* uri2, size_t len2);\n  #define MATCH_REGEX psychic_uri_match_regex\n#endif\n\n#endif // PsychicHttpServer_h"
  },
  {
    "path": "src/PsychicHttpsServer.cpp",
    "content": "#include \"PsychicHttpsServer.h\"\n\n#ifdef CONFIG_ESP_HTTPS_SERVER_ENABLE\n\nPsychicHttpsServer::PsychicHttpsServer(uint16_t port) : PsychicHttpServer(port)\n{\n  // for a SSL server\n  ssl_config = HTTPD_SSL_CONFIG_DEFAULT();\n  ssl_config.httpd.open_fn = PsychicHttpServer::openCallback;\n  ssl_config.httpd.close_fn = PsychicHttpServer::closeCallback;\n  ssl_config.httpd.uri_match_fn = httpd_uri_match_wildcard;\n  ssl_config.httpd.global_user_ctx = this;\n  ssl_config.httpd.global_user_ctx_free_fn = destroy;\n  ssl_config.httpd.max_uri_handlers = 20;\n\n  // each SSL connection takes about 45kb of heap\n  // a barebones sketch with PsychicHttp has ~150kb of heap available\n  // if we set it higher than 2 and use all the connections, we get lots of memory errors.\n  // not to mention there is no heap left over for the program itself.\n  ssl_config.httpd.max_open_sockets = 2;\n\n  setPort(port);\n}\n\nPsychicHttpsServer::~PsychicHttpsServer() {}\n\nvoid PsychicHttpsServer::setPort(uint16_t port)\n{\n  this->ssl_config.port_secure = port;\n}\n\nuint16_t PsychicHttpsServer::getPort()\n{\n  return this->ssl_config.port_secure;\n}\n\nvoid PsychicHttpsServer::setCertificate(const uint8_t* cert, size_t cert_size, const uint8_t* private_key, size_t private_key_size)\n{\n  if (cert) {\n  #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 2)\n    this->ssl_config.servercert = cert;\n    this->ssl_config.servercert_len = cert_size;\n  #else\n    this->ssl_config.cacert_pem = cert;\n    this->ssl_config.cacert_len = cert_size;\n  #endif\n  }\n\n  if (private_key) {\n    this->ssl_config.prvtkey_pem = private_key;\n    this->ssl_config.prvtkey_len = private_key_size;\n  }\n}\n\nesp_err_t PsychicHttpsServer::_startServer()\n{\n  // sync fields that start() calculated into our ssl_config.httpd before handing off\n  ssl_config.httpd.max_uri_handlers = config.max_uri_handlers;\n  ssl_config.httpd.stack_size = config.stack_size;\n  return httpd_ssl_start(&this->server, &this->ssl_config);\n}\n\nesp_err_t PsychicHttpsServer::_stopServer()\n{\n  #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 2)\n  return httpd_ssl_stop(this->server);\n  #else\n  httpd_ssl_stop(this->server);\n  return ESP_OK;\n  #endif\n}\n\n#endif // CONFIG_ESP_HTTPS_SERVER_ENABLE"
  },
  {
    "path": "src/PsychicHttpsServer.h",
    "content": "#ifndef PsychicHttpsServer_h\n#define PsychicHttpsServer_h\n\n#include <sdkconfig.h>\n\n#ifdef CONFIG_ESP_HTTPS_SERVER_ENABLE\n\n  #include \"PsychicCore.h\"\n  #include \"PsychicHttpServer.h\"\n  #include <esp_https_server.h>\n  #if !CONFIG_HTTPD_WS_SUPPORT\n    #error PsychicHttpsServer cannot be used unless HTTPD_WS_SUPPORT is enabled in esp-http-server component configuration\n  #endif\n\n  #ifndef PSY_ENABLE_SSL\n    #define PSY_ENABLE_SSL // you can use this define in your code to enable/disable these features\n  #endif\n\nclass PsychicHttpsServer : public PsychicHttpServer\n{\n  protected:\n    virtual esp_err_t _startServer() override final;\n    virtual esp_err_t _stopServer() override final;\n\n  public:\n    PsychicHttpsServer(uint16_t port = 443);\n    ~PsychicHttpsServer();\n\n    httpd_ssl_config_t ssl_config;\n\n    // using PsychicHttpServer::listen; // keep the regular version\n    virtual void setPort(uint16_t port) override final;\n    virtual uint16_t getPort() override final;\n    // Pointer to certificate data in PEM format\n    void setCertificate(const char* cert, const char* private_key) override final { setCertificate((const uint8_t*)cert, strlen(cert) + 1, (const uint8_t*)private_key, private_key ? strlen(private_key) + 1 : 0); }\n    // Pointer to certificate data in PEM or DER format. PEM-format must have a terminating NULL-character. DER-format requires the length to be passed in certSize and keySize.\n    void setCertificate(const uint8_t* cert, size_t cert_size, const uint8_t* private_key, size_t private_key_size) override final;\n};\n\n#else\n  #warning ESP-IDF https server support not enabled.\n#endif // CONFIG_ESP_HTTPS_SERVER_ENABLE\n\n#endif // PsychicHttpsServer_h\n"
  },
  {
    "path": "src/PsychicJson.cpp",
    "content": "#include \"PsychicJson.h\"\n\n#ifdef ARDUINOJSON_6_COMPATIBILITY\nPsychicJsonResponse::PsychicJsonResponse(PsychicResponse* response, bool isArray, size_t maxJsonBufferSize) : __response(response),\n                                                                                                              _jsonBuffer(maxJsonBufferSize)\n{\n  response->setContentType(JSON_MIMETYPE);\n  if (isArray)\n    _root = _jsonBuffer.createNestedArray();\n  else\n    _root = _jsonBuffer.createNestedObject();\n}\n#else\nPsychicJsonResponse::PsychicJsonResponse(PsychicResponse* response, bool isArray) : PsychicResponseDelegate(response)\n{\n  setContentType(JSON_MIMETYPE);\n  if (isArray)\n    _root = _jsonBuffer.add<JsonArray>();\n  else\n    _root = _jsonBuffer.add<JsonObject>();\n}\n#endif\n\nJsonVariant& PsychicJsonResponse::getRoot()\n{\n  return _root;\n}\n\nsize_t PsychicJsonResponse::getLength()\n{\n  return measureJson(_root);\n}\n\nesp_err_t PsychicJsonResponse::send()\n{\n  esp_err_t err = ESP_OK;\n  size_t length = getLength();\n  size_t buffer_size;\n  char* buffer;\n\n  // how big of a buffer do we want?\n  if (length < JSON_BUFFER_SIZE)\n    buffer_size = length + 1;\n  else\n    buffer_size = JSON_BUFFER_SIZE;\n\n  buffer = (char*)malloc(buffer_size);\n  if (buffer == NULL) {\n    return error(HTTPD_500_INTERNAL_SERVER_ERROR, \"Unable to allocate memory.\");\n  }\n\n  // send it in one shot or no?\n  if (length < JSON_BUFFER_SIZE) {\n    serializeJson(_root, buffer, buffer_size);\n\n    setContent((uint8_t*)buffer, length);\n    setContentType(JSON_MIMETYPE);\n\n    err = PsychicResponseDelegate::send();\n  } else {\n    // helper class that acts as a stream to print chunked responses\n    ChunkPrinter dest(_response, (uint8_t*)buffer, buffer_size);\n\n    // keep our headers\n    sendHeaders();\n\n    serializeJson(_root, dest);\n\n    // send the last bits\n    dest.flush();\n\n    // done with our chunked response too\n    err = finishChunking();\n  }\n\n  // let the buffer go\n  free(buffer);\n\n  return err;\n}\n\n#ifdef ARDUINOJSON_6_COMPATIBILITY\nPsychicJsonHandler::PsychicJsonHandler(size_t maxJsonBufferSize) : _onRequest(NULL),\n                                                                   _maxJsonBufferSize(maxJsonBufferSize) {};\n\nPsychicJsonHandler::PsychicJsonHandler(PsychicJsonRequestCallback onRequest, size_t maxJsonBufferSize) : _onRequest(onRequest),\n                                                                                                         _maxJsonBufferSize(maxJsonBufferSize)\n{\n}\n#else\nPsychicJsonHandler::PsychicJsonHandler() : _onRequest(NULL) {};\n\nPsychicJsonHandler::PsychicJsonHandler(PsychicJsonRequestCallback onRequest) : _onRequest(onRequest)\n{\n}\n#endif\n\nvoid PsychicJsonHandler::onRequest(PsychicJsonRequestCallback fn)\n{\n  _onRequest = fn;\n}\n\nesp_err_t PsychicJsonHandler::handleRequest(PsychicRequest* request, PsychicResponse* response)\n{\n  // process basic stuff\n  PsychicWebHandler::handleRequest(request, response);\n\n  if (_onRequest) {\n#ifdef ARDUINOJSON_6_COMPATIBILITY\n    DynamicJsonDocument jsonBuffer(this->_maxJsonBufferSize);\n    DeserializationError error = deserializeJson(jsonBuffer, request->body());\n    if (error)\n      return response->send(400);\n\n    JsonVariant json = jsonBuffer.as<JsonVariant>();\n#else\n    JsonDocument jsonBuffer;\n    DeserializationError error = deserializeJson(jsonBuffer, request->body());\n    if (error)\n      return response->send(400);\n\n    JsonVariant json = jsonBuffer.as<JsonVariant>();\n#endif\n\n    return _onRequest(request, response, json);\n  } else\n    return response->send(500);\n}"
  },
  {
    "path": "src/PsychicJson.h",
    "content": "// PsychicJson.h\n/*\n  Async Response to use with ArduinoJson and AsyncWebServer\n  Written by Andrew Melvin (SticilFace) with help from me-no-dev and BBlanchon.\n  Ported to PsychicHttp by Zach Hoeken\n\n*/\n#ifndef PSYCHIC_JSON_H_\n#define PSYCHIC_JSON_H_\n\n#include \"ChunkPrinter.h\"\n#include \"PsychicRequest.h\"\n#include \"PsychicWebHandler.h\"\n#include <ArduinoJson.h>\n\n#if ARDUINOJSON_VERSION_MAJOR == 6\n  #define ARDUINOJSON_6_COMPATIBILITY\n  #ifndef DYNAMIC_JSON_DOCUMENT_SIZE\n    #define DYNAMIC_JSON_DOCUMENT_SIZE 4096\n  #endif\n#endif\n\n#ifndef JSON_BUFFER_SIZE\n  #define JSON_BUFFER_SIZE 4 * 1024\n#endif\n\nconstexpr const char* JSON_MIMETYPE = \"application/json\";\n\n/*\n * Json Response\n * */\n\nclass PsychicJsonResponse : public PsychicResponseDelegate\n{\n  protected:\n#ifdef ARDUINOJSON_5_COMPATIBILITY\n    DynamicJsonBuffer _jsonBuffer;\n#elif ARDUINOJSON_VERSION_MAJOR == 6\n    DynamicJsonDocument _jsonBuffer;\n#else\n    JsonDocument _jsonBuffer;\n#endif\n\n    JsonVariant _root;\n    size_t _contentLength;\n\n  public:\n#ifdef ARDUINOJSON_5_COMPATIBILITY\n    PsychicJsonResponse(PsychicResponse* response, bool isArray = false);\n#elif ARDUINOJSON_VERSION_MAJOR == 6\n    PsychicJsonResponse(PsychicResponse* response, bool isArray = false, size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE);\n#else\n    PsychicJsonResponse(PsychicResponse* response, bool isArray = false);\n#endif\n\n    ~PsychicJsonResponse()\n    {\n    }\n\n    JsonVariant& getRoot();\n    size_t getLength();\n\n    esp_err_t send();\n};\n\nclass PsychicJsonHandler : public PsychicWebHandler\n{\n  protected:\n    PsychicJsonRequestCallback _onRequest;\n#if ARDUINOJSON_VERSION_MAJOR == 6\n    const size_t _maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE;\n#endif\n\n  public:\n#ifdef ARDUINOJSON_5_COMPATIBILITY\n    PsychicJsonHandler();\n    PsychicJsonHandler(PsychicJsonRequestCallback onRequest);\n#elif ARDUINOJSON_VERSION_MAJOR == 6\n    PsychicJsonHandler(size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE);\n    PsychicJsonHandler(PsychicJsonRequestCallback onRequest, size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE);\n#else\n    PsychicJsonHandler();\n    PsychicJsonHandler(PsychicJsonRequestCallback onRequest);\n#endif\n\n    void onRequest(PsychicJsonRequestCallback fn);\n    virtual esp_err_t handleRequest(PsychicRequest* request, PsychicResponse* response) override;\n};\n\n#endif"
  },
  {
    "path": "src/PsychicMiddleware.cpp",
    "content": "#include \"PsychicMiddleware.h\"\n\nesp_err_t PsychicMiddlewareFunction::run(PsychicRequest* request, PsychicResponse* response, PsychicMiddlewareNext next)\n{\n  return _fn(request, request->response(), next);\n}\n"
  },
  {
    "path": "src/PsychicMiddleware.h",
    "content": "#ifndef PsychicMiddleware_h\n#define PsychicMiddleware_h\n\n#include \"PsychicCore.h\"\n#include \"PsychicRequest.h\"\n#include \"PsychicResponse.h\"\n\nclass PsychicMiddlewareChain;\n/*\n * PsychicMiddleware :: fancy callback wrapper for handling requests and responses.\n * */\n\nclass PsychicMiddleware\n{\n  public:\n    virtual ~PsychicMiddleware() {}\n    virtual esp_err_t run(PsychicRequest* request, PsychicResponse* response, PsychicMiddlewareNext next)\n    {\n      return next();\n    }\n\n  private:\n    friend PsychicMiddlewareChain;\n    bool _freeOnRemoval = false;\n};\n\nclass PsychicMiddlewareFunction : public PsychicMiddleware\n{\n  public:\n    PsychicMiddlewareFunction(PsychicMiddlewareCallback fn) : _fn(fn) { assert(_fn); }\n    esp_err_t run(PsychicRequest* request, PsychicResponse* response, PsychicMiddlewareNext next) override;\n\n  protected:\n    PsychicMiddlewareCallback _fn;\n};\n\n#endif\n"
  },
  {
    "path": "src/PsychicMiddlewareChain.cpp",
    "content": "#include \"PsychicMiddlewareChain.h\"\n\nPsychicMiddlewareChain::~PsychicMiddlewareChain()\n{\n  for (auto middleware : _middleware)\n    if (middleware->_freeOnRemoval)\n      delete middleware;\n  _middleware.clear();\n}\n\nvoid PsychicMiddlewareChain::addMiddleware(PsychicMiddleware* middleware)\n{\n  _middleware.push_back(middleware);\n}\n\nvoid PsychicMiddlewareChain::addMiddleware(PsychicMiddlewareCallback fn)\n{\n  PsychicMiddlewareFunction* closure = new PsychicMiddlewareFunction(fn);\n  closure->_freeOnRemoval = true;\n  _middleware.push_back(closure);\n}\n\nvoid PsychicMiddlewareChain::removeMiddleware(PsychicMiddleware* middleware)\n{\n  _middleware.remove(middleware);\n  if (middleware->_freeOnRemoval)\n    delete middleware;\n}\n\nesp_err_t PsychicMiddlewareChain::runChain(PsychicRequest* request, PsychicMiddlewareNext finalizer)\n{\n  if (_middleware.size() == 0)\n    return finalizer();\n\n  PsychicMiddlewareNext next;\n  std::list<PsychicMiddleware*>::iterator it = _middleware.begin();\n\n  next = [this, &next, &it, request, finalizer]() {\n    if (it == _middleware.end())\n      return finalizer();\n    PsychicMiddleware* m = *it;\n    it++;\n    return m->run(request, request->response(), next);\n  };\n\n  return next();\n}"
  },
  {
    "path": "src/PsychicMiddlewareChain.h",
    "content": "#ifndef PsychicMiddlewareChain_h\n#define PsychicMiddlewareChain_h\n\n#include \"PsychicCore.h\"\n#include \"PsychicMiddleware.h\"\n#include \"PsychicRequest.h\"\n#include \"PsychicResponse.h\"\n\n/*\n * PsychicMiddlewareChain - handle tracking and executing our chain of middleware objects\n * */\n\nclass PsychicMiddlewareChain\n{\n  public:\n    virtual ~PsychicMiddlewareChain();\n\n    void addMiddleware(PsychicMiddleware* middleware);\n    void addMiddleware(PsychicMiddlewareCallback fn);\n    void removeMiddleware(PsychicMiddleware* middleware);\n\n    esp_err_t runChain(PsychicRequest* request, PsychicMiddlewareNext finalizer);\n\n  protected:\n    std::list<PsychicMiddleware*> _middleware;\n};\n\n#endif"
  },
  {
    "path": "src/PsychicMiddlewares.cpp",
    "content": "#include \"PsychicMiddlewares.h\"\n\nvoid LoggingMiddleware::setOutput(Print &output) {\n  _out = &output;\n}\n\nesp_err_t LoggingMiddleware::run(PsychicRequest* request, PsychicResponse* response, PsychicMiddlewareNext next)\n{\n  _out->print(\"* Connection from \");\n  _out->print(request->client()->remoteIP().toString());\n  _out->print(\":\");\n  _out->println(request->client()->remotePort());\n\n  _out->print(\"> \");\n  _out->print(request->methodStr());\n  _out->print(\" \");\n  _out->print(request->uri());\n  _out->print(\" \");\n  _out->println(request->version());\n\n  // TODO: find a way to collect all headers\n  // int n = request->headerCount();\n  //  for (int i = 0; i < n; i++) {\n  //    String v = server.header(i);\n  //    if (!v.isEmpty()) {\n  //      // because these 2 are always there, eventually empty: \"Authorization\", \"If-None-Match\"\n  //      _out->print(\"< \");\n  //      _out->print(server.headerName(i));\n  //      _out->print(\": \");\n  //      _out->println(server.header(i));\n  //    }\n  //  }\n\n  _out->println(\">\");\n\n  esp_err_t ret = next();\n\n  if (ret != HTTPD_404_NOT_FOUND) {\n    _out->println(\"* Processed!\");\n\n    _out->print(\"< \");\n    _out->print(response->version());\n    _out->print(\" \");\n    _out->print(response->getCode());\n    _out->print(\" \");\n    _out->println(http_status_reason(response->getCode()));\n\n    // iterate over response->headers()\n    std::list<HTTPHeader>::iterator it = response->headers().begin();\n    while (it != response->headers().end()) {\n      HTTPHeader h = *it;\n      _out->print(\"< \");\n      _out->print(h.field);\n      _out->print(\": \");\n      _out->println(h.value);\n      it++;\n    }\n\n    _out->println(\"<\");\n\n  } else {\n    _out->println(\"* Not processed!\");\n  }\n\n  return ret;\n}\n\nAuthenticationMiddleware& AuthenticationMiddleware::setUsername(const char* username)\n{\n  _username = username;\n  return *this;\n}\n\nAuthenticationMiddleware& AuthenticationMiddleware::setPassword(const char* password)\n{\n  _password = password;\n  return *this;\n}\n\nAuthenticationMiddleware& AuthenticationMiddleware::setRealm(const char* realm)\n{\n  _realm = realm;\n  return *this;\n}\n\nAuthenticationMiddleware& AuthenticationMiddleware::setAuthMethod(HTTPAuthMethod method)\n{\n  _method = method;\n  return *this;\n}\n\nAuthenticationMiddleware& AuthenticationMiddleware::setAuthFailureMessage(const char* message)\n{\n  _authFailMsg = message;\n  return *this;\n}\n\nbool AuthenticationMiddleware::isAllowed(PsychicRequest* request) const\n{\n  if (!_username.isEmpty() && !_password.isEmpty()) {\n    return request->authenticate(_username.c_str(), _password.c_str());\n  }\n\n  return true;\n}\n\nesp_err_t AuthenticationMiddleware::run(PsychicRequest* request, PsychicResponse* response, PsychicMiddlewareNext next)\n{\n  bool authenticationRequired = false;\n\n  if (!_username.isEmpty() && !_password.isEmpty()) {\n    authenticationRequired = !request->authenticate(_username.c_str(), _password.c_str());\n  }\n\n  if (authenticationRequired) {\n    return request->requestAuthentication(_method, _realm.c_str(), _authFailMsg.c_str());\n  } else {\n    return next();\n  }\n}\n\nCorsMiddleware& CorsMiddleware::setOrigin(const char* origin)\n{\n  _origin = origin;\n  return *this;\n}\n\nCorsMiddleware& CorsMiddleware::setMethods(const char* methods)\n{\n  _methods = methods;\n  return *this;\n}\n\nCorsMiddleware& CorsMiddleware::setHeaders(const char* headers)\n{\n  _headers = headers;\n  return *this;\n}\n\nCorsMiddleware& CorsMiddleware::setAllowCredentials(bool credentials)\n{\n  _credentials = credentials;\n  return *this;\n}\n\nCorsMiddleware& CorsMiddleware::setMaxAge(uint32_t seconds)\n{\n  _maxAge = seconds;\n  return *this;\n}\n\nvoid CorsMiddleware::addCORSHeaders(PsychicResponse* response)\n{\n  response->addHeader(\"Access-Control-Allow-Origin\", _origin.c_str());\n  response->addHeader(\"Access-Control-Allow-Methods\", _methods.c_str());\n  response->addHeader(\"Access-Control-Allow-Headers\", _headers.c_str());\n  response->addHeader(\"Access-Control-Allow-Credentials\", _credentials ? \"true\" : \"false\");\n  response->addHeader(\"Access-Control-Max-Age\", String(_maxAge).c_str());\n}\n\nesp_err_t CorsMiddleware::run(PsychicRequest* request, PsychicResponse* response, PsychicMiddlewareNext next)\n{\n  if (request->hasHeader(\"Origin\")) {\n    addCORSHeaders(response);\n    if (request->method() == HTTP_OPTIONS) {\n      return response->send(200);\n    }\n  }\n  return next();\n}\n"
  },
  {
    "path": "src/PsychicMiddlewares.h",
    "content": "#ifndef PsychicMiddlewares_h\n#define PsychicMiddlewares_h\n\n#include \"PsychicMiddleware.h\"\n\n#include <Stream.h>\n#include <http_status.h>\n\n// curl-like logging middleware\nclass LoggingMiddleware : public PsychicMiddleware\n{\n  public:\n    void setOutput(Print& output);\n\n    esp_err_t run(PsychicRequest* request, PsychicResponse* response, PsychicMiddlewareNext next) override;\n\n  private:\n    Print* _out;\n};\n\nclass AuthenticationMiddleware : public PsychicMiddleware\n{\n  public:\n    AuthenticationMiddleware& setUsername(const char* username);\n    AuthenticationMiddleware& setPassword(const char* password);\n\n    AuthenticationMiddleware& setRealm(const char* realm);\n    AuthenticationMiddleware& setAuthMethod(HTTPAuthMethod method);\n    AuthenticationMiddleware& setAuthFailureMessage(const char* message);\n\n    const String& getUsername() const { return _username; }\n    const String& getPassword() const { return _password; }\n\n    const String& getRealm() const { return _realm; }\n    HTTPAuthMethod getAuthMethod() const { return _method; }\n    const String& getAuthFailureMessage() const { return _authFailMsg; }\n\n    bool isAllowed(PsychicRequest* request) const;\n\n    esp_err_t run(PsychicRequest* request, PsychicResponse* response, PsychicMiddlewareNext next) override;\n\n  private:\n    String _username;\n    String _password;\n\n    String _realm;\n    HTTPAuthMethod _method = BASIC_AUTH;\n    String _authFailMsg;\n};\n\nclass CorsMiddleware : public PsychicMiddleware\n{\n  public:\n    CorsMiddleware& setOrigin(const char* origin);\n    CorsMiddleware& setMethods(const char* methods);\n    CorsMiddleware& setHeaders(const char* headers);\n    CorsMiddleware& setAllowCredentials(bool credentials);\n    CorsMiddleware& setMaxAge(uint32_t seconds);\n\n    const String& getOrigin() const { return _origin; }\n    const String& getMethods() const { return _methods; }\n    const String& getHeaders() const { return _headers; }\n    bool getAllowCredentials() const { return _credentials; }\n    uint32_t getMaxAge() const { return _maxAge; }\n\n    void addCORSHeaders(PsychicResponse* response);\n\n    esp_err_t run(PsychicRequest* request, PsychicResponse* response, PsychicMiddlewareNext next) override;\n\n  private:\n    String _origin = \"*\";\n    String _methods = \"*\";\n    String _headers = \"*\";\n    bool _credentials = true;\n    uint32_t _maxAge = 86400;\n};\n\n#endif\n"
  },
  {
    "path": "src/PsychicRequest.cpp",
    "content": "#include \"PsychicRequest.h\"\n#include \"MultipartProcessor.h\"\n#include \"PsychicHttpServer.h\"\n#include \"http_status.h\"\n\nPsychicRequest::PsychicRequest(PsychicHttpServer* server, httpd_req_t* req) : _server(server),\n                                                                              _req(req),\n                                                                              _endpoint(nullptr),\n                                                                              _method(HTTP_GET),\n                                                                              _uri(\"\"),\n                                                                              _query(\"\"),\n                                                                              _body(\"\"),\n                                                                              _tempObject(nullptr)\n{\n  // load up our client.\n  this->_client = server->getClient(req);\n\n  // handle our session data\n  if (req->sess_ctx != NULL)\n    this->_session = (SessionData*)req->sess_ctx;\n  else {\n    this->_session = new SessionData();\n    req->sess_ctx = this->_session;\n  }\n\n  // callback for freeing the session later\n  req->free_ctx = this->freeSession;\n\n  // load and parse our uri.\n  this->_setUri(this->_req->uri);\n\n  _response = new PsychicResponse(this);\n}\n\nPsychicRequest::~PsychicRequest()\n{\n  // temorary user object\n  if (_tempObject != NULL)\n    free(_tempObject);\n\n  // our web parameters\n  for (auto* param : _params)\n    delete (param);\n  _params.clear();\n\n  delete _response;\n}\n\nvoid PsychicRequest::freeSession(void* ctx)\n{\n  if (ctx != NULL) {\n    SessionData* session = (SessionData*)ctx;\n    delete session;\n  }\n}\n\nPsychicHttpServer* PsychicRequest::server()\n{\n  return _server;\n}\n\nhttpd_req_t* PsychicRequest::request()\n{\n  return _req;\n}\n\nPsychicClient* PsychicRequest::client()\n{\n  return _client;\n}\n\nPsychicEndpoint* PsychicRequest::endpoint()\n{\n  return _endpoint;\n}\n\nvoid PsychicRequest::setEndpoint(PsychicEndpoint* endpoint)\n{\n  _endpoint = endpoint;\n}\n\n#ifdef PSY_ENABLE_REGEX\nbool PsychicRequest::getRegexMatches(std::smatch& matches, bool use_full_uri)\n{\n  if (_endpoint != nullptr) {\n    std::regex pattern(_endpoint->uri().c_str());\n    std::string s(this->path().c_str());\n    if (use_full_uri)\n      s = this->uri().c_str();\n\n    return std::regex_search(s, matches, pattern);\n  }\n\n  return false;\n}\n#endif\n\nconst String PsychicRequest::getFilename()\n{\n  // parse the content-disposition header\n  if (this->hasHeader(\"Content-Disposition\")) {\n    ContentDisposition cd = this->getContentDisposition();\n    if (cd.filename != \"\")\n      return cd.filename;\n  }\n\n  // fall back to passed in query string\n  PsychicWebParameter* param = getParam(\"_filename\");\n  if (param != NULL)\n    return param->name();\n\n  // fall back to parsing it from url (useful for wildcard uploads)\n  String uri = this->uri();\n  int filenameStart = uri.lastIndexOf('/') + 1;\n  String filename = uri.substring(filenameStart);\n  if (filename != \"\")\n    return filename;\n\n  // finally, unknown.\n  ESP_LOGE(PH_TAG, \"Did not get a valid filename from the upload.\");\n  return \"unknown.txt\";\n}\n\nconst ContentDisposition PsychicRequest::getContentDisposition()\n{\n  ContentDisposition cd;\n  String header = this->header(\"Content-Disposition\");\n  int start;\n  int end;\n\n  if (header.indexOf(\"form-data\") == 0)\n    cd.disposition = FORM_DATA;\n  else if (header.indexOf(\"attachment\") == 0)\n    cd.disposition = ATTACHMENT;\n  else if (header.indexOf(\"inline\") == 0)\n    cd.disposition = INLINE;\n  else\n    cd.disposition = NONE;\n\n  start = header.indexOf(\"filename=\");\n  if (start >= 0) {\n    end = header.indexOf('\"', start + 10);\n    cd.filename = header.substring(start + 10, end - 1);\n  }\n\n  start = header.indexOf(\"name=\");\n  if (start >= 0) {\n    end = header.indexOf('\"', start + 6);\n    cd.name = header.substring(start + 6, end - 1);\n  }\n\n  return cd;\n}\n\nesp_err_t PsychicRequest::loadBody()\n{\n  if (_bodyParsed != ESP_ERR_NOT_FINISHED)\n    return _bodyParsed;\n\n  // quick size check.\n  if (contentLength() > server()->maxRequestBodySize) {\n    ESP_LOGE(PH_TAG, \"Body size larger than maxRequestBodySize\");\n    return _bodyParsed = ESP_ERR_INVALID_SIZE;\n  }\n\n  this->_body = String();\n\n  size_t remaining = this->_req->content_len;\n  size_t actuallyReceived = 0;\n  char* buf = (char*)malloc(remaining + 1);\n  if (buf == NULL) {\n    ESP_LOGE(PH_TAG, \"Failed to allocate memory for body\");\n    return _bodyParsed = ESP_FAIL;\n  }\n\n  while (remaining > 0) {\n    int received = httpd_req_recv(this->_req, buf + actuallyReceived, remaining);\n\n    if (received == HTTPD_SOCK_ERR_TIMEOUT) {\n      continue;\n    } else if (received == HTTPD_SOCK_ERR_FAIL) {\n      ESP_LOGE(PH_TAG, \"Failed to receive data.\");\n      _bodyParsed = ESP_FAIL;\n      break;\n    }\n\n    remaining -= received;\n    actuallyReceived += received;\n  }\n\n  buf[actuallyReceived] = '\\0';\n  this->_body = String(buf);\n  free(buf);\n\n  _bodyParsed = ESP_OK;\n\n  return _bodyParsed;\n}\n\nhttp_method PsychicRequest::method()\n{\n  return (http_method)this->_req->method;\n}\n\nconst String PsychicRequest::methodStr()\n{\n  return String(http_method_str((http_method)this->_req->method));\n}\n\nconst String PsychicRequest::path()\n{\n  int index = _uri.indexOf(\"?\");\n  if (index == -1)\n    return _uri;\n  else\n    return _uri.substring(0, index);\n}\n\nconst String& PsychicRequest::uri()\n{\n  return this->_uri;\n}\n\nconst String& PsychicRequest::query()\n{\n  return this->_query;\n}\n\n// no way to get list of headers yet....\n// int PsychicRequest::headers()\n// {\n// }\n\nconst String PsychicRequest::header(const char* name)\n{\n  size_t header_len = httpd_req_get_hdr_value_len(this->_req, name);\n\n  // if we've got one, allocated it and load it\n  if (header_len) {\n    char header[header_len + 1];\n    httpd_req_get_hdr_value_str(this->_req, name, header, sizeof(header));\n    return String(header);\n  } else\n    return \"\";\n}\n\nbool PsychicRequest::hasHeader(const char* name)\n{\n  return httpd_req_get_hdr_value_len(this->_req, name) > 0;\n}\n\nconst String PsychicRequest::host()\n{\n  return this->header(\"Host\");\n}\n\nconst String PsychicRequest::contentType()\n{\n  return header(\"Content-Type\");\n}\n\nsize_t PsychicRequest::contentLength()\n{\n  return this->_req->content_len;\n}\n\nconst String& PsychicRequest::body()\n{\n  return this->_body;\n}\n\nbool PsychicRequest::isMultipart()\n{\n  const String& type = this->contentType();\n\n  return (this->contentType().indexOf(\"multipart/form-data\") >= 0);\n}\n\nbool PsychicRequest::hasCookie(const char* key, size_t* size)\n{\n  char buffer;\n\n  // this keeps our size for the user.\n  if (size != nullptr) {\n    *size = 1;\n    return getCookie(key, &buffer, size) != ESP_ERR_NOT_FOUND;\n  }\n  // this just checks that it exists.\n  else {\n    size_t mysize = 1;\n    return getCookie(key, &buffer, &mysize) != ESP_ERR_NOT_FOUND;\n  }\n}\n\nesp_err_t PsychicRequest::getCookie(const char* key, char* buffer, size_t* size)\n{\n  return httpd_req_get_cookie_val(this->_req, key, buffer, size);\n}\n\nString PsychicRequest::getCookie(const char* key)\n{\n  String cookie = \"\";\n\n  // how big is our cookie?\n  size_t size;\n  if (!hasCookie(key, &size))\n    return cookie;\n\n  // allocate cookie buffer... keep it on the stack\n  char buf[size];\n\n  // load it up.\n  esp_err_t err = getCookie(key, buf, &size);\n  if (err == ESP_OK)\n    cookie.concat(buf);\n\n  return cookie;\n}\n\nvoid PsychicRequest::replaceResponse(PsychicResponse* response)\n{\n  delete _response;\n  _response = response;\n}\n\nvoid PsychicRequest::addResponseHeader(const char* key, const char* value)\n{\n  _response->addHeader(key, value);\n}\n\nstd::list<HTTPHeader>& PsychicRequest::getResponseHeaders()\n{\n  return _response->headers();\n}\n\nvoid PsychicRequest::loadParams()\n{\n  if (_paramsParsed != ESP_ERR_NOT_FINISHED)\n    return;\n\n  // convenience shortcut to allow calling loadParams()\n  if (_bodyParsed == ESP_ERR_NOT_FINISHED)\n    loadBody();\n\n  // various form data as parameters\n  if (this->method() == HTTP_POST) {\n    if (this->contentType().startsWith(\"application/x-www-form-urlencoded\"))\n      _addParams(_body, true);\n\n    if (this->isMultipart()) {\n      MultipartProcessor mpp(this);\n      _paramsParsed = mpp.process(_body.c_str());\n      return;\n    }\n  }\n\n  _paramsParsed = ESP_OK;\n}\n\nvoid PsychicRequest::_setUri(const char* uri)\n{\n  // save it\n  _uri = String(uri);\n\n  // look for our query separator\n  int index = _uri.indexOf('?', 0);\n  if (index >= 0) {\n    // parse them.\n    _query = _uri.substring(index + 1);\n    _addParams(_query, false);\n  }\n}\n\nvoid PsychicRequest::_addParams(const String& params, bool post)\n{\n  size_t start = 0;\n  while (start < params.length()) {\n    int end = params.indexOf('&', start);\n    if (end < 0)\n      end = params.length();\n    int equal = params.indexOf('=', start);\n    if (equal < 0 || equal > end)\n      equal = end;\n    String name = params.substring(start, equal);\n    String value = equal + 1 < end ? params.substring(equal + 1, end) : String();\n    addParam(name, value, true, post);\n    start = end + 1;\n  }\n}\n\nPsychicWebParameter* PsychicRequest::addParam(const String& name, const String& value, bool decode, bool post)\n{\n  if (decode)\n    return addParam(new PsychicWebParameter(urlDecode(name.c_str()), urlDecode(value.c_str()), post));\n  else\n    return addParam(new PsychicWebParameter(name, value, post));\n}\n\nPsychicWebParameter* PsychicRequest::addParam(PsychicWebParameter* param)\n{\n  // ESP_LOGD(PH_TAG, \"Adding param: '%s' = '%s'\", param->name().c_str(), param->value().c_str());\n  _params.push_back(param);\n  return param;\n}\n\nbool PsychicRequest::hasParam(const char* key)\n{\n  return getParam(key) != NULL;\n}\n\nbool PsychicRequest::hasParam(const char* key, bool isPost, bool isFile)\n{\n  return getParam(key, isPost, isFile) != NULL;\n}\n\nPsychicWebParameter* PsychicRequest::getParam(const char* key)\n{\n  for (auto* param : _params)\n    if (param->name().equals(key))\n      return param;\n\n  return NULL;\n}\n\nPsychicWebParameter* PsychicRequest::getParam(const char* key, bool isPost, bool isFile)\n{\n  for (auto* param : _params)\n    if (param->name().equals(key) && isPost == param->isPost() && isFile == param->isFile())\n      return param;\n  return NULL;\n}\n\nbool PsychicRequest::hasSessionKey(const String& key)\n{\n  return this->_session->find(key) != this->_session->end();\n}\n\nconst String PsychicRequest::getSessionKey(const String& key)\n{\n  auto it = this->_session->find(key);\n  if (it != this->_session->end())\n    return it->second;\n  else\n    return \"\";\n}\n\nvoid PsychicRequest::setSessionKey(const String& key, const String& value)\n{\n  this->_session->insert(std::pair<String, String>(key, value));\n}\n\nstatic const String md5str(const String& in)\n{\n  MD5Builder md5 = MD5Builder();\n  md5.begin();\n  md5.add(in);\n  md5.calculate();\n  return md5.toString();\n}\n\nbool PsychicRequest::authenticate(const char * username, const char * password, bool passwordIsHashed)\n{\n  if (hasHeader(\"Authorization\")) {\n    String authReq = header(\"Authorization\");\n    if (authReq.startsWith(\"Basic\")) {\n      authReq = authReq.substring(6);\n      authReq.trim();\n      int toencodeLen = strlen(username) + strlen(password) + 1;\n      char* toencode = new char[toencodeLen + 1];\n      if (toencode == NULL) {\n        authReq = \"\";\n        return false;\n      }\n      char* encoded = new char[base64_encode_expected_len(toencodeLen) + 1];\n      if (encoded == NULL) {\n        authReq = \"\";\n        delete[] toencode;\n        return false;\n      }\n      sprintf(toencode, \"%s:%s\", username, password);\n      if (base64_encode_chars(toencode, toencodeLen, encoded) > 0 && authReq.equalsConstantTime(encoded)) {\n        authReq = \"\";\n        delete[] toencode;\n        delete[] encoded;\n        return true;\n      }\n      delete[] toencode;\n      delete[] encoded;\n    } else if (authReq.startsWith(F(\"Digest\"))) {\n      authReq = authReq.substring(7);\n      String _username = _extractParam(authReq, F(\"username=\\\"\"), '\\\"');\n      if (!_username.length() || _username != String(username)) {\n        authReq = \"\";\n        return false;\n      }\n      // extracting required parameters for RFC 2069 simpler Digest\n      String _realm = _extractParam(authReq, F(\"realm=\\\"\"), '\\\"');\n      String _nonce = _extractParam(authReq, F(\"nonce=\\\"\"), '\\\"');\n      String _url = _extractParam(authReq, F(\"uri=\\\"\"), '\\\"');\n      String _resp = _extractParam(authReq, F(\"response=\\\"\"), '\\\"');\n      String _opaque = _extractParam(authReq, F(\"opaque=\\\"\"), '\\\"');\n\n      if ((!_realm.length()) || (!_nonce.length()) || (!_url.length()) || (!_resp.length()) || (!_opaque.length())) {\n        authReq = \"\";\n        return false;\n      }\n      if ((_opaque != this->getSessionKey(\"opaque\")) || (_nonce != this->getSessionKey(\"nonce\")) || (_realm != this->getSessionKey(\"realm\"))) {\n        authReq = \"\";\n        return false;\n      }\n      // parameters for the RFC 2617 newer Digest\n      String _nc, _cnonce;\n      if (authReq.indexOf(\"qop=auth\") != -1 || authReq.indexOf(\"qop=\\\"auth\\\"\") != -1) {\n        _nc = _extractParam(authReq, F(\"nc=\"), ',');\n        _cnonce = _extractParam(authReq, F(\"cnonce=\\\"\"), '\\\"');\n      }\n      \n\n      String _H1 = passwordIsHashed ? String(password) : md5str(String(username) + ':' + _realm + ':' + String(password));      \n      //ESP_LOGD(PH_TAG, \"Hash of user:realm:pass=%s\", _H1.c_str());\n      \n      String _H2 = \"\";\n      switch(method()) {\n        case HTTP_GET:\n          _H2 = md5str(String(F(\"GET:\")) + _uri);\n          break;\n        case HTTP_POST:\n          _H2 = md5str(String(F(\"POST:\")) + _uri);\n          break;\n        case HTTP_PUT:\n          _H2 = md5str(String(F(\"PUT:\")) + _uri);\n          break;\n        case HTTP_DELETE:\n          _H2 = md5str(String(F(\"DELETE:\")) + _uri);\n          break;\n        default:\n          _H2 = md5str(String(F(\"GET:\")) + _uri);\n          break;\n      }\n\n      //ESP_LOGD(PH_TAG, \"Hash of GET:uri=%s\", _H2.c_str());\n      \n      String _responsecheck = \"\";\n      if (authReq.indexOf(\"qop=auth\") != -1 || authReq.indexOf(\"qop=\\\"auth\\\"\") != -1) {\n        _responsecheck = md5str(_H1 + ':' + _nonce + ':' + _nc + ':' + _cnonce + F(\":auth:\") + _H2);\n      } else {\n        _responsecheck = md5str(_H1 + ':' + _nonce + ':' + _H2);\n      }\n\n      // ESP_LOGD(PH_TAG, \"The Proper response=%s\", _responsecheck.c_str());\n      if (_resp == _responsecheck) {\n        authReq = \"\";\n        return true;\n      }\n    }\n    authReq = \"\";\n  }\n  return false;\n}\n\nconst String PsychicRequest::_extractParam(const String& authReq, const String& param, const char delimit)\n{\n  int _begin = authReq.indexOf(param);\n  if (_begin == -1)\n    return \"\";\n  return authReq.substring(_begin + param.length(), authReq.indexOf(delimit, _begin + param.length()));\n}\n\nconst String PsychicRequest::_getRandomHexString()\n{\n  char buffer[33]; // buffer to hold 32 Hex Digit + /0\n  int i;\n  for (i = 0; i < 4; i++) {\n    sprintf(buffer + (i * 8), \"%08lx\", (unsigned long int)esp_random());\n  }\n  return String(buffer);\n}\n\nesp_err_t PsychicRequest::requestAuthentication(HTTPAuthMethod mode, const char* realm, const char* authFailMsg)\n{\n  // what is thy realm, sire?\n  if (!strcmp(realm, \"\"))\n    this->setSessionKey(\"realm\", \"Login Required\");\n  else\n    this->setSessionKey(\"realm\", realm);\n\n  PsychicResponse response(this);\n  String authStr;\n\n  // what kind of auth?\n  if (mode == BASIC_AUTH) {\n    authStr = \"Basic realm=\\\"\" + this->getSessionKey(\"realm\") + \"\\\"\";\n    response.addHeader(\"WWW-Authenticate\", authStr.c_str());\n  } else {\n    // only make new ones if we havent sent them yet\n    if (this->getSessionKey(\"nonce\").isEmpty())\n      this->setSessionKey(\"nonce\", _getRandomHexString());\n    if (this->getSessionKey(\"opaque\").isEmpty())\n      this->setSessionKey(\"opaque\", _getRandomHexString());\n\n    authStr = \"Digest realm=\\\"\" + this->getSessionKey(\"realm\") + \"\\\", qop=\\\"auth\\\", nonce=\\\"\" + this->getSessionKey(\"nonce\") + \"\\\", opaque=\\\"\" + this->getSessionKey(\"opaque\") + \"\\\"\";\n    response.addHeader(\"WWW-Authenticate\", authStr.c_str());\n  }\n\n  response.setCode(401);\n  response.setContentType(\"text/html\");\n  response.setContent(authFailMsg);\n  return response.send();\n}\n"
  },
  {
    "path": "src/PsychicRequest.h",
    "content": "#ifndef PsychicRequest_h\n#define PsychicRequest_h\n\n#include \"PsychicClient.h\"\n#include \"PsychicCore.h\"\n#include \"PsychicEndpoint.h\"\n#include \"PsychicHttpServer.h\"\n#include \"PsychicWebParameter.h\"\n\n#ifdef PSY_ENABLE_REGEX\n  #include <regex>\n#endif\n\ntypedef std::map<String, String> SessionData;\n\nenum Disposition {\n  NONE,\n  INLINE,\n  ATTACHMENT,\n  FORM_DATA\n};\n\nstruct ContentDisposition {\n    Disposition disposition;\n    String filename;\n    String name;\n};\n\nclass PsychicRequest\n{\n    friend PsychicHttpServer;\n    friend PsychicResponse;\n\n  protected:\n    PsychicHttpServer* _server;\n    httpd_req_t* _req;\n    SessionData* _session;\n    PsychicClient* _client;\n    PsychicEndpoint* _endpoint;\n\n    http_method _method;\n    String _uri;\n    String _query;\n    String _body;\n    esp_err_t _bodyParsed = ESP_ERR_NOT_FINISHED;\n    esp_err_t _paramsParsed = ESP_ERR_NOT_FINISHED;\n\n    std::list<PsychicWebParameter*> _params;\n\n    PsychicResponse* _response;\n\n    void _setUri(const char* uri);\n    void _addParams(const String& params, bool post);\n    void _parseGETParams();\n    void _parsePOSTParams();\n\n    const String _extractParam(const String& authReq, const String& param, const char delimit);\n    const String _getRandomHexString();\n\n  public:\n    PsychicRequest(PsychicHttpServer* server, httpd_req_t* req);\n    virtual ~PsychicRequest();\n\n    void* _tempObject;\n\n    PsychicHttpServer* server();\n    httpd_req_t* request();\n    virtual PsychicClient* client();\n\n    PsychicEndpoint* endpoint();\n    void setEndpoint(PsychicEndpoint* endpoint);\n\n#ifdef PSY_ENABLE_REGEX\n    bool getRegexMatches(std::smatch& matches, bool use_full_uri = false);\n#endif\n\n    bool isMultipart();\n    esp_err_t loadBody();\n\n    const String header(const char* name);\n    bool hasHeader(const char* name);\n\n    static void freeSession(void* ctx);\n    bool hasSessionKey(const String& key);\n    const String getSessionKey(const String& key);\n    void setSessionKey(const String& key, const String& value);\n\n    bool hasCookie(const char* key, size_t* size = nullptr);\n\n    PsychicResponse* response() { return _response; }\n    void replaceResponse(PsychicResponse* response);\n    void addResponseHeader(const char* key, const char* value);\n    std::list<HTTPHeader>& getResponseHeaders();\n\n    /**\n     * @brief   Get the value string of a cookie value from the \"Cookie\" request headers by cookie name.\n     *\n     * @param[in]       key             The cookie name to be searched in the request\n     * @param[out]      buffer          Pointer to the buffer into which the value of cookie will be copied if the cookie is found\n     * @param[inout]    size            Pointer to size of the user buffer \"val\". This variable will contain cookie length if\n     *                                  ESP_OK is returned and required buffer length in case ESP_ERR_HTTPD_RESULT_TRUNC is returned.\n     *\n     * @return\n     *  - ESP_OK : Key is found in the cookie string and copied to buffer. The value is null-terminated.\n     *  - ESP_ERR_NOT_FOUND          : Key not found\n     *  - ESP_ERR_INVALID_ARG        : Null arguments\n     *  - ESP_ERR_HTTPD_RESULT_TRUNC : Value string truncated\n     *  - ESP_ERR_NO_MEM             : Memory allocation failure\n     */\n    esp_err_t getCookie(const char* key, char* buffer, size_t* size);\n\n    // convenience / lazy function for getting cookies.\n    String getCookie(const char* key);\n\n    http_method method();       // returns the HTTP method used as enum value (eg. HTTP_GET)\n    const String methodStr();   // returns the HTTP method used as a string (eg. \"GET\")\n    const String path();        // returns the request path (eg /page?foo=bar returns \"/page\")\n    const String& uri();        // returns the full request uri (eg /page?foo=bar)\n    const String& query();      // returns the request query data (eg /page?foo=bar returns \"foo=bar\")\n    const String host();        // returns the requested host (request to http://psychic.local/foo will return \"psychic.local\")\n    const String contentType(); // returns the Content-Type header value\n    size_t contentLength();     // returns the Content-Length header value\n    const String& body();       // returns the body of the request\n    const ContentDisposition getContentDisposition();\n    const char* version() { return \"HTTP/1.1\"; }\n\n    const String& queryString() { return query(); } // compatability function.  same as query()\n    const String& url() { return uri(); }           // compatability function.  same as uri()\n\n    void loadParams();\n    PsychicWebParameter* addParam(PsychicWebParameter* param);\n    PsychicWebParameter* addParam(const String& name, const String& value, bool decode = true, bool post = false);\n    bool hasParam(const char* key);\n    bool hasParam(const char* key, bool isPost, bool isFile = false);\n    PsychicWebParameter* getParam(const char* name);\n    PsychicWebParameter* getParam(const char* name, bool isPost, bool isFile = false);\n    const std::list<PsychicWebParameter*>& getParams() { return _params; }\n\n    const String getFilename();\n\n    bool authenticate(const char * username, const char * password, bool passwordIsHashed = false);\n    esp_err_t requestAuthentication(HTTPAuthMethod mode, const char* realm, const char* authFailMsg);\n};\n\n#endif // PsychicRequest_h\n"
  },
  {
    "path": "src/PsychicResponse.cpp",
    "content": "#include \"PsychicResponse.h\"\n#include \"PsychicRequest.h\"\n#include <http_status.h>\n\nPsychicResponse::PsychicResponse(PsychicRequest* request) : _request(request),\n                                                            _code(0),\n                                                            _status(\"\"),\n                                                            _contentType(emptyString),\n                                                            _contentLength(0),\n                                                            _body(\"\")\n{\n  // get our global headers out of the way\n  for (auto& header : DefaultHeaders::Instance().getHeaders())\n    addHeader(header.field.c_str(), header.value.c_str());\n}\n\nPsychicResponse::~PsychicResponse()\n{\n  _headers.clear();\n}\n\nvoid PsychicResponse::addHeader(const char* field, const char* value)\n{\n  // erase any existing ones.\n  for (auto itr = _headers.begin(); itr != _headers.end();) {\n    if (itr->field.equalsIgnoreCase(field))\n      itr = _headers.erase(itr);\n    else\n      itr++;\n  }\n\n  // now add it.\n  _headers.push_back({field, value});\n}\n\nvoid PsychicResponse::setCookie(const char* name, const char* value, unsigned long secondsFromNow, const char* extras)\n{\n  time_t now = time(nullptr);\n\n  String output;\n  output = urlEncode(name) + \"=\" + urlEncode(value);\n\n  // if current time isn't modern, default to using max age\n  if (now < 1700000000)\n    output += \"; Max-Age=\" + String(secondsFromNow);\n  // otherwise, set an expiration date\n  else {\n    time_t expirationTimestamp = now + secondsFromNow;\n\n    // Convert the expiration timestamp to a formatted string for the \"expires\" attribute\n    struct tm* tmInfo = gmtime(&expirationTimestamp);\n    char expires[30];\n    strftime(expires, sizeof(expires), \"%a, %d %b %Y %H:%M:%S GMT\", tmInfo);\n    output += \"; Expires=\" + String(expires);\n  }\n\n  // did we get any extras?\n  if (strlen(extras))\n    output += \"; \" + String(extras);\n\n  // okay, add it in.\n  addHeader(\"Set-Cookie\", output.c_str());\n}\n\nvoid PsychicResponse::setCode(int code)\n{\n  _code = code;\n}\n\nvoid PsychicResponse::setContentType(const char* contentType)\n{\n  _contentType = contentType;\n}\n\nvoid PsychicResponse::setContent(const char* content)\n{\n  _body = content;\n  setContentLength(strlen(content));\n}\n\nvoid PsychicResponse::setContent(const uint8_t* content, size_t len)\n{\n  _body = (char*)content;\n  setContentLength(len);\n}\n\nconst char* PsychicResponse::getContent()\n{\n  return _body;\n}\n\nsize_t PsychicResponse::getContentLength()\n{\n  return _contentLength;\n}\n\nesp_err_t PsychicResponse::send()\n{\n  if (!_code)\n    setCode(200);\n  // our headers too\n  this->sendHeaders();\n\n  // now send it off\n  esp_err_t err = httpd_resp_send(_request->request(), getContent(), getContentLength());\n\n  // did something happen?\n  if (err != ESP_OK)\n    ESP_LOGE(PH_TAG, \"Send response failed (%s)\", esp_err_to_name(err));\n\n  return err;\n}\n\nvoid PsychicResponse::sendHeaders()\n{\n  // esp-idf makes you set the whole status.\n  sprintf(_status, \"%d %s\", _code, http_status_reason(_code));\n  httpd_resp_set_status(_request->request(), _status);\n\n  // set the content type\n  httpd_resp_set_type(_request->request(), _contentType.c_str());\n\n  // now do our individual headers\n  for (auto& header : _headers)\n    httpd_resp_set_hdr(this->_request->request(), header.field.c_str(), header.value.c_str());\n}\n\nesp_err_t PsychicResponse::sendChunk(uint8_t* chunk, size_t chunksize)\n{\n  /* Send the buffer contents as HTTP response chunk */\n  ESP_LOGD(PH_TAG, \"Sending chunk: %d\", chunksize);\n  esp_err_t err = httpd_resp_send_chunk(request(), (char*)chunk, chunksize);\n  if (err != ESP_OK) {\n    ESP_LOGE(PH_TAG, \"File sending failed (%s)\", esp_err_to_name(err));\n\n    /* Abort sending file */\n    httpd_resp_sendstr_chunk(this->_request->request(), NULL);\n  }\n\n  return err;\n}\n\nesp_err_t PsychicResponse::finishChunking()\n{\n  /* Respond with an empty chunk to signal HTTP response completion */\n  return httpd_resp_send_chunk(this->_request->request(), NULL, 0);\n}\n\nesp_err_t PsychicResponse::redirect(const char* url)\n{\n  if (!_code)\n    setCode(301);\n  addHeader(\"Location\", url);\n  return send();\n}\n\nesp_err_t PsychicResponse::send(int code)\n{\n  setCode(code);\n  return send();\n}\n\nesp_err_t PsychicResponse::send(const char* content)\n{\n  if (!_code)\n    setCode(200);\n  if (_contentType.isEmpty())\n    setContentType(\"text/html\");\n  setContent(content);\n  return send();\n}\n\nesp_err_t PsychicResponse::send(const char* contentType, const char* content)\n{\n  if (!_code)\n    setCode(200);\n  setContentType(contentType);\n  setContent(content);\n  return send();\n}\n\nesp_err_t PsychicResponse::send(int code, const char* contentType, const char* content)\n{\n  setCode(code);\n  setContentType(contentType);\n  setContent(content);\n  return send();\n}\n\nesp_err_t PsychicResponse::send(int code, const char* contentType, const uint8_t* content, size_t len)\n{\n  setCode(code);\n  setContentType(contentType);\n  setContent(content, len);\n  return send();\n}\n\nesp_err_t PsychicResponse::error(httpd_err_code_t code, const char* message)\n{\n  return httpd_resp_send_err(_request->_req, code, message);\n}\n\nhttpd_req_t* PsychicResponse::request()\n{\n  return _request->_req;\n}\n"
  },
  {
    "path": "src/PsychicResponse.h",
    "content": "#ifndef PsychicResponse_h\n#define PsychicResponse_h\n\n#include \"PsychicCore.h\"\n#include \"time.h\"\n\nclass PsychicRequest;\n\nclass PsychicResponse\n{\n  protected:\n    PsychicRequest* _request;\n\n    int _code;\n    char _status[60];\n    std::list<HTTPHeader> _headers;\n    String _contentType;\n    int64_t _contentLength;\n    const char* _body;\n\n  public:\n    PsychicResponse(PsychicRequest* request);\n    virtual ~PsychicResponse();\n\n    const char* version() { return \"HTTP/1.1\"; }\n\n    void setCode(int code);\n    int getCode() { return _code; }\n    \n    void setContentType(const char* contentType);\n    String& getContentType() { return _contentType; }\n\n    void setContentLength(int64_t contentLength) { _contentLength = contentLength; }\n    int64_t getContentLength(int64_t contentLength) { return _contentLength; }\n\n    void addHeader(const char* field, const char* value);\n    std::list<HTTPHeader>& headers() { return _headers; }\n\n    void setCookie(const char* key, const char* value, unsigned long max_age = 60 * 60 * 24 * 30, const char* extras = \"\");\n\n    void setContent(const char* content);\n    void setContent(const uint8_t* content, size_t len);\n\n    const char* getContent();\n    size_t getContentLength();\n\n    virtual esp_err_t send();\n    void sendHeaders();\n    esp_err_t sendChunk(uint8_t* chunk, size_t chunksize);\n    esp_err_t finishChunking();\n\n    esp_err_t redirect(const char* url);\n    esp_err_t send(int code);\n    esp_err_t send(const char* content);\n    esp_err_t send(const char* contentType, const char* content);\n    esp_err_t send(int code, const char* contentType, const char* content);\n    esp_err_t send(int code, const char* contentType, const uint8_t* content, size_t len);\n    esp_err_t error(httpd_err_code_t code, const char* message);\n\n    httpd_req_t* request();\n};\n\nclass PsychicResponseDelegate\n{\n  protected:\n    PsychicResponse* _response;\n\n  public:\n    PsychicResponseDelegate(PsychicResponse* response) : _response(response) {}\n    virtual ~PsychicResponseDelegate() {}\n\n    const char* version() { return _response->version(); }\n\n    void setCode(int code) { _response->setCode(code); }\n\n    void setContentType(const char* contentType) { _response->setContentType(contentType); }\n    String& getContentType() { return _response->getContentType(); }\n\n    void setContentLength(int64_t contentLength) { _response->setContentLength(contentLength); }\n    int64_t getContentLength(int64_t contentLength) { return _response->getContentLength(); }\n\n    void addHeader(const char* field, const char* value) { _response->addHeader(field, value); }\n\n    void setCookie(const char* key, const char* value, unsigned long max_age = 60 * 60 * 24 * 30, const char* extras = \"\") { _response->setCookie(key, value, max_age, extras); }\n\n    void setContent(const char* content) { _response->setContent(content); }\n    void setContent(const uint8_t* content, size_t len) { _response->setContent(content, len); }\n\n    const char* getContent() { return _response->getContent(); }\n    size_t getContentLength() { return _response->getContentLength(); }\n\n    esp_err_t send() { return _response->send(); }\n    void sendHeaders() { _response->sendHeaders(); }\n\n    esp_err_t sendChunk(uint8_t* chunk, size_t chunksize) { return _response->sendChunk(chunk, chunksize); }\n    esp_err_t finishChunking() { return _response->finishChunking(); }\n\n    esp_err_t redirect(const char* url) { return _response->redirect(url); }\n    esp_err_t send(int code) { return _response->send(code); }\n    esp_err_t send(const char* content) { return _response->send(content); }\n    esp_err_t send(const char* contentType, const char* content) { return _response->send(contentType, content); }\n    esp_err_t send(int code, const char* contentType, const char* content) { return _response->send(code, contentType, content); }\n    esp_err_t send(int code, const char* contentType, const uint8_t* content, size_t len) { return _response->send(code, contentType, content, len); }\n    esp_err_t error(httpd_err_code_t code, const char* message) { return _response->error(code, message); }\n\n    httpd_req_t* request() { return _response->request(); }\n};\n\n#endif // PsychicResponse_h"
  },
  {
    "path": "src/PsychicRewrite.cpp",
    "content": "#include \"PsychicRewrite.h\"\n#include \"PsychicRequest.h\"\n\n    PsychicRewrite::PsychicRewrite(const char* from, const char* to):\n\t\t_fromPath(from),\n\t\t_toUri(to),\n\t\t_toPath(String()),\n\t\t_toParams(String()),\n\t\t_filter(nullptr)\n\t{\n      int index = _toUri.indexOf('?');\n      if (index > 0) {\n        _toParams = _toUri.substring(index + 1);\n        _toPath = _toUri.substring(0, index);\n      }\n\t  else\n\t  \t_toPath = _toUri;\n    }\n    PsychicRewrite::~PsychicRewrite()\n\t{\n\t\t\n\t}\n\n    PsychicRewrite* PsychicRewrite::setFilter(PsychicRequestFilterFunction fn)\n\t{\n\t\t_filter = fn; return this;\n\t}\n    \n\tbool PsychicRewrite::filter(PsychicRequest *request) const\n\t{\n\t\treturn _filter == nullptr || _filter(request);\n\t}\n    \n\tconst String& PsychicRewrite::from(void) const\n\t{\n\t\treturn _fromPath;\n\t}\n    const String& PsychicRewrite::toUrl(void) const\n\t{\n\t\treturn _toUri;\n\t}\n    \n\tconst String& PsychicRewrite::params(void) const\n\t{\n\t\treturn _toParams;\n\t}\n\n    bool PsychicRewrite::match(PsychicRequest *request)\n\t{\n\t\tif (!filter(request))\n\t\t\treturn false;\n\n\t\treturn _fromPath == request->path();\n\t}"
  },
  {
    "path": "src/PsychicRewrite.h",
    "content": "#ifndef PsychicRewrite_h\n#define PsychicRewrite_h\n\n#include \"PsychicCore.h\"\n\n/*\n * REWRITE :: One instance can be handle any Request (done by the Server)\n * */\n\nclass PsychicRewrite {\n  protected:\n    String _fromPath;\n    String _toUri;\n    String _toPath;\n    String _toParams;\n    PsychicRequestFilterFunction _filter;\n\n  public:\n    PsychicRewrite(const char* from, const char* to);\n    virtual ~PsychicRewrite();\n\n    PsychicRewrite* setFilter(PsychicRequestFilterFunction fn);\n    bool filter(PsychicRequest *request) const;\n    const String& from(void) const;\n    const String& toUrl(void) const;\n    const String& params(void) const;\n    virtual bool match(PsychicRequest *request);\n};\n\n#endif"
  },
  {
    "path": "src/PsychicStaticFileHander.cpp",
    "content": "#include \"PsychicStaticFileHandler.h\"\n\n/*************************************/\n/*  PsychicStaticFileHandler         */\n/*************************************/\n\nPsychicStaticFileHandler::PsychicStaticFileHandler(const char* uri, FS& fs, const char* path, const char* cache_control)\n    : _fs(fs), _uri(uri), _path(path), _default_file(\"index.html\"), _cache_control(cache_control), _last_modified(\"\")\n{\n  // Ensure leading '/'\n  if (_uri.length() == 0 || _uri[0] != '/')\n    _uri = \"/\" + _uri;\n  if (_path.length() == 0 || _path[0] != '/')\n    _path = \"/\" + _path;\n\n  // If path ends with '/' we assume a hint that this is a directory to improve performance.\n  // However - if it does not end with '/' we, can't assume a file, path can still be a directory.\n  _isDir = _path[_path.length() - 1] == '/';\n\n  // Remove the trailing '/' so we can handle default file\n  // Notice that root will be \"\" not \"/\"\n  if (_uri[_uri.length() - 1] == '/')\n    _uri = _uri.substring(0, _uri.length() - 1);\n  if (_path[_path.length() - 1] == '/')\n    _path = _path.substring(0, _path.length() - 1);\n\n  // Reset stats\n  _gzipFirst = false;\n  _gzipStats = 0xF8;\n}\n\nPsychicStaticFileHandler* PsychicStaticFileHandler::setIsDir(bool isDir)\n{\n  _isDir = isDir;\n  return this;\n}\n\nPsychicStaticFileHandler* PsychicStaticFileHandler::setDefaultFile(const char* filename)\n{\n  _default_file = filename;\n  return this;\n}\n\nPsychicStaticFileHandler* PsychicStaticFileHandler::setCacheControl(const char* cache_control)\n{\n  _cache_control = cache_control;\n  return this;\n}\n\nPsychicStaticFileHandler* PsychicStaticFileHandler::setLastModified(const char* last_modified)\n{\n  _last_modified = String(last_modified);\n  return this;\n}\n\nPsychicStaticFileHandler* PsychicStaticFileHandler::setLastModified(struct tm* last_modified)\n{\n  char result[30];\n  strftime(result, 30, \"%a, %d %b %Y %H:%M:%S %Z\", last_modified);\n  return setLastModified((const char*)result);\n}\n\nbool PsychicStaticFileHandler::canHandle(PsychicRequest* request)\n{\n  if (request->method() != HTTP_GET) {\n    ESP_LOGD(PH_TAG, \"Request %s refused by PsychicStaticFileHandler: %s\", request->uri().c_str(), request->methodStr().c_str());\n    return false;\n  }\n\n  if (!request->uri().startsWith(_uri)) {\n    ESP_LOGD(PH_TAG, \"Request %s refused by PsychicStaticFileHandler: does not start with %s\", request->uri().c_str(), _uri.c_str());\n    return false;\n  }\n\n  if (_getFile(request)) {\n    return true;\n  }\n\n  ESP_LOGD(PH_TAG, \"Request %s refused by PsychicStaticFileHandler: file not found\", request->uri().c_str());\n  return false;\n}\n\nbool PsychicStaticFileHandler::_getFile(PsychicRequest* request)\n{\n  // Remove the found uri\n  String path = request->uri().substring(_uri.length());\n\n  // Reject any path that contains directory traversal sequences\n  if (path.indexOf(\"..\") >= 0)\n    return false;\n\n  // We can skip the file check and look for default if request is to the root of a directory or that request path ends with '/'\n  bool canSkipFileCheck = (_isDir && path.length() == 0) || (path.length() && path[path.length() - 1] == '/');\n\n  path = _path + path;\n\n  // Do we have a file or .gz file\n  if (!canSkipFileCheck && _fileExists(path))\n    return true;\n\n  // Can't handle if not default file\n  if (_default_file.length() == 0)\n    return false;\n\n  // Try to add default file, ensure there is a trailing '/' ot the path.\n  if (path.length() == 0 || path[path.length() - 1] != '/')\n    path += \"/\";\n  path += _default_file;\n\n  return _fileExists(path);\n}\n\n#define FILE_IS_REAL(f) (f == true && !f.isDirectory())\n\nbool PsychicStaticFileHandler::_fileExists(const String& path)\n{\n  bool fileFound = false;\n  bool gzipFound = false;\n\n  String gzip = path + \".gz\";\n\n  if (_gzipFirst) {\n    _file = _fs.open(gzip, \"r\");\n    gzipFound = FILE_IS_REAL(_file);\n    if (!gzipFound) {\n      _file = _fs.open(path, \"r\");\n      fileFound = FILE_IS_REAL(_file);\n    }\n  } else {\n    _file = _fs.open(path, \"r\");\n    fileFound = FILE_IS_REAL(_file);\n    if (!fileFound) {\n      _file = _fs.open(gzip, \"r\");\n      gzipFound = FILE_IS_REAL(_file);\n    }\n  }\n\n  bool found = fileFound || gzipFound;\n\n  if (found) {\n    _filename = path;\n\n    // Calculate gzip statistic\n    _gzipStats = (_gzipStats << 1) + (gzipFound ? 1 : 0);\n    if (_gzipStats == 0x00)\n      _gzipFirst = false; // All files are not gzip\n    else if (_gzipStats == 0xFF)\n      _gzipFirst = true; // All files are gzip\n    else\n      _gzipFirst = _countBits(_gzipStats) > 4; // IF we have more gzip files - try gzip first\n  }\n\n  ESP_LOGD(PH_TAG, \"PsychicStaticFileHandler _fileExists(%s): %d\", path.c_str(), found);\n\n  return found;\n}\n\nuint8_t PsychicStaticFileHandler::_countBits(const uint8_t value) const\n{\n  uint8_t w = value;\n  uint8_t n;\n  for (n = 0; w != 0; n++)\n    w &= w - 1;\n  return n;\n}\n\nesp_err_t PsychicStaticFileHandler::handleRequest(PsychicRequest* request, PsychicResponse* res)\n{\n  if (_file == true) {\n    // is it not modified?\n    String etag = String(_file.size());\n    if (_last_modified.length() && _last_modified == request->header(\"If-Modified-Since\")) {\n      _file.close();\n      res->send(304); // Not modified\n    }\n    // does our Etag match?\n    else if (_cache_control.length() && request->hasHeader(\"If-None-Match\") && request->header(\"If-None-Match\").equals(etag)) {\n      _file.close();\n\n      res->addHeader(\"Cache-Control\", _cache_control.c_str());\n      res->addHeader(\"ETag\", etag.c_str());\n      res->setCode(304);\n      res->send();\n    }\n    // nope, send them the full file.\n    else {\n      _file.close();\n      PsychicFileResponse response(res, _fs, _filename);\n\n      if (_last_modified.length())\n        response.addHeader(\"Last-Modified\", _last_modified.c_str());\n      if (_cache_control.length()) {\n        response.addHeader(\"Cache-Control\", _cache_control.c_str());\n        response.addHeader(\"ETag\", etag.c_str());\n      }\n\n      return response.send();\n    }\n  } else {\n    return res->send(404);\n  }\n\n  return ESP_OK;\n}"
  },
  {
    "path": "src/PsychicStaticFileHandler.h",
    "content": "#ifndef PsychicStaticFileHandler_h\n#define PsychicStaticFileHandler_h\n\n#include \"PsychicCore.h\"\n#include \"PsychicFileResponse.h\"\n#include \"PsychicRequest.h\"\n#include \"PsychicResponse.h\"\n#include \"PsychicWebHandler.h\"\n\nclass PsychicStaticFileHandler : public PsychicWebHandler\n{\n    using File = fs::File;\n    using FS = fs::FS;\n\n  private:\n    bool _getFile(PsychicRequest* request);\n    bool _fileExists(const String& path);\n    uint8_t _countBits(const uint8_t value) const;\n\n  protected:\n    FS _fs;\n    File _file;\n    String _filename;\n    String _uri;\n    String _path;\n    String _default_file;\n    String _cache_control;\n    String _last_modified;\n    bool _isDir;\n    bool _gzipFirst;\n    uint8_t _gzipStats;\n\n  public:\n    PsychicStaticFileHandler(const char* uri, FS& fs, const char* path, const char* cache_control);\n    bool canHandle(PsychicRequest* request) override;\n    esp_err_t handleRequest(PsychicRequest* request, PsychicResponse* response) override;\n    PsychicStaticFileHandler* setIsDir(bool isDir);\n    PsychicStaticFileHandler* setDefaultFile(const char* filename);\n    PsychicStaticFileHandler* setCacheControl(const char* cache_control);\n    PsychicStaticFileHandler* setLastModified(const char* last_modified);\n    PsychicStaticFileHandler* setLastModified(struct tm* last_modified);\n    // PsychicStaticFileHandler* setTemplateProcessor(AwsTemplateProcessor newCallback) {_callback = newCallback; return *this;}\n};\n\n#endif /* PsychicHttp_h */"
  },
  {
    "path": "src/PsychicStreamResponse.cpp",
    "content": "#include \"PsychicStreamResponse.h\"\n#include \"PsychicRequest.h\"\n#include \"PsychicResponse.h\"\n\nPsychicStreamResponse::PsychicStreamResponse(PsychicResponse* response, const String& contentType)\n    : PsychicResponseDelegate(response), _buffer(NULL)\n{\n\n  setContentType(contentType.c_str());\n  addHeader(\"Content-Disposition\", \"inline\");\n}\n\nPsychicStreamResponse::PsychicStreamResponse(PsychicResponse* response, const String& contentType, const String& name)\n    : PsychicResponseDelegate(response), _buffer(NULL)\n{\n\n  setContentType(contentType.c_str());\n\n  char buf[26 + name.length()];\n  snprintf(buf, sizeof(buf), \"attachment; filename=\\\"%s\\\"\", name.c_str());\n  addHeader(\"Content-Disposition\", buf);\n}\n\nPsychicStreamResponse::~PsychicStreamResponse()\n{\n  endSend();\n}\n\nesp_err_t PsychicStreamResponse::beginSend()\n{\n  if (_buffer)\n    return ESP_OK;\n\n  // Buffer to hold ChunkPrinter and stream buffer. Using placement new will keep us at a single allocation.\n  _buffer = (uint8_t*)malloc(STREAM_CHUNK_SIZE + sizeof(ChunkPrinter));\n\n  if (!_buffer) {\n    /* Respond with 500 Internal Server Error */\n    ESP_LOGE(PH_TAG, \"Unable to allocate %zu bytes to send chunk\", STREAM_CHUNK_SIZE + sizeof(ChunkPrinter));\n    httpd_resp_send_err(request(), HTTPD_500_INTERNAL_SERVER_ERROR, \"Unable to allocate memory.\");\n    return ESP_FAIL;\n  }\n\n  _printer = new (_buffer) ChunkPrinter(_response, _buffer + sizeof(ChunkPrinter), STREAM_CHUNK_SIZE);\n\n  sendHeaders();\n  return ESP_OK;\n}\n\nesp_err_t PsychicStreamResponse::endSend()\n{\n  esp_err_t err = ESP_OK;\n\n  if (!_buffer)\n    err = ESP_FAIL;\n  else {\n    _printer->~ChunkPrinter(); // flushed on destruct\n    err = finishChunking();\n    free(_buffer);\n    _buffer = NULL;\n  }\n  return err;\n}\n\nvoid PsychicStreamResponse::flush()\n{\n  if (_buffer)\n    _printer->flush();\n}\n\nsize_t PsychicStreamResponse::write(uint8_t data)\n{\n  return _buffer ? _printer->write(data) : 0;\n}\n\nsize_t PsychicStreamResponse::write(const uint8_t* buffer, size_t size)\n{\n  return _buffer ? _printer->write(buffer, size) : 0;\n}\n\nsize_t PsychicStreamResponse::copyFrom(Stream& stream)\n{\n  if (_buffer)\n    return _printer->copyFrom(stream);\n\n  return 0;\n}\n"
  },
  {
    "path": "src/PsychicStreamResponse.h",
    "content": "#ifndef PsychicStreamResponse_h\n#define PsychicStreamResponse_h\n\n#include \"ChunkPrinter.h\"\n#include \"PsychicCore.h\"\n#include \"PsychicResponse.h\"\n\nclass PsychicRequest;\n\nclass PsychicStreamResponse : public PsychicResponseDelegate, public Print\n{\n  private:\n    ChunkPrinter* _printer;\n    uint8_t* _buffer;\n\n  public:\n    PsychicStreamResponse(PsychicResponse* response, const String& contentType);\n    PsychicStreamResponse(PsychicResponse* response, const String& contentType, const String& name); // Download\n\n    ~PsychicStreamResponse();\n\n    esp_err_t beginSend();\n    esp_err_t endSend();\n\n    void flush() override;\n\n    size_t write(uint8_t data) override;\n    size_t write(const uint8_t* buffer, size_t size) override;\n\n    size_t copyFrom(Stream& stream);\n\n    using Print::write;\n};\n\n#endif // PsychicStreamResponse_h\n"
  },
  {
    "path": "src/PsychicUploadHandler.cpp",
    "content": "#include \"PsychicUploadHandler.h\"\n\nPsychicUploadHandler::PsychicUploadHandler() : PsychicWebHandler(), _uploadCallback(nullptr)\n{\n}\nPsychicUploadHandler::~PsychicUploadHandler() {}\n\nbool PsychicUploadHandler::canHandle(PsychicRequest* request)\n{\n  return true;\n}\n\nesp_err_t PsychicUploadHandler::handleRequest(PsychicRequest* request, PsychicResponse* response)\n{\n  esp_err_t err = ESP_OK;\n\n  /* File cannot be larger than a limit */\n  if (request->contentLength() > request->server()->maxUploadSize)\n  {\n    ESP_LOGE(PH_TAG, \"File too large : %zu bytes\", request->contentLength());\n\n    /* Respond with 400 Bad Request */\n    char error[50];\n    sprintf(error, \"File size must be less than %lu bytes!\", request->server()->maxUploadSize);\n    return httpd_resp_send_err(request->request(), HTTPD_400_BAD_REQUEST, error);\n  }\n\n  // TODO: support for the 100 header.  not sure if we can do it.\n  //  if (request->header(\"Expect\").equals(\"100-continue\"))\n  //  {\n  //    char response[] = \"100 Continue\";\n  //    httpd_socket_send(self->server, httpd_req_to_sockfd(req), response, strlen(response), 0);\n  //  }\n\n  // 2 types of upload requests\n  if (request->isMultipart())\n    err = _multipartUploadHandler(request);\n  else\n    err = _basicUploadHandler(request);\n\n  // we can also call onRequest for some final processing and response\n  if (err == ESP_OK)\n  {\n    if (_requestCallback != NULL)\n      err = _requestCallback(request, response);\n    else\n      err = response->send(\"Upload Successful.\");\n  }\n  else if (err == ESP_ERR_HTTPD_INVALID_REQ)\n    response->send(400, \"text/html\", \"No multipart boundary found.\");\n  else\n    response->send(500, \"text/html\", \"Error processing upload.\");\n\n  return err;\n}\n\nesp_err_t PsychicUploadHandler::_basicUploadHandler(PsychicRequest* request)\n{\n  esp_err_t err = ESP_OK;\n\n  String filename = request->getFilename();\n\n  /* Retrieve the pointer to scratch buffer for temporary storage */\n  char* buf = (char*)malloc(FILE_CHUNK_SIZE);\n  int received;\n  unsigned long index = 0;\n\n  /* Content length of the request gives the size of the file being uploaded */\n  int remaining = request->contentLength();\n\n  while (remaining > 0)\n  {\n#ifdef ENABLE_ASYNC\n    httpd_sess_update_lru_counter(request->server()->server, request->client()->socket());\n#endif\n\n    // ESP_LOGD(PH_TAG, \"Remaining size : %d\", remaining);\n\n    /* Receive the file part by part into a buffer */\n    if ((received = httpd_req_recv(request->request(), buf, min(remaining, FILE_CHUNK_SIZE))) <= 0)\n    {\n      /* Retry if timeout occurred */\n      if (received == HTTPD_SOCK_ERR_TIMEOUT)\n        continue;\n      // bail if we got an error\n      else if (received == HTTPD_SOCK_ERR_FAIL)\n      {\n        ESP_LOGE(PH_TAG, \"Socket error\");\n        err = ESP_FAIL;\n        break;\n      }\n    }\n\n    // call our upload callback here.\n    if (_uploadCallback != NULL)\n    {\n      err = _uploadCallback(request, filename, index, (uint8_t*)buf, received, (remaining - received == 0));\n      if (err != ESP_OK)\n        break;\n    }\n    else\n    {\n      ESP_LOGE(PH_TAG, \"No upload callback specified!\");\n      err = ESP_FAIL;\n      break;\n    }\n\n    /* Keep track of remaining size of the file left to be uploaded */\n    if (received > 0) \n    {\n      remaining -= received;\n      index += received;\n    }\n  }\n\n  // dont forget to free our buffer\n  free(buf);\n\n  return err;\n}\n\nesp_err_t PsychicUploadHandler::_multipartUploadHandler(PsychicRequest* request)\n{\n  MultipartProcessor mpp(request, _uploadCallback);\n  return mpp.process();\n}\n\nPsychicUploadHandler* PsychicUploadHandler::onUpload(PsychicUploadCallback fn)\n{\n  _uploadCallback = fn;\n  return this;\n}\n"
  },
  {
    "path": "src/PsychicUploadHandler.h",
    "content": "#ifndef PsychicUploadHandler_h\n#define PsychicUploadHandler_h\n\n#include \"MultipartProcessor.h\"\n#include \"PsychicCore.h\"\n#include \"PsychicHttpServer.h\"\n#include \"PsychicRequest.h\"\n#include \"PsychicWebHandler.h\"\n\n/*\n * HANDLER :: Can be attached to any endpoint or as a generic request handler.\n */\n\nclass PsychicUploadHandler : public PsychicWebHandler\n{\n  protected:\n    esp_err_t _basicUploadHandler(PsychicRequest* request);\n    esp_err_t _multipartUploadHandler(PsychicRequest* request);\n\n    PsychicUploadCallback _uploadCallback;\n\n  public:\n    PsychicUploadHandler();\n    ~PsychicUploadHandler();\n\n    bool canHandle(PsychicRequest* request) override;\n    esp_err_t handleRequest(PsychicRequest* request, PsychicResponse* response) override;\n\n    PsychicUploadHandler* onUpload(PsychicUploadCallback fn);\n};\n\n#endif // PsychicUploadHandler_h"
  },
  {
    "path": "src/PsychicVersion.h",
    "content": "// Copyright 2019 Espressif Systems (Shanghai) PTE LTD\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n#pragma once\n\n/** Major version number (X.x.x) */\n#define PSYCHIC_VERSION_MAJOR 2\n/** Minor version number (x.X.x) */\n#define PSYCHIC_VERSION_MINOR 2\n/** Patch version number (x.x.X) */\n#define PSYCHIC_VERSION_PATCH 0\n\n/**\n * Macro to convert PsychicHttp version number into an integer\n *\n * To be used in comparisons, such as PSYCHIC_VERSION >= PSYCHIC_VERSION_VAL(2, 0, 0)\n */\n#define PSYCHIC_VERSION_VAL(major, minor, patch) ((major << 16) | (minor << 8) | (patch))\n\n/**\n * Current PsychicHttp version, as an integer\n *\n * To be used in comparisons, such as PSYCHIC_VERSION >= PSYCHIC_VERSION_VAL(2, 0, 0)\n */\n#define PSYCHIC_VERSION PSYCHIC_VERSION_VAL(PSYCHIC_VERSION_MAJOR, PSYCHIC_VERSION_MINOR, PSYCHIC_VERSION_PATCH)\n\n/**\n * Current PsychicHttp version, as string\n */\n#ifndef PSYCHIC_df2xstr\n  #define PSYCHIC_df2xstr(s) #s\n#endif\n#ifndef PSYCHIC_df2str\n  #define PSYCHIC_df2str(s) PSYCHIC_df2xstr(s)\n#endif\n#define PSYCHIC_VERSION_STR PSYCHIC_df2str(PSYCHIC_VERSION_MAJOR) \".\" PSYCHIC_df2str(PSYCHIC_VERSION_MINOR) \".\" PSYCHIC_df2str(PSYCHIC_VERSION_PATCH)\n"
  },
  {
    "path": "src/PsychicWebHandler.cpp",
    "content": "#include \"PsychicWebHandler.h\"\n\nPsychicWebHandler::PsychicWebHandler() : PsychicHandler(),\n                                         _requestCallback(NULL),\n                                         _onOpen(NULL),\n                                         _onClose(NULL)\n{\n}\nPsychicWebHandler::~PsychicWebHandler() {}\n\nbool PsychicWebHandler::canHandle(PsychicRequest* request)\n{\n  return true;\n}\n\nesp_err_t PsychicWebHandler::handleRequest(PsychicRequest* request, PsychicResponse* response)\n{\n  // lookup our client\n  PsychicClient* client = checkForNewClient(request->client());\n  if (client->isNew)\n    openCallback(client);\n\n  /* Request body cannot be larger than a limit */\n  if (request->contentLength() > request->server()->maxRequestBodySize)\n  {\n    ESP_LOGE(PH_TAG, \"Request body too large : %zu bytes\", request->contentLength());\n\n    /* Respond with 400 Bad Request */\n    char error[60];\n    sprintf(error, \"Request body must be less than %lu bytes!\", request->server()->maxRequestBodySize);\n    response->send(400, \"text/html\", error);\n\n    /* Return failure to close underlying connection else the incoming file content will keep the socket busy */\n    return ESP_FAIL;\n  }\n\n  // get our body loaded up.\n  esp_err_t err = request->loadBody();\n  if (err != ESP_OK)\n    return response->send(400, \"text/html\", \"Error loading request body.\");\n\n  // load our params in.\n  request->loadParams();\n\n  // okay, pass on to our callback.\n  if (this->_requestCallback != NULL)\n    err = this->_requestCallback(request, response);\n\n  return err;\n}\n\nPsychicWebHandler* PsychicWebHandler::onRequest(PsychicHttpRequestCallback fn)\n{\n  _requestCallback = fn;\n  return this;\n}\n\nvoid PsychicWebHandler::openCallback(PsychicClient* client)\n{\n  if (_onOpen != NULL)\n    _onOpen(client);\n}\n\nvoid PsychicWebHandler::closeCallback(PsychicClient* client)\n{\n  if (_onClose != NULL)\n    _onClose(getClient(client));\n}\n\nPsychicWebHandler* PsychicWebHandler::onOpen(PsychicClientCallback fn)\n{\n  _onOpen = fn;\n  return this;\n}\n\nPsychicWebHandler* PsychicWebHandler::onClose(PsychicClientCallback fn)\n{\n  _onClose = fn;\n  return this;\n}"
  },
  {
    "path": "src/PsychicWebHandler.h",
    "content": "#ifndef PsychicWebHandler_h\n#define PsychicWebHandler_h\n\n// #include \"PsychicCore.h\"\n// #include \"PsychicHttpServer.h\"\n// #include \"PsychicRequest.h\"\n#include \"PsychicHandler.h\"\n\n/*\n * HANDLER :: Can be attached to any endpoint or as a generic request handler.\n */\n\nclass PsychicWebHandler : public PsychicHandler\n{\n  protected:\n    PsychicHttpRequestCallback _requestCallback;\n    PsychicClientCallback _onOpen;\n    PsychicClientCallback _onClose;\n\n  public:\n    PsychicWebHandler();\n    ~PsychicWebHandler();\n\n    virtual bool canHandle(PsychicRequest* request) override;\n    virtual esp_err_t handleRequest(PsychicRequest* request, PsychicResponse* response) override;\n    PsychicWebHandler* onRequest(PsychicHttpRequestCallback fn);\n\n    virtual void openCallback(PsychicClient* client);\n    virtual void closeCallback(PsychicClient* client);\n\n    PsychicWebHandler* onOpen(PsychicClientCallback fn);\n    PsychicWebHandler* onClose(PsychicClientCallback fn);\n};\n\n#endif"
  },
  {
    "path": "src/PsychicWebParameter.h",
    "content": "#ifndef PsychicWebParameter_h\n#define PsychicWebParameter_h\n\n/*\n * PARAMETER :: Chainable object to hold GET/POST and FILE parameters\n * */\n\nclass PsychicWebParameter\n{\n  private:\n    String _name;\n    String _value;\n    size_t _size;\n    bool _isForm;\n    bool _isFile;\n\n  public:\n    PsychicWebParameter(const String& name, const String& value, bool form = false, bool file = false, size_t size = 0) : _name(name), _value(value), _size(size), _isForm(form), _isFile(file) {}\n    const String& name() const { return _name; }\n    const String& value() const { return _value; }\n    size_t size() const { return _size; }\n    bool isPost() const { return _isForm; }\n    bool isFile() const { return _isFile; }\n};\n\n#endif // PsychicWebParameter_h"
  },
  {
    "path": "src/PsychicWebSocket.cpp",
    "content": "#include \"PsychicWebSocket.h\"\n\n/*************************************/\n/*  PsychicWebSocketRequest      */\n/*************************************/\n\nPsychicWebSocketRequest::PsychicWebSocketRequest(PsychicRequest* req) : PsychicRequest(req->server(), req->request()),\n                                                                        _client(req->client())\n{\n}\n\nPsychicWebSocketRequest::~PsychicWebSocketRequest()\n{\n}\n\nPsychicWebSocketClient* PsychicWebSocketRequest::client()\n{\n  return &_client;\n}\n\nesp_err_t PsychicWebSocketRequest::reply(httpd_ws_frame_t* ws_pkt)\n{\n  return httpd_ws_send_frame(this->_req, ws_pkt);\n}\n\nesp_err_t PsychicWebSocketRequest::reply(httpd_ws_type_t op, const void* data, size_t len)\n{\n  httpd_ws_frame_t ws_pkt;\n  memset(&ws_pkt, 0, sizeof(httpd_ws_frame_t));\n\n  ws_pkt.payload = (uint8_t*)data;\n  ws_pkt.len = len;\n  ws_pkt.type = op;\n\n  return this->reply(&ws_pkt);\n}\n\nesp_err_t PsychicWebSocketRequest::reply(const char* buf)\n{\n  return this->reply(HTTPD_WS_TYPE_TEXT, buf, strlen(buf));\n}\n\n/*************************************/\n/*  PsychicWebSocketClient   */\n/*************************************/\n\nPsychicWebSocketClient::PsychicWebSocketClient(PsychicClient* client)\n    : PsychicClient(client->server(), client->socket())\n{\n}\n\nPsychicWebSocketClient::~PsychicWebSocketClient()\n{\n}\n\nvoid PsychicWebSocketClient::_sendMessageCallback(esp_err_t err, int socket, void* arg)\n{\n  // free our frame.\n  httpd_ws_frame_t* ws_pkt = (httpd_ws_frame_t*)arg;\n  free(ws_pkt->payload);\n  free(ws_pkt);\n\n  if (err == ESP_OK)\n    return;\n  else if (err == ESP_FAIL)\n    ESP_LOGE(PH_TAG, \"Websocket: send - socket error (#%d)\", socket);\n  else if (err == ESP_ERR_INVALID_STATE)\n    ESP_LOGE(PH_TAG, \"Websocket: Handshake was already done beforehand (#%d)\", socket);\n  else if (err == ESP_ERR_INVALID_ARG)\n    ESP_LOGE(PH_TAG, \"Websocket: Argument is invalid (null or non-WebSocket) (#%d)\", socket);\n  else\n    ESP_LOGE(PH_TAG, \"Websocket: Send message unknown error. (#%d)\", socket);\n}\n\nesp_err_t PsychicWebSocketClient::sendMessage(httpd_ws_frame_t* ws_pkt)\n{\n  return sendMessage(ws_pkt->type, ws_pkt->payload, ws_pkt->len);\n}\n\nesp_err_t PsychicWebSocketClient::sendMessage(httpd_ws_type_t op, const void* data, size_t len)\n{\n  // init our frame.\n  httpd_ws_frame_t* ws_pkt = (httpd_ws_frame_t*)malloc(sizeof(httpd_ws_frame_t));\n  if (ws_pkt == NULL) {\n    ESP_LOGE(PH_TAG, \"Websocket: out of memory\");\n    return ESP_ERR_NO_MEM;\n  }\n  memset(ws_pkt, 0, sizeof(httpd_ws_frame_t)); // zero the datastructure out\n\n  // allocate for event text\n  ws_pkt->payload = (uint8_t*)malloc(len);\n  if (ws_pkt->payload == NULL) {\n    ESP_LOGE(PH_TAG, \"Websocket: out of memory\");\n    free(ws_pkt); // free our other memory\n    return ESP_ERR_NO_MEM;\n  }\n  memcpy(ws_pkt->payload, data, len);\n\n  ws_pkt->len = len;\n  ws_pkt->type = op;\n\n  esp_err_t err = httpd_ws_send_data_async(server(), socket(), ws_pkt, PsychicWebSocketClient::_sendMessageCallback, ws_pkt);\n\n  // take care of memory\n  if (err != ESP_OK) {\n    free(ws_pkt->payload);\n    free(ws_pkt);\n  }\n\n  return err;\n}\n\nesp_err_t PsychicWebSocketClient::sendMessage(const char* buf)\n{\n  return this->sendMessage(HTTPD_WS_TYPE_TEXT, buf, strlen(buf));\n}\n\nPsychicWebSocketHandler::PsychicWebSocketHandler() : PsychicHandler(),\n                                                     _onOpen(NULL),\n                                                     _onFrame(NULL),\n                                                     _onClose(NULL)\n{\n}\n\nPsychicWebSocketHandler::~PsychicWebSocketHandler()\n{\n}\n\nPsychicWebSocketClient* PsychicWebSocketHandler::getClient(int socket)\n{\n  PsychicClient* client = PsychicHandler::getClient(socket);\n  if (client == NULL)\n    return NULL;\n\n  if (client->_friend == NULL) {\n    return NULL;\n  }\n\n  return (PsychicWebSocketClient*)client->_friend;\n}\n\nPsychicWebSocketClient* PsychicWebSocketHandler::getClient(PsychicClient* client)\n{\n  return getClient(client->socket());\n}\n\nvoid PsychicWebSocketHandler::addClient(PsychicClient* client)\n{\n  client->_friend = new PsychicWebSocketClient(client);\n  PsychicHandler::addClient(client);\n}\n\nvoid PsychicWebSocketHandler::removeClient(PsychicClient* client)\n{\n  PsychicHandler::removeClient(client);\n  delete (PsychicWebSocketClient*)client->_friend;\n  client->_friend = NULL;\n}\n\nvoid PsychicWebSocketHandler::openCallback(PsychicClient* client)\n{\n  PsychicWebSocketClient* buddy = getClient(client);\n  if (buddy == NULL) {\n    return;\n  }\n\n  if (_onOpen != NULL)\n    _onOpen(getClient(buddy));\n}\n\nvoid PsychicWebSocketHandler::closeCallback(PsychicClient* client)\n{\n  PsychicWebSocketClient* buddy = getClient(client);\n  if (buddy == NULL) {\n    return;\n  }\n\n  if (_onClose != NULL)\n    _onClose(getClient(buddy));\n}\n\nbool PsychicWebSocketHandler::isWebSocket() { return true; }\n\nesp_err_t PsychicWebSocketHandler::handleRequest(PsychicRequest* request, PsychicResponse* response)\n{\n  // lookup our client\n  PsychicClient* client = checkForNewClient(request->client());\n\n  // beginning of the ws URI handler and our onConnect hook\n  if (request->method() == HTTP_GET) {\n    if (client->isNew)\n      openCallback(client);\n\n    return ESP_OK;\n  }\n\n  // prep our request\n  PsychicWebSocketRequest wsRequest(request);\n\n  // init our memory for storing the packet\n  httpd_ws_frame_t ws_pkt;\n  memset(&ws_pkt, 0, sizeof(httpd_ws_frame_t));\n  ws_pkt.type = HTTPD_WS_TYPE_TEXT;\n  uint8_t* buf = NULL;\n\n  /* Set max_len = 0 to get the frame len */\n  esp_err_t ret = httpd_ws_recv_frame(wsRequest.request(), &ws_pkt, 0);\n  if (ret != ESP_OK) {\n    ESP_LOGE(PH_TAG, \"httpd_ws_recv_frame failed to get frame len with %s\", esp_err_to_name(ret));\n    return ret;\n  }\n\n  // okay, now try to load the packet\n  // ESP_LOGD(PH_TAG, \"frame len is %d\", ws_pkt.len);\n  if (ws_pkt.len) {\n    /* ws_pkt.len + 1 is for NULL termination as we are expecting a string */\n    buf = (uint8_t*)calloc(1, ws_pkt.len + 1);\n    if (buf == NULL) {\n      ESP_LOGE(PH_TAG, \"Failed to calloc memory for buf\");\n      return ESP_ERR_NO_MEM;\n    }\n    ws_pkt.payload = buf;\n    /* Set max_len = ws_pkt.len to get the frame payload */\n    ret = httpd_ws_recv_frame(wsRequest.request(), &ws_pkt, ws_pkt.len);\n    if (ret != ESP_OK) {\n      ESP_LOGE(PH_TAG, \"httpd_ws_recv_frame failed with %s\", esp_err_to_name(ret));\n      free(buf);\n      return ret;\n    }\n    // ESP_LOGD(PH_TAG, \"Got packet with message: %s\", ws_pkt.payload);\n  }\n  if (ws_pkt.type == HTTPD_WS_TYPE_PING) {\n      // Respond to ping with pong using the same payload\n      ret = wsRequest.reply(HTTPD_WS_TYPE_PONG, ws_pkt.payload, ws_pkt.len);\n      if (ret != ESP_OK) {\n          ESP_LOGE(PH_TAG, \"Failed to send pong response: %s\", esp_err_to_name(ret));\n      }\n  }\n  // Text messages are our payload.\n  if (ws_pkt.type == HTTPD_WS_TYPE_TEXT || ws_pkt.type == HTTPD_WS_TYPE_BINARY) {\n    if (this->_onFrame != NULL)\n      ret = this->_onFrame(&wsRequest, &ws_pkt);\n  }\n\n  // logging housekeeping\n  if (ret != ESP_OK)\n    ESP_LOGE(PH_TAG, \"httpd_ws_send_frame failed with %s\", esp_err_to_name(ret));\n  // ESP_LOGD(PH_TAG, \"ws_handler: httpd_handle_t=%p, sockfd=%d, client_info:%d\",\n  //   request->server(),\n  //   httpd_req_to_sockfd(request->request()),\n  //   httpd_ws_get_fd_info(request->server()->server, httpd_req_to_sockfd(request->request())));\n\n  // dont forget to release our buffer memory\n  free(buf);\n\n  return ret;\n}\n\nPsychicWebSocketHandler* PsychicWebSocketHandler::onOpen(PsychicWebSocketClientCallback fn)\n{\n  _onOpen = fn;\n  return this;\n}\n\nPsychicWebSocketHandler* PsychicWebSocketHandler::onFrame(PsychicWebSocketFrameCallback fn)\n{\n  _onFrame = fn;\n  return this;\n}\n\nPsychicWebSocketHandler* PsychicWebSocketHandler::onClose(PsychicWebSocketClientCallback fn)\n{\n  _onClose = fn;\n  return this;\n}\n\nvoid PsychicWebSocketHandler::sendAll(httpd_ws_frame_t* ws_pkt)\n{\n  for (PsychicClient* client : _clients) {\n    // ESP_LOGD(PH_TAG, \"Active client (fd=%d) -> sending async message\", client->socket());\n\n    if (client->_friend == NULL) {\n      continue;\n    }\n\n    if (((PsychicWebSocketClient*)client->_friend)->sendMessage(ws_pkt) != ESP_OK)\n      break;\n  }\n}\n\nvoid PsychicWebSocketHandler::sendAll(httpd_ws_type_t op, const void* data, size_t len)\n{\n  httpd_ws_frame_t ws_pkt;\n  memset(&ws_pkt, 0, sizeof(httpd_ws_frame_t));\n\n  ws_pkt.payload = (uint8_t*)data;\n  ws_pkt.len = len;\n  ws_pkt.type = op;\n\n  this->sendAll(&ws_pkt);\n}\n\nvoid PsychicWebSocketHandler::sendAll(const char* buf)\n{\n  this->sendAll(HTTPD_WS_TYPE_TEXT, buf, strlen(buf));\n}\n"
  },
  {
    "path": "src/PsychicWebSocket.h",
    "content": "#ifndef PsychicWebSocket_h\n#define PsychicWebSocket_h\n\n#include \"PsychicCore.h\"\n#include \"PsychicRequest.h\"\n\nclass PsychicWebSocketRequest;\nclass PsychicWebSocketClient;\n\n// callback function definitions\ntypedef std::function<void(PsychicWebSocketClient* client)> PsychicWebSocketClientCallback;\ntypedef std::function<esp_err_t(PsychicWebSocketRequest* request, httpd_ws_frame* frame)> PsychicWebSocketFrameCallback;\n\nclass PsychicWebSocketClient : public PsychicClient\n{\n  protected:\n    static void _sendMessageCallback(esp_err_t err, int socket, void* arg);\n\n  public:\n    PsychicWebSocketClient(PsychicClient* client);\n    ~PsychicWebSocketClient();\n\n    esp_err_t sendMessage(httpd_ws_frame_t* ws_pkt);\n    esp_err_t sendMessage(httpd_ws_type_t op, const void* data, size_t len);\n    esp_err_t sendMessage(const char* buf);\n};\n\nclass PsychicWebSocketRequest : public PsychicRequest\n{\n  private:\n    PsychicWebSocketClient _client;\n\n  public:\n    PsychicWebSocketRequest(PsychicRequest* req);\n    virtual ~PsychicWebSocketRequest();\n\n    PsychicWebSocketClient* client() override;\n\n    esp_err_t reply(httpd_ws_frame_t* ws_pkt);\n    esp_err_t reply(httpd_ws_type_t op, const void* data, size_t len);\n    esp_err_t reply(const char* buf);\n};\n\nclass PsychicWebSocketHandler : public PsychicHandler\n{\n  protected:\n    PsychicWebSocketClientCallback _onOpen;\n    PsychicWebSocketFrameCallback _onFrame;\n    PsychicWebSocketClientCallback _onClose;\n\n  public:\n    PsychicWebSocketHandler();\n    ~PsychicWebSocketHandler();\n\n    PsychicWebSocketClient* getClient(int socket) override;\n    PsychicWebSocketClient* getClient(PsychicClient* client) override;\n    void addClient(PsychicClient* client) override;\n    void removeClient(PsychicClient* client) override;\n    void openCallback(PsychicClient* client) override;\n    void closeCallback(PsychicClient* client) override;\n\n    bool isWebSocket() override final;\n    esp_err_t handleRequest(PsychicRequest* request, PsychicResponse* response) override;\n\n    PsychicWebSocketHandler* onOpen(PsychicWebSocketClientCallback fn);\n    PsychicWebSocketHandler* onFrame(PsychicWebSocketFrameCallback fn);\n    PsychicWebSocketHandler* onClose(PsychicWebSocketClientCallback fn);\n\n    void sendAll(httpd_ws_frame_t* ws_pkt);\n    void sendAll(httpd_ws_type_t op, const void* data, size_t len);\n    void sendAll(const char* buf);\n};\n\n#endif // PsychicWebSocket_h"
  },
  {
    "path": "src/TemplatePrinter.cpp",
    "content": "/************************************************************\n\nTemplatePrinter Class\n\nA basic templating engine for a stream of text.\nThis wraps the Arduino Print interface and writes to any\nPrint interface.\n\nWritten by Christopher Andrews (https://github.com/Chris--A)\n\n************************************************************/\n\n#include \"TemplatePrinter.h\"\n\nvoid TemplatePrinter::resetParam(bool flush)\n{\n  if (flush && _inParam)\n  {\n    _stream.write(_delimiter);\n\n    if (_paramPos)\n      _stream.print(_paramBuffer);\n  }\n\n  memset(_paramBuffer, 0, sizeof(_paramBuffer));\n  _paramPos = 0;\n  _inParam = false;\n}\n\nvoid TemplatePrinter::flush()\n{\n  resetParam(true);\n  _stream.flush();\n}\n\nsize_t TemplatePrinter::write(uint8_t data)\n{\n\n  if (data == _delimiter)\n  {\n\n    // End of parameter, send to callback\n    if (_inParam)\n    {\n\n      // On false, return the parameter place holder as is: not a parameter\n      // Bug fix: ignore parameters that are zero length.\n      if (!_paramPos || !_cb(_stream, _paramBuffer))\n      {\n        resetParam(true);\n        _stream.write(data);\n      }\n      else\n      {\n        resetParam(false);\n      }\n\n      // Start collecting parameter\n    }\n    else\n    {\n      _inParam = true;\n    }\n  }\n  else\n  {\n\n    // Are we collecting\n    if (_inParam)\n    {\n\n      // Is param still valid\n      if (isalnum(data) || data == '_')\n      {\n\n        // Total param len must be 63, 1 for null.\n        if (_paramPos < sizeof(_paramBuffer) - 1)\n        {\n          _paramBuffer[_paramPos++] = data;\n\n          // Not a valid param\n        }\n        else\n        {\n          resetParam(true);\n        }\n      }\n      else\n      {\n        resetParam(true);\n        _stream.write(data);\n      }\n\n      // Just output\n    }\n    else\n    {\n      _stream.write(data);\n    }\n  }\n  return 1;\n}\n\nsize_t TemplatePrinter::copyFrom(Stream& stream)\n{\n  size_t count = 0;\n\n  while (stream.available())\n    count += this->write(stream.read());\n\n  return count;\n}\n"
  },
  {
    "path": "src/TemplatePrinter.h",
    "content": "#ifndef TemplatePrinter_h\n#define TemplatePrinter_h\n\n#include \"PsychicCore.h\"\n#include <Print.h>\n\n/************************************************************\n\nTemplatePrinter Class\n\nA basic templating engine for a stream of text.\nThis wraps the Arduino Print interface and writes to any\nPrint interface.\n\nWritten by Christopher Andrews (https://github.com/Chris--A)\n\n************************************************************/\n\nclass TemplatePrinter;\n\ntypedef std::function<bool(Print& output, const char* parameter)> TemplateCallback;\ntypedef std::function<void(TemplatePrinter& printer)> TemplateSourceCallback;\n\nclass TemplatePrinter : public Print\n{\n  private:\n    bool _inParam;\n    char _paramBuffer[64];\n    uint8_t _paramPos;\n    Print& _stream;\n    TemplateCallback _cb;\n    char _delimiter;\n\n    void resetParam(bool flush);\n\n  public:\n    using Print::write;\n\n    static void start(Print& stream, TemplateCallback cb, TemplateSourceCallback entry)\n    {\n      TemplatePrinter printer(stream, cb);\n      entry(printer);\n    }\n\n    TemplatePrinter(Print& stream, TemplateCallback cb, const char delimeter = '%') : _stream(stream), _cb(cb), _delimiter(delimeter) { resetParam(false); }\n    ~TemplatePrinter() { flush(); }\n\n    void flush() override;\n    size_t write(uint8_t data) override;\n    size_t copyFrom(Stream& stream);\n};\n\n#endif\n"
  },
  {
    "path": "src/UrlEncode.cpp",
    "content": "// MIT License\n// Copyright (c) Masayuki Sugahara\n// https://github.com/plageoj/urlencode\n\n#include \"UrlEncode.h\"\n\nString urlEncode(const char *msg) {\n  const char *hex = \"0123456789ABCDEF\";\n  String encodedMsg = \"\";\n\n  while (*msg != '\\0') {\n    if (\n        ('a' <= *msg && *msg <= 'z') || ('A' <= *msg && *msg <= 'Z') || ('0' <= *msg && *msg <= '9') || *msg == '-' || *msg == '_' || *msg == '.' || *msg == '~') {\n      encodedMsg += *msg;\n    } else {\n      encodedMsg += '%';\n      encodedMsg += hex[(unsigned char)*msg >> 4];\n      encodedMsg += hex[*msg & 0xf];\n    }\n    msg++;\n  }\n  return encodedMsg;\n}\n\nString urlEncode(String msg) {\n  return urlEncode(msg.c_str());\n}"
  },
  {
    "path": "src/UrlEncode.h",
    "content": "// MIT License\n// Copyright (c) Masayuki Sugahara\n// https://github.com/plageoj/urlencode\n\n#ifndef _PLAGEOJ_URLENCODE_H\n#define _PLAGEOJ_URLENCODE_H\n\n#include <Arduino.h>\n\n/**\n * Percent-encodes a string.\n * @param msg UTF-8 string to encode.\n * @returns Percent-encoded string.\n */\nString urlEncode(const char *msg);\n\n/**\n * Percent-encodes a string.\n * @param msg UTF-8 string to encode.\n * @returns Percent-encoded string.\n */\nString urlEncode(String msg);\n\n#endif"
  },
  {
    "path": "src/async_worker.cpp",
    "content": "#include \"async_worker.h\"\n\nbool is_on_async_worker_thread(void)\n{\n  // is our handle one of the known async handles?\n  TaskHandle_t handle = xTaskGetCurrentTaskHandle();\n  for (int i = 0; i < ASYNC_WORKER_COUNT; i++) {\n    if (worker_handles[i] == handle) {\n      return true;\n    }\n  }\n  return false;\n}\n\n// Submit an HTTP req to the async worker queue\nesp_err_t submit_async_req(httpd_req_t* req, httpd_req_handler_t handler)\n{\n  // must create a copy of the request that we own\n  httpd_req_t* copy = NULL;\n  esp_err_t err = httpd_req_async_handler_begin(req, &copy);\n  if (err != ESP_OK) {\n    return err;\n  }\n\n  httpd_async_req_t async_req = {\n    .req = copy,\n    .handler = handler,\n  };\n\n  // How should we handle resource exhaustion?\n  // In this example, we immediately respond with an\n  // http error if no workers are available.\n  int ticks = 0;\n\n  // counting semaphore: if success, we know 1 or\n  // more asyncReqTaskWorkers are available.\n  if (xSemaphoreTake(worker_ready_count, ticks) == false) {\n    ESP_LOGE(PH_TAG, \"No workers are available\");\n    httpd_req_async_handler_complete(copy); // cleanup\n    return ESP_FAIL;\n  }\n\n  // Since worker_ready_count > 0 the queue should already have space.\n  // But lets wait up to 100ms just to be safe.\n  if (xQueueSend(async_req_queue, &async_req, pdMS_TO_TICKS(100)) == false) {\n    ESP_LOGE(PH_TAG, \"worker queue is full\");\n    httpd_req_async_handler_complete(copy); // cleanup\n    return ESP_FAIL;\n  }\n\n  return ESP_OK;\n}\n\nvoid async_req_worker_task(void* p)\n{\n  ESP_LOGI(PH_TAG, \"starting async req task worker\");\n\n  while (true) {\n\n    // counting semaphore - this signals that a worker\n    // is ready to accept work\n    xSemaphoreGive(worker_ready_count);\n\n    // wait for a request\n    httpd_async_req_t async_req;\n    if (xQueueReceive(async_req_queue, &async_req, portMAX_DELAY)) {\n\n      ESP_LOGI(PH_TAG, \"invoking %s\", async_req.req->uri);\n\n      // call the handler\n      async_req.handler(async_req.req);\n\n      // Inform the server that it can purge the socket used for\n      // this request, if needed.\n      if (httpd_req_async_handler_complete(async_req.req) != ESP_OK) {\n        ESP_LOGE(PH_TAG, \"failed to complete async req\");\n      }\n    }\n  }\n\n  ESP_LOGW(PH_TAG, \"worker stopped\");\n  vTaskDelete(NULL);\n}\n\nvoid start_async_req_workers(void)\n{\n\n  // counting semaphore keeps track of available workers\n  worker_ready_count = xSemaphoreCreateCounting(\n    ASYNC_WORKER_COUNT, // Max Count\n    0);                 // Initial Count\n  if (worker_ready_count == NULL) {\n    ESP_LOGE(PH_TAG, \"Failed to create workers counting Semaphore\");\n    return;\n  }\n\n  // create queue\n  async_req_queue = xQueueCreate(1, sizeof(httpd_async_req_t));\n  if (async_req_queue == NULL) {\n    ESP_LOGE(PH_TAG, \"Failed to create async_req_queue\");\n    vSemaphoreDelete(worker_ready_count);\n    return;\n  }\n\n  // start worker tasks\n  for (int i = 0; i < ASYNC_WORKER_COUNT; i++) {\n\n    bool success = xTaskCreate(async_req_worker_task, \"async_req_worker\",\n      ASYNC_WORKER_TASK_STACK_SIZE, // stack size\n      (void*)0,                     // argument\n      ASYNC_WORKER_TASK_PRIORITY,   // priority\n      &worker_handles[i]);\n\n    if (!success) {\n      ESP_LOGE(PH_TAG, \"Failed to start asyncReqWorker\");\n      continue;\n    }\n  }\n}\n\n/****\n *\n * This code is backported from the 5.1.x branch\n *\n ****/\n\n#ifndef ESP_HTTPD_HAS_ASYNC_API\n\n\n#ifndef MAX\n  #define MAX(a, b) (((a) > (b)) ? (a) : (b))\n#endif\n\n/* Calculate the maximum size needed for the scratch buffer */\n#if ESP_ARDUINO_VERSION_MAJOR < 3\n\t#define HTTPD_SCRATCH_BUF  MAX(HTTPD_MAX_REQ_HDR_LEN, HTTPD_MAX_URI_LEN)\n#else\n\t#define HTTPD_SCRATCH_BUF  MAX(CONFIG_HTTPD_MAX_REQ_HDR_LEN, CONFIG_HTTPD_MAX_URI_LEN)\n#endif\n\n/**\n * @brief   Auxiliary data structure for use during reception and processing\n *          of requests and temporarily keeping responses\n */\nstruct httpd_req_aux {\n    struct sock_db* sd;                  /*!< Pointer to socket database */\n    char scratch[HTTPD_SCRATCH_BUF + 1]; /*!< Temporary buffer for our operations (1 byte extra for null termination) */\n    size_t remaining_len;                /*!< Amount of data remaining to be fetched */\n    char* status;                        /*!< HTTP response's status code */\n    char* content_type;                  /*!< HTTP response's content type */\n    bool first_chunk_sent;               /*!< Used to indicate if first chunk sent */\n    unsigned req_hdrs_count;             /*!< Count of total headers in request packet */\n    unsigned resp_hdrs_count;            /*!< Count of additional headers in response packet */\n    struct resp_hdr {\n        const char* field;\n        const char* value;\n    }* resp_hdrs;                         /*!< Additional headers in response packet */\n    struct http_parser_url url_parse_res; /*!< URL parsing result, used for retrieving URL elements */\n  #ifdef CONFIG_HTTPD_WS_SUPPORT\n    bool ws_handshake_detect; /*!< WebSocket handshake detection flag */\n    httpd_ws_type_t ws_type;  /*!< WebSocket frame type */\n    bool ws_final;            /*!< WebSocket FIN bit (final frame or not) */\n    uint8_t mask_key[4];      /*!< WebSocket mask key for this payload */\n  #endif\n};\n\n#if ESP_ARDUINO_VERSION_MAJOR < 3\nesp_err_t httpd_req_async_handler_begin(httpd_req_t *r, httpd_req_t **out)\n{\n  if (r == NULL || out == NULL) {\n    return ESP_ERR_INVALID_ARG;\n  }\n\n  // alloc async req\n  httpd_req_t* async = (httpd_req_t*)malloc(sizeof(httpd_req_t));\n  if (async == NULL) {\n    return ESP_ERR_NO_MEM;\n  }\n  memcpy((void*)async, (void*)r, sizeof(httpd_req_t));\n\n  // alloc async aux\n  async->aux = (httpd_req_aux*)malloc(sizeof(struct httpd_req_aux));\n  if (async->aux == NULL) {\n    free(async);\n    return ESP_ERR_NO_MEM;\n  }\n  memcpy(async->aux, r->aux, sizeof(struct httpd_req_aux));\n\n  // not available in 4.4.x\n  // mark socket as \"in use\"\n  // struct httpd_req_aux *ra = r->aux;\n  // ra->sd->for_async_req = true;\n\n  *out = async;\n\n  return ESP_OK;\n}\n\nesp_err_t httpd_req_async_handler_complete(httpd_req_t* r)\n{\n  if (r == NULL) {\n    return ESP_ERR_INVALID_ARG;\n  }\n\n  // not available in 4.4.x\n  // struct httpd_req_aux *ra = (httpd_req_aux *)r->aux;\n  // ra->sd->for_async_req = false;\n\n  free(r->aux);\n  free(r);\n\n  return ESP_OK;\n}\n\n#endif\n#endif\n"
  },
  {
    "path": "src/async_worker.h",
    "content": "#ifndef async_worker_h\n#define async_worker_h\n\n#include \"PsychicCore.h\"\n#include \"freertos/FreeRTOS.h\"\n#include \"freertos/semphr.h\"\n\n#define ASYNC_WORKER_TASK_PRIORITY   5\n#define ASYNC_WORKER_TASK_STACK_SIZE (4 * 1024)\n#define ASYNC_WORKER_COUNT           8\n\n// Detect presence of async API in your ESP-IDF\n#if defined(ESP_IDF_VERSION_MAJOR)\n  #if (ESP_IDF_VERSION_MAJOR > 5) || (ESP_IDF_VERSION_MAJOR == 5 && ESP_IDF_VERSION_MINOR >= 1)\n    #define ESP_HTTPD_HAS_ASYNC_API 1\n  #endif\n#endif\n\n// Async requests are queued here while they wait to be processed by the workers\nstatic QueueHandle_t async_req_queue;\n\n// Track the number of free workers at any given time\nstatic SemaphoreHandle_t worker_ready_count;\n\n// Each worker has its own thread\nstatic TaskHandle_t worker_handles[ASYNC_WORKER_COUNT];\n\ntypedef esp_err_t (*httpd_req_handler_t)(httpd_req_t* req);\n\ntypedef struct\n{\n    httpd_req_t* req;\n    httpd_req_handler_t handler;\n} httpd_async_req_t;\n\nbool is_on_async_worker_thread(void);\nesp_err_t submit_async_req(httpd_req_t* req, httpd_req_handler_t handler);\nvoid async_req_worker_task(void* p);\nvoid start_async_req_workers(void);\n\n/****\n *\n * This code is backported from the 5.1.x branch\n *\n ****/\n#ifndef ESP_HTTPD_HAS_ASYNC_API\nesp_err_t httpd_req_async_handler_begin(httpd_req_t* r, httpd_req_t** out);\nesp_err_t httpd_req_async_handler_complete(httpd_req_t* r);\n#endif\n\n#endif // async_worker_h"
  },
  {
    "path": "src/http_status.cpp",
    "content": "#include \"http_status.h\"\n\nbool http_informational(int code)\n{\n  return code >= 100 && code < 200;\n}\n\nbool http_success(int code)\n{\n  return code >= 200 && code < 300;\n}\n\nbool http_redirection(int code)\n{\n  return code >= 300 && code < 400;\n}\n\nbool http_client_error(int code)\n{\n  return code >= 400 && code < 500;\n}\n\nbool http_server_error(int code)\n{\n  return code >= 500 && code < 600;\n}\n\nbool http_failure(int code)\n{\n  return code >= 400 && code < 600;\n}\n\nconst char* http_status_group(int code)\n{\n  if (http_informational(code))\n    return \"Informational\";\n\n  if (http_success(code))\n    return \"Success\";\n\n  if (http_redirection(code))\n    return \"Redirection\";\n\n  if (http_client_error(code))\n    return \"Client Error\";\n\n  if (http_server_error(code))\n    return \"Server Error\";\n\n  return \"Unknown\";\n}\n\nconst char* http_status_reason(int code)\n{\n  switch (code)\n  {\n    /*####### 1xx - Informational #######*/\n    case 100:\n      return \"Continue\";\n    case 101:\n      return \"Switching Protocols\";\n    case 102:\n      return \"Processing\";\n    case 103:\n      return \"Early Hints\";\n\n    /*####### 2xx - Successful #######*/\n    case 200:\n      return \"OK\";\n    case 201:\n      return \"Created\";\n    case 202:\n      return \"Accepted\";\n    case 203:\n      return \"Non-Authoritative Information\";\n    case 204:\n      return \"No Content\";\n    case 205:\n      return \"Reset Content\";\n    case 206:\n      return \"Partial Content\";\n    case 207:\n      return \"Multi-Status\";\n    case 208:\n      return \"Already Reported\";\n    case 226:\n      return \"IM Used\";\n\n    /*####### 3xx - Redirection #######*/\n    case 300:\n      return \"Multiple Choices\";\n    case 301:\n      return \"Moved Permanently\";\n    case 302:\n      return \"Found\";\n    case 303:\n      return \"See Other\";\n    case 304:\n      return \"Not Modified\";\n    case 305:\n      return \"Use Proxy\";\n    case 307:\n      return \"Temporary Redirect\";\n    case 308:\n      return \"Permanent Redirect\";\n\n    /*####### 4xx - Client Error #######*/\n    case 400:\n      return \"Bad Request\";\n    case 401:\n      return \"Unauthorized\";\n    case 402:\n      return \"Payment Required\";\n    case 403:\n      return \"Forbidden\";\n    case 404:\n      return \"Not Found\";\n    case 405:\n      return \"Method Not Allowed\";\n    case 406:\n      return \"Not Acceptable\";\n    case 407:\n      return \"Proxy Authentication Required\";\n    case 408:\n      return \"Request Timeout\";\n    case 409:\n      return \"Conflict\";\n    case 410:\n      return \"Gone\";\n    case 411:\n      return \"Length Required\";\n    case 412:\n      return \"Precondition Failed\";\n    case 413:\n      return \"Content Too Large\";\n    case 414:\n      return \"URI Too Long\";\n    case 415:\n      return \"Unsupported Media Type\";\n    case 416:\n      return \"Range Not Satisfiable\";\n    case 417:\n      return \"Expectation Failed\";\n    case 418:\n      return \"I'm a teapot\";\n    case 421:\n      return \"Misdirected Request\";\n    case 422:\n      return \"Unprocessable Content\";\n    case 423:\n      return \"Locked\";\n    case 424:\n      return \"Failed Dependency\";\n    case 425:\n      return \"Too Early\";\n    case 426:\n      return \"Upgrade Required\";\n    case 428:\n      return \"Precondition Required\";\n    case 429:\n      return \"Too Many Requests\";\n    case 431:\n      return \"Request Header Fields Too Large\";\n    case 451:\n      return \"Unavailable For Legal Reasons\";\n\n    /*####### 5xx - Server Error #######*/\n    case 500:\n      return \"Internal Server Error\";\n    case 501:\n      return \"Not Implemented\";\n    case 502:\n      return \"Bad Gateway\";\n    case 503:\n      return \"Service Unavailable\";\n    case 504:\n      return \"Gateway Timeout\";\n    case 505:\n      return \"HTTP Version Not Supported\";\n    case 506:\n      return \"Variant Also Negotiates\";\n    case 507:\n      return \"Insufficient Storage\";\n    case 508:\n      return \"Loop Detected\";\n    case 510:\n      return \"Not Extended\";\n    case 511:\n      return \"Network Authentication Required\";\n\n    default:\n      return \"Unknown\";\n  }\n}"
  },
  {
    "path": "src/http_status.h",
    "content": "#ifndef MICRO_HTTP_STATUS_H\n#define MICRO_HTTP_STATUS_H\n\n#include <stdbool.h>\n\nbool http_informational(int code);\nbool http_success(int code);\nbool http_redirection(int code);\nbool http_client_error(int code);\nbool http_server_error(int code);\nbool http_failure(int code);\nconst char* http_status_group(int code);\nconst char* http_status_reason(int code);\n\n#endif // MICRO_HTTP_STATUS_H"
  }
]