README.rst
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