.. 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
-------------------------------
There are configuration files for various setups in the
:zephyr_file:`samples/net/sockets/http_server` directory:
.. list-table::
* - :zephyr_file:`prj.conf <samples/net/sockets/http_server/prj.conf>`
- This is the standard default config.
* - :zephyr_file:`ieee802154-overlay.conf <samples/net/sockets/http_server/ieee802154-overlay.conf>`
- This overlay config can be added for IEEE 802.15.4 support.
* - :zephyr_file:`overlay-netusb.conf <samples/net/sockets/http_server/overlay-netusb.conf>`
- This overlay config can be added for connecting via network USB.
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_echo")
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.