Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
c5f78c7
net: lib: http_server: Initial HTTP server support
jukkar Nov 9, 2023
7bdd5de
tests: net: http_server: Add tests for the HTTP server
jukkar Nov 9, 2023
cd910ec
samples: net: http_server: Add HTTP server sample application
jukkar Nov 9, 2023
fa84695
tests: net: http_server: Change the tests to use picolibc
jukkar Oct 26, 2023
1ebcad4
samples: net: socket: http_server: Fix the config options
jukkar Oct 26, 2023
67bf810
net: lib: http_server: Use debug level set in prj.conf file
jukkar Oct 26, 2023
dc13989
net: lib: http_server: Remove the option to run in Linux
jukkar Oct 26, 2023
3523962
net: lib: http_server: Do not use Posix socket API names
jukkar Oct 26, 2023
f964efd
net: lib: https_server: Compile test TLS support always
jukkar Oct 26, 2023
719b956
net: http: service: Allow user to set TLS security tag list
jukkar Oct 28, 2023
553b3d6
net: lib: http_server: Remove separate method bitmasks
jukkar Oct 28, 2023
394a615
net: lib: http_server: Support multiple services and clients
jukkar Oct 28, 2023
e146f2a
net: lib: http_server: Remove the sec tag values from lib
jukkar Nov 4, 2023
e75f636
net: lib: http_server: Save few bytes if TLS is disabled
jukkar Nov 9, 2023
770c053
samples: net: http_server: Add HTTPS support
jukkar Oct 26, 2023
3300ed7
net: lib: http_server: Add support for dynamic GET services
jukkar Nov 25, 2023
9e34984
samples: net: http_server: Add dynamic GET support
jukkar Nov 25, 2023
3934ddb
samples: net: http_server: Restart the app if needed
jukkar Nov 25, 2023
dfadeb7
net: lib: http_server: Add support for dynamic POST services
jukkar Feb 27, 2024
7600ca0
net: lib: http_server: Removed the original REST specific code
jukkar Feb 27, 2024
474929e
net: lib: http_server: Refactor the TEMP_BUF_LEN define
jukkar Feb 27, 2024
475444e
net: lib: http_server: Use snake_case for http_client_ctx members
rlubos Mar 15, 2024
6e98e1c
net: lib: http_server: Fix HTTP/2 headers parsing
rlubos Mar 15, 2024
4b4b38a
net: lib: http_server: Fix HTTP/1 to HTTP/2 upgrade
rlubos Mar 15, 2024
7e5905a
net: lib: http_server: Send server preface when connection starts
rlubos Mar 25, 2024
c422303
net: lib: http_server: Remove incorrect handling of window udpate frame
rlubos Mar 25, 2024
a34d3ee
net: lib: http_server: Make sure preface is sent only once
rlubos Mar 26, 2024
6fbae0b
net: lib: http_server: Clear revents flag on new connection
rlubos Mar 26, 2024
2ec4cf1
net: lib: http_server: Improve POLLERR handling for server sockets
rlubos Mar 27, 2024
706ff09
net: lib: http_server: Fix the memset parameters
jukkar Mar 27, 2024
153c25b
net: lib: http_server: Implement server cleanup
jukkar Apr 2, 2024
36e90ed
samples: net: http_server: Do not test compile with native_posix
jukkar Apr 6, 2024
6ab1e8a
tests: net: http_server: Fix the tests
jukkar Apr 2, 2024
74b228a
net: lib: http_server: Handle parser errors correctly
rlubos Mar 28, 2024
655a4fd
net: lib: http_server: Centralize buffer data move
rlubos Apr 5, 2024
ac5e7b1
net: lib: http_server: Rework HPACK decoder
rlubos Apr 8, 2024
13b155d
net: lib: http_server: Implement Huffman decoding
rlubos Apr 9, 2024
fe475e2
tests: net: lib: http_server: Remove HPACK tests temporarily
rlubos Apr 10, 2024
4c83bcb
tests: net: http_server: Fix tests
rlubos Apr 10, 2024
6bc36f6
net: lib: http_server: Add user specified Content-Encoding support
jukkar Apr 8, 2024
bdee3d3
samples: net: http_server: Serve gzipped static pages
jukkar Apr 8, 2024
fcf0b84
net: lib: http_server: Fix resource string matching for dynamic paths
jukkar Apr 10, 2024
0c4d5c2
net: lib: http_server: Add dynamic support to http2
jukkar Apr 16, 2024
85d39b7
samples: net: http_server: Add dynamic support to the application
jukkar Apr 16, 2024
da7f068
net: lib: http_server: Add HPACK encoder
rlubos Apr 12, 2024
a6b1ba4
net: lib: http_server: Add Huffman encoder
rlubos Apr 16, 2024
5bd1dcc
net: lib: http_server: Use HPACK encoder for headers frame creation
rlubos Apr 16, 2024
9078128
net: lib: http_server: Encode settings in settings frame
rlubos Apr 16, 2024
b726a25
net: lib: http_server: Update flag checking function names
rlubos Apr 16, 2024
30f0fde
net: lib: http_server: Split HTTP server into multiple files
rlubos Apr 17, 2024
b56eda5
net: lib: http_server: Place HTTP parser init to separate function
jukkar Apr 17, 2024
4c0317c
net: lib: http_server: Wait all HTTP/1 headers before handling request
jukkar Apr 17, 2024
7c1e6aa
net: lib: http_server: Remove POSIX_API dependency
jukkar Apr 17, 2024
370ae60
net: lib: http_server: Fix large HTTP1 payload uploads
rlubos Apr 17, 2024
8820d5c
samples: net: sockets: http_server: Keep track of total received bytes
rlubos Apr 18, 2024
ba72827
net: lib: http_server: Fix stream allocation on data frame
rlubos Apr 18, 2024
7bfabdd
net: lib: http_server: Fix large HTTP2 payload uploads
rlubos Apr 18, 2024
69f70ad
net: lib: http_server: Fix socket count passed to poll()
rlubos Apr 18, 2024
23d8156
net: lib: http_server: Fix HTTP upgrade for dynamic resources
rlubos Apr 19, 2024
a27b694
net: lib: http_server: Optimize responses in HTTP2 post
rlubos Apr 19, 2024
de03c84
net: lib: http_server: Remove another POSIX_API dependency
rlubos Apr 19, 2024
d4821b0
net: lib: http_server: Initial implementation of flow-control
rlubos Apr 19, 2024
9d0ddd8
net: lib: http_server: Rename server_functions.h header
rlubos Apr 22, 2024
fcd8ce6
net: lib: http_server: Remove http_service.h internal header
rlubos Apr 22, 2024
1db81a3
net: lib: http_server: Add incactivity timer
rlubos Apr 19, 2024
38aff7d
net: lib: http_server: Make HTTP server run in a background thread
rlubos Apr 23, 2024
3928013
net: lib: http_server: Remove references to server context
rlubos Apr 23, 2024
886d81d
net: lib: http_server: Use zsock_ symbols where missed
rlubos Apr 23, 2024
3be45c2
net: lib: http_server: Remove HTTP_HPACK_TABLE config
rlubos Apr 23, 2024
38f3a71
net: lib: http_server: Avoid dummy data frame for static resource
rlubos Apr 23, 2024
0bdd53a
test: net: lib: http_server: Fix tests
rlubos Apr 23, 2024
cb78eb1
net: lib: http_server: Add resource lock for dynamic resources
rlubos Apr 24, 2024
afd87d2
net: lib: http_server: Report communication errors to the resource cb
rlubos Apr 25, 2024
0bc5c86
samples: net: http_server: Align the sample with new dynamic cb format
rlubos Apr 25, 2024
5001659
net: lib: http_server: Remove unused Kconfigs
rlubos Apr 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/zephyr/linker/common-rom/common-rom-net.ld
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#endif

#if defined(CONFIG_HTTP_SERVER)
ITERABLE_SECTION_ROM(http_resource_desc, 4)
ITERABLE_SECTION_ROM(http_service_desc, 4)
#endif

Expand Down
52 changes: 52 additions & 0 deletions include/zephyr/net/http/frame.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Copyright (c) 2023, Emna Rekik
*
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef ZEPHYR_INCLUDE_NET_HTTP_SERVER_FRAME_H_
#define ZEPHYR_INCLUDE_NET_HTTP_SERVER_FRAME_H_

#include <stdint.h>

enum http_frame_type {
HTTP_SERVER_DATA_FRAME = 0x00,
HTTP_SERVER_HEADERS_FRAME = 0x01,
HTTP_SERVER_PRIORITY_FRAME = 0x02,
HTTP_SERVER_RST_STREAM_FRAME = 0x03,
HTTP_SERVER_SETTINGS_FRAME = 0x04,
HTTP_SERVER_PUSH_PROMISE_FRAME = 0x05,
HTTP_SERVER_PING_FRAME = 0x06,
HTTP_SERVER_GOAWAY_FRAME = 0x07,
HTTP_SERVER_WINDOW_UPDATE_FRAME = 0x08,
HTTP_SERVER_CONTINUATION_FRAME = 0x09
};

#define HTTP_SERVER_HPACK_METHOD 0
#define HTTP_SERVER_HPACK_PATH 1

#define HTTP_SERVER_FLAG_SETTINGS_ACK 0x1
#define HTTP_SERVER_FLAG_END_HEADERS 0x4
#define HTTP_SERVER_FLAG_END_STREAM 0x1

#define HTTP_SERVER_FRAME_HEADER_SIZE 9
#define HTTP_SERVER_FRAME_LENGTH_OFFSET 0
#define HTTP_SERVER_FRAME_TYPE_OFFSET 3
#define HTTP_SERVER_FRAME_FLAGS_OFFSET 4
#define HTTP_SERVER_FRAME_STREAM_ID_OFFSET 5

struct http_settings_field {
uint16_t id;
uint32_t value;
} __packed;

enum http_settings {
HTTP_SETTINGS_HEADER_TABLE_SIZE = 1,
HTTP_SETTINGS_ENABLE_PUSH = 2,
HTTP_SETTINGS_MAX_CONCURRENT_STREAMS = 3,
HTTP_SETTINGS_INITIAL_WINDOW_SIZE = 4,
HTTP_SETTINGS_MAX_FRAME_SIZE = 5,
HTTP_SETTINGS_MAX_HEADER_LIST_SIZE = 6,
};

#endif
134 changes: 134 additions & 0 deletions include/zephyr/net/http/hpack.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
/** @file
* @brief HTTP HPACK
*/

/*
* Copyright (c) 2023 Emna Rekik
*
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef ZEPHYR_INCLUDE_NET_HTTP_SERVER_HPACK_H_
#define ZEPHYR_INCLUDE_NET_HTTP_SERVER_HPACK_H_

#include <stddef.h>
#include <stdint.h>

/**
* @brief HTTP HPACK
* @defgroup http_hpack HTTP HPACK
* @ingroup networking
* @{
*/

#ifdef __cplusplus
extern "C" {
#endif

enum http_hpack_static_key {
HTTP_SERVER_HPACK_INVALID = 0,
HTTP_SERVER_HPACK_AUTHORITY = 1,
HTTP_SERVER_HPACK_METHOD_GET = 2,
HTTP_SERVER_HPACK_METHOD_POST = 3,
HTTP_SERVER_HPACK_PATH_ROOT = 4,
HTTP_SERVER_HPACK_PATH_INDEX = 5,
HTTP_SERVER_HPACK_SCHEME_HTTP = 6,
HTTP_SERVER_HPACK_SCHEME_HTTPS = 7,
HTTP_SERVER_HPACK_STATUS_200 = 8,
HTTP_SERVER_HPACK_STATUS_204 = 9,
HTTP_SERVER_HPACK_STATUS_206 = 10,
HTTP_SERVER_HPACK_STATUS_304 = 11,
HTTP_SERVER_HPACK_STATUS_400 = 12,
HTTP_SERVER_HPACK_STATUS_404 = 13,
HTTP_SERVER_HPACK_STATUS_500 = 14,
HTTP_SERVER_HPACK_ACCEPT_CHARSET = 15,
HTTP_SERVER_HPACK_ACCEPT_ENCODING = 16,
HTTP_SERVER_HPACK_ACCEPT_LANGUAGE = 17,
HTTP_SERVER_HPACK_ACCEPT_RANGES = 18,
HTTP_SERVER_HPACK_ACCEPT = 19,
HTTP_SERVER_HPACK_ACCESS_CONTROL_ALLOW_ORIGIN = 20,
HTTP_SERVER_HPACK_AGE = 21,
HTTP_SERVER_HPACK_ALLOW = 22,
HTTP_SERVER_HPACK_AUTHORIZATION = 23,
HTTP_SERVER_HPACK_CACHE_CONTROL = 24,
HTTP_SERVER_HPACK_CONTENT_DISPOSITION = 25,
HTTP_SERVER_HPACK_CONTENT_ENCODING = 26,
HTTP_SERVER_HPACK_CONTENT_LANGUAGE = 27,
HTTP_SERVER_HPACK_CONTENT_LENGTH = 28,
HTTP_SERVER_HPACK_CONTENT_LOCATION = 29,
HTTP_SERVER_HPACK_CONTENT_RANGE = 30,
HTTP_SERVER_HPACK_CONTENT_TYPE = 31,
HTTP_SERVER_HPACK_COOKIE = 32,
HTTP_SERVER_HPACK_DATE = 33,
HTTP_SERVER_HPACK_ETAG = 34,
HTTP_SERVER_HPACK_EXPECT = 35,
HTTP_SERVER_HPACK_EXPIRES = 36,
HTTP_SERVER_HPACK_FROM = 37,
HTTP_SERVER_HPACK_HOST = 38,
HTTP_SERVER_HPACK_IF_MATCH = 39,
HTTP_SERVER_HPACK_IF_MODIFIED_SINCE = 40,
HTTP_SERVER_HPACK_IF_NONE_MATCH = 41,
HTTP_SERVER_HPACK_IF_RANGE = 42,
HTTP_SERVER_HPACK_IF_UNMODIFIED_SINCE = 43,
HTTP_SERVER_HPACK_LAST_MODIFIED = 44,
HTTP_SERVER_HPACK_LINK = 45,
HTTP_SERVER_HPACK_LOCATION = 46,
HTTP_SERVER_HPACK_MAX_FORWARDS = 47,
HTTP_SERVER_HPACK_PROXY_AUTHENTICATE = 48,
HTTP_SERVER_HPACK_PROXY_AUTHORIZATION = 49,
HTTP_SERVER_HPACK_RANGE = 50,
HTTP_SERVER_HPACK_REFERER = 51,
HTTP_SERVER_HPACK_REFRESH = 52,
HTTP_SERVER_HPACK_RETRY_AFTER = 53,
HTTP_SERVER_HPACK_SERVER = 54,
HTTP_SERVER_HPACK_SET_COOKIE = 55,
HTTP_SERVER_HPACK_STRICT_TRANSPORT_SECURITY = 56,
HTTP_SERVER_HPACK_TRANSFER_ENCODING = 57,
HTTP_SERVER_HPACK_USER_AGENT = 58,
HTTP_SERVER_HPACK_VARY = 59,
HTTP_SERVER_HPACK_VIA = 60,
HTTP_SERVER_HPACK_WWW_AUTHENTICATE = 61,
};

/* TODO Kconfig */
#define HTTP2_HEADER_FIELD_MAX_LEN 256

/** HTTP2 header field with decoding buffer. */
struct http_hpack_header_buf {
/** A pointer to the decoded header field name. */
const char *name;

/** A pointer to the decoded header field value. */
const char *value;

/** Length of the decoded header field name. */
size_t name_len;

/** Length of the decoded header field value. */
size_t value_len;

/** Encoding/Decoding buffer. Used with Huffman encoding/decoding. */
uint8_t buf[CONFIG_HTTP_SERVER_HUFFMAN_DECODE_BUFFER_SIZE];

/** Length of the data in the decoding buffer. */
size_t datalen;
};

int http_hpack_huffman_decode(const uint8_t *encoded_buf, size_t encoded_len,
uint8_t *buf, size_t buflen);
int http_hpack_huffman_encode(const uint8_t *str, size_t str_len,
uint8_t *buf, size_t buflen);
int http_hpack_decode_header(const uint8_t *buf, size_t datalen,
struct http_hpack_header_buf *header);
int http_hpack_encode_header(uint8_t *buf, size_t buflen,
struct http_hpack_header_buf *header);

#ifdef __cplusplus
}
#endif

/**
* @}
*/

#endif
2 changes: 2 additions & 0 deletions include/zephyr/net/http/method.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ enum http_method {
HTTP_MKCALENDAR = 30, /**< MKCALENDAR */
HTTP_LINK = 31, /**< LINK */
HTTP_UNLINK = 32, /**< UNLINK */

HTTP_METHOD_END_VALUE /* keep this the last value */
};

#ifdef __cplusplus
Expand Down
175 changes: 175 additions & 0 deletions include/zephyr/net/http/server.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
/*
* Copyright (c) 2023, Emna Rekik
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef ZEPHYR_INCLUDE_NET_HTTP_SERVER_H_
#define ZEPHYR_INCLUDE_NET_HTTP_SERVER_H_

#include <stdint.h>

#include <zephyr/kernel.h>
#include <zephyr/net/http/parser.h>
#include <zephyr/net/http/hpack.h>
#include <zephyr/net/socket.h>

#define HTTP_SERVER_CLIENT_BUFFER_SIZE CONFIG_HTTP_SERVER_CLIENT_BUFFER_SIZE
#define HTTP_SERVER_MAX_STREAMS CONFIG_HTTP_SERVER_MAX_STREAMS
#define HTTP_SERVER_MAX_CONTENT_TYPE_LEN CONFIG_HTTP_SERVER_MAX_CONTENT_TYPE_LENGTH

#define HTTP2_PREFACE "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"

enum http_resource_type {
HTTP_RESOURCE_TYPE_STATIC,
HTTP_RESOURCE_TYPE_DYNAMIC,
HTTP_RESOURCE_TYPE_REST
};

struct http_resource_detail {
uint32_t bitmask_of_supported_http_methods;
enum http_resource_type type;
int path_len; /* length of the URL path */
const char *content_encoding;
};
BUILD_ASSERT(NUM_BITS(
sizeof(((struct http_resource_detail *)0)->bitmask_of_supported_http_methods))
>= (HTTP_METHOD_END_VALUE - 1));

struct http_resource_detail_static {
struct http_resource_detail common;
const void *static_data;
size_t static_data_len;
};

struct http_client_ctx;

/** Indicates the status of the currently processed piece of data. */
enum http_data_status {
/** Transaction aborted, data incomplete. */
HTTP_SERVER_DATA_ABORTED = -1,
/** Transaction incomplete, more data expected. */
HTTP_SERVER_DATA_MORE = 0,
/** Final data fragment in current transaction. */
HTTP_SERVER_DATA_FINAL = 1,
};

/**
* @typedef http_resource_dynamic_cb_t
* @brief Callback used when data is received. Data to be sent to client
* can be specified.
*
* @param client HTTP context information for this client connection.
* @param status HTTP data status, indicate whether more data is expected or not.
* @param data_buffer Data received.
* @param data_len Amount of data received.
* @param user_data User specified data.
*
* @return >0 amount of data to be sent to client, let server to call this
* function again when new data is received.
* 0 nothing to sent to client, close the connection
* <0 error, close the connection.
*/
typedef int (*http_resource_dynamic_cb_t)(struct http_client_ctx *client,
enum http_data_status status,
uint8_t *data_buffer,
size_t data_len,
void *user_data);

struct http_resource_detail_dynamic {
struct http_resource_detail common;
http_resource_dynamic_cb_t cb;
uint8_t *data_buffer;
size_t data_buffer_len;
struct http_client_ctx *holder;
void *user_data;
};

struct http_resource_detail_rest {
struct http_resource_detail common;
};

enum http_stream_state {
HTTP_SERVER_STREAM_IDLE,
HTTP_SERVER_STREAM_RESERVED_LOCAL,
HTTP_SERVER_STREAM_RESERVED_REMOTE,
HTTP_SERVER_STREAM_OPEN,
HTTP_SERVER_STREAM_HALF_CLOSED_LOCAL,
HTTP_SERVER_STREAM_HALF_CLOSED_REMOTE,
HTTP_SERVER_STREAM_CLOSED
};

enum http_server_state {
HTTP_SERVER_FRAME_HEADER_STATE,
HTTP_SERVER_PREFACE_STATE,
HTTP_SERVER_REQUEST_STATE,
HTTP_SERVER_FRAME_DATA_STATE,
HTTP_SERVER_FRAME_HEADERS_STATE,
HTTP_SERVER_FRAME_SETTINGS_STATE,
HTTP_SERVER_FRAME_PRIORITY_STATE,
HTTP_SERVER_FRAME_WINDOW_UPDATE_STATE,
HTTP_SERVER_FRAME_CONTINUATION_STATE,
HTTP_SERVER_FRAME_PING_STATE,
HTTP_SERVER_FRAME_RST_STREAM_STATE,
HTTP_SERVER_FRAME_GOAWAY_STATE,
HTTP_SERVER_DONE_STATE,
};

enum http1_parser_state {
HTTP1_INIT_HEADER_STATE,
HTTP1_WAITING_HEADER_STATE,
HTTP1_RECEIVING_HEADER_STATE,
HTTP1_RECEIVED_HEADER_STATE,
HTTP1_RECEIVING_DATA_STATE,
HTTP1_MESSAGE_COMPLETE_STATE,
};

#define HTTP_SERVER_INITIAL_WINDOW_SIZE 65536

struct http_stream_ctx {
int stream_id;
enum http_stream_state stream_state;
int window_size; /**< Stream-level window size. */
};

struct http_frame {
uint32_t length;
uint32_t stream_identifier;
uint8_t type;
uint8_t flags;
uint8_t *payload;
};

struct http_client_ctx {
int fd;
bool preface_sent;
bool has_upgrade_header;
unsigned char buffer[HTTP_SERVER_CLIENT_BUFFER_SIZE];
unsigned char *cursor; /**< Cursor indicating currently processed byte. */
size_t data_len; /**< Data left to process in the buffer. */
int window_size; /**< Connection-level window size. */
enum http_server_state server_state;
struct http_frame current_frame;
struct http_resource_detail *current_detail;
struct http_hpack_header_buf header_field;
struct http_stream_ctx streams[HTTP_SERVER_MAX_STREAMS];
struct http_parser_settings parser_settings;
struct http_parser parser;
unsigned char url_buffer[CONFIG_HTTP_SERVER_MAX_URL_LENGTH];
unsigned char content_type[CONFIG_HTTP_SERVER_MAX_CONTENT_TYPE_LENGTH];
size_t content_len;
enum http_method method;
enum http1_parser_state parser_state;
int http1_frag_data_len;
bool headers_sent;
struct k_work_delayable inactivity_timer;
};

/* Starts the HTTP2 server */
int http_server_start(void);

/* Stops the HTTP2 server */
int http_server_stop(void);

#endif
Loading