1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
|
/*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at https://mozilla.org/MPL/2.0/.
*/
#include <stdint.h>
#include <zephyr/init.h>
#include <zephyr/logging/log.h>
#include <zephyr/net/http/server.h>
#include <zephyr/net/http/service.h>
#include <zephyr/net/http/status.h>
#include "ws.h"
LOG_MODULE_REGISTER(http);
static const uint8_t index_html_gz[] = {
#include "index.html.gz.inc"
};
struct http_resource_detail_static index_resource_detail = {
.common = {
.type = HTTP_RESOURCE_TYPE_STATIC,
.bitmask_of_supported_http_methods = BIT(HTTP_GET),
.content_encoding = "gzip",
.content_type = "text/html",
},
.static_data = index_html_gz,
.static_data_len = sizeof(index_html_gz),
};
static const uint8_t css_gz[] = {
#include "simple.css.gz.inc"
};
struct http_resource_detail_static css_resource_detail = {
.common = {
.type = HTTP_RESOURCE_TYPE_STATIC,
.bitmask_of_supported_http_methods = BIT(HTTP_GET),
.content_encoding = "gzip",
.content_type = "text/css",
},
.static_data = css_gz,
.static_data_len = sizeof(css_gz),
};
static const uint8_t js_html_gz[] = {
#include "iot-contact.js.gz.inc"
};
struct http_resource_detail_static js_resource_detail = {
.common = {
.type = HTTP_RESOURCE_TYPE_STATIC,
.bitmask_of_supported_http_methods = BIT(HTTP_GET),
.content_encoding = "gzip",
.content_type = "text/javascript",
},
.static_data = js_html_gz,
.static_data_len = sizeof(js_html_gz),
};
static int favicon_handler(
struct http_client_ctx *client,
enum http_data_status status,
const struct http_request_ctx *request_ctx,
struct http_response_ctx *response_ctx,
void *user_data
) {
LOG_DBG("Handling favicon request");
response_ctx->body = NULL;
response_ctx->body_len = 0;
response_ctx->final_chunk = true;
response_ctx->status = HTTP_204_NO_CONTENT;
LOG_DBG("Favicon request handled");
return 0;
}
static struct http_resource_detail_dynamic favicon_resource_detail = {
.common = {
.type = HTTP_RESOURCE_TYPE_DYNAMIC,
.bitmask_of_supported_http_methods = BIT(HTTP_GET),
},
.cb = favicon_handler,
.user_data = NULL,
};
static int settings_handler(
struct http_client_ctx *client,
enum http_data_status status,
const struct http_request_ctx *request_ctx,
struct http_response_ctx *response_ctx,
void *user_data
) {
static const char dummy[] = "{\"syslog\":{\"target\":{\"ip\":\"fe80::1\"}}}\n";
response_ctx->body = (const uint8_t *)dummy;
response_ctx->body_len = sizeof(dummy) - 1;
response_ctx->final_chunk = true;
response_ctx->status = HTTP_200_OK;
return 0;
}
static struct http_resource_detail_dynamic settings_resource_detail = {
.common = {
.type = HTTP_RESOURCE_TYPE_DYNAMIC,
.bitmask_of_supported_http_methods = BIT(HTTP_GET),
},
.cb = settings_handler,
.user_data = NULL,
};
static uint8_t websocket_read_buffer[1024];
struct http_resource_detail_websocket websocket_resource_detail = {
.common = {
.type = HTTP_RESOURCE_TYPE_WEBSOCKET,
.bitmask_of_supported_http_methods = BIT(HTTP_GET),
},
.cb = ws_upgrade_handler,
.data_buffer = websocket_read_buffer,
.data_buffer_len = sizeof(websocket_read_buffer),
};
static uint16_t http_port = 80;
HTTP_SERVICE_DEFINE(http_service, NULL, &http_port, 1, 10, NULL, NULL);
HTTP_RESOURCE_DEFINE(index_resource, http_service, "/", &index_resource_detail);
HTTP_RESOURCE_DEFINE(websocket_resource, http_service, "/", &websocket_resource_detail);
HTTP_RESOURCE_DEFINE(favicon_resource, http_service, "/favicon.ico", &favicon_resource_detail);
HTTP_RESOURCE_DEFINE(css_resource, http_service, "/simple.css", &css_resource_detail);
HTTP_RESOURCE_DEFINE(js_resource, http_service, "/iot-contact.js", &js_resource_detail);
HTTP_RESOURCE_DEFINE(settings_resource, http_service, "/settings.json", &settings_resource_detail);
int init_http_server(void) {
LOG_DBG("Starting HTTP server");
int ret = http_server_start();
if (ret < 0) {
LOG_ERR("Failed to start HTTP server (%d)", ret);
return ret;
}
LOG_INF("HTTP server was started");
return 0;
}
SYS_INIT(init_http_server, APPLICATION, 99);
|