
Hi Mikhail,
On Mon, 9 Sept 2024 at 16:27, Mikhail Kshevetskiy mikhail.kshevetskiy@iopsys.eu wrote:
This is an example web-server implementation. It can be used for files uploading to u-boot using a web-browser. It acts much like tftpget, but no special servers needs to be installed by the user.
This code can be used as a base for other implementations like firmware upgrade web-server used by some vendors.
Usage: u-boot: start the we-server using the "httpd_upload" command PC: open the "http://your_uboot_ip" link in the browser
Signed-off-by: Mikhail Kshevetskiy mikhail.kshevetskiy@iopsys.eu
cmd/Kconfig | 14 ++++ cmd/net.c | 20 ++++++ include/net/httpd-upload.h | 12 ++++ net/Makefile | 19 +++++ net/httpd-upload.c | 123 ++++++++++++++++++++++++++++++++ net/httpd_upload/error_400.html | 9 +++ net/httpd_upload/error_404.html | 10 +++ net/httpd_upload/index.html | 14 ++++ net/httpd_upload/upload_ok.html | 7 ++ 9 files changed, 228 insertions(+) create mode 100644 include/net/httpd-upload.h create mode 100644 net/httpd-upload.c create mode 100644 net/httpd_upload/error_400.html create mode 100644 net/httpd_upload/error_404.html create mode 100644 net/httpd_upload/index.html create mode 100644 net/httpd_upload/upload_ok.html
Can you just include the strings in the C file?
diff --git a/cmd/Kconfig b/cmd/Kconfig index abcd003f7f1..55b9d04f2fa 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -2014,6 +2014,20 @@ config CMD_NETCAT netcat is a simple command to load/store kernel, or other files, using netcat like manner over TCP.
+config CMD_HTTPD_UPLOAD
bool "an example HTTP server for file uploading"
depends on HTTPD_COMMON
help
HTTP/1.1 compatible server for file uploading.
Please expand help
+config CMD_HTTPD_UPLOAD_MAX_SIZE
int "Maximum uploading size"
depends on CMD_HTTPD_UPLOAD
default 209715200
help
This sets maximum size of uploaded file. Real transfer will be
sets the maximum
of any uploaded
slightly more than this limit.
Please describe why
config CMD_MII bool "mii" imply CMD_MDIO diff --git a/cmd/net.c b/cmd/net.c index 364139ec5b9..e5fddc8c7c5 100644 --- a/cmd/net.c +++ b/cmd/net.c @@ -21,6 +21,9 @@ #include <net/udp.h> #include <net/sntp.h> #include <net/ncsi.h> +#if defined(CONFIG_CMD_HTTPD_UPLOAD) +#include <net/httpd-upload.h> +#endif
static int netboot_common(enum proto_t, struct cmd_tbl *, int, char * const []);
@@ -228,6 +231,23 @@ U_BOOT_CMD( ); #endif
+#if defined(CONFIG_CMD_HTTPD_UPLOAD) +static int do_httpd_upload(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) +{
if (argc < 2)
return 1;
httpd_upload_prepare();
return netboot_common(HTTPD, cmdtp, argc, argv);
+}
+U_BOOT_CMD(
httpd_upload, 2, 1, do_httpd_upload,
"starts httpd server for file uploading",
"[loadAddress]\n"
+); +#endif
static void netboot_update_env(void) { char tmp[46]; diff --git a/include/net/httpd-upload.h b/include/net/httpd-upload.h new file mode 100644 index 00000000000..a80df214668 --- /dev/null +++ b/include/net/httpd-upload.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: BSD-2-Clause
- httpd-upload include file
- Copyright (C) 2024 IOPSYS Software Solutions AB
- Author: Mikhail Kshevetskiy mikhail.kshevetskiy@iopsys.eu
- */
+#ifndef __NET_HTTPD_UPLOAD_TCP_H__ +#define __NET_HTTPD_UPLOAD_TCP_H__
+void httpd_upload_prepare(void);
+#endif /* __NET_HTTPD_UPLOAD_TCP_H__ */ diff --git a/net/Makefile b/net/Makefile index c1f491fad02..e7cbbc2248e 100644 --- a/net/Makefile +++ b/net/Makefile @@ -35,8 +35,27 @@ obj-$(CONFIG_PROT_TCP) += tcp.o obj-$(CONFIG_CMD_WGET) += wget.o obj-$(CONFIG_CMD_NETCAT) += netcat.o obj-$(CONFIG_HTTPD_COMMON) += httpd.o +obj-$(CONFIG_CMD_HTTPD_UPLOAD) += httpd-upload.o
# Disable this warning as it is triggered by: # sprintf(buf, index ? "foo%d" : "foo", index) # and this is intentional usage. CFLAGS_eth_common.o += -Wno-format-extra-args
+STATIC_SUBST := 's/^(unsigned char )/static \1/' +SIZE_REMOVE_SUBST := 's/^unsigned int .*//'
+httpd_upload_generated:
rm -rf $(src)/httpd_upload_generated
mkdir -p $(src)/httpd_upload_generated
cd $(src)/httpd_upload && find . -type f | while read fname; do \
name="$${fname##*/}" && \
name="$${name%%.*}" && \
set -o pipefail && xxd -i "$${fname##./}" | \
sed $(STATIC_SUBST) | \
sed $(SIZE_REMOVE_SUBST) > ../httpd_upload_generated/$${name}.h; \
done
+.PHONY: httpd_upload_generated
+net/httpd-upload.o: httpd_upload_generated diff --git a/net/httpd-upload.c b/net/httpd-upload.c new file mode 100644 index 00000000000..1e1e0b1cf75 --- /dev/null +++ b/net/httpd-upload.c @@ -0,0 +1,123 @@ +// SPDX-License-Identifier: GPL-2.0 +/*
- httpd-upload support driver
- Copyright (C) 2024 IOPSYS Software Solutions AB
- Author: Mikhail Kshevetskiy mikhail.kshevetskiy@iopsys.eu
- */
+#include <command.h> +#include <net.h> +#include <net/httpd.h> +#include <net/httpd-upload.h>
+#define MAX_FILE_SIZE CONFIG_CMD_HTTPD_UPLOAD_MAX_SIZE
+static enum net_loop_state httpd_on_stop(void);
+static enum httpd_req_check httpd_pre_post(void *req_id, const char *url,
struct httpd_post_data *post);
+static struct http_reply *httpd_get(void *req_id, const char *url); +static struct http_reply *httpd_post(void *req_id, const char *url,
struct httpd_post_data *post);
+static void httpd_on_req_end(void *req_id);
+#include "httpd_upload_generated/error_400.h" +#include "httpd_upload_generated/error_404.h" +#include "httpd_upload_generated/index.h" +#include "httpd_upload_generated/upload_ok.h"
+static struct http_reply error_400 = {
.code = 400,
.code_msg = "Bad Request",
.data_type = "text/html; charset=utf-8",
.data = error_400_html,
.len = sizeof(error_400_html)
+};
+static struct http_reply error_404 = {
.code = 404,
.code_msg = "Not Found",
.data_type = "text/html; charset=utf-8",
.data = error_404_html,
.len = sizeof(error_404_html)
+};
+static struct http_reply index = {
.code = 200,
.code_msg = "OK",
.data_type = "text/html; charset=utf-8",
.data = index_html,
.len = sizeof(index_html)
+};
+static struct http_reply upload_ok = {
.code = 200,
.code_msg = "OK",
.data_type = "text/html; charset=utf-8",
.data = upload_ok_html,
.len = sizeof(upload_ok_html)
+};
+static struct httpd_config cfg = {
.on_stop = httpd_on_stop,
.on_req_end = httpd_on_req_end,
.get = httpd_get,
.post = httpd_post,
.pre_post = httpd_pre_post,
.error_400 = &error_400,
.error_404 = &error_404,
+};
+static enum net_loop_state httpd_loop_state; +static void *post_req_id;
+void httpd_upload_prepare(void) +{
httpd_setup(&cfg);
httpd_loop_state = NETLOOP_FAIL;
+}
+static enum httpd_req_check httpd_pre_post(void *req_id, const char *url,
struct httpd_post_data *post)
+{
if (post->size > MAX_FILE_SIZE) {
printf("HTTPD: reset connection, upload file is too large\n");
return HTTPD_CLNT_RST;
}
post_req_id = req_id;
return HTTPD_REQ_OK;
+}
+static struct http_reply *httpd_post(void *req_id, const char *url,
struct httpd_post_data *post)
+{
if (strcmp(url, "/file_upload"))
return &error_404;
httpd_loop_state = NETLOOP_SUCCESS;
printf("HTTPD: upload OK\n");
return &upload_ok;
+}
+static struct http_reply *httpd_get(void *req_id, const char *url) +{
if (!strcmp(url, "/"))
return &index;
if (!strcmp(url, "/index.html"))
return &index;
return &error_404;
+}
+static void httpd_on_req_end(void *req_id) +{
if (req_id == post_req_id) {
post_req_id = NULL;
httpd_stop();
}
+}
+static enum net_loop_state httpd_on_stop(void) +{
return httpd_loop_state;
+} diff --git a/net/httpd_upload/error_400.html b/net/httpd_upload/error_400.html new file mode 100644 index 00000000000..de654364edf --- /dev/null +++ b/net/httpd_upload/error_400.html @@ -0,0 +1,9 @@ +<html>
<head><title>400</title></head>
<body>
<h1>400 - Bad Request</h1>
<p>
Sorry, the request you are trying to do is wrong.
</p>
</body>
+</html> diff --git a/net/httpd_upload/error_404.html b/net/httpd_upload/error_404.html new file mode 100644 index 00000000000..9dac22d497d --- /dev/null +++ b/net/httpd_upload/error_404.html @@ -0,0 +1,10 @@ +<html>
<head><title>404</title></head>
<body>
<h1>404 - Page not found</h1>
<p>
Sorry, the page you are requesting was not found on this
server.
</p>
</body>
+</html> diff --git a/net/httpd_upload/index.html b/net/httpd_upload/index.html new file mode 100644 index 00000000000..e7d5ac943b6 --- /dev/null +++ b/net/httpd_upload/index.html @@ -0,0 +1,14 @@ +<html>
<head><title>Upload File</title></head>
<body>
<h1>Upload File.</h1>
<p>This will write the uploaded file to the memory arear pointed by ${loadaddr}.
<form method="post" enctype="multipart/form-data" action="file_upload">
File to upload:
<input type="file" name="fileID" size="500" /><br />
<p> <input type="submit" value="upload" />
<p>It takes no more than a second after the file has been uploaded until status OK is shown.
</form>
</p>
</body>
+</html> diff --git a/net/httpd_upload/upload_ok.html b/net/httpd_upload/upload_ok.html new file mode 100644 index 00000000000..8d2e561982f --- /dev/null +++ b/net/httpd_upload/upload_ok.html @@ -0,0 +1,7 @@ +<html>
<head><title>OK</title></head>
<body>
<h1>Upload OK</h1>
<p>The file was uploaded.</p>
</body>
+</html>
2.45.2
REgards, Simon