Commit Graph

161 Commits

Author SHA1 Message Date
Matt Rodgers
2eda6df48a net: lib: http_server: add option to use ALPN
Web browsers don't support HTTP Upgrade mechanism to upgrade to HTTP2.
Instead, HTTP2 is supported only over TLS, and ALPN is used to negotiate
the protocol to be used.

This commit adds the supported HTTP protocols to the ALPN list, so that
web browsers can use HTTP2 with the server.

Signed-off-by: Matt Rodgers <mrodgers@witekio.com>
2024-11-16 15:19:36 -05:00
Flavio Ceolin
ea0a211d6f net: http_server: Fix possible buffer underrun
Avoid possible underruns when an url is shorter than a handled
extension.

Signed-off-by: Flavio Ceolin <flavio.ceolin@gmail.com>
2024-10-29 07:06:50 -05:00
Gerhard Jörges
372b3a9b8d net: lib: http: add missing includes
filesystem includes, that are required by the static_fs_resource, were
missing.

Signed-off-by: Gerhard Jörges <joerges@metratec.com>
2024-10-21 16:00:14 +02:00
Gerhard Jörges
fc30792b48 net: lib: http: add missing zsock_ prefix
the zsock_ prefix is missing at one setsockopt call

Signed-off-by: Gerhard Jörges <joerges@metratec.com>
2024-10-21 16:00:14 +02:00
Jukka Rissanen
7510e2d940 shell: backend: Create a websocket transport backend
This creates a websocket based shell backend that is used to
implement a websocket console that can be connected using a browser.

Signed-off-by: Jukka Rissanen <jukka.rissanen@nordicsemi.no>
2024-10-15 04:11:03 -04:00
Jukka Rissanen
0515bfff7a net: lib: http-client: Use memcpy() to avoid gcc warning
GCC 12.2.0 can give this warning (version 11.4.0 did not), when
CONFIG_SPEED_OPTIMIZATIONS=y

subsys/net/lib/http/http_client.c: In function 'http_send_data.constprop':
subsys/net/lib/http/http_client.c:114:33: warning: 'strncpy' specified
bound depends on the length of the source argument [-Wstringop-truncation]
  114 |                                 strncpy(send_buf + end_of_send,
      |                                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  115 |                                         data + end_of_data,
      |                                         ~~~~~~~~~~~~~~~~~~~
  116 |                                         remaining);
      |                                         ~~~~~~~~~~
subsys/net/lib/http/http_client.c:87:41: note: length computed here
   87 |                         remaining_len = strlen(data + end_of_data);
      |                                         ^~~~~~~~~~~~~~~~~~~~~~~~~~

The code properly checks that we do not overwrite the destination
buffer even if we use the source buffer length to determine how much
to copy. One possible fix is to use memcpy() or strcpy(), I opted
to use memcpy() because it has the length option which feels more
natural.

Fixes #79326

Signed-off-by: Jukka Rissanen <jukka.rissanen@nordicsemi.no>
2024-10-04 13:24:17 -05:00
Pete Skeggs
09fab7e680 net: lib: http: ensure SYS_FOREVER_MS behavior
The http_client_req() function's timeout parameter is allowed
to be SYS_FOREVER_MS. However, K_MSEC() does not convert this
to a proper k_timeout_t, so sys_timepoint_calc() ends up
returning 0, which is causes immediate timeouts.

Check for this case specifically and force value passed to
sys_timepoint_calc() to be correct.

Signed-off-by: Pete Skeggs <peter.skeggs@nordicsemi.no>
2024-09-29 21:20:50 +02:00
Yangbo Lu
6fe7f6c55d net: lib: http_server: fix snprintk issue of size_t
The size_t type may vary from machines. Current snprintk code was
causing below build issue on arm64.

error: format '%x' expects argument of type 'unsigned int', but argument
4 has type 'size_t' {aka 'long unsigned int'} [-Werror=format=].

Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
2024-09-25 04:00:02 -04:00
Matt Rodgers
f2d8766b5d net: lib: http_server: remove dynamic resource data buffer
After introduction of struct http_response_ctx, the dynamic resource
data buffer is no longer needed for transferring data between the
application callback and the server. It is therefore removed to avoid
unnecessary copying of data.

Signed-off-by: Matt Rodgers <mrodgers@witekio.com>
2024-09-23 12:00:54 +02:00
Matt Rodgers
96061428e0 tests: http_server: add tests for dynamic response context
Add tests covering new method of providing a response for dynamic
resources.

Tests cover the application sending response codes and headers,
overriding "default" headers, and sending various combinations of
headers and body data. Each case is tested for HTTP1 & HTTP2, both POST
and GET methods.

Signed-off-by: Matt Rodgers <mrodgers@witekio.com>
2024-09-23 12:00:54 +02:00
Matt Rodgers
4cc905c513 net: lib: http_server: allow application to send headers/response code
Allow the application to send headers and response codes from a dynamic
resource callback by filling out a response context structure.

This also allows simple requests to be completed in a single execution
of the callback, by setting the final_chunk flag.

Signed-off-by: Matt Rodgers <mrodgers@witekio.com>
2024-09-23 12:00:54 +02:00
Jukka Rissanen
dcb71a754f net: http_server: Enable v4-to-v6 mapping by default
Fixing the regression caused by 3949873886 ("Allow service to be
created with NULL host"). If the host parameter is null when creating
the HTTP service, the IPv6 socket is created by default. This can cause
issues if both IPv4 and IPv6 are enabled, like in HTTP server sample,
and the HTTP client connection is done by IPv4.
To fix this, we need to enable IPv4-to-IPv6 mapping in order to allow
IPv6 socket to serve a IPv4 connection. Allow also user to override this
if needed.

Fixes #78112

Signed-off-by: Jukka Rissanen <jukka.rissanen@nordicsemi.no>
2024-09-10 21:51:54 -04:00
Matt Rodgers
0c8bdbc45d net: lib: http_server: allow application to access request headers
Allow application to register certain HTTP request headers to be stored
by the server. These stored headers can then be accessed from a dynamic
resource callback.

Signed-off-by: Matt Rodgers <mrodgers@witekio.com>
2024-09-06 11:27:37 -04:00
Jukka Rissanen
5480960fcf net: http_server: Turn off V6ONLY if IPv4-to-IPv6 mapping is enabled
Without this it is not possible to serve both IPv6 and IPv4
connections if service host is NULL.

Signed-off-by: Jukka Rissanen <jukka.rissanen@nordicsemi.no>
2024-09-06 09:58:50 -05:00
Jukka Rissanen
3949873886 net: http_server: Allow service to be created with NULL host
Allow NULL host parameter when creating HTTP service. This means
that the socket is created without specifying binding address.

Signed-off-by: Jukka Rissanen <jukka.rissanen@nordicsemi.no>
2024-09-06 09:58:50 -05:00
Matt Rodgers
989fdadfe2 net: lib: http_server: prevent falsely matching HTTP headers
Using strncasecmp to match HTTP headers can give unexpected results when
the strings to be compared match up until the end of one string, but the
other string contains additional characters. This can result in falsely
matching a HTTP header value, for example:

strncasecmp("Upgrade-Something", "Upgrade", sizeof("Upgrade") - 1) --> 0

In this case we know that both strings are NULL terminated since one is
a string literal and we have just length-checked and explicitly NULL
terminated the other. So we can just use strcasecmp without a max
length.

Signed-off-by: Matt Rodgers <mrodgers@witekio.com>
2024-09-02 12:33:03 -04:00
Robert Lubos
086faa56aa net: lib: http_server: Clear http1_headers_sent flag on new request
http1_headers_sent flag has to be cleared when entering
HTTP_SERVER_REQUEST_STATE and not only on the client init. Otherwise,
serving multiple HTTP1 POST requests over the same connection does not
work as intended (headers were not sent for the second and further
requests).

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2024-08-12 15:54:03 +02:00
Tom Finet
c1235bb4fb net: http: fix %d format string to %zu
Fixes logging of size_t variable to work on both 32
and 64 bit platforms.

Signed-off-by: Tom Finet <tomfinet@outlook.com>
2024-08-05 11:32:08 +02:00
Gerhard Jörges
e55278a87b net: lib: http_server: add static fs resource
adds filesystem as a resource for the http_server which serves static
(gzipped) files from a filesystem to the client.

Signed-off-by: Gerhard Jörges <joerges@metratec.com>
2024-07-31 10:08:16 +02:00
Pieter De Gendt
ac983f633e net: lib: http: Use Kconfig constants
Replace Kconfig values with UINT32_MAX

Signed-off-by: Pieter De Gendt <pieter.degendt@basalte.be>
2024-07-30 18:31:11 +01:00
Robert Lubos
5251533f97 net: lib: http_server: Respect Connection close header
In case no "Connection: close" header is present in the request, the
server should keep the connection open for the client. Hence, after
serving a request, we need to check if the header was present (the
parser sets a flag for it), and only close the connection immediately,
if the client requested it. In case the client remains silent, the
connection will be closed anyway after the inactivity timer kicks in.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2024-07-11 13:11:04 -04:00
Robert Lubos
0e601d4103 net: lib: http_server: Add restart delay
In case there were active connections when restarting the server, it
can't be re-initialized immediately, as binding to the server port will
fail. We need to wait for the TCP connection teardown, as even with
REUSEADDR socket option set, binding will fail if the sockets are not in
TCP TIMED_WAIT state (i. e. connections are active).

Because of this, add a configurable delay when restarting the server.
Additionally, make server initialization failures non-fatal, i. e. try
to restart the server again after the delay if the initialization fails.
It's been observed with Chromium, that it tends to keep connections open
even after closing them on the server side (socket lingers in FIN_WAIT_2
state), so the server re-initialization may fail even with delay, so
it's beneficial in  such case to keep retrying the server
re-initialization.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2024-07-11 13:11:04 -04:00
Robert Lubos
fc10a94683 net: lib: http_server: Close sockets on server core errors
In case of fatal errors (during poll() or when handling listening
socket), the server operation is restarted. It was missed however, that
sockets opened for the server should be closed in such case.

Additionally, in case there were active client connections, it's needed
to cleanup related resources, otherwise running timers may trigger a
crash.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2024-07-11 13:11:04 -04:00
Robert Lubos
be7175351a net: lib: http_server: Fix HTTP1 POST request handling
In previous batch of fixes it was overlooked that streams are
HTTP2-specific concept. While for HTTP2 we need to track headers reply
state for each individual stream, at HTTP1 level we need to track this
at the client level. Hence, reintroduce respective flags to track
headers reply state, but only for HTTP1.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2024-07-11 13:10:09 -04:00
Robert Lubos
9db2dc4aa2 net: lib: http_server: Move stream-specific flags to stream context
The information about replied headers or END_OF_STREAM flag are
stream-specific and not general for a client. Hence, need to move them
to the stream context.

For the upgrade case, we need to allocate a new stream now when HTTP1
request /w upgrade field is received. The stream ID in such case is
assumed to be 1 according to RFC.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2024-07-09 15:20:57 -04:00
Robert Lubos
0e1c0a7b6b net: lib: http_server: Fix trailing headers frame processing
In case client decides to send a trailing headers frame, the last data
frame will not carry END_STREAM flag. In result, with current logic
server would not include END_STREAM flag either, causing the connection
to stall. This commit fixes this logic, so that the server replies
accordingly in case END_STREAM flag is present in the trailing headers
frame.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2024-07-09 15:20:57 -04:00
Robert Lubos
b4cfee090d net: lib: http_server: Implement proper CONTINUATION frame processing
CONTINUATION frames are tricky, because individual header fields can be
split between HEADERS frame and CONTINUATION frame, or two CONTINUATION
frames. Therefore, some extra logic is needed when header parsing
returns -EAGAIN, as we may need to remove the CONTINUATION frame header
from the stream before proceeding with headers parsing.

This commit implements the above logic and additionally adds more checks
to detect when CONTINUATION frame is expected. Not receiving a
CONTINUATION frame when expect should be treated as a protocol error.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2024-07-09 15:20:57 -04:00
Robert Lubos
7e22dd45a0 net: lib: http_server: Fix frame printouts
Frame printouts should not be done from the state handlers, but rather
during state transition, otherwise a single frame can be printed several
times as new data arrive. This also simplifies code a bit, as we just
print the frame in a single place, instead of duplicating code.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2024-07-09 15:20:57 -04:00
Robert Lubos
78c2f48091 net: lib: http_server: Remove upper bounds on buffer sizes
There's really no good reason to have an upper bound on the buffer sizes
and this limits testing in some cases, so just remove them.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2024-07-09 15:20:57 -04:00
Robert Lubos
ccf2e9b025 net: lib: http_server: Implement proper RST_STREAM frame processing
In case RST_STREAM frame is received it should not be ignored, but the
corresponding stream should be closed.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2024-07-09 15:20:57 -04:00
Robert Lubos
b98edfd951 net: lib: http_server: Fix parsing of HTTP2 header frames with priority
In case priority flag is present in the HTTP2 headers frame header, we
should expect additional priority fields before the actual frame
content.

The stream priority signalling has been deprecated by RFC 9113, however
we should still be able to handle this in case some implementation
(nghttp for instance) sends them.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2024-07-09 15:20:57 -04:00
Robert Lubos
2e288aed08 net: lib: http_server: Fix handling of HTTP2 frames with padding
Data and header frames can contain padding - we need to take this into
account when parsing them, otherwise the stream is broken.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2024-07-09 15:20:57 -04:00
Robert Lubos
245b8351f4 net: lib: http_server: Unify HTTP2 header flags checking
Instead of multiplying function to check header flags, just have a
single one, with flag mask as parameter.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2024-07-09 15:20:57 -04:00
Robert Lubos
adfdc54434 net: lib: http_server: Update HTTP2-specific structs/enums naming
For HTTP2-specific structures and enums, use "http2_" prefix to clearly
indicate the distinction from the generic HTTP stuff.

Additionally, some structures/enums describing HTTP2 protocol details
had "server" in the name, while in reality they describe nothing
server-specific. Hence, drop the "server" part where applicable.

Remove unused macros.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2024-07-09 15:20:57 -04:00
Robert Lubos
e1e50bdda9 net: lib: http_server: Simplify HTTP2 frame header parsing
* Remove unneeded variable.
* Use system utilities to read big endian numbers instead of parsing
  manually.
* Remove `payload` member from the http_frame structure. It's not used
  for anything useful, and could actually be misleading, as in case of
  large frames, where not entire frame is parsed at once it will point
  to incorrect location.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2024-07-09 15:20:57 -04:00
Andrey Dodonov
15ead53ad9 net: lib: http: call socket poll for http_client send
If we couldn't send all (or any data) via the socket,
invoke poll instead of blindly retrying and flooding the socket.
Respect timeout through http_client_req

Signed-off-by: Andrey Dodonov <Andrey.Dodonov@endress.com>
2024-07-09 14:04:29 +02:00
Robert Lubos
cd5e1cd0a5 net: lib: http_server: Fix possible NULL pointer dereference
Fix possible NULL pointer dereference in http_hpack_decode_header().

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2024-06-24 12:41:22 -04:00
Alberto Escolar Piedras
f13196429e subsys/net/lib/http: Set feature macro as required
This file uses strnlen() but the C library
is not require to expose its prototype unless
_POSIX_C_SOURCE is defined.
So let's define it to avoid an implicit function
declaration warning.

Signed-off-by: Alberto Escolar Piedras <alberto.escolar.piedras@nordicsemi.no>
2024-06-24 13:01:38 +02:00
Henrik Maier
abeae8fd08 net: lib: http_server: Fix dynamic HTTP post zero 0 length reply
Fix issue in http server that a http post
was unable to send a 0 length reply.

Signed-off-by: Henrik Maier <hwmaier@gmail.com>
2024-06-20 08:58:03 +02:00
frei tycho
382670690c net: change controlling expressions in while to Boolean
Use `do { ... } while (false)` instead of `do { ... } while (0)`.

Signed-off-by: frei tycho <tfrei@baumer.com>
2024-06-11 20:03:16 +03:00
Jukka Rissanen
a124dd2596 net: http_server: Send chunked response correctly
The chunked response was not sent properly. There were extra
"\r\n" before the chunk lenght and the length of the string
to be sent was calculated incorrectly.

Fixes #72887

Signed-off-by: Jukka Rissanen <jukka.rissanen@nordicsemi.no>
2024-06-03 15:39:09 +02:00
Jukka Rissanen
08dc8f93fe net: http_server: Add wildcard support to resource strings
Allow user to specify resource string using wildcard characters
so that multiple URL paths can be served with just one handler.

Fixes #73367

Signed-off-by: Jukka Rissanen <jukka.rissanen@nordicsemi.no>
2024-05-31 09:57:22 -05:00
Jukka Rissanen
6d129b2a2d net: http_server: Add support for specifying Content-Type
Allow user to specify the Content-Type header field for the
HTTP response.

Signed-off-by: Jukka Rissanen <jukka.rissanen@nordicsemi.no>
2024-05-14 20:22:58 -04:00
Fin Maaß
9bd0170aad net: http: client: mark as unstable
As the http client API is currently used by two applications
(websocket and hawkbit), it should be marked as unstable, according
to the docs:
https://docs.zephyrproject.org/latest/develop/api/api_lifecycle.html

Signed-off-by: Fin Maaß <f.maass@vogl-electronic.com>
2024-05-13 16:02:55 -04:00
Jukka Rissanen
3c9513e9cc net: http_server: Add websocket support
After upgrading the HTTP connection to websocket, call the
application registered callback to transfer the ownership of
the socket to the application.

Signed-off-by: Jukka Rissanen <jukka.rissanen@nordicsemi.no>
2024-05-08 15:02:16 -05:00
Jukka Rissanen
535d4b40a8 net: lib: http_server: Upgrade from HTTP/1.1 to websocket
Allow connection to be upgraded from HTTP/1.1 to websocket.
This commit does nothing yet with the upgraded connection.

Signed-off-by: Jukka Rissanen <jukka.rissanen@nordicsemi.no>
2024-05-08 15:02:16 -05:00
Jukka Rissanen
37956465e1 net: lib: http_server: Check HTTP/1.1 Upgrade field
Check what kind of upgrading we are doing and return error
if we receive upgrade that we do not support.

Signed-off-by: Jukka Rissanen <jukka.rissanen@nordicsemi.no>
2024-05-08 15:02:16 -05:00
Jukka Rissanen
4b157b9099 net: lib: http_server: Initial HTTP server support
Original code developed as a GSoC 2023 project by Emna Rekik.

Code refactored in order to provide better bisectability
as the origical commits were not bisectable.

The server supports static and dynamic resources, managed by
HTTP_SERVICE/HTTP_RESOURCE macros.

Fixes #59685
Fixes #59686
Fixes #59688
Fixes #59690
Fixes #59670
Fixes #59700
Fixes #59684
Fixes #59693
Fixes #59693
Fixes #59694
Fixes #59699
Fixes #59696
Fixes #59688
Fixes #59690
Fixes #59670
Fixes #59700
Fixes #59685
Fixes #59686
Fixes #59688
Fixes #59691

Signed-off-by: Emna Rekik <emna.rekik007@gmail.com>
Signed-off-by: Jukka Rissanen <jukka.rissanen@nordicsemi.no>
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2024-04-30 13:25:22 +02:00
Robert Lubos
318dcb6336 net: lib: http_server: Add HPACK and Huffman code encoder/decoder
Add HTTP/2 helper libraries to encode and decode HPACK encoded headers,
according to RFC7541.

HPACK string encoding requires to support certain set of Huffman codes,
therefore implement Huffman encoder/decoder as well.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2024-04-30 13:25:22 +02:00
Georges Oates_Larsen
7fc6ef28d3 net: lib: http: Correct http_client edge-case behavior
Correct various small edge-case behaviors that have been accidentally
introduced in the http_client.

- http_client_req no longer incorrectly returns -ETIMEDOUT on NULL HTTP
  resonse. -ETIMEDOUT is now only returned when the underlying TLS
  socket times out.
- http_client_req now returns -ECONRESET upon incomplete (but non-NULL)
  HTTP response. The request callback is no longer called in this case
  (as with any other error state).
- http_wait_data has been refactored slightly to increase clarity.

Signed-off-by: Georges Oates_Larsen <georges.larsen@nordicsemi.no>
2024-04-05 13:35:22 -05:00