@cryptotaxi247 / netdata / commits / 481155084

Remove H2O web server code from Netdata. (#20713)

We never actually switched to using it on any platform, and it’s causing build issues on some newer systems, so just drop it altogether.

Austin S. Hemmelgarn committed Jul 23, 2025 at 06:53 UTC 4811550844103106962591aaf2b6a2ba28b4f374
29 files changed +15 -1430
.codacy.yml
-1
@@ -9,7 +9,6 @@ exclude_paths:
9 - src/libnetdata/libjudy/**
10 - src/database/sqlite/sqlite3.c
11 - src/ml/dlib/**
12 - - src/web/server/h2o/libh2o/**
12 - build/**
13 - build_external/**
14 - packaging/**
CMakeLists.txt
+2 -140
@@ -210,8 +210,6 @@ option(ENABLE_BUNDLED_PROTOBUF "Use a vendored copy of protobuf" False)
210 # Experimental features
211 option(ENABLE_WEBRTC "Enable WebRTC dashboard communications (experimental)" False)
212 mark_as_advanced(ENABLE_WEBRTC)
213 -option(ENABLE_H2O "Enable H2O web server (experimental)" False)
214 -mark_as_advanced(ENABLE_H2O)
213
214 # Other optional functionality
215 option(ENABLE_SENTRY "Build with Sentry Native crash reporting" False)
@@ -1145,92 +1143,10 @@ set(LIBNETDATA_FILES
1143 list(APPEND LIBNETDATA_FILES ${INICFG_FILES})
1144 list(APPEND LIBNETDATA_FILES ${CONFIG_FILES})
1145
1148 -set(LIBH2O_FILES
1149 - src/web/server/h2o/libh2o/deps/cloexec/cloexec.c
1150 - src/web/server/h2o/libh2o/deps/libgkc/gkc.c
1151 - src/web/server/h2o/libh2o/deps/libyrmcds/close.c
1152 - src/web/server/h2o/libh2o/deps/libyrmcds/connect.c
1153 - src/web/server/h2o/libh2o/deps/libyrmcds/recv.c
1154 - src/web/server/h2o/libh2o/deps/libyrmcds/send.c
1155 - src/web/server/h2o/libh2o/deps/libyrmcds/send_text.c
1156 - src/web/server/h2o/libh2o/deps/libyrmcds/socket.c
1157 - src/web/server/h2o/libh2o/deps/libyrmcds/strerror.c
1158 - src/web/server/h2o/libh2o/deps/libyrmcds/text_mode.c
1159 - src/web/server/h2o/libh2o/deps/picohttpparser/picohttpparser.c
1160 - src/web/server/h2o/libh2o/lib/common/cache.c
1161 - src/web/server/h2o/libh2o/lib/common/file.c
1162 - src/web/server/h2o/libh2o/lib/common/filecache.c
1163 - src/web/server/h2o/libh2o/lib/common/hostinfo.c
1164 - src/web/server/h2o/libh2o/lib/common/http1client.c
1165 - src/web/server/h2o/libh2o/lib/common/memcached.c
1166 - src/web/server/h2o/libh2o/lib/common/memory.c
1167 - src/web/server/h2o/libh2o/lib/common/multithread.c
1168 - src/web/server/h2o/libh2o/lib/common/serverutil.c
1169 - src/web/server/h2o/libh2o/lib/common/socket.c
1170 - src/web/server/h2o/libh2o/lib/common/socketpool.c
1171 - src/web/server/h2o/libh2o/lib/common/string.c
1172 - src/web/server/h2o/libh2o/lib/common/time.c
1173 - src/web/server/h2o/libh2o/lib/common/timeout.c
1174 - src/web/server/h2o/libh2o/lib/common/url.c
1175 - src/web/server/h2o/libh2o/lib/core/config.c
1176 - src/web/server/h2o/libh2o/lib/core/configurator.c
1177 - src/web/server/h2o/libh2o/lib/core/context.c
1178 - src/web/server/h2o/libh2o/lib/core/headers.c
1179 - src/web/server/h2o/libh2o/lib/core/logconf.c
1180 - src/web/server/h2o/libh2o/lib/core/proxy.c
1181 - src/web/server/h2o/libh2o/lib/core/request.c
1182 - src/web/server/h2o/libh2o/lib/core/token.c
1183 - src/web/server/h2o/libh2o/lib/core/util.c
1184 - src/web/server/h2o/libh2o/lib/handler/access_log.c
1185 - src/web/server/h2o/libh2o/lib/handler/chunked.c
1186 - src/web/server/h2o/libh2o/lib/handler/compress.c
1187 - src/web/server/h2o/libh2o/lib/handler/compress/gzip.c
1188 - src/web/server/h2o/libh2o/lib/handler/errordoc.c
1189 - src/web/server/h2o/libh2o/lib/handler/expires.c
1190 - src/web/server/h2o/libh2o/lib/handler/fastcgi.c
1191 - src/web/server/h2o/libh2o/lib/handler/file.c
1192 - src/web/server/h2o/libh2o/lib/handler/headers.c
1193 - src/web/server/h2o/libh2o/lib/handler/mimemap.c
1194 - src/web/server/h2o/libh2o/lib/handler/proxy.c
1195 - src/web/server/h2o/libh2o/lib/handler/redirect.c
1196 - src/web/server/h2o/libh2o/lib/handler/reproxy.c
1197 - src/web/server/h2o/libh2o/lib/handler/throttle_resp.c
1198 - src/web/server/h2o/libh2o/lib/handler/status.c
1199 - src/web/server/h2o/libh2o/lib/handler/headers_util.c
1200 - src/web/server/h2o/libh2o/lib/handler/status/events.c
1201 - src/web/server/h2o/libh2o/lib/handler/status/requests.c
1202 - src/web/server/h2o/libh2o/lib/handler/http2_debug_state.c
1203 - src/web/server/h2o/libh2o/lib/handler/status/durations.c
1204 - src/web/server/h2o/libh2o/lib/handler/configurator/access_log.c
1205 - src/web/server/h2o/libh2o/lib/handler/configurator/compress.c
1206 - src/web/server/h2o/libh2o/lib/handler/configurator/errordoc.c
1207 - src/web/server/h2o/libh2o/lib/handler/configurator/expires.c
1208 - src/web/server/h2o/libh2o/lib/handler/configurator/fastcgi.c
1209 - src/web/server/h2o/libh2o/lib/handler/configurator/file.c
1210 - src/web/server/h2o/libh2o/lib/handler/configurator/headers.c
1211 - src/web/server/h2o/libh2o/lib/handler/configurator/proxy.c
1212 - src/web/server/h2o/libh2o/lib/handler/configurator/redirect.c
1213 - src/web/server/h2o/libh2o/lib/handler/configurator/reproxy.c
1214 - src/web/server/h2o/libh2o/lib/handler/configurator/throttle_resp.c
1215 - src/web/server/h2o/libh2o/lib/handler/configurator/status.c
1216 - src/web/server/h2o/libh2o/lib/handler/configurator/http2_debug_state.c
1217 - src/web/server/h2o/libh2o/lib/handler/configurator/headers_util.c
1218 - src/web/server/h2o/libh2o/lib/http1.c
1219 - src/web/server/h2o/libh2o/lib/tunnel.c
1220 - src/web/server/h2o/libh2o/lib/http2/cache_digests.c
1221 - src/web/server/h2o/libh2o/lib/http2/casper.c
1222 - src/web/server/h2o/libh2o/lib/http2/connection.c
1223 - src/web/server/h2o/libh2o/lib/http2/frame.c
1224 - src/web/server/h2o/libh2o/lib/http2/hpack.c
1225 - src/web/server/h2o/libh2o/lib/http2/scheduler.c
1226 - src/web/server/h2o/libh2o/lib/http2/stream.c
1227 - src/web/server/h2o/libh2o/lib/http2/http2_debug_state.c
1228 -)
1229 -
1146 set(DAEMON_FILES
1147 src/daemon/buildinfo.c
1148 src/daemon/buildinfo.h
1233 - src/daemon/h2o-common.c
1149 + src/daemon/common.c
1150 src/daemon/common.h
1151 src/daemon/daemon.c
1152 src/daemon/daemon.h
@@ -1355,21 +1271,6 @@ if(ENABLE_SYSTEMD_DBUS)
1271 list(APPEND DAEMON_FILES ${DAEMON_SYSTEMD_WATCHER_FILES})
1272 endif()
1273
1358 -set(H2O_FILES
1359 - src/web/server/h2o/http_server.c
1360 - src/web/server/h2o/http_server.h
1361 - src/web/server/h2o/h2o_utils.c
1362 - src/web/server/h2o/h2o_utils.h
1363 - src/web/server/h2o/rrdpush.c
1364 - src/web/server/h2o/streaming.h
1365 - src/web/server/h2o/connlist.c
1366 - src/web/server/h2o/connlist.h
1367 -)
1368 -
1369 -if(ENABLE_H2O)
1370 - list(APPEND DAEMON_FILES ${H2O_FILES})
1371 -endif()
1372 -
1274 set(API_PLUGIN_FILES
1275 src/web/api/web_api.c
1276 src/web/api/web_api.h
@@ -1823,7 +1724,6 @@ set(STREAMING_PLUGIN_FILES
1724 src/streaming/stream-sender.c
1725 src/streaming/stream-replication-sender.c
1726 src/streaming/stream-replication-sender.h
1826 - src/streaming/h2o-common.h
1727 src/streaming/protocol/command-nodeid.c
1728 src/streaming/protocol/commands.c
1729 src/streaming/protocol/commands.h
@@ -2261,41 +2161,6 @@ set(PROMETHEUS_REMOTE_WRITE_EXPORTING_FILES
2161 src/exporting/prometheus/remote_write/remote_write_request.h
2162 )
2163
2264 -#
2265 -# build h2o
2266 -#
2267 -
2268 -if(ENABLE_H2O)
2269 - add_library(h2o STATIC ${LIBH2O_FILES})
2270 -
2271 - target_include_directories(h2o BEFORE PUBLIC
2272 - "${CMAKE_SOURCE_DIR}/src/web/server/h2o/libh2o/include"
2273 - "${CMAKE_SOURCE_DIR}/src/web/server/h2o/libh2o/deps/cloexec"
2274 - "${CMAKE_SOURCE_DIR}/src/web/server/h2o/libh2o/deps/brotli/enc"
2275 - "${CMAKE_SOURCE_DIR}/src/web/server/h2o/libh2o/deps/golombset"
2276 - "${CMAKE_SOURCE_DIR}/src/web/server/h2o/libh2o/deps/libgkc"
2277 - "${CMAKE_SOURCE_DIR}/src/web/server/h2o/libh2o/deps/libyrmcds"
2278 - "${CMAKE_SOURCE_DIR}/src/web/server/h2o/libh2o/deps/klib"
2279 - "${CMAKE_SOURCE_DIR}/src/web/server/h2o/libh2o/deps/neverbleed"
2280 - "${CMAKE_SOURCE_DIR}/src/web/server/h2o/libh2o/deps/picohttpparser"
2281 - "${CMAKE_SOURCE_DIR}/src/web/server/h2o/libh2o/deps/picotest"
2282 - "${CMAKE_SOURCE_DIR}/src/web/server/h2o/libh2o/deps/yaml/include"
2283 - "${CMAKE_SOURCE_DIR}/src/web/server/h2o/libh2o/deps/yoml"
2284 - )
2285 -
2286 - target_compile_options(h2o PRIVATE
2287 - -Wno-all -Wno-extra
2288 - -Wno-shadow
2289 - -Wno-deprecated-declarations
2290 - -Wformat
2291 - )
2292 -
2293 - target_compile_options(h2o PUBLIC -DH2O_USE_LIBUV=0)
2294 - target_link_libraries(h2o PRIVATE PkgConfig::TLS)
2295 - target_compile_definitions(h2o PRIVATE
2296 - "$<$<NOT:$<BOOL:${ARCH_SUPPORTS_64BIT_ATOMICS}>>:H2O_NO_64BIT_ATOMICS>")
2297 -endif()
2298 -
2164 #
2165 # build libjudy
2166 #
@@ -2566,8 +2431,7 @@ if(ENABLE_MQTTWEBSOCKETS)
2431 -DRBUF_CUSTOM_MALLOC
2432 -DMQTT_WSS_CPUSTATS)
2433
2569 - target_include_directories(mqttwebsockets PUBLIC ${CMAKE_SOURCE_DIR}/aclk/helpers
2570 - ${CMAKE_SOURCE_DIR}/src/web/server/h2o/libh2o/include)
2434 + target_include_directories(mqttwebsockets PUBLIC ${CMAKE_SOURCE_DIR}/aclk/helpers)
2435
2436 target_link_libraries(mqttwebsockets PRIVATE libnetdata)
2437
@@ -3165,7 +3029,6 @@ endif()
3029 add_executable(netdata
3030 ${NETDATA_FILES}
3031 "${ACLK_FILES}"
3168 - "$<$<BOOL:${ENABLE_H2O}>:${H2O_FILES}>"
3032 "$<$<BOOL:${ENABLE_EXPORTER_MONGODB}>:${MONGODB_EXPORTING_FILES}>"
3033 "$<$<BOOL:${ENABLE_EXPORTER_PROMETHEUS_REMOTE_WRITE}>:${PROMETHEUS_REMOTE_WRITE_EXPORTING_FILES}>"
3034 "$<$<BOOL:${OS_WINDOWS}>:${NETDATA_RES_FILES}>"
@@ -3202,7 +3065,6 @@ target_link_libraries(netdata PRIVATE
3065 "$<$<BOOL:${OS_MACOS}>:${IOKIT};${FOUNDATION}>"
3066 "$<$<BOOL:${ENABLE_SENTRY}>:sentry>"
3067 "$<$<BOOL:${ENABLE_WEBRTC}>:LibDataChannel::LibDataChannelStatic>"
3205 - "$<$<BOOL:${ENABLE_H2O}>:h2o>"
3068 "$<$<BOOL:${CURL_FOUND}>:PkgConfig::CURL>"
3069 "$<$<BOOL:${OS_WINDOWS}>:odbc32;setupapi>"
3070 )
netdata.spec.in
-1
@@ -399,7 +399,6 @@ advanced correlations and fast root cause analysis, native horizontal scalabilit
399 -DENABLE_EXPORTER_MONGODB=Off \
400 %endif
401 -DENABLE_DBENGINE=On \
402 - -DENABLE_H2O=On \
402 -DENABLE_PLUGIN_APPS=On \
403 -DENABLE_PLUGIN_CGROUP_NETWORK=On \
404 -DENABLE_PLUGIN_DEBUGFS=On \
packaging/build-package.sh
-1
@@ -28,7 +28,6 @@ add_cmake_option CMAKE_BUILD_TYPE RelWithDebInfo
28 add_cmake_option CMAKE_INSTALL_PREFIX /
29 add_cmake_option ENABLE_DASHBOARD on
30 add_cmake_option ENABLE_DBENGINE On
31 -add_cmake_option ENABLE_H2O Off
31 add_cmake_option ENABLE_ML On
32
33 add_cmake_option ENABLE_PLUGIN_APPS On
packaging/cmake/config.cmake.h.in
-1
@@ -126,7 +126,6 @@
126
127 #cmakedefine ENABLE_ML
128 #cmakedefine ENABLE_EXPORTING_MONGODB
129 -#cmakedefine ENABLE_H2O
129 #cmakedefine ENABLE_DBENGINE
130 #cmakedefine ENABLE_LZ4
131 #cmakedefine ENABLE_ZSTD
packaging/installer/functions.sh
-1
@@ -375,7 +375,6 @@ prepare_cmake_options() {
375
376 enable_feature BUNDLED_JSONC "${NETDATA_BUILD_JSON_C:-0}"
377 enable_feature DBENGINE "${ENABLE_DBENGINE:-1}"
378 - enable_feature H2O "${ENABLE_H2O:-0}"
378 enable_feature ML "${NETDATA_ENABLE_ML:-1}"
379 enable_feature PLUGIN_APPS "${ENABLE_APPS:-1}"
380
packaging/utils/compile-and-run-windows.sh
-1
@@ -72,7 +72,6 @@ then
72 -DUSE_MOLD=Off \
73 -DNETDATA_USER="${USER}" \
74 -DDEFAULT_FEATURE_STATE=Off \
75 - -DENABLE_H2O=Off \
75 -DENABLE_ML=On \
76 -DENABLE_BUNDLED_JSONC=On \
77 -DENABLE_BUNDLED_PROTOBUF=Off \
packaging/windows/compile-on-windows.sh
-1
@@ -39,7 +39,6 @@ CFLAGS="${BUILD_CFLAGS}" /usr/bin/cmake \
39 -DNETDATA_USER="${USER}" \
40 -DENABLE_ACLK=On \
41 -DENABLE_CLOUD=On \
42 - -DENABLE_H2O=Off \
42 -DENABLE_ML=On \
43 -DENABLE_PLUGIN_GO=On \
44 -DENABLE_EXPORTER_PROMETHEUS_REMOTE_WRITE=Off \
src/daemon/buildinfo.c
-12
@@ -62,7 +62,6 @@ typedef enum __attribute__((packed)) {
62 BIB_DB_NONE,
63 BIB_CONNECTIVITY_ACLK,
64 BIB_CONNECTIVITY_HTTPD_STATIC,
65 - BIB_CONNECTIVITY_HTTPD_H2O,
65 BIB_CONNECTIVITY_WEBRTC,
66 BIB_CONNECTIVITY_NATIVE_HTTPS,
67 BIB_CONNECTIVITY_TLS_HOST_VERIFY,
@@ -600,14 +599,6 @@ static struct {
599 .json = "static",
600 .value = NULL,
601 },
603 - [BIB_CONNECTIVITY_HTTPD_H2O] = {
604 - .category = BIC_CONNECTIVITY,
605 - .type = BIT_BOOLEAN,
606 - .analytics = NULL,
607 - .print = "h2o (web server)",
608 - .json = "h2o",
609 - .value = NULL,
610 - },
602 [BIB_CONNECTIVITY_WEBRTC] = {
603 .category = BIC_CONNECTIVITY,
604 .type = BIT_BOOLEAN,
@@ -1247,9 +1238,6 @@ __attribute__((constructor)) void initialize_build_info(void) {
1238 build_info_set_status(BIB_DB_NONE, true);
1239
1240 build_info_set_status(BIB_CONNECTIVITY_HTTPD_STATIC, true);
1250 -#ifdef ENABLE_H2O
1251 - build_info_set_status(BIB_CONNECTIVITY_HTTPD_H2O, true);
1252 -#endif
1241 #ifdef ENABLE_WEBRTC
1242 build_info_set_status(BIB_CONNECTIVITY_WEBRTC, true);
1243 #endif
src/daemon/common.c renamed
src/daemon/common.h
-5
@@ -30,11 +30,6 @@ extern "C" {
30 // the netdata webserver(s)
31 #include "web/server/web_server.h"
32
33 -// the new h2o based netdata webserver
34 -#ifdef ENABLE_H2O
35 -#include "web/server/h2o/http_server.h"
36 -#endif
37 -
33 // streaming metrics between netdata servers
34 #include "streaming/stream.h"
35
src/daemon/static_threads.c
-13
@@ -144,19 +144,6 @@ const struct netdata_static_thread static_threads_common[] = {
144 .start_routine = socket_listen_main_static_threaded
145 },
146
147 -#ifdef ENABLE_H2O
148 - {
149 - .name = "h2o",
150 - .config_section = NULL,
151 - .config_name = NULL,
152 - .enable_routine = httpd_is_enabled,
153 - .enabled = 0,
154 - .thread = NULL,
155 - .init_routine = NULL,
156 - .start_routine = h2o_main
157 - },
158 -#endif
159 -
147 {
148 .name = "ACLK_MAIN",
149 .config_section = NULL,
src/libnetdata/user-auth/http-access.h
-2
@@ -89,7 +89,6 @@ typedef enum __attribute__((packed)) {
89 HTTP_ACL_API = (1 << 1), // from the internal web server (TCP port)
90 HTTP_ACL_API_UDP = (1 << 2), // from the internal web server (UDP port)
91 HTTP_ACL_API_UNIX = (1 << 3), // from the internal web server (UNIX socket)
92 - HTTP_ACL_H2O = (1 << 4), // from the h2o web server
92 HTTP_ACL_ACLK = (1 << 5), // from ACLK
93 HTTP_ACL_WEBRTC = (1 << 6), // from WebRTC
94
@@ -123,7 +122,6 @@ typedef enum __attribute__((packed)) {
122 HTTP_ACL_API \
123 | HTTP_ACL_API_UDP \
124 | HTTP_ACL_API_UNIX \
126 - | HTTP_ACL_H2O \
125 | HTTP_ACL_ACLK \
126 | HTTP_ACL_WEBRTC \
127 )
src/plugins.d/pluginsd_internals.c
-5
@@ -9,11 +9,6 @@ ssize_t send_to_plugin(const char *txt, PARSER *parser, STREAM_TRAFFIC_TYPE type
9 if(parser->send_to_plugin_cb)
10 return parser->send_to_plugin_cb(txt, parser->send_to_plugin_data, type);
11
12 -#ifdef ENABLE_H2O
13 - if(parser->h2o_ctx)
14 - return h2o_stream_write(parser->h2o_ctx, txt, strlen(txt));
15 -#endif
16 -
12 spinlock_lock(&parser->writer.spinlock);
13
14 ND_SOCK tmp = { .fd = parser->fd_output, };
src/plugins.d/pluginsd_parser.h
-4
@@ -111,10 +111,6 @@ struct parser {
111 send_to_plugin_callback_t send_to_plugin_cb;
112 void *send_to_plugin_data;
113
114 -#ifdef ENABLE_H2O
115 - void *h2o_ctx; // if set we use h2o_stream functions to send data
116 -#endif
117 -
114 PARSER_USER_OBJECT user; // User defined structure to hold extra state between calls
115
116 struct buffered_reader reader;
src/streaming/stream-receiver-connection.c
+11 -27
@@ -3,7 +3,6 @@
3 #include "stream.h"
4 #include "stream-thread.h"
5 #include "stream-receiver-internals.h"
6 -#include "web/server/h2o/http_server.h"
6 #include "stream-replication-sender.h"
7
8 void svc_rrdhost_obsolete_all_charts(RRDHOST *host);
@@ -273,9 +272,6 @@ static bool stream_receiver_send_first_response(struct receiver_state *rpt) {
272 // OUR FIRST RESPONSE IS READY!
273
274 // web server sockets are non-blocking - set them to blocking mode
276 -#ifdef ENABLE_H2O
277 - unless_h2o_rrdpush(rpt)
278 -#endif
275 {
276 // remove the non-blocking flag from the socket
277 if(sock_setnonblock(rpt->sock.fd, false) != 0)
@@ -293,31 +289,23 @@ static bool stream_receiver_send_first_response(struct receiver_state *rpt) {
289 }
290
291 netdata_log_debug(D_STREAM, "Initial response to %s: %s", rpt->remote_ip, initial_response);
296 -#ifdef ENABLE_H2O
297 - if (is_h2o_rrdpush(rpt)) {
298 - h2o_stream_write(rpt->h2o_ctx, initial_response, strlen(initial_response));
299 - } else {
300 -#endif
301 - ssize_t bytes_sent = nd_sock_send_timeout(&rpt->sock, initial_response, strlen(initial_response), 0, 60);
302 -
303 - if(bytes_sent != (ssize_t)strlen(initial_response)) {
304 - internal_error(true, "Cannot send response, got %zd bytes, expecting %zu bytes", bytes_sent, strlen(initial_response));
305 - stream_receiver_log_status(
306 - rpt,
307 - "cannot reply back, dropping connection",
308 - STREAM_HANDSHAKE_CONNECT_SEND_TIMEOUT, NDLP_ERR);
309 - rrdhost_clear_receiver(rpt, STREAM_HANDSHAKE_DISCONNECT_SOCKET_WRITE_FAILED);
310 - return false;
311 - }
312 -#ifdef ENABLE_H2O
292 + ssize_t bytes_sent = nd_sock_send_timeout(&rpt->sock, initial_response, strlen(initial_response), 0, 60);
293 +
294 + if(bytes_sent != (ssize_t)strlen(initial_response)) {
295 + internal_error(true, "Cannot send response, got %zd bytes, expecting %zu bytes", bytes_sent, strlen(initial_response));
296 + stream_receiver_log_status(
297 + rpt,
298 + "cannot reply back, dropping connection",
299 + STREAM_HANDSHAKE_CONNECT_SEND_TIMEOUT, NDLP_ERR);
300 + rrdhost_clear_receiver(rpt, STREAM_HANDSHAKE_DISCONNECT_SOCKET_WRITE_FAILED);
301 + return false;
302 }
314 -#endif
303 }
304
305 return true;
306 }
307
320 -int stream_receiver_accept_connection(struct web_client *w, char *decoded_query_string, void *h2o_ctx __maybe_unused) {
308 +int stream_receiver_accept_connection(struct web_client *w, char *decoded_query_string) {
309 pulse_parent_receiver_request();
310
311 if(!service_running(ABILITY_STREAMING_CONNECTIONS))
@@ -332,10 +320,6 @@ int stream_receiver_accept_connection(struct web_client *w, char *decoded_query_
320
321 rpt->capabilities = STREAM_CAP_INVALID;
322
335 -#ifdef ENABLE_H2O
336 - rpt->h2o_ctx = h2o_ctx;
337 -#endif
338 -
323 __atomic_add_fetch(&netdata_buffers_statistics.rrdhost_receivers, sizeof(*rpt), __ATOMIC_RELAXED);
324
325 rpt->system_info = rrdhost_system_info_create();
src/streaming/stream-receiver-internals.h
-9
@@ -99,17 +99,8 @@ struct receiver_state {
99 FILE *fp;
100 } log;
101 #endif
102 -
103 -#ifdef ENABLE_H2O
104 - void *h2o_ctx;
105 -#endif
102 };
103
108 -#ifdef ENABLE_H2O
109 -#define is_h2o_rrdpush(x) ((x)->h2o_ctx != NULL)
110 -#define unless_h2o_rrdpush(x) if(!is_h2o_rrdpush(x))
111 -#endif
112 -
104 bool rrdhost_set_receiver(RRDHOST *host, struct receiver_state *rpt);
105 void rrdhost_clear_receiver(struct receiver_state *rpt, STREAM_HANDSHAKE reason);
106 void stream_receiver_log_status(struct receiver_state *rpt, const char *msg, STREAM_HANDSHAKE reason, ND_LOG_FIELD_PRIORITY priority);
src/streaming/stream-receiver.c
-27
@@ -3,7 +3,6 @@
3 #include "stream.h"
4 #include "stream-thread.h"
5 #include "stream-receiver-internals.h"
6 -#include "web/server/h2o/http_server.h"
6
7 #ifdef NETDATA_LOG_STREAM_RECEIVER
8 void stream_receiver_log_payload(struct receiver_state *rpt, const char *payload, STREAM_TRAFFIC_TYPE type __maybe_unused, bool inbound) {
@@ -124,17 +123,6 @@ static ssize_t write_stream(struct receiver_state *r, char* buffer, size_t size)
123 return -2;
124 }
125
127 -#ifdef ENABLE_H2O
128 - if (is_h2o_rrdpush(r)) {
129 - if(nd_thread_signaled_to_cancel()) {
130 - errno_clear();
131 - return -3;
132 - }
133 -
134 - return (ssize_t)h2o_stream_write(r->h2o_ctx, buffer, size);
135 - }
136 -#endif
137 -
126 ssize_t bytes_written = nd_sock_send_nowait(&r->sock, buffer, size);
127 return bytes_written;
128 }
@@ -147,17 +135,6 @@ static ssize_t read_stream(struct receiver_state *r, char* buffer, size_t size)
135 return -2;
136 }
137
150 -#ifdef ENABLE_H2O
151 - if (is_h2o_rrdpush(r)) {
152 - if(nd_thread_signaled_to_cancel()) {
153 - errno_clear();
154 - return -3;
155 - }
156 -
157 - return (ssize_t)h2o_stream_read(r->h2o_ctx, buffer, size);
158 - }
159 -#endif
160 -
138 ssize_t bytes_read = nd_sock_revc_nowait(&r->sock, buffer, size);
139 return bytes_read;
140 }
@@ -496,10 +473,6 @@ void stream_receiver_move_to_running_unsafe(struct stream_thread *sth, struct re
473 __atomic_store_n(&rpt->thread.parser, parser, __ATOMIC_RELAXED);
474 }
475
499 -#ifdef ENABLE_H2O
500 - parser->h2o_ctx = rpt->h2o_ctx;
501 -#endif
502 -
476 if(stream_receive.replication.enabled)
477 pulse_host_status(rpt->host, PULSE_HOST_STATUS_RCV_REPLICATION_WAIT, 0);
478 else
src/streaming/stream.h
+1 -1
@@ -33,7 +33,7 @@ bool stream_sender_has_capabilities(struct rrdhost *host, STREAM_CAPABILITIES ca
33 // receiver API
34 uint32_t stream_receivers_currently_connected(void);
35 struct web_client;
36 -int stream_receiver_accept_connection(struct web_client *w, char *decoded_query_string, void *h2o_ctx);
36 +int stream_receiver_accept_connection(struct web_client *w, char *decoded_query_string);
37 bool receiver_has_capability(struct rrdhost *host, STREAM_CAPABILITIES caps);
38 void stream_receiver_free(struct receiver_state *rpt);
39 bool stream_receiver_signal_to_stop_and_wait(struct rrdhost *host, STREAM_HANDSHAKE reason);
src/web/server/h2o/connlist.c deleted
-157
@@ -1,157 +0,0 @@
1 -#include "libnetdata/libnetdata.h"
2 -#include "connlist.h"
3 -
4 -conn_list_t conn_list = { NULL, NULL, 0, 0, PTHREAD_MUTEX_INITIALIZER };
5 -
6 -static h2o_stream_conn_t **conn_list_get_null_element_unsafe(conn_list_t *list)
7 -{
8 - struct conn_list_leaf *leaf = list->head;
9 - while (leaf != NULL) {
10 - for (int i = 0; i < CONN_LIST_MEMPOOL_SIZE; i++) {
11 - if (leaf->conn[i] == NULL)
12 - return &leaf->conn[i];
13 - }
14 - leaf = leaf->next;
15 - }
16 - return NULL;
17 -}
18 -
19 -void conn_list_insert(conn_list_t *list, h2o_stream_conn_t *conn)
20 -{
21 - pthread_mutex_lock(&list->lock);
22 -
23 - // in case the allocated capacity is not used up
24 - // we can reuse the null element
25 - if (list->capacity != list->size) {
26 - h2o_stream_conn_t **null_element = conn_list_get_null_element_unsafe(list);
27 - if (unlikely(null_element == NULL)) {
28 - pthread_mutex_unlock(&list->lock);
29 - error_report("conn_list_insert: capacity != size but no null element found");
30 - return;
31 - }
32 - *null_element = conn;
33 - list->size++;
34 - pthread_mutex_unlock(&list->lock);
35 - return;
36 - }
37 -
38 - // if not, we need to allocate a new leaf
39 - struct conn_list_leaf *old_tail = list->tail;
40 - list->tail = callocz(1, sizeof(struct conn_list_leaf));
41 - if (unlikely(old_tail == NULL))
42 - list->head = list->tail;
43 - else
44 - old_tail->next = list->tail;
45 -
46 - list->tail->conn[0] = conn;
47 - list->size++;
48 - list->capacity += CONN_LIST_MEMPOOL_SIZE;
49 -
50 - pthread_mutex_unlock(&list->lock);
51 -}
52 -
53 -typedef struct {
54 - conn_list_t *list;
55 - struct conn_list_leaf *leaf;
56 - int idx;
57 -} conn_list_iter_t;
58 -
59 -static inline void conn_list_iter_create_unsafe(conn_list_iter_t *iter, conn_list_t *list)
60 -{
61 - iter->list = list;
62 - iter->leaf = list->head;
63 - iter->idx = 0;
64 -}
65 -
66 -static inline int conn_list_iter_next_unsafe(conn_list_iter_t *iter, h2o_stream_conn_t **conn)
67 -{
68 - if (unlikely(iter->idx == iter->list->capacity))
69 - return 0;
70 -
71 - if (iter->idx && iter->idx % CONN_LIST_MEMPOOL_SIZE == 0) {
72 - iter->leaf = iter->leaf->next;
73 - }
74 -
75 - *conn = iter->leaf->conn[iter->idx++ % CONN_LIST_MEMPOOL_SIZE];
76 - return 1;
77 -}
78 -
79 -void conn_list_iter_all(conn_list_t *list, void (*cb)(h2o_stream_conn_t *conn))
80 -{
81 - pthread_mutex_lock(&list->lock);
82 - conn_list_iter_t iter;
83 - conn_list_iter_create_unsafe(&iter, list);
84 - h2o_stream_conn_t *conn;
85 - while (conn_list_iter_next_unsafe(&iter, &conn)) {
86 - if (conn == NULL)
87 - continue;
88 - cb(conn);
89 - }
90 - pthread_mutex_unlock(&list->lock);
91 -}
92 -
93 -static void conn_list_garbage_collect_unsafe(conn_list_t *list)
94 -{
95 - if (list->capacity - list->size > CONN_LIST_MEMPOOL_SIZE) {
96 - struct conn_list_leaf *new_tail = list->head;
97 - while (new_tail->next != list->tail)
98 - new_tail = new_tail->next;
99 -
100 - // check if the tail leaf is empty and move the data if not
101 - for (int i = 0; i < CONN_LIST_MEMPOOL_SIZE; i++) {
102 - if (list->tail->conn[i] != NULL) {
103 - h2o_stream_conn_t **null_element = conn_list_get_null_element_unsafe(list);
104 - if (unlikely(null_element == NULL)) {
105 - error_report("conn_list_garbage_collect_unsafe: list->capacity - list->size > CONN_LIST_MEMPOOL_SIZE but no null element found?");
106 - return;
107 - }
108 - *null_element = list->tail->conn[i];
109 - list->tail->conn[i] = NULL;
110 - }
111 - }
112 -
113 - freez(list->tail);
114 - new_tail->next = NULL;
115 - list->tail = new_tail;
116 - list->capacity -= CONN_LIST_MEMPOOL_SIZE;
117 - }
118 -}
119 -
120 -static inline int conn_list_iter_remove(conn_list_iter_t *iter, h2o_stream_conn_t *conn)
121 -{
122 - if (unlikely(iter->idx == iter->list->capacity))
123 - return -1;
124 -
125 - if (iter->idx && iter->idx % CONN_LIST_MEMPOOL_SIZE == 0) {
126 - iter->leaf = iter->leaf->next;
127 - }
128 -
129 - if(conn == iter->leaf->conn[iter->idx % CONN_LIST_MEMPOOL_SIZE]) {
130 - iter->leaf->conn[iter->idx % CONN_LIST_MEMPOOL_SIZE] = NULL;
131 -
132 - iter->idx++;
133 - return 1;
134 - }
135 -
136 - iter->idx++;
137 - return 0;
138 -}
139 -
140 -int conn_list_remove_conn(conn_list_t *list, h2o_stream_conn_t *conn)
141 -{
142 - pthread_mutex_lock(&list->lock);
143 - conn_list_iter_t iter;
144 - conn_list_iter_create_unsafe(&iter, list);
145 - int rc;
146 - while (!(rc = conn_list_iter_remove(&iter, conn)));
147 - if (rc == -1) {
148 - pthread_mutex_unlock(&list->lock);
149 - error_report("conn_list_remove_conn: conn not found");
150 - return 0;
151 - }
152 - list->size--;
153 - conn_list_garbage_collect_unsafe(list);
154 - pthread_mutex_unlock(&list->lock);
155 - return 1;
156 -}
157 -
src/web/server/h2o/connlist.h deleted
-30
@@ -1,30 +0,0 @@
1 -// SPDX-License-Identifier: GPL-3.0-or-later
2 -
3 -#ifndef HTTPD_CONNLIST_H
4 -#define HTTPD_CONNLIST_H
5 -
6 -#include "streaming.h"
7 -
8 -// (-1) in following macro is to keep conn list + next pointer
9 -// be power of 2
10 -#define CONN_LIST_MEMPOOL_SIZE ((2^5)-1)
11 -struct conn_list_leaf {
12 - h2o_stream_conn_t *conn[CONN_LIST_MEMPOOL_SIZE];
13 - struct conn_list_leaf *next;
14 -};
15 -
16 -typedef struct {
17 - struct conn_list_leaf *head;
18 - struct conn_list_leaf *tail;
19 - int size;
20 - int capacity;
21 - pthread_mutex_t lock;
22 -} conn_list_t;
23 -
24 -extern conn_list_t conn_list;
25 -
26 -void conn_list_insert(conn_list_t *list, h2o_stream_conn_t *conn);
27 -void conn_list_iter_all(conn_list_t *list, void (*cb)(h2o_stream_conn_t *conn));
28 -int conn_list_remove_conn(conn_list_t *list, h2o_stream_conn_t *conn);
29 -
30 -#endif /* HTTPD_CONNLIST_H */
src/web/server/h2o/h2o_utils.c deleted
-60
@@ -1,60 +0,0 @@
1 -// SPDX-License-Identifier: GPL-3.0-or-later
2 -
3 -#include "h2o_utils.h"
4 -
5 -#include "h2o/string_.h"
6 -
7 -#include "libnetdata/libnetdata.h"
8 -
9 -char *iovec_to_cstr(h2o_iovec_t *str)
10 -{
11 - char *c_str = mallocz(str->len + 1);
12 - memcpy(c_str, str->base, str->len);
13 - c_str[str->len] = 0;
14 - return c_str;
15 -}
16 -
17 -#define KEY_VAL_BUFFER_GROWTH_STEP 5
18 -h2o_iovec_pair_vector_t *parse_URL_params(h2o_mem_pool_t *pool, h2o_iovec_t params_string)
19 -{
20 - h2o_iovec_pair_vector_t *params_vec = h2o_mem_alloc_shared(pool, sizeof(h2o_iovec_pair_vector_t), NULL);
21 - memset(params_vec, 0, sizeof(h2o_iovec_pair_vector_t));
22 -
23 - h2o_iovec_pair_t param;
24 - while ((param.name.base = (char*)h2o_next_token(&params_string, '&', &param.name.len, &param.value)) != NULL) {
25 - if (params_vec->capacity == params_vec->size)
26 - h2o_vector_reserve(pool, params_vec, params_vec->capacity + KEY_VAL_BUFFER_GROWTH_STEP);
27 -
28 - params_vec->entries[params_vec->size++] = param;
29 - }
30 -
31 - return params_vec;
32 -}
33 -
34 -h2o_iovec_pair_t *get_URL_param_by_name(h2o_iovec_pair_vector_t *params_vec, const void *needle, size_t needle_len)
35 -{
36 - for (size_t i = 0; i < params_vec->size; i++) {
37 - h2o_iovec_pair_t *ret = &params_vec->entries[i];
38 - if (h2o_memis(ret->name.base, ret->name.len, needle, needle_len))
39 - return ret;
40 - }
41 - return NULL;
42 -}
43 -
44 -char *url_unescape(const char *url)
45 -{
46 - char *result = mallocz(strlen(url) + 1);
47 -
48 - int i, j;
49 - for (i = 0, j = 0; url[i] != 0; i++, j++) {
50 - if (url[i] == '%' && isxdigit(url[i+1]) && isxdigit(url[i+2])) {
51 - char hex[3] = { url[i+1], url[i+2], 0 };
52 - result[j] = strtol(hex, NULL, 16);
53 - i += 2;
54 - } else
55 - result[j] = url[i];
56 - }
57 - result[j] = 0;
58 -
59 - return result;
60 -}
src/web/server/h2o/h2o_utils.h deleted
-38
@@ -1,38 +0,0 @@
1 -// SPDX-License-Identifier: GPL-3.0-or-later
2 -
3 -#ifndef NETDATA_H2O_UTILS_H
4 -#define NETDATA_H2O_UTILS_H
5 -
6 -#include "h2o/memory.h"
7 -
8 -#define __HAS_URL_PARAMS(reqptr) ((reqptr)->query_at != SIZE_MAX && ((reqptr)->path.len - (reqptr)->query_at > 1))
9 -#define IF_HAS_URL_PARAMS(reqptr) if __HAS_URL_PARAMS(reqptr)
10 -#define UNLESS_HAS_URL_PARAMS(reqptr) if (!__HAS_URL_PARAMS(reqptr))
11 -#define URL_PARAMS_IOVEC_INIT(reqptr) { .base = &(reqptr)->path.base[(reqptr)->query_at + 1], \
12 - .len = (reqptr)->path.len - (reqptr)->query_at - 1 }
13 -#define URL_PARAMS_IOVEC_INIT_WITH_QUESTIONMARK(reqptr) { .base = &(reqptr)->path.base[(reqptr)->query_at], \
14 - .len = (reqptr)->path.len - (reqptr)->query_at }
15 -
16 -#define PRINTF_H2O_IOVEC_FMT "%.*s"
17 -#define PRINTF_H2O_IOVEC(iovec) ((int)(iovec)->len), ((iovec)->base)
18 -
19 -char *iovec_to_cstr(h2o_iovec_t *str);
20 -
21 -typedef struct h2o_iovec_pair {
22 - h2o_iovec_t name;
23 - h2o_iovec_t value;
24 -} h2o_iovec_pair_t;
25 -
26 -typedef H2O_VECTOR(h2o_iovec_pair_t) h2o_iovec_pair_vector_t;
27 -
28 -// Takes the part of url behind ? (the url encoded parameters)
29 -// and parse it to vector of name/value pairs without copying the actual strings
30 -h2o_iovec_pair_vector_t *parse_URL_params(h2o_mem_pool_t *pool, h2o_iovec_t params_string);
31 -
32 -// Searches for parameter by name (provided in needle)
33 -// returns pointer to it or NULL
34 -h2o_iovec_pair_t *get_URL_param_by_name(h2o_iovec_pair_vector_t *params_vec, const void *needle, size_t needle_len);
35 -
36 -char *url_unescape(const char *url);
37 -
38 -#endif /* NETDATA_H2O_UTILS_H */
src/web/server/h2o/http_server.c deleted
-428
@@ -1,428 +0,0 @@
1 -// SPDX-License-Identifier: GPL-3.0-or-later
2 -
3 -#include "database/rrd.h"
4 -#include "streaming/h2o-common.h"
5 -#include "http_server.h"
6 -
7 -#pragma GCC diagnostic push
8 -#pragma GCC diagnostic ignored "-Wunused-parameter"
9 -#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
10 -#pragma GCC diagnostic ignored "-Wtype-limits"
11 -#include "h2o.h"
12 -#include "h2o/http1.h"
13 -#pragma GCC diagnostic pop
14 -
15 -#include "streaming.h"
16 -#include "h2o_utils.h"
17 -
18 -static h2o_globalconf_t config;
19 -static h2o_context_t ctx;
20 -static h2o_accept_ctx_t accept_ctx;
21 -
22 -#define CONTENT_JSON_UTF8 H2O_STRLIT("application/json; charset=utf-8")
23 -#define CONTENT_TEXT_UTF8 H2O_STRLIT("text/plain; charset=utf-8")
24 -#define NBUF_INITIAL_SIZE_RESP (4096)
25 -#define API_V1_PREFIX "/api/v1/"
26 -#define API_V2_PREFIX "/api/v2/"
27 -#define API_V3_PREFIX "/api/v3/"
28 -#define HOST_SELECT_PREFIX "/host/"
29 -
30 -#define HTTPD_CONFIG_SECTION "httpd"
31 -#define HTTPD_ENABLED_DEFAULT false
32 -
33 -static void on_accept(h2o_socket_t *listener, const char *err)
34 -{
35 - h2o_socket_t *sock;
36 -
37 - if (err != NULL) {
38 - return;
39 - }
40 -
41 - if ((sock = h2o_evloop_socket_accept(listener)) == NULL)
42 - return;
43 - h2o_accept(&accept_ctx, sock);
44 -}
45 -
46 -static int create_listener(const char *ip, int port)
47 -{
48 - struct sockaddr_in addr;
49 - int fd, reuseaddr_flag = 1;
50 - h2o_socket_t *sock;
51 -
52 - memset(&addr, 0, sizeof(addr));
53 - addr.sin_family = AF_INET;
54 - addr.sin_addr.s_addr = inet_addr(ip);
55 - addr.sin_port = htons(port);
56 -
57 - if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == -1 ||
58 - setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr_flag, sizeof(reuseaddr_flag)) != 0 ||
59 - bind(fd, (struct sockaddr *)&addr, sizeof(addr)) != 0 || listen(fd, SOMAXCONN) != 0) {
60 - if (fd != -1)
61 - close(fd);
62 - return -1;
63 - }
64 -
65 - sock = h2o_evloop_socket_create(ctx.loop, fd, H2O_SOCKET_FLAG_DONT_READ);
66 - h2o_socket_read_start(sock, on_accept);
67 -
68 - return 0;
69 -}
70 -
71 -static int ssl_init()
72 -{
73 - if (!inicfg_get_boolean(&netdata_config, HTTPD_CONFIG_SECTION, "ssl", false))
74 - return 0;
75 -
76 - char default_fn[FILENAME_MAX + 1];
77 -
78 - snprintfz(default_fn, FILENAME_MAX, "%s/ssl/key.pem", netdata_configured_user_config_dir);
79 - const char *key_fn = inicfg_get(&netdata_config, HTTPD_CONFIG_SECTION, "ssl key", default_fn);
80 -
81 - snprintfz(default_fn, FILENAME_MAX, "%s/ssl/cert.pem", netdata_configured_user_config_dir);
82 - const char *cert_fn = inicfg_get(&netdata_config, HTTPD_CONFIG_SECTION, "ssl certificate", default_fn);
83 -
84 -#if OPENSSL_VERSION_NUMBER < OPENSSL_VERSION_110
85 - accept_ctx.ssl_ctx = SSL_CTX_new(SSLv23_server_method());
86 -#else
87 - accept_ctx.ssl_ctx = SSL_CTX_new(TLS_server_method());
88 -#endif
89 - if (!accept_ctx.ssl_ctx) {
90 - netdata_log_error("Could not allocate a new SSL_CTX");
91 - return -1;
92 - }
93 -
94 - SSL_CTX_set_options(accept_ctx.ssl_ctx, SSL_OP_NO_SSLv2);
95 -
96 - /* load certificate and private key */
97 - if (SSL_CTX_use_PrivateKey_file(accept_ctx.ssl_ctx, key_fn, SSL_FILETYPE_PEM) != 1) {
98 - netdata_log_error("Could not load server key from \"%s\"", key_fn);
99 - return -1;
100 - }
101 - if (SSL_CTX_use_certificate_file(accept_ctx.ssl_ctx, cert_fn, SSL_FILETYPE_PEM) != 1) {
102 - netdata_log_error("Could not load certificate from \"%s\"", cert_fn);
103 - return -1;
104 - }
105 -
106 - h2o_ssl_register_alpn_protocols(accept_ctx.ssl_ctx, h2o_http2_alpn_protocols);
107 -
108 - netdata_log_info("SSL support enabled");
109 -
110 - return 0;
111 -}
112 -
113 -// I did not find a way to do wildcard paths to make common handler for urls like:
114 -// /api/v1/info
115 -// /host/child/api/v1/info
116 -// /host/uuid/api/v1/info
117 -// ideally we could do something like "/*/api/v1/info" subscription
118 -// so we do it "manually" here with uberhandler
119 -static inline int _netdata_uberhandler(h2o_req_t *req, RRDHOST **host)
120 -{
121 - if (!h2o_memis(req->method.base, req->method.len, H2O_STRLIT("GET")))
122 - return -1;
123 -
124 - static h2o_generator_t generator = { NULL, NULL };
125 -
126 - h2o_iovec_t norm_path = req->path_normalized;
127 -
128 - if (norm_path.len > strlen(HOST_SELECT_PREFIX) && !memcmp(norm_path.base, HOST_SELECT_PREFIX, strlen(HOST_SELECT_PREFIX))) {
129 - h2o_iovec_t host_id; // host_id can be either and UUID or a hostname of the child
130 -
131 - norm_path.base += strlen(HOST_SELECT_PREFIX);
132 - norm_path.len -= strlen(HOST_SELECT_PREFIX);
133 -
134 - host_id = norm_path;
135 -
136 - size_t end_loc = h2o_strstr(host_id.base, host_id.len, "/", 1);
137 - if (end_loc != SIZE_MAX) {
138 - host_id.len = end_loc;
139 - norm_path.base += end_loc;
140 - norm_path.len -= end_loc;
141 - }
142 -
143 - char *c_host_id = iovec_to_cstr(&host_id);
144 - *host = rrdhost_find_by_hostname(c_host_id);
145 - if (!*host)
146 - *host = rrdhost_find_by_guid(c_host_id);
147 - if (!*host)
148 - *host = rrdhost_find_by_node_id(c_host_id);
149 - if (!*host) {
150 - req->res.status = HTTP_RESP_BAD_REQUEST;
151 - req->res.reason = "Wrong host id";
152 - h2o_send_inline(req, H2O_STRLIT("Host id provided was not found!\n"));
153 - freez(c_host_id);
154 - return 0;
155 - }
156 - freez(c_host_id);
157 -
158 - // we have to rewrite URL here in case this is not an api call
159 - // so that the subsequent file upload handler can send the correct
160 - // files to the client
161 - // if this is not an API call we will abort this handler later
162 - // and let the internal serve file handler of h2o care for things
163 -
164 - if (end_loc == SIZE_MAX) {
165 - req->path.len = 1;
166 - req->path_normalized.len = 1;
167 - } else {
168 - size_t offset = norm_path.base - req->path_normalized.base;
169 - req->path.len -= offset;
170 - req->path.base += offset;
171 - req->query_at -= offset;
172 - req->path_normalized.len -= offset;
173 - req->path_normalized.base += offset;
174 - }
175 - }
176 -
177 - // workaround for a dashboard bug which causes sometimes urls like
178 - // "//api/v1/info" to be caled instead of "/api/v1/info"
179 - if (norm_path.len > 2 &&
180 - norm_path.base[0] == '/' &&
181 - norm_path.base[1] == '/' ) {
182 - norm_path.base++;
183 - norm_path.len--;
184 - }
185 -
186 - unsigned int api_version = 3;
187 - size_t api_loc = h2o_strstr(norm_path.base, norm_path.len, H2O_STRLIT(API_V3_PREFIX));
188 - if (api_loc == SIZE_MAX) {
189 - api_version = 2;
190 - api_loc = h2o_strstr(norm_path.base, norm_path.len, H2O_STRLIT(API_V2_PREFIX));
191 - if (api_loc == SIZE_MAX) {
192 - api_version = 1;
193 - api_loc = h2o_strstr(norm_path.base, norm_path.len, H2O_STRLIT(API_V1_PREFIX));
194 - if (api_loc == SIZE_MAX)
195 - return 1;
196 - }
197 - }
198 -
199 - // API_V1_PREFIX and API_V2_PREFIX are the same length
200 - // but I did this just in case someone changes the length of the prefix in future
201 - // so he will not be shot in the leg here
202 - // until then compiler will optimize this out
203 - size_t api_len = api_version == 1 ? strlen(API_V1_PREFIX) : strlen(API_V2_PREFIX);
204 -
205 - h2o_iovec_t api_command = norm_path;
206 - api_command.base += api_loc + api_len;
207 - api_command.len -= api_loc + api_len;
208 -
209 - if (!api_command.len)
210 - return 1;
211 -
212 - // TODO - get a web_client from the cache
213 - // this (emulating struct web_client) is a hack and will be removed
214 - // in future PRs but needs bigger changes in old http_api_v1
215 - // we need to make the web_client_api_request_v1 to be web server
216 - // agnostic and remove the old webservers dependency creep into the
217 - // individual response generators and thus remove the need to "emulate"
218 - // the old webserver calling this function here and in ACLK
219 - struct web_client w;
220 - memset(&w, 0, sizeof(w));
221 - w.response.data = buffer_create(NBUF_INITIAL_SIZE_RESP, NULL);
222 - w.response.header = buffer_create(NBUF_INITIAL_SIZE_RESP, NULL);
223 - w.url_query_string_decoded = buffer_create(NBUF_INITIAL_SIZE_RESP, NULL);
224 - w.url_as_received = buffer_create(NBUF_INITIAL_SIZE_RESP, NULL);
225 - w.port_acl = HTTP_ACL_H2O | HTTP_ACL_ALL_FEATURES;
226 - w.acl = w.port_acl; // TODO - web_client_update_acl_matches(w) to restrict this based on user configuration
227 -
228 - char *path_c_str = iovec_to_cstr(&api_command);
229 - char *path_unescaped = url_unescape(path_c_str);
230 - buffer_strcat(w.url_as_received, iovec_to_cstr(&norm_path));
231 - freez(path_c_str);
232 -
233 - IF_HAS_URL_PARAMS(req) {
234 - h2o_iovec_t query_params = URL_PARAMS_IOVEC_INIT_WITH_QUESTIONMARK(req);
235 - char *query_c_str = iovec_to_cstr(&query_params);
236 - char *query_unescaped = url_unescape(query_c_str);
237 - freez(query_c_str);
238 - buffer_strcat(w.url_query_string_decoded, query_unescaped);
239 - freez(query_unescaped);
240 - }
241 -
242 -//inline int web_client_api_request_v2(RRDHOST *host, struct web_client *w, char *url_path_endpoint) {
243 - if (api_version == 3)
244 - web_client_api_request_v3(*host, &w, path_unescaped);
245 - else if (api_version == 2)
246 - web_client_api_request_v2(*host, &w, path_unescaped);
247 - else
248 - web_client_api_request_v1(*host, &w, path_unescaped);
249 - freez(path_unescaped);
250 -
251 - // we move msg body to req->pool managed memory as it has to
252 - // live until whole response has been encrypted and sent
253 - // when req is finished memory will be freed with the pool
254 - h2o_iovec_t body;
255 - {
256 - BUFFER *wb = w.response.data;
257 - body.base = wb->buffer;
258 - body.len = wb->len;
259 -
260 - void *managed = h2o_mem_alloc_shared(&req->pool, body.len, NULL);
261 - memcpy(managed, body.base, body.len);
262 - body.base = managed;
263 - }
264 -
265 - req->res.status = HTTP_RESP_OK;
266 - req->res.reason = "OK";
267 - if (w.response.data->content_type == CT_APPLICATION_JSON)
268 - h2o_add_header(&req->pool, &req->res.headers, H2O_TOKEN_CONTENT_TYPE, NULL, CONTENT_JSON_UTF8);
269 - else
270 - h2o_add_header(&req->pool, &req->res.headers, H2O_TOKEN_CONTENT_TYPE, NULL, CONTENT_TEXT_UTF8);
271 - h2o_start_response(req, &generator);
272 - h2o_send(req, &body, 1, H2O_SEND_STATE_FINAL);
273 -
274 - buffer_free(w.response.data);
275 - buffer_free(w.response.header);
276 - buffer_free(w.url_query_string_decoded);
277 - buffer_free(w.url_as_received);
278 -
279 - return 0;
280 -}
281 -
282 -static int netdata_uberhandler(h2o_handler_t *self, h2o_req_t *req)
283 -{
284 - UNUSED(self);
285 - RRDHOST *host = localhost;
286 -
287 - int ret = _netdata_uberhandler(req, &host);
288 -
289 - if (!ret) {
290 - char host_uuid_str[UUID_STR_LEN];
291 -
292 - if (host != NULL)
293 - uuid_unparse_lower(host->host_id.uuid, host_uuid_str);
294 -
295 - nd_log(NDLS_ACCESS, NDLP_DEBUG, "HTTPD OK method: " PRINTF_H2O_IOVEC_FMT
296 - ", path: " PRINTF_H2O_IOVEC_FMT
297 - ", as host: %s"
298 - ", response: %d",
299 - PRINTF_H2O_IOVEC(&req->method),
300 - PRINTF_H2O_IOVEC(&req->input.path),
301 - host == NULL ? "unknown" : (localhost ? "localhost" : host_uuid_str),
302 - req->res.status);
303 - } else {
304 - nd_log(NDLS_ACCESS, NDLP_DEBUG, "HTTPD %d"
305 - " method: " PRINTF_H2O_IOVEC_FMT
306 - ", path: " PRINTF_H2O_IOVEC_FMT
307 - ", forwarding to file handler as path: " PRINTF_H2O_IOVEC_FMT,
308 - ret,
309 - PRINTF_H2O_IOVEC(&req->method),
310 - PRINTF_H2O_IOVEC(&req->input.path),
311 - PRINTF_H2O_IOVEC(&req->path));
312 - }
313 -
314 - return ret;
315 -}
316 -
317 -static int hdl_netdata_conf(h2o_handler_t *self, h2o_req_t *req)
318 -{
319 - UNUSED(self);
320 - if (!h2o_memis(req->method.base, req->method.len, H2O_STRLIT("GET")))
321 - return -1;
322 -
323 - BUFFER *buf = buffer_create(NBUF_INITIAL_SIZE_RESP, NULL);
324 - inicfg_generate(&netdata_config, buf, 0, true);
325 -
326 - void *managed = h2o_mem_alloc_shared(&req->pool, buf->len, NULL);
327 - memcpy(managed, buf->buffer, buf->len);
328 -
329 - req->res.status = HTTP_RESP_OK;
330 - req->res.reason = "OK";
331 - h2o_add_header(&req->pool, &req->res.headers, H2O_TOKEN_CONTENT_TYPE, NULL, CONTENT_TEXT_UTF8);
332 - h2o_send_inline(req, managed, buf->len);
333 - buffer_free(buf);
334 -
335 - return 0;
336 -}
337 -
338 -static int hdl_stream(h2o_handler_t *self, h2o_req_t *req)
339 -{
340 - UNUSED(self);
341 - netdata_log_info("Streaming request trough h2o received");
342 - h2o_stream_conn_t *conn = mallocz(sizeof(*conn));
343 - h2o_stream_conn_t_init(conn);
344 -
345 - if (is_streaming_handshake(req)) {
346 - h2o_stream_conn_t_destroy(conn);
347 - freez(conn);
348 - return 1;
349 - }
350 -
351 - /* build response */
352 - req->res.status = HTTP_RESP_SWITCH_PROTO;
353 - req->res.reason = "Switching Protocols";
354 - h2o_add_header(&req->pool, &req->res.headers, H2O_TOKEN_UPGRADE, NULL, H2O_STRLIT(NETDATA_STREAM_PROTO_NAME));
355 -
356 -// TODO we should consider adding some nonce header here
357 -// h2o_add_header_by_str(&req->pool, &req->res.headers, H2O_STRLIT("whatever reply"), 0, NULL, accept_key,
358 -// strlen(accept_key));
359 -
360 - h2o_http1_upgrade(req, NULL, 0, stream_on_complete, conn);
361 -
362 - return 0;
363 -}
364 -
365 -#define POLL_INTERVAL 100
366 -
367 -void *h2o_main(void *ptr) {
368 - struct netdata_static_thread *static_thread = (struct netdata_static_thread *)ptr;
369 -
370 - h2o_pathconf_t *pathconf;
371 - h2o_hostconf_t *hostconf;
372 -
373 - const char *bind_addr = inicfg_get(&netdata_config, HTTPD_CONFIG_SECTION, "bind to", "127.0.0.1");
374 - int bind_port = inicfg_get_number(&netdata_config, HTTPD_CONFIG_SECTION, "port", 19998);
375 -
376 - h2o_config_init(&config);
377 - hostconf = h2o_config_register_host(&config, h2o_iovec_init(H2O_STRLIT("default")), bind_port);
378 -
379 - pathconf = h2o_config_register_path(hostconf, "/netdata.conf", 0);
380 - h2o_handler_t *handler = h2o_create_handler(pathconf, sizeof(*handler));
381 - handler->on_req = hdl_netdata_conf;
382 -
383 - pathconf = h2o_config_register_path(hostconf, NETDATA_STREAM_URL, 0);
384 - handler = h2o_create_handler(pathconf, sizeof(*handler));
385 - handler->on_req = hdl_stream;
386 -
387 - pathconf = h2o_config_register_path(hostconf, "/", 0);
388 - handler = h2o_create_handler(pathconf, sizeof(*handler));
389 - handler->on_req = netdata_uberhandler;
390 - h2o_file_register(pathconf, netdata_configured_web_dir, NULL, NULL, H2O_FILE_FLAG_SEND_COMPRESSED);
391 -
392 - h2o_context_init(&ctx, h2o_evloop_create(), &config);
393 -
394 - if(ssl_init()) {
395 - error_report("SSL was requested but could not be properly initialized. Aborting.");
396 - return NULL;
397 - }
398 -
399 - accept_ctx.ctx = &ctx;
400 - accept_ctx.hosts = config.hosts;
401 -
402 - if (create_listener(bind_addr, bind_port) != 0) {
403 - netdata_log_error("failed to create listener %s:%d", bind_addr, bind_port);
404 - return NULL;
405 - }
406 -
407 - usec_t last_wpoll = now_monotonic_usec();
408 - while (service_running(SERVICE_HTTPD)) {
409 - int rc = h2o_evloop_run(ctx.loop, POLL_INTERVAL);
410 - if (rc < 0 && errno != EINTR) {
411 - netdata_log_error("h2o_evloop_run returned (%d) with errno other than EINTR. Aborting", rc);
412 - break;
413 - }
414 - usec_t now = now_monotonic_usec();
415 - if (now - last_wpoll > POLL_INTERVAL * USEC_PER_MS) {
416 - last_wpoll = now;
417 -
418 - h2o_stream_check_pending_write_reqs();
419 - }
420 - }
421 -
422 - static_thread->enabled = NETDATA_MAIN_THREAD_EXITED;
423 - return NULL;
424 -}
425 -
426 -bool httpd_is_enabled() {
427 - return inicfg_get_boolean(&netdata_config, HTTPD_CONFIG_SECTION, "enabled", HTTPD_ENABLED_DEFAULT);
428 -}
src/web/server/h2o/http_server.h deleted
-15
@@ -1,15 +0,0 @@
1 -// SPDX-License-Identifier: GPL-3.0-or-later
2 -
3 -#ifndef HTTP_SERVER_H
4 -#define HTTP_SERVER_H
5 -
6 -#include <stddef.h>
7 -
8 -void *h2o_main(void * ptr);
9 -
10 -int h2o_stream_write(void *ctx, const char *data, size_t data_len);
11 -size_t h2o_stream_read(void *ctx, char *buf, size_t read_bytes);
12 -
13 -bool httpd_is_enabled();
14 -
15 -#endif /* HTTP_SERVER_H */
src/web/server/h2o/libh2o deleted
-1
@@ -1 +0,0 @@
1 -Subproject commit 7359e98d78d018a35f5da7523feac69f64eddb4b
src/web/server/h2o/rrdpush.c deleted
-384
@@ -1,384 +0,0 @@
1 -// SPDX-License-Identifier: GPL-3.0-or-later
2 -
3 -#include "database/rrd.h"
4 -#include "streaming.h"
5 -#include "connlist.h"
6 -#include "h2o_utils.h"
7 -#include "streaming/h2o-common.h"
8 -
9 -static int pending_write_reqs = 0;
10 -
11 -#define H2O2STREAM_BUF_SIZE (1024 * 1024)
12 -
13 -// h2o_stream_conn_t related functions
14 -void h2o_stream_conn_t_init(h2o_stream_conn_t *conn)
15 -{
16 - memset(conn, 0, sizeof(*conn));
17 - conn->rx = rbuf_create(H2O2STREAM_BUF_SIZE);
18 - conn->tx = rbuf_create(H2O2STREAM_BUF_SIZE);
19 -
20 - pthread_mutex_init(&conn->rx_buf_lock, NULL);
21 - pthread_mutex_init(&conn->tx_buf_lock, NULL);
22 - pthread_cond_init(&conn->rx_buf_cond, NULL);
23 - // no need to check for NULL as rbuf_create uses mallocz internally
24 -}
25 -
26 -void h2o_stream_conn_t_destroy(h2o_stream_conn_t *conn)
27 -{
28 - rbuf_free(conn->rx);
29 - rbuf_free(conn->tx);
30 -
31 - freez(conn->url);
32 - freez(conn->user_agent);
33 -
34 - pthread_mutex_destroy(&conn->rx_buf_lock);
35 - pthread_mutex_destroy(&conn->tx_buf_lock);
36 - pthread_cond_destroy(&conn->rx_buf_cond);
37 -}
38 -
39 -// streaming upgrade related functions
40 -int is_streaming_handshake(h2o_req_t *req)
41 -{
42 - /* method */
43 - if (!h2o_memis(req->input.method.base, req->input.method.len, H2O_STRLIT("GET")))
44 - return 1;
45 -
46 - if (!h2o_memis(req->path_normalized.base, req->path_normalized.len, H2O_STRLIT(NETDATA_STREAM_URL))) {
47 - return 1;
48 - }
49 -
50 - /* upgrade header */
51 - if (req->upgrade.base == NULL || !h2o_lcstris(req->upgrade.base, req->upgrade.len, H2O_STRLIT(NETDATA_STREAM_PROTO_NAME)))
52 - return 1;
53 -
54 - // TODO consider adding some key in form of random number
55 - // to prevent caching on route especially if TLS is not used
56 - // e.g. client sends random number
57 - // server replies with it xored
58 -
59 - return 0;
60 -}
61 -
62 -static void stream_on_close(h2o_stream_conn_t *conn);
63 -void stream_process(h2o_stream_conn_t *conn, int initial);
64 -
65 -void stream_on_complete(void *user_data, h2o_socket_t *sock, size_t reqsize)
66 -{
67 - h2o_stream_conn_t *conn = user_data;
68 -
69 - /* close the connection on error */
70 - if (sock == NULL) {
71 - stream_on_close(conn);
72 - return;
73 - }
74 -
75 - conn->sock = sock;
76 - sock->data = conn;
77 -
78 - conn_list_insert(&conn_list, conn);
79 -
80 - h2o_buffer_consume(&sock->input, reqsize);
81 - stream_process(conn, 1);
82 -}
83 -
84 -// handling of active streams
85 -static void stream_on_close(h2o_stream_conn_t *conn)
86 -{
87 - if (conn->sock != NULL)
88 - h2o_socket_close(conn->sock);
89 -
90 - conn_list_remove_conn(&conn_list, conn);
91 -
92 - pthread_mutex_lock(&conn->rx_buf_lock);
93 - conn->shutdown = 1;
94 - pthread_cond_broadcast(&conn->rx_buf_cond);
95 - pthread_mutex_unlock(&conn->rx_buf_lock);
96 -
97 - h2o_stream_conn_t_destroy(conn);
98 - freez(conn);
99 -}
100 -
101 -static void on_write_complete(h2o_socket_t *sock, const char *err)
102 -{
103 - h2o_stream_conn_t *conn = sock->data;
104 -
105 - if (err != NULL) {
106 - stream_on_close(conn);
107 - error_report("Streaming connection error \"%s\"", err);
108 - return;
109 - }
110 -
111 - pthread_mutex_lock(&conn->tx_buf_lock);
112 -
113 - rbuf_bump_tail(conn->tx, conn->tx_buf.len);
114 -
115 - conn->tx_buf.base = NULL;
116 - conn->tx_buf.len = 0;
117 -
118 - pthread_mutex_unlock(&conn->tx_buf_lock);
119 -
120 - stream_process(conn, 0);
121 -}
122 -
123 -static void stream_on_recv(h2o_socket_t *sock, const char *err)
124 -{
125 - h2o_stream_conn_t *conn = sock->data;
126 -
127 - if (err != NULL) {
128 - stream_on_close(conn);
129 - error_report("Streaming connection error \"%s\"", err);
130 - return;
131 - }
132 - stream_process(conn, 0);
133 -}
134 -
135 -#define PARSE_DONE 1
136 -#define PARSE_ERROR -1
137 -#define GIMME_MORE_OF_DEM_SWEET_BYTEZ 0
138 -
139 -#define STREAM_METHOD "STREAM "
140 -#define USER_AGENT "User-Agent: "
141 -
142 -#define NEED_MIN_BYTES(buf, bytes) do { \
143 - if(rbuf_bytes_available(buf) < bytes) \
144 - return GIMME_MORE_OF_DEM_SWEET_BYTEZ;\
145 -} while(0)
146 -
147 -// TODO check in streaming code this is probably defined somewhere already
148 -#define MAX_LEN_STREAM_HELLO (1024*2)
149 -
150 -static int process_STREAM_X_HTTP_1_1(http_stream_parse_state_t *parser_state, rbuf_t buf, char **url, char **user_agent)
151 -{
152 - int idx;
153 - switch(*parser_state) {
154 - case HTTP_STREAM:
155 - NEED_MIN_BYTES(buf, strlen(STREAM_METHOD));
156 - if (rbuf_memcmp_n(buf, H2O_STRLIT(STREAM_METHOD))) {
157 - error_report("Expected \"%s\"", STREAM_METHOD);
158 - return PARSE_ERROR;
159 - }
160 - rbuf_bump_tail(buf, strlen(STREAM_METHOD));
161 - *parser_state = HTTP_URL;
162 - /* FALLTHROUGH */
163 - case HTTP_URL:
164 - if (!rbuf_find_bytes(buf, " ", 1, &idx)) {
165 - if (rbuf_bytes_available(buf) >= MAX_LEN_STREAM_HELLO) {
166 - error_report("The initial \"STREAM [URL]" HTTP_1_1 "\" over max of %d", MAX_LEN_STREAM_HELLO);
167 - return PARSE_ERROR;
168 - }
169 - }
170 - *url = mallocz(idx + 1);
171 - rbuf_pop(buf, *url, idx);
172 - (*url)[idx] = 0;
173 -
174 - *parser_state = HTTP_PROTO;
175 - /* FALLTHROUGH */
176 - case HTTP_PROTO:
177 - NEED_MIN_BYTES(buf, strlen(HTTP_1_1));
178 - if (rbuf_memcmp_n(buf, H2O_STRLIT(HTTP_1_1))) {
179 - error_report("Expected \"%s\"", HTTP_1_1);
180 - return PARSE_ERROR;
181 - }
182 - rbuf_bump_tail(buf, strlen(HTTP_1_1));
183 - *parser_state = HTTP_USER_AGENT_KEY;
184 - /* FALLTHROUGH */
185 - case HTTP_USER_AGENT_KEY:
186 - // and OF COURSE EVERYTHING is passed in URL except
187 - // for user agent which we need and is passed as HTTP header
188 - // not worth writing a parser for this so we manually extract
189 - // just the single header we need and skip everything else
190 - if (!rbuf_find_bytes(buf, USER_AGENT, strlen(USER_AGENT), &idx)) {
191 - if (rbuf_bytes_available(buf) >= (size_t)(rbuf_get_capacity(buf) * 0.9)) {
192 - error_report("The initial \"STREAM [URL]" HTTP_1_1 "\" over max of %d", MAX_LEN_STREAM_HELLO);
193 - return PARSE_ERROR;
194 - }
195 - return GIMME_MORE_OF_DEM_SWEET_BYTEZ;
196 - }
197 - rbuf_bump_tail(buf, idx + strlen(USER_AGENT));
198 - *parser_state = HTTP_USER_AGENT_VALUE;
199 - /* FALLTHROUGH */
200 - case HTTP_USER_AGENT_VALUE:
201 - if (!rbuf_find_bytes(buf, "\r\n", 2, &idx)) {
202 - if (rbuf_bytes_available(buf) >= (size_t)(rbuf_get_capacity(buf) * 0.9)) {
203 - error_report("The initial \"STREAM [URL]" HTTP_1_1 "\" over max of %d", MAX_LEN_STREAM_HELLO);
204 - return PARSE_ERROR;
205 - }
206 - return GIMME_MORE_OF_DEM_SWEET_BYTEZ;
207 - }
208 -
209 - *user_agent = mallocz(idx + 1);
210 - rbuf_pop(buf, *user_agent, idx);
211 - (*user_agent)[idx] = 0;
212 -
213 - *parser_state = HTTP_HDR;
214 - /* FALLTHROUGH */
215 - case HTTP_HDR:
216 - if (!rbuf_find_bytes(buf, HTTP_HDR_END, strlen(HTTP_HDR_END), &idx)) {
217 - if (rbuf_bytes_available(buf) >= (size_t)(rbuf_get_capacity(buf) * 0.9)) {
218 - error_report("The initial \"STREAM [URL]" HTTP_1_1 "\" over max of %d", MAX_LEN_STREAM_HELLO);
219 - return PARSE_ERROR;
220 - }
221 - return GIMME_MORE_OF_DEM_SWEET_BYTEZ;
222 - }
223 - rbuf_bump_tail(buf, idx + strlen(HTTP_HDR_END));
224 -
225 - *parser_state = HTTP_DONE;
226 - return PARSE_DONE;
227 - case HTTP_DONE:
228 - error_report("Parsing is done. No need to call again.");
229 - return PARSE_DONE;
230 - default:
231 - error_report("Unknown parser state %d", (int)*parser_state);
232 - return PARSE_ERROR;
233 - }
234 -}
235 -
236 -#define SINGLE_WRITE_MAX (1024)
237 -
238 -void stream_process(h2o_stream_conn_t *conn, int initial)
239 -{
240 - int rc;
241 - struct web_client w;
242 -
243 - pthread_mutex_lock(&conn->tx_buf_lock);
244 - if (h2o_socket_is_writing(conn->sock) || rbuf_bytes_available(conn->tx)) {
245 - if (rbuf_bytes_available(conn->tx) && !conn->tx_buf.base) {
246 - conn->tx_buf.base = rbuf_get_linear_read_range(conn->tx, &conn->tx_buf.len);
247 - if (conn->tx_buf.base) {
248 - conn->tx_buf.len = MIN(conn->tx_buf.len, SINGLE_WRITE_MAX);
249 - h2o_socket_write(conn->sock, &conn->tx_buf, 1, on_write_complete);
250 - }
251 - }
252 - }
253 - pthread_mutex_unlock(&conn->tx_buf_lock);
254 -
255 - if (initial)
256 - h2o_socket_read_start(conn->sock, stream_on_recv);
257 -
258 - if (conn->sock->input->size) {
259 - size_t insert_max;
260 - pthread_mutex_lock(&conn->rx_buf_lock);
261 - char *insert_loc = rbuf_get_linear_insert_range(conn->rx, &insert_max);
262 - if (insert_loc == NULL) {
263 - pthread_cond_broadcast(&conn->rx_buf_cond);
264 - pthread_mutex_unlock(&conn->rx_buf_lock);
265 - return;
266 - }
267 - insert_max = MIN(insert_max, conn->sock->input->size);
268 - memcpy(insert_loc, conn->sock->input->bytes, insert_max);
269 - rbuf_bump_head(conn->rx, insert_max);
270 -
271 - h2o_buffer_consume(&conn->sock->input, insert_max);
272 -
273 - pthread_cond_broadcast(&conn->rx_buf_cond);
274 - pthread_mutex_unlock(&conn->rx_buf_lock);
275 - }
276 -
277 - switch (conn->state) {
278 - case STREAM_X_HTTP_1_1:
279 - // no conn->rx lock here as at this point we are still single threaded
280 - // until we call rrdpush_receiver_thread_spawn() later down
281 - rc = process_STREAM_X_HTTP_1_1(&conn->parse_state, conn->rx, &conn->url, &conn->user_agent);
282 - if (rc == PARSE_ERROR) {
283 - error_report("error parsing the STREAM hello");
284 - break;
285 - }
286 - if (rc != PARSE_DONE)
287 - break;
288 - conn->state = STREAM_X_HTTP_1_1_DONE;
289 - /* FALLTHROUGH */
290 - case STREAM_X_HTTP_1_1_DONE:
291 - memset(&w, 0, sizeof(w));
292 - w.response.data = buffer_create(1024, NULL);
293 -
294 - // get client ip from the conn->sock
295 - struct sockaddr client;
296 - socklen_t len = h2o_socket_getpeername(conn->sock, &client);
297 - char peername[NI_MAXHOST];
298 - size_t peername_len = h2o_socket_getnumerichost(&client, len, peername);
299 - size_t cpy_len = sizeof(w.user_auth.client_ip) < peername_len ? sizeof(w.user_auth.client_ip) : peername_len;
300 - memcpy(w.user_auth.client_ip, peername, cpy_len);
301 - w.user_auth.client_ip[cpy_len - 1] = 0;
302 - w.user_agent = conn->user_agent;
303 -
304 - rc = stream_receiver_accept_connection(&w, conn->url, conn);
305 - if (rc != HTTP_RESP_OK) {
306 - error_report("HTTPD Failed to spawn the receiver thread %d", rc);
307 - conn->state = STREAM_CLOSE;
308 - stream_on_close(conn);
309 - } else {
310 - conn->state = STREAM_ACTIVE;
311 - }
312 - buffer_free(w.response.data);
313 - /* FALLTHROUGH */
314 - case STREAM_ACTIVE:
315 - break;
316 - default:
317 - error_report("Unknown conn->state");
318 - }
319 -}
320 -
321 -// read and write functions to be used by streaming parser
322 -int h2o_stream_write(void *ctx, const char *data, size_t data_len)
323 -{
324 - h2o_stream_conn_t *conn = (h2o_stream_conn_t *)ctx;
325 -
326 - pthread_mutex_lock(&conn->tx_buf_lock);
327 - size_t avail = rbuf_bytes_free(conn->tx);
328 - avail = MIN(avail, data_len);
329 - rbuf_push(conn->tx, data, avail);
330 - pthread_mutex_unlock(&conn->tx_buf_lock);
331 - __atomic_add_fetch(&pending_write_reqs, 1, __ATOMIC_SEQ_CST);
332 - return avail;
333 -}
334 -
335 -size_t h2o_stream_read(void *ctx, char *buf, size_t read_bytes)
336 -{
337 - int ret;
338 - h2o_stream_conn_t *conn = (h2o_stream_conn_t *)ctx;
339 -
340 - pthread_mutex_lock(&conn->rx_buf_lock);
341 - size_t avail = rbuf_bytes_available(conn->rx);
342 -
343 - if (!avail) {
344 - if (conn->shutdown) {
345 - pthread_mutex_unlock(&conn->rx_buf_lock);
346 - return -1;
347 - }
348 - pthread_cond_wait(&conn->rx_buf_cond, &conn->rx_buf_lock);
349 - if (conn->shutdown) {
350 - pthread_mutex_unlock(&conn->rx_buf_lock);
351 - return -1;
352 - }
353 - avail = rbuf_bytes_available(conn->rx);
354 - if (!avail) {
355 - pthread_mutex_unlock(&conn->rx_buf_lock);
356 - return 0;
357 - }
358 - }
359 -
360 - avail = MIN(avail, read_bytes);
361 -
362 - ret = rbuf_pop(conn->rx, buf, avail);
363 - pthread_mutex_unlock(&conn->rx_buf_lock);
364 -
365 - return ret;
366 -}
367 -
368 -// periodic check for pending write requests
369 -void check_tx_buf(h2o_stream_conn_t *conn)
370 -{
371 - pthread_mutex_lock(&conn->tx_buf_lock);
372 - if (rbuf_bytes_available(conn->tx)) {
373 - pthread_mutex_unlock(&conn->tx_buf_lock);
374 - stream_process(conn, 0);
375 - } else
376 - pthread_mutex_unlock(&conn->tx_buf_lock);
377 -}
378 -
379 -void h2o_stream_check_pending_write_reqs(void)
380 -{
381 - int _write_reqs = __atomic_exchange_n(&pending_write_reqs, 0, __ATOMIC_SEQ_CST);
382 - if (_write_reqs > 0)
383 - conn_list_iter_all(&conn_list, check_tx_buf);
384 -}
src/web/server/h2o/streaming.h deleted
-64
@@ -1,64 +0,0 @@
1 -// SPDX-License-Identifier: GPL-3.0-or-later
2 -
3 -#ifndef HTTPD_STREAMING_H
4 -#define HTTPD_STREAMING_H
5 -
6 -#pragma GCC diagnostic push
7 -#pragma GCC diagnostic ignored "-Wunused-parameter"
8 -#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
9 -#pragma GCC diagnostic ignored "-Wtype-limits"
10 -#include "h2o.h"
11 -#pragma GCC diagnostic pop
12 -
13 -typedef enum {
14 - STREAM_X_HTTP_1_1 = 0,
15 - STREAM_X_HTTP_1_1_DONE,
16 - STREAM_ACTIVE,
17 - STREAM_CLOSE
18 -} h2o_stream_state_t;
19 -
20 -typedef enum {
21 - HTTP_STREAM = 0,
22 - HTTP_URL,
23 - HTTP_PROTO,
24 - HTTP_USER_AGENT_KEY,
25 - HTTP_USER_AGENT_VALUE,
26 - HTTP_HDR,
27 - HTTP_DONE
28 -} http_stream_parse_state_t;
29 -
30 -typedef struct {
31 - h2o_socket_t *sock;
32 - h2o_stream_state_t state;
33 -
34 - rbuf_t rx;
35 - pthread_cond_t rx_buf_cond;
36 - pthread_mutex_t rx_buf_lock;
37 -
38 - rbuf_t tx;
39 - h2o_iovec_t tx_buf;
40 - pthread_mutex_t tx_buf_lock;
41 -
42 - http_stream_parse_state_t parse_state;
43 - char *url;
44 - char *user_agent;
45 -
46 - int shutdown;
47 -} h2o_stream_conn_t;
48 -
49 -// h2o_stream_conn_t related functions
50 -void h2o_stream_conn_t_init(h2o_stream_conn_t *conn);
51 -void h2o_stream_conn_t_destroy(h2o_stream_conn_t *conn);
52 -
53 -// streaming upgrade related functions
54 -int is_streaming_handshake(h2o_req_t *req);
55 -void stream_on_complete(void *user_data, h2o_socket_t *sock, size_t reqsize);
56 -
57 -// read and write functions to be used by streaming parser
58 -int h2o_stream_write(void *ctx, const char *data, size_t data_len);
59 -size_t h2o_stream_read(void *ctx, char *buf, size_t read_bytes);
60 -
61 -// call this periodically to check if there are any pending write requests
62 -void h2o_stream_check_pending_write_reqs(void);
63 -
64 -#endif /* HTTPD_STREAMING_H */
src/web/server/web_client.c
+1 -1
@@ -1329,7 +1329,7 @@ void web_client_process_request_from_web_server(struct web_client *w) {
1329 }
1330
1331 w->response.code = stream_receiver_accept_connection(
1332 - w, (char *)buffer_tostring(w->url_query_string_decoded), NULL);
1332 + w, (char *)buffer_tostring(w->url_query_string_decoded));
1333 return;
1334
1335 case HTTP_REQUEST_MODE_WEBSOCKET: