Skip to content

Commit a174d2e

Browse files
jukkarAnas Nashif
authored andcommitted
net: http: Add HTTP server library support
This commit creates a HTTP server library. So instead of creating a complex HTTP server application for serving HTTP requests, the developer can use the HTTP server API to create HTTP server insteances. This commit also adds support for creating HTTPS servers. Signed-off-by: Jukka Rissanen <[email protected]>
1 parent 43b37ce commit a174d2e

File tree

21 files changed

+2310
-1644
lines changed

21 files changed

+2310
-1644
lines changed

include/net/http.h

Lines changed: 444 additions & 31 deletions
Large diffs are not rendered by default.

samples/net/http_server/Makefile

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,8 @@
44
# SPDX-License-Identifier: Apache-2.0
55
#
66

7-
BOARD ?= frdm_k64f
7+
BOARD ?= qemu_x86
88
CONF_FILE ?= prj_$(BOARD).conf
99

1010
include $(ZEPHYR_BASE)/Makefile.inc
11-
ifeq ($(BOARD), qemu_x86)
12-
include $(ZEPHYR_BASE)/samples/net/common/Makefile.ipstack
13-
endif
11+
include $(ZEPHYR_BASE)/samples/net/common/Makefile.ipstack

samples/net/http_server/README.rst

Lines changed: 55 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,13 @@ Overview
77
********
88

99
The HTTP Server sample application for Zephyr implements a basic TCP server
10-
on top of the HTTP Parser Library that is able to receive HTTP 1.1 requests,
10+
on top of the HTTP Server Library that is able to receive HTTP 1.1 requests,
1111
parse them and write back the responses.
1212

13-
This sample code generates HTTP 1.1 responses dynamically
14-
and does not serve content from a file system. The source code includes
15-
examples on how to write HTTP 1.1 responses: 200 OK, 400 Bad Request,
16-
403 Forbidden, 404 Not Found and soft HTTP errors like 200 OK with a 404
17-
Not Found HTML message.
13+
This sample code generates HTTP 1.1 responses dynamically and does not serve
14+
content from a file system. The source code includes examples on how to write
15+
HTTP 1.1 responses: 200 OK, 400 Bad Request, 403 Forbidden, 404 Not Found and
16+
soft HTTP errors like 200 OK with a 404 Not Found HTML message.
1817

1918
The source code for this sample application can be found at:
2019
:file:`samples/net/http_server`.
@@ -23,39 +22,24 @@ Requirements
2322
************
2423

2524
- Linux machine with wget and the screen terminal emulator
26-
- Freedom Board (FRDM-K64F)
25+
- Either QEMU or real device like Freedom Board (FRDM-K64F)
2726
- LAN for testing purposes (Ethernet)
2827

2928
Building and Running
3029
********************
3130

32-
Currently, the HTTP Server application is configured to listen at port 80,
33-
This value is defined in the :file:`samples/net/http_server/src/config.h`
34-
file:
31+
Currently, the HTTP Server application is configured to listen at port 80.
32+
If you want to modify the http-server sample application, please check
33+
the configuration settings in :file:`samples/net/http_server/src/main.c` file
34+
and also in the :file:`samples/net/http_server/src/config.h` file.
3535

36-
.. code-block:: c
37-
38-
#define ZEPHYR_PORT 80
39-
40-
Open the project configuration file for your platform, for example the
41-
:file:`prj_frdm_k64f.conf` file is the configuration file for the
42-
:ref:`frdm_k64f` board. For IPv4 networks, set the following variables:
43-
44-
.. code-block:: console
45-
46-
CONFIG_NET_IPV4=y
47-
CONFIG_NET_IPV6=n
48-
49-
IPv6 is the preferred routing technology for this sample application,
50-
if CONFIG_NET_IPV6=y is set, the value of CONFIG_NET_IPV4=y is ignored.
51-
52-
This sample code only supports static IP addresses that are defined in the
53-
project configuration file:
36+
This sample code supports both static and dynamic (DHCPv4) IP addresses that
37+
can be defined in the project configuration file:
5438

5539
.. code-block:: console
5640
5741
CONFIG_NET_APP_MY_IPV6_ADDR="2001:db8::1"
58-
CONFIG_NET_APP_MY_IPV4_ADDR="192.168.1.101"
42+
CONFIG_NET_APP_MY_IPV4_ADDR="192.0.2.1"
5943
6044
Adding URLs
6145
===========
@@ -66,9 +50,11 @@ following lines:
6650

6751
.. code-block:: c
6852
69-
http_url_default_handler(http_write_soft_404_not_found);
70-
http_url_add("/headers", HTTP_URL_STANDARD, http_write_header_fields);
71-
http_url_add("/index.html", HTTP_URL_STANDARD, http_write_it_works);
53+
http_server_add_default(&http_urls, http_response_soft_404);
54+
http_server_add_url(&http_urls, "/headers", HTTP_URL_STANDARD,
55+
http_response_header_fields);
56+
http_server_add_url(&http_urls, "/index.html", HTTP_URL_STANDARD,
57+
http_response_it_works);
7258
7359
The first line defines how Zephyr will deal with unknown URLs. In this case,
7460
it will respond with a soft HTTP 404 status code, i.e. an HTTP 200 OK status
@@ -114,19 +100,20 @@ serial console under other operating systems.
114100
Sample Output
115101
=============
116102

117-
Assume that this HTTP server is configured to listen at 192.168.1.101 port 80.
103+
Assume in this example that this HTTP server is configured to listen at
104+
IPv4 address 192.168.1.120 and IPv6 address 2001:db8::1 port 80.
118105
On your Linux host computer, open a terminal window and type:
119106

120107
.. code-block:: console
121108
122-
wget 192.168.1.101/index.html
109+
wget 192.168.1.120/index.html
123110
124111
wget will show:
125112

126113
.. code-block:: console
127114
128-
--2017-01-17 00:37:44-- http://192.168.1.101/
129-
Connecting to 192.168.1.101:80... connected.
115+
--2017-01-17 00:37:44-- http://192.168.1.120/
116+
Connecting to 192.168.1.120:80... connected.
130117
HTTP request sent, awaiting response... 200 OK
131118
Length: unspecified [text/html]
132119
Saving to: 'index.html'
@@ -146,32 +133,38 @@ The screen application will display the following information:
146133

147134
.. code-block:: console
148135
149-
[dev/eth_mcux] [INF] eth_0_init: Enabled 100M full-duplex mode.
150-
[dev/eth_mcux] [DBG] eth_0_init: MAC 00:04:9f:c9:29:6e
151-
Zephyr HTTP Server
152-
Address: 192.168.1.101, port: 80
153-
154-
----------------------------------------------------
155-
[print_client_banner:42] Connection accepted
156-
Address: 192.168.1.10, port: 54327
157-
[http_ctx_get:268] Free ctx found, index: 0
158-
[http_write:59] net_pkt_get_tx, rc: 0 <OK>
159-
[http_write:82] net_context_send: 0 <OK>
160-
[http_rx_tx:86] Connection closed by peer
136+
[dev/eth_mcux] [DBG] eth_0_init: MAC 00:04:9f:52:44:02
137+
[sample/net] [INF] net_sample_app_init: Run HTTPS server
138+
[sample/net] [INF] setup_dhcpv4: Running
139+
[dev/eth_mcux] [DBG] eth_0_init: MAC 00:04:9f:f1:80:9e
140+
[sample/net] [INF] net_sample_app_init: Run HTTPS server
141+
[sample/net] [INF] setup_dhcpv4: Running dhcpv4 client...
142+
[sample/net] [INF] ipv6_event_handler: IPv6 address: 2001:db8::1
143+
[dev/eth_mcux] [INF] eth_mcux_phy_event: Enabled 10M half-duplex mode.
144+
[sample/net] [INF] ipv4_addr_add_handler: IPv4 address: 192.168.1.120
145+
[sample/net] [INF] ipv4_addr_add_handler: Lease time: 86400 seconds
146+
[sample/net] [INF] ipv4_addr_add_handler: Subnet: 255.255.255.0
147+
[sample/net] [INF] ipv4_addr_add_handler: Router: 192.168.1.1
148+
[https/server] [INF] new_server: Zephyr HTTPS Server (0x20002370)
149+
[https/server] [DBG] https_handler: (0x2000b5b4): HTTPS handler starting
150+
[https/server] [INF] new_server: Zephyr HTTP Server (0x20001840)
151+
[https/server] [INF] new_client: HTTP connection from 192.168.1.107:44410 (0x20006af4)
152+
[https/server] [DBG] http_recv: (0x2000d6b4): Received 336 bytes data
153+
[https/server] [DBG] http_process_recv: (0x2000d6b4): Calling handler 0x00000d89 context 0x20001840
161154
162155
163156
To obtain the HTTP Header Fields web page, use the following command:
164157

165158
.. code-block:: console
166159
167-
wget 192.168.1.101/headers -O index.html
160+
wget 192.168.1.120/headers -O index.html
168161
169162
wget will show:
170163

171164
.. code-block:: console
172165
173-
--2017-01-19 22:09:55-- http://192.168.1.101/headers
174-
Connecting to 192.168.1.101:80... connected.
166+
--2017-01-19 22:09:55-- http://192.168.1.120/headers
167+
Connecting to 192.168.1.120:80... connected.
175168
HTTP request sent, awaiting response... 200 OK
176169
Length: unspecified [text/html]
177170
Saving to: 'index.html'
@@ -190,7 +183,7 @@ This is the HTML file generated by Zephyr and downloaded by wget:
190183
<ul>
191184
<li>User-Agent: Wget/1.16 (linux-gnu)</li>
192185
<li>Accept: */*</li>
193-
<li>Host: 192.168.1.101</li>
186+
<li>Host: 192.168.1.120</li>
194187
<li>Connection: Keep-Alive</li>
195188
</ul>
196189
<h2>HTTP Method: GET</h2>
@@ -203,7 +196,7 @@ To test the 404 Not Found soft error, use the following command:
203196

204197
.. code-block:: console
205198
206-
wget 192.168.1.101/not_found -O index.html
199+
wget 192.168.1.120/not_found -O index.html
207200
208201
Zephyr will generate an HTTP response with the following header:
209202

@@ -224,32 +217,11 @@ and this is the HTML message that wget will save:
224217
<body><h1><center>404 Not Found</center></h1></body>
225218
</html>
226219

227-
To test the HTTP Basic Authentication functionality, use the
228-
following command:
229-
230-
.. code-block:: console
231-
232-
wget 192.168.1.101/auth -O index.html --user=zephyr --password=0123456789
233-
234-
the :file:`index.html` file will contain the following information:
235-
236-
.. code-block:: html
237-
238-
<html>
239-
<head>
240-
<title>Zephyr HTTP Server</title>
241-
</head>
242-
<body>
243-
<h1><center>Zephyr HTTP server</center></h1>
244-
<h2><center>user: zephyr, password: 0123456789</center></h2>
245-
</body>
246-
</html>
247-
248220
HTTPS Server
249221
============
250222

251223
The sample code also includes a HTTPS (HTTP over TLS) server example
252-
running side by side with the HTTP server, this server runs on qemu.
224+
running side by side with the HTTP server, this server runs on QEMU.
253225
In order to compile and run the code execute:
254226

255227
.. code-block:: console
@@ -266,25 +238,23 @@ The app will show the following on the screen:
266238

267239
.. code-block:: console
268240
269-
Zephyr HTTP Server
270-
Address: 192.0.2.1, port: 80
271-
Zephyr HTTPS Server
272-
Address: 192.0.2.1, port: 443
273-
failed
274-
! mbedtls_ssl_handshake returned -29312
241+
[https/server] [INF] new_client: HTTPS connection from 192.168.1.107:35982 (0x20006b4c)
242+
[https/server] [DBG] https_handler: (0x2000b5b4): Read HTTPS request
243+
[https/server] [DBG] https_handler: (0x2000b5b4): Write HTTPS response
244+
[https/server] [DBG] http_process_recv: (0x2000b5b4): Calling handler 0x00000ce9 context 0x20002370
275245
276246
Now execute the following command on a different terminal window
277247

278248
.. code-block:: console
279249
280-
wget https://192.0.2.1 --no-check-certificate
250+
wget https://192.168.1.120 --no-check-certificate
281251
282252
This will be shown on the screen
283253

284254
.. code-block:: console
285255
286-
Connecting to 192.0.2.1:443... connected.
287-
WARNING: cannot verify 192.0.2.1's certificate
256+
Connecting to 192.168.1.120:443... connected.
257+
WARNING: cannot verify 192.168.1.120's certificate
288258
Unable to locally verify the issuer's authority.
289259
HTTP request sent, awaiting response... 200 OK
290260
Length: unspecified [text/html]
@@ -304,7 +274,4 @@ Known Issues and Limitations
304274

305275
- Currently, this sample application only generates HTTP responses in
306276
chunk transfer mode.
307-
- Clients must close the connection to allow the HTTP server to release
308-
the network context and accept another connection.
309-
- The use of mbedTLS and IPv6 takes more than the available ram for the
310-
emulation platform, so only IPv4 works for now in QEMU.
277+
- Basic authentication is not yet implemented.

samples/net/http_server/prj_arduino_101.conf

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,26 +11,38 @@ CONFIG_NET_PKT_TX_COUNT=16
1111
CONFIG_NET_BUF_RX_COUNT=16
1212
CONFIG_NET_BUF_TX_COUNT=16
1313

14-
CONFIG_NET_IPV6_RA_RDNSS=y
15-
CONFIG_NET_IFACE_UNICAST_IPV4_ADDR_COUNT=3
14+
CONFIG_NET_IF_UNICAST_IPV6_ADDR_COUNT=2
15+
CONFIG_NET_IF_MCAST_IPV6_ADDR_COUNT=4
16+
17+
CONFIG_NET_MAX_CONTEXTS=16
1618

1719
CONFIG_TEST_RANDOM_GENERATOR=y
1820

1921
CONFIG_STDOUT_CONSOLE=y
2022

23+
CONFIG_SYS_LOG_SHOW_COLOR=y
24+
CONFIG_SYS_LOG_NET_LEVEL=4
25+
CONFIG_NET_DEBUG_HTTP=y
26+
2127
CONFIG_HTTP_SERVER=y
22-
CONFIG_HTTP_PARSER=y
2328

24-
# Enable IPv6 support
2529
CONFIG_NET_IPV6=y
26-
# Enable IPv4 support
27-
CONFIG_NET_IPV4=n
30+
CONFIG_NET_IPV4=y
31+
#CONFIG_NET_DHCPV4=y
32+
33+
CONFIG_HTTPS=y
34+
CONFIG_MBEDTLS=y
35+
CONFIG_MBEDTLS_BUILTIN=y
36+
CONFIG_MBEDTLS_CFG_FILE="config-mini-tls1_2.h"
2837

2938
CONFIG_NET_APP_SETTINGS=y
3039
CONFIG_NET_APP_MY_IPV6_ADDR="2001:db8::1"
31-
CONFIG_NET_APP_MY_IPV4_ADDR="192.168.1.101"
40+
CONFIG_NET_APP_MY_IPV4_ADDR="192.0.2.1"
3241

33-
CONFIG_NET_MAX_CONTEXTS=16
42+
CONFIG_NET_SHELL=y
43+
44+
CONFIG_NET_MGMT=y
45+
CONFIG_NET_MGMT_EVENT=y
3446

3547
# ENC28J60 Ethernet Device
3648
CONFIG_ETH_ENC28J60=y
@@ -42,4 +54,3 @@ CONFIG_ETH_ENC28J60_0_MAC5=0x36
4254

4355
# Arduino 101
4456
CONFIG_SPI=y
45-
Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
CONFIG_NETWORKING=y
22
CONFIG_NET_TCP=y
33
CONFIG_RANDOM_GENERATOR=y
4-
CONFIG_NET_ARP=y
54
CONFIG_NET_LOG=y
65
CONFIG_INIT_STACKS=y
76

@@ -10,24 +9,32 @@ CONFIG_NET_PKT_TX_COUNT=16
109
CONFIG_NET_BUF_RX_COUNT=16
1110
CONFIG_NET_BUF_TX_COUNT=16
1211

13-
CONFIG_NET_IPV6_RA_RDNSS=y
14-
CONFIG_NET_IFACE_UNICAST_IPV4_ADDR_COUNT=3
12+
CONFIG_NET_IF_UNICAST_IPV6_ADDR_COUNT=3
13+
CONFIG_NET_IF_MCAST_IPV6_ADDR_COUNT=4
1514

1615
CONFIG_STDOUT_CONSOLE=y
1716

17+
CONFIG_SYS_LOG_SHOW_COLOR=y
18+
CONFIG_SYS_LOG_NET_LEVEL=4
19+
CONFIG_NET_DEBUG_HTTP=y
20+
1821
CONFIG_HTTP_SERVER=y
19-
CONFIG_HTTP_PARSER=y
2022

21-
# Enable IPv6 support
2223
CONFIG_NET_IPV6=y
23-
# Enable IPv4 support
2424
CONFIG_NET_IPV4=n
2525

26+
CONFIG_HTTPS=y
27+
CONFIG_MBEDTLS=y
28+
CONFIG_MBEDTLS_BUILTIN=y
29+
CONFIG_MBEDTLS_CFG_FILE="config-mini-tls1_2.h"
30+
2631
CONFIG_NET_APP_SETTINGS=y
2732
CONFIG_NET_APP_MY_IPV6_ADDR="2001:db8::1"
28-
CONFIG_NET_APP_MY_IPV4_ADDR="192.168.1.101"
2933

30-
CONFIG_NET_MAX_CONTEXTS=16
34+
CONFIG_NET_SHELL=y
35+
36+
CONFIG_NET_MGMT=y
37+
CONFIG_NET_MGMT_EVENT=y
3138

3239
CONFIG_BLUETOOTH=y
3340
CONFIG_BLUETOOTH_DEBUG_LOG=y
@@ -40,7 +47,7 @@ CONFIG_TEST_RANDOM_GENERATOR=y
4047
CONFIG_NET_L2_BLUETOOTH=y
4148
CONFIG_NET_L2_BLUETOOTH_ZEP1656=y
4249
CONFIG_NET_DEBUG_L2_BLUETOOTH=y
43-
CONFIG_SYS_LOG_SHOW_COLOR=y
4450
CONFIG_NET_STATISTICS=y
45-
CONFIG_NET_IF_UNICAST_IPV6_ADDR_COUNT=3
46-
CONFIG_NET_IF_MCAST_IPV6_ADDR_COUNT=2
51+
52+
# This sample is meant to be compilable in QEMU only
53+
CONFIG_RAM_SIZE=300

0 commit comments

Comments
 (0)