zephyr/samples/net/sockets/http_server
Benjamin Cabé f6d0383a97 samples: net: http_server: use proper language in code-block
Achieve proper syntax highlighting using "console"
language when command snippets start with a prompt.

Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
2024-06-20 14:07:32 -04:00
..
src samples: net: http_server: Add example of passing Content-Type field 2024-05-14 20:22:58 -04:00
CMakeLists.txt
Kconfig
prj.conf samples: net: sockets: http_server: Disable PSA crypto 2024-06-07 16:45:05 +03:00
README.rst samples: net: http_server: use proper language in code-block 2024-06-20 14:07:32 -04:00
sample.yaml samples: net: sockets: Add netif dependency where missing 2024-06-07 16:45:05 +03:00
sections-rom.ld

.. zephyr:code-sample:: sockets-http-server
   :name: HTTP Server
   :relevant-api: http_service http_server tls_credentials

   Implement an HTTP(s) Server demonstrating various resource types.

Overview
--------

This sample application demonstrates the use of the :ref:`http_server_interface` library.
This library provides high-level functions to simplify and abstract server implementation.
The server supports the HTTP/1.1 protocol which can also be upgraded to HTTP/2,
it also support native HTTP/2 protocol without upgrading.

Requirement
-----------

`QEMU Networking <https://docs.zephyrproject.org/latest/connectivity/networking/qemu_setup.html#networking-with-qemu>`_

Building and running the server
-------------------------------

To build and run the application:

.. code-block:: bash

   $ west build -p auto -b <board_to_use> -t run samples/net/sockets/http_server

When the server is up, we can make requests to the server using either HTTP/1.1 or
HTTP/2 protocol from the host machine.

**With HTTP/1.1:**

- Using a browser: ``http://192.0.2.1/``
- Using curl: ``curl -v --compressed http://192.0.2.1/``
- Using ab (Apache Bench): ``ab -n10 http://192.0.2.1/``

**With HTTP/2:**

- Using nghttp client: ``nghttp -v --no-dep http://192.0.2.1/``
- Using curl: ``curl --http2 -v --compressed http://192.0.2.1/``
- Using h2load: ``h2load -n10 http://192.0.2.1/``

Server Customization
---------------------

The server sample contains several parameters that can be customized based on
the requirements. These are the configurable parameters:

- ``CONFIG_NET_SAMPLE_HTTP_SERVER_SERVICE_PORT``: Configures the service port.

- ``CONFIG_HTTP_SERVER_MAX_CLIENTS``: Defines the maximum number of HTTP/2
  clients that the server can handle simultaneously.

- ``CONFIG_HTTP_SERVER_MAX_STREAMS``: Specifies the maximum number of HTTP/2
  streams that can be established per client.

- ``CONFIG_HTTP_SERVER_CLIENT_BUFFER_SIZE``: Defines the buffer size allocated
  for each client. This limits the maximum length of an individual HTTP header
  supported.

- ``CONFIG_HTTP_SERVER_MAX_URL_LENGTH``: Specifies the maximum length of an HTTP
  URL that the server can process.

- ``CONFIG_NET_SAMPLE_WEBSOCKET_SERVICE``: Enables Websocket service endpoint.
  This allows a Websocket client to connect to ``/`` endpoint, all the data that
  the client sends is echoed back.

To customize these options, we can run ``west build -t menuconfig``, which provides
us with an interactive configuration interface. Then we could navigate from the top-level
menu to: ``-> Subsystems and OS Services -> Networking -> Network Protocols``.

Websocket Connectivity
----------------------

You can use a simple Websocket client application like this to test the Websocket
connectivity.

.. code-block:: python

   import websocket

   websocket.enableTrace(True)
   ws = websocket.WebSocket()
   ws.connect("ws://192.0.2.1/")
   ws.send("Hello, Server")
   print(ws.recv())
   while True:
     line = input("> ")
     if line == "quit":
       break
     ws.send(line)
     print(ws.recv())
   ws.close()


Performance Analysis
--------------------

CPU Usage Profiling
*******************

We can use ``perf`` to collect statistics about the CPU usage of our server
running in native_sim board with the ``stat`` command:

.. code-block:: console

   $ sudo perf stat -p <pid_of_server>

``perf stat`` will then start monitoring our server. We can let it run while
sending requests to our server. Once we've collected enough data, we can
stop ``perf stat``, which will print a summary of the performance statistics.

Hotspot Analysis
****************

``perf record`` and ``perf report`` can be used together to identify the
functions in our code that consume the most CPU time:

.. code-block:: console

   $ sudo perf record -g -p <pid_of_server> -o perf.data

After running our server under load (For example, using ApacheBench tool),
we can stop the recording and analyze the data using:

.. code-block:: console

   $ sudo perf report -i perf.data

After generating a file named ``perf.data`` which contains the profiling data,
we can visualize it using ``FlameGraph`` tool. It's particularly useful for
identifying the most expensive code-paths and inspect where our application is
spending the most time.

To do this, we need to convert the ``perf.data`` to a format that ``FlameGraph``
can understand:

.. code-block:: console

   $ sudo perf script | ~/FlameGraph/stackcollapse-perf.pl > out.perf-folded

And, then, generate the ``FlameGraph``:

.. code-block:: console

   $ ~/FlameGraph/flamegraph.pl out.perf-folded > flamegraph.svg

We can view flamegraph.svg using a web browser.