1 /*
2  * Copyright (c) 2024 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/logging/log.h>
8 LOG_MODULE_DECLARE(net_shell);
9 
10 #include "net_shell_private.h"
11 #include <zephyr/net/http/service.h>
12 #include <zephyr/net/http/server.h>
13 #include <zephyr/net/http/method.h>
14 #include <zephyr/net/http/parser.h>
15 
16 #define IS_BIT_SET(val, bit) (((val >> bit) & (0x1)) != 0)
17 
cmd_net_http(const struct shell * sh,size_t argc,char * argv[])18 static int cmd_net_http(const struct shell *sh, size_t argc, char *argv[])
19 {
20 #if defined(CONFIG_HTTP_SERVER)
21 	int res_count = 0, serv_count = 0;
22 
23 	PR("%-15s\t%-12s\n",
24 	   "Host:Port", "Concurrent/Backlog");
25 	PR("\tResource type\tMethods\t\tEndpoint\n");
26 
27 	HTTP_SERVICE_FOREACH(svc) {
28 		PR("\n");
29 		PR("%s:%d\t%zu/%zu\n",
30 		   svc->host == NULL || svc->host[0] == '\0' ?
31 		   "<any>" : svc->host, svc->port ? *svc->port : 0,
32 		   svc->concurrent, svc->backlog);
33 
34 		HTTP_SERVICE_FOREACH_RESOURCE(svc, res) {
35 			struct http_resource_detail *detail = res->detail;
36 			const char *detail_type = "<unknown>";
37 			int method_count = 0;
38 			bool print_comma;
39 
40 			switch (detail->type) {
41 			case HTTP_RESOURCE_TYPE_STATIC:
42 				detail_type = "static";
43 				break;
44 			case HTTP_RESOURCE_TYPE_STATIC_FS:
45 				detail_type = "static_fs";
46 				break;
47 			case HTTP_RESOURCE_TYPE_DYNAMIC:
48 				detail_type = "dynamic";
49 				break;
50 			case HTTP_RESOURCE_TYPE_WEBSOCKET:
51 				detail_type = "websocket";
52 				break;
53 			}
54 
55 			PR("\t%12s\t", detail_type);
56 
57 			print_comma = false;
58 
59 			for (int i = 0; i < NUM_BITS(uint32_t); i++) {
60 				if (IS_BIT_SET(detail->bitmask_of_supported_http_methods, i)) {
61 					PR("%s%s", print_comma ? "," : "", http_method_str(i));
62 					print_comma = true;
63 					method_count++;
64 				}
65 			}
66 
67 			if (method_count < 2) {
68 				/* make columns line up better */
69 				PR("\t");
70 			}
71 
72 			PR("\t%s\n", res->resource);
73 			res_count++;
74 		}
75 
76 		serv_count++;
77 	}
78 
79 	if (res_count == 0 && serv_count == 0) {
80 		PR("No HTTP services and resources found.\n");
81 	} else {
82 		PR("\n%d service%sand %d resource%sfound.\n",
83 		   serv_count, serv_count > 1 ? "s " : " ",
84 		   res_count, res_count > 1 ? "s " : " ");
85 	}
86 
87 #else /* CONFIG_HTTP_SERVER */
88 	ARG_UNUSED(argc);
89 	ARG_UNUSED(argv);
90 
91 	PR_INFO("Set %s to enable %s support.\n",
92 		"CONFIG_HTTP_SERVER",
93 		"HTTP information");
94 #endif
95 
96 	return 0;
97 }
98 
99 SHELL_SUBCMD_ADD((net), http, NULL,
100 		 "Show HTTP services.",
101 		 cmd_net_http, 1, 0);
102