| 434 | } |
| 435 | |
| 436 | void addDefaultHandlersFactory( |
| 437 | HTTPRequestHandlerFactoryMain & factory, |
| 438 | IServer & server, |
| 439 | const Poco::Util::AbstractConfiguration & config, |
| 440 | AsynchronousMetrics & async_metrics) |
| 441 | { |
| 442 | addCommonDefaultHandlersFactory(factory, server, config); |
| 443 | |
| 444 | /// `/webterminal` is intentionally registered only on the user-facing HTTP |
| 445 | /// port, never on the interserver port (which `createInterserverHTTPHandlerFactory` |
| 446 | /// builds via `addCommonDefaultHandlersFactory`). The interserver port has a |
| 447 | /// different (HMAC) trust model and is typically less-firewalled inside the |
| 448 | /// cluster, so exposing an interactive PTY shell there would punch a hole |
| 449 | /// through that boundary even when `enable_webterminal` is set. |
| 450 | auto webterminal_handler = std::make_shared<HandlingRuleHTTPHandlerFactory<WebTerminalRequestHandler>>(server); |
| 451 | webterminal_handler->attachNonStrictPath("/webterminal"); |
| 452 | webterminal_handler->allowGetAndHeadRequest(); |
| 453 | factory.addPathToHints("/webterminal"); |
| 454 | factory.addHandler(webterminal_handler); |
| 455 | |
| 456 | auto dynamic_creator = [&server] () -> std::unique_ptr<DynamicQueryHandler> |
| 457 | { |
| 458 | return std::make_unique<DynamicQueryHandler>(server, HTTPHandlerConnectionConfig{}, "query"); |
| 459 | }; |
| 460 | auto query_handler = std::make_shared<HandlingRuleHTTPHandlerFactory<DynamicQueryHandler>>(std::move(dynamic_creator)); |
| 461 | query_handler->addFilter([](const auto & request) |
| 462 | { |
| 463 | bool path_matches_get_or_head = startsWith(request.getURI(), "?") |
| 464 | || startsWith(request.getURI(), "/?") |
| 465 | || startsWith(request.getURI(), "/query?"); |
| 466 | bool is_get_or_head_request = request.getMethod() == Poco::Net::HTTPRequest::HTTP_GET |
| 467 | || request.getMethod() == Poco::Net::HTTPRequest::HTTP_HEAD; |
| 468 | |
| 469 | bool path_matches_post_or_options = path_matches_get_or_head |
| 470 | || request.getURI() == "/" |
| 471 | || request.getURI().empty(); |
| 472 | bool is_post_or_options_request = request.getMethod() == Poco::Net::HTTPRequest::HTTP_POST |
| 473 | || request.getMethod() == Poco::Net::HTTPRequest::HTTP_OPTIONS; |
| 474 | |
| 475 | return (path_matches_get_or_head && is_get_or_head_request) || (path_matches_post_or_options && is_post_or_options_request); |
| 476 | } |
| 477 | ); |
| 478 | factory.addHandler(query_handler); |
| 479 | |
| 480 | /// createPrometheusHandlerFactoryForHTTPRuleDefaults() can return nullptr if prometheus protocols must not be served on http port. |
| 481 | if (auto prometheus_handler = createPrometheusHandlerFactoryForHTTPRuleDefaults(server, config, async_metrics)) |
| 482 | factory.addHandler(prometheus_handler); |
| 483 | } |
| 484 | |
| 485 | } |
no test coverage detected