-
Notifications
You must be signed in to change notification settings - Fork 7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
net: http: Add compression support in HTTP server
Add compression support using the accept-encoding header to the http server static filesystem resource. Signed-off-by: Carlo Kirchmeier <carlo.kirchmeier@zuehlke.com>
- Loading branch information
Showing
8 changed files
with
280 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
/** @file | ||
* @brief HTTP compressions | ||
*/ | ||
|
||
/* | ||
* Copyright (c) 2025 Endress+Hauser | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#ifndef ZEPHYR_INCLUDE_NET_HTTP_COMPRESSION_H_ | ||
#define ZEPHYR_INCLUDE_NET_HTTP_COMPRESSION_H_ | ||
|
||
/** | ||
* @brief HTTP compressions | ||
* @defgroup http_compressions HTTP compressions | ||
* @since 4.2 | ||
* @version 0.1.0 | ||
* @ingroup networking | ||
* @{ | ||
*/ | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
#include <stdint.h> | ||
#include <stddef.h> | ||
|
||
#define HTTP_COMPRESSION_MAX_STRING_LEN 8 | ||
|
||
/** @brief HTTP compressions */ | ||
enum http_compression { | ||
HTTP_GZIP = 0, /**< GZIP */ | ||
HTTP_COMPRESS = 1, /**< COMPRESS */ | ||
HTTP_DEFLATE = 2, /**< DEFLATE */ | ||
HTTP_BR = 3, /**< BR */ | ||
HTTP_ZSTD = 4 /**< ZSTD */ | ||
}; | ||
|
||
void http_compression_parse_accept_encoding(const char *accept_encoding, size_t len, | ||
uint8_t *supported_compression); | ||
const char *http_compression_text(enum http_compression compression); | ||
int http_compression_from_text(enum http_compression compression[static 1], const char *text); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
/** | ||
* @} | ||
*/ | ||
|
||
#endif /* ZEPHYR_INCLUDE_NET_HTTP_COMPRESSION_H_ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
/** @file | ||
* @brief HTTP compression handling functions | ||
* | ||
* Helper functions to handle compression formats | ||
*/ | ||
|
||
/* | ||
* Copyright (c) 2025 Endress+Hauser | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
#include <assert.h> | ||
#include <stdbool.h> | ||
#include <string.h> | ||
#include <strings.h> | ||
|
||
#include <zephyr/net/http/compression.h> | ||
#include <zephyr/sys/util.h> | ||
|
||
static bool compression_value_is_valid(enum http_compression compression); | ||
static int http_compression_match(enum http_compression compression[static 1], const char *text, | ||
enum http_compression expected); | ||
|
||
void http_compression_parse_accept_encoding(const char *accept_encoding, size_t len, | ||
uint8_t *supported_compression) | ||
{ | ||
enum http_compression detected_compression; | ||
char strbuf[HTTP_COMPRESSION_MAX_STRING_LEN + 1] = {0}; | ||
const char *start = accept_encoding; | ||
const char *end = NULL; | ||
bool priority_string = false; | ||
|
||
*supported_compression = 0; | ||
for (size_t i = 0; i < len; i++) { | ||
if (accept_encoding[i] == 0) { | ||
break; | ||
} else if (accept_encoding[i] == ' ') { | ||
start = &accept_encoding[i + 1]; | ||
continue; | ||
} else if (accept_encoding[i] == ';') { | ||
end = &accept_encoding[i]; | ||
priority_string = true; | ||
} else if (accept_encoding[i] == ',') { | ||
if (!priority_string) { | ||
end = &accept_encoding[i]; | ||
} | ||
priority_string = false; | ||
} else if (i + 1 == len) { | ||
end = &accept_encoding[i + 1]; | ||
} | ||
|
||
if (end == NULL) { | ||
continue; | ||
} | ||
|
||
if (end - start > HTTP_COMPRESSION_MAX_STRING_LEN) { | ||
end = NULL; | ||
start = end + 1; | ||
continue; | ||
} | ||
|
||
memcpy(strbuf, start, end - start); | ||
strbuf[end - start] = 0; | ||
|
||
if (http_compression_from_text(&detected_compression, strbuf) == 0) { | ||
WRITE_BIT(*supported_compression, detected_compression, true); | ||
} | ||
|
||
end = NULL; | ||
start = end + 1; | ||
} | ||
} | ||
|
||
const char *http_compression_text(enum http_compression compression) | ||
{ | ||
switch (compression) { | ||
case HTTP_GZIP: | ||
return "gzip"; | ||
case HTTP_COMPRESS: | ||
return "compress"; | ||
case HTTP_DEFLATE: | ||
return "deflate"; | ||
case HTTP_BR: | ||
return "br"; | ||
case HTTP_ZSTD: | ||
return "zstd"; | ||
} | ||
return ""; | ||
} | ||
|
||
int http_compression_from_text(enum http_compression compression[static 1], const char *text) | ||
{ | ||
assert(compression); | ||
assert(text); | ||
|
||
for (enum http_compression i = 0; compression_value_is_valid(i); ++i) { | ||
if (http_compression_match(compression, text, i) == 0) { | ||
return 0; | ||
} | ||
} | ||
return 1; | ||
} | ||
|
||
static bool compression_value_is_valid(enum http_compression compression) | ||
{ | ||
switch (compression) { | ||
case HTTP_GZIP: | ||
case HTTP_COMPRESS: | ||
case HTTP_DEFLATE: | ||
case HTTP_BR: | ||
case HTTP_ZSTD: | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
static int http_compression_match(enum http_compression compression[static 1], const char *text, | ||
enum http_compression expected) | ||
{ | ||
assert(compression); | ||
assert(text); | ||
|
||
if (strcasecmp(http_compression_text(expected), text) == 0) { | ||
*compression = expected; | ||
return 0; | ||
} else { | ||
return 1; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.