1.. zephyr:code-sample:: sockets-http-server 2 :name: HTTP Server 3 :relevant-api: http_service http_server tls_credentials 4 5 Implement an HTTP(s) Server demonstrating various resource types. 6 7Overview 8-------- 9 10This sample application demonstrates the use of the :ref:`http_server_interface` library. 11This library provides high-level functions to simplify and abstract server implementation. 12The server supports the HTTP/1.1 protocol which can also be upgraded to HTTP/2, 13it also support native HTTP/2 protocol without upgrading. 14 15Requirement 16----------- 17 18`QEMU Networking <https://docs.zephyrproject.org/latest/connectivity/networking/qemu_setup.html#networking-with-qemu>`_ 19 20Building and running the server 21------------------------------- 22 23There are configuration files for various setups in the 24:zephyr_file:`samples/net/sockets/http_server` directory: 25 26.. list-table:: 27 28 * - :zephyr_file:`prj.conf <samples/net/sockets/http_server/prj.conf>` 29 - This is the standard default config. 30 31 * - :zephyr_file:`ieee802154-overlay.conf <samples/net/sockets/http_server/ieee802154-overlay.conf>` 32 - This overlay config can be added for IEEE 802.15.4 support. 33 34 * - :zephyr_file:`overlay-netusb.conf <samples/net/sockets/http_server/overlay-netusb.conf>` 35 - This overlay config can be added for connecting via network USB. 36 37To build and run the application: 38 39.. code-block:: bash 40 41 $ west build -p auto -b <board_to_use> -t run samples/net/sockets/http_server 42 43When the server is up, we can make requests to the server using either HTTP/1.1 or 44HTTP/2 protocol from the host machine. 45 46**With HTTP/1.1:** 47 48- Using a browser: ``http://192.0.2.1/`` 49- Using curl: ``curl -v --compressed http://192.0.2.1/`` 50- Using ab (Apache Bench): ``ab -n10 http://192.0.2.1/`` 51 52**With HTTP/2:** 53 54- Using nghttp client: ``nghttp -v --no-dep http://192.0.2.1/`` 55- Using curl: ``curl --http2 -v --compressed http://192.0.2.1/`` 56- Using h2load: ``h2load -n10 http://192.0.2.1/`` 57 58Web browsers use stricter security settings for the HTTP/2 protocol. So to use HTTP/2 59with a web browser, you must enable ``CONFIG_NET_SAMPLE_HTTPS_SERVICE`` and 60``CONFIG_NET_SAMPLE_HTTPS_USE_ALPN``. Additionally the server certificate must be signed 61by a CA certificate trusted by your browser. 62 63The best way to do this is to generate your own CA certificate: 64 65.. code-block:: bash 66 67 $ west build -b <board_to_use> -t sample_ca_cert samples/net/sockets/http_server 68 69Generate a server certificate signed by this CA certificate: 70 71.. code-block:: bash 72 73 $ west build -t sample_server_cert samples/net/sockets/http_server 74 75And then build the application with the newly generated server certificate and key: 76 77.. code-block:: bash 78 79 $ west build samples/net/sockets/http_server 80 81The CA certificate should be added to your browser's list of trusted authorities to 82enable usage of HTTP/2. If using Firefox, it may also be required to change the setting 83``network.http.http2.enforce-tls-profile`` to false, since it seems that using a CA 84certificate issued by an authority unknown to Firefox is considered a security error when 85using HTTP/2. 86 87Server Customization 88--------------------- 89 90The server sample contains several parameters that can be customized based on 91the requirements. These are the configurable parameters: 92 93- ``CONFIG_NET_SAMPLE_HTTP_SERVER_SERVICE_PORT``: Configures the service port. 94 95- ``CONFIG_HTTP_SERVER_MAX_CLIENTS``: Defines the maximum number of HTTP/2 96 clients that the server can handle simultaneously. 97 98- ``CONFIG_HTTP_SERVER_MAX_STREAMS``: Specifies the maximum number of HTTP/2 99 streams that can be established per client. 100 101- ``CONFIG_HTTP_SERVER_CLIENT_BUFFER_SIZE``: Defines the buffer size allocated 102 for each client. This limits the maximum length of an individual HTTP header 103 supported. 104 105- ``CONFIG_HTTP_SERVER_MAX_URL_LENGTH``: Specifies the maximum length of an HTTP 106 URL that the server can process. 107 108- ``CONFIG_NET_SAMPLE_WEBSOCKET_SERVICE``: Enables Websocket service endpoint. 109 This allows a Websocket client to connect to ``/`` endpoint, all the data that 110 the client sends is echoed back. 111 112To customize these options, we can run ``west build -t menuconfig``, which provides 113us with an interactive configuration interface. Then we could navigate from the top-level 114menu to: ``-> Subsystems and OS Services -> Networking -> Network Protocols``. 115 116Websocket Connectivity 117---------------------- 118 119You can use a simple Websocket client application like this to test the Websocket 120connectivity. 121 122.. code-block:: python 123 124 import websocket 125 126 websocket.enableTrace(True) 127 ws = websocket.WebSocket() 128 ws.connect("ws://192.0.2.1/ws_echo") 129 ws.send("Hello, Server") 130 print(ws.recv()) 131 while True: 132 line = input("> ") 133 if line == "quit": 134 break 135 ws.send(line) 136 print(ws.recv()) 137 ws.close() 138 139 140Performance Analysis 141-------------------- 142 143CPU Usage Profiling 144******************* 145 146We can use ``perf`` to collect statistics about the CPU usage of our server 147running in native_sim board with the ``stat`` command: 148 149.. code-block:: console 150 151 $ sudo perf stat -p <pid_of_server> 152 153``perf stat`` will then start monitoring our server. We can let it run while 154sending requests to our server. Once we've collected enough data, we can 155stop ``perf stat``, which will print a summary of the performance statistics. 156 157Hotspot Analysis 158**************** 159 160``perf record`` and ``perf report`` can be used together to identify the 161functions in our code that consume the most CPU time: 162 163.. code-block:: console 164 165 $ sudo perf record -g -p <pid_of_server> -o perf.data 166 167After running our server under load (For example, using ApacheBench tool), 168we can stop the recording and analyze the data using: 169 170.. code-block:: console 171 172 $ sudo perf report -i perf.data 173 174After generating a file named ``perf.data`` which contains the profiling data, 175we can visualize it using ``FlameGraph`` tool. It's particularly useful for 176identifying the most expensive code-paths and inspect where our application is 177spending the most time. 178 179To do this, we need to convert the ``perf.data`` to a format that ``FlameGraph`` 180can understand: 181 182.. code-block:: console 183 184 $ sudo perf script | ~/FlameGraph/stackcollapse-perf.pl > out.perf-folded 185 186And, then, generate the ``FlameGraph``: 187 188.. code-block:: console 189 190 $ ~/FlameGraph/flamegraph.pl out.perf-folded > flamegraph.svg 191 192We can view flamegraph.svg using a web browser. 193