diff options
author | Alexey Efimov <xeno@ydb.tech> | 2025-05-23 11:14:06 +0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-05-23 11:14:06 +0700 |
commit | 8309fbe29b9bccd50769803fc993deac18cd7c2d (patch) | |
tree | 6dbba831870fc3aae010f9aaca387f0571872bc4 | |
parent | 0e4d027cd6d5b101b6237440de440014625614e5 (diff) | |
download | ydb-8309fbe29b9bccd50769803fc993deac18cd7c2d.tar.gz |
support form-urlencoded in base class (#18675)
-rw-r--r-- | ydb/core/viewer/json_pipe_req.cpp | 17 | ||||
-rw-r--r-- | ydb/core/viewer/json_pipe_req.h | 1 | ||||
-rw-r--r-- | ydb/core/viewer/viewer_render.h | 144 | ||||
-rw-r--r-- | ydb/core/viewer/viewer_request.cpp | 2 |
4 files changed, 65 insertions, 99 deletions
diff --git a/ydb/core/viewer/json_pipe_req.cpp b/ydb/core/viewer/json_pipe_req.cpp index 8a7ff5ecc34..822e29f7bb6 100644 --- a/ydb/core/viewer/json_pipe_req.cpp +++ b/ydb/core/viewer/json_pipe_req.cpp @@ -143,6 +143,11 @@ void TViewerPipeClient::BuildParamsFromJson(TStringBuf data) { case NJson::EJsonValueType::JSON_BOOLEAN: Params.InsertUnescaped(key, value.GetStringRobust()); break; + case NJson::EJsonValueType::JSON_ARRAY: + for (const auto& item : value.GetArray()) { + Params.InsertUnescaped(key, item.GetStringRobust()); + } + break; default: break; } @@ -152,6 +157,12 @@ void TViewerPipeClient::BuildParamsFromJson(TStringBuf data) { } } +void TViewerPipeClient::BuildParamsFromFormData(TStringBuf data) { + for (const auto& [key, value] : TCgiParameters(data)) { + Params.InsertUnescaped(key, value); + } +} + void TViewerPipeClient::SetupTracing(const TString& handlerName) { auto request = GetRequest(); NWilson::TTraceId traceId; @@ -191,6 +202,9 @@ TViewerPipeClient::TViewerPipeClient(IViewer* viewer, NMon::TEvHttpInfo::TPtr& e if (NHttp::Trim(Event->Get()->Request.GetHeader("Content-Type").Before(';'), ' ') == "application/json") { BuildParamsFromJson(Event->Get()->Request.GetPostContent()); } + if (NHttp::Trim(Event->Get()->Request.GetHeader("Content-Type").Before(';'), ' ') == "application/x-www-form-urlencoded") { + BuildParamsFromFormData(Event->Get()->Request.GetPostContent()); + } InitConfig(Params); SetupTracing(handlerName); } @@ -204,6 +218,9 @@ TViewerPipeClient::TViewerPipeClient(IViewer* viewer, NHttp::TEvHttpProxy::TEvHt if (NHttp::Trim(headers.Get("Content-Type").Before(';'), ' ') == "application/json") { BuildParamsFromJson(HttpEvent->Get()->Request->Body); } + if (NHttp::Trim(headers.Get("Content-Type").Before(';'), ' ') == "application/x-www-form-urlencoded") { + BuildParamsFromFormData(HttpEvent->Get()->Request->Body); + } InitConfig(Params); SetupTracing(handlerName); } diff --git a/ydb/core/viewer/json_pipe_req.h b/ydb/core/viewer/json_pipe_req.h index 3910c85244e..fc5fe76da7c 100644 --- a/ydb/core/viewer/json_pipe_req.h +++ b/ydb/core/viewer/json_pipe_req.h @@ -332,6 +332,7 @@ protected: void InitConfig(const TCgiParameters& params); void InitConfig(const TRequestSettings& settings); void BuildParamsFromJson(TStringBuf data); + void BuildParamsFromFormData(TStringBuf data); void SetupTracing(const TString& handlerName); template<typename TJson> diff --git a/ydb/core/viewer/viewer_render.h b/ydb/core/viewer/viewer_render.h index 44aea71caff..8d3532c13b2 100644 --- a/ydb/core/viewer/viewer_render.h +++ b/ydb/core/viewer/viewer_render.h @@ -14,62 +14,38 @@ using namespace NMonitoring; class TJsonRender : public TViewerPipeClient { using TThis = TJsonRender; using TBase = TViewerPipeClient; - TEvViewer::TEvViewerRequest::TPtr ViewerRequest; - ui32 Timeout = 0; + using TBase::ReplyAndPassAway; std::vector<TString> Metrics; - TCgiParameters Params; public: TJsonRender(IViewer* viewer, NMon::TEvHttpInfo::TPtr& ev) : TViewerPipeClient(viewer, ev) { - const auto& params(Event->Get()->Request.GetParams()); - - InitConfig(params); - Timeout = FromStringWithDefault<ui32>(params.Get("timeout"), 30000); - } - - TJsonRender(TEvViewer::TEvViewerRequest::TPtr& ev) - : ViewerRequest(ev) - { - auto& request = ViewerRequest->Get()->Record.GetRenderRequest(); - - TCgiParameters params(request.GetUri()); - InitConfig(params); - Direct = true; - Timeout = ViewerRequest->Get()->Record.GetTimeout(); } void Bootstrap() override { if (NeedToRedirect()) { return; } - auto postData = Event - ? Event->Get()->Request.GetPostContent() - : ViewerRequest->Get()->Record.GetRenderRequest().GetContent(); - BLOG_D("PostData=" << postData); NKikimrGraph::TEvGetMetrics getRequest; - if (postData) { - Params = TCgiParameters(postData); - if (Params.Has("target")) { - TString metric; - size_t num = 0; - for (;;) { - metric = Params.Get("target", num); - if (metric.empty()) { - break; - } - Metrics.push_back(metric); - ++num; + if (Params.Has("target")) { + TString metric; + size_t num = 0; + for (;;) { + metric = Params.Get("target", num); + if (metric.empty()) { + break; } + Metrics.push_back(metric); + ++num; } SendGraphRequest(); } else { - ReplyAndPassAway(Viewer->GetHTTPBADREQUEST(Event->Get(), {}, "Bad Request")); + ReplyAndPassAway(GetHTTPBADREQUEST("text/plain", "Bad Request")); return; } - Become(&TThis::StateWork, TDuration::MilliSeconds(Timeout), new TEvents::TEvWakeup()); + Become(&TThis::StateWork, Timeout, new TEvents::TEvWakeup()); } STATEFN(StateWork) { @@ -90,7 +66,7 @@ public: "\x03\x00\x00\x00\x25\xdb\x56\xca\x00\x00\x00\x03\x50\x4c\x54\x45\x00\x00\x00\xa7\x7a\x3d\xda\x00\x00" "\x00\x01\x74\x52\x4e\x53\x00\x40\xe6\xd8\x66\x00\x00\x00\x0a\x49\x44\x41\x54\x08\xd7\x63\x60\x00\x00" "\x00\x02\x00\x01\xe2\x21\xbc\x33\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82"; - Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPOK(Event->Get(), "image/png", png1x1), 0, NMon::IEvHttpInfoRes::EContentType::Custom)); + ReplyAndPassAway(GetHTTPOK("image/png", png1x1)); return PassAway(); } if (Params.Has("from")) { @@ -106,82 +82,56 @@ public: } void HandleRenderResponse(NKikimrGraph::TEvMetricsResult& response) { - if (Event) { - NJson::TJsonValue json; + NJson::TJsonValue json; - if (response.GetError()) { - json["status"] = "error"; - json["error"] = response.GetError(); - return ReplyAndPassAway(GetHTTPOKJSON(json)); - } - if (response.DataSize() != Metrics.size()) { + if (response.GetError()) { + json["status"] = "error"; + json["error"] = response.GetError(); + return ReplyAndPassAway(GetHTTPOKJSON(json)); + } + if (response.DataSize() != Metrics.size()) { + json["status"] = "error"; + json["error"] = "Invalid data size received"; + return ReplyAndPassAway(GetHTTPOKJSON(json)); + } + for (size_t nMetric = 0; nMetric < response.DataSize(); ++nMetric) { + const auto& protoMetric(response.GetData(nMetric)); + if (response.TimeSize() != protoMetric.ValuesSize()) { json["status"] = "error"; - json["error"] = "Invalid data size received"; + json["error"] = "Invalid value size received"; return ReplyAndPassAway(GetHTTPOKJSON(json)); } + } + { // graphite + json.SetType(NJson::JSON_ARRAY); for (size_t nMetric = 0; nMetric < response.DataSize(); ++nMetric) { const auto& protoMetric(response.GetData(nMetric)); - if (response.TimeSize() != protoMetric.ValuesSize()) { - json["status"] = "error"; - json["error"] = "Invalid value size received"; - return ReplyAndPassAway(GetHTTPOKJSON(json)); - } - } - { // graphite - json.SetType(NJson::JSON_ARRAY); - for (size_t nMetric = 0; nMetric < response.DataSize(); ++nMetric) { - const auto& protoMetric(response.GetData(nMetric)); - NJson::TJsonValue& jsonMetric(json.AppendValue({})); - jsonMetric["target"] = Metrics[nMetric]; - jsonMetric["title"] = Metrics[nMetric]; - jsonMetric["tags"]["name"] = Metrics[nMetric]; - NJson::TJsonValue& jsonDataPoints(jsonMetric["datapoints"]); - jsonDataPoints.SetType(NJson::JSON_ARRAY); - for (size_t nTime = 0; nTime < response.TimeSize(); ++nTime) { - NJson::TJsonValue& jsonDataPoint(jsonDataPoints.AppendValue({})); - double value = protoMetric.GetValues(nTime); - if (isnan(value)) { - jsonDataPoint.AppendValue(NJson::TJsonValue(NJson::JSON_NULL)); - } else { - jsonDataPoint.AppendValue(value); - } - jsonDataPoint.AppendValue(response.GetTime(nTime)); + NJson::TJsonValue& jsonMetric(json.AppendValue({})); + jsonMetric["target"] = Metrics[nMetric]; + jsonMetric["title"] = Metrics[nMetric]; + jsonMetric["tags"]["name"] = Metrics[nMetric]; + NJson::TJsonValue& jsonDataPoints(jsonMetric["datapoints"]); + jsonDataPoints.SetType(NJson::JSON_ARRAY); + for (size_t nTime = 0; nTime < response.TimeSize(); ++nTime) { + NJson::TJsonValue& jsonDataPoint(jsonDataPoints.AppendValue({})); + double value = protoMetric.GetValues(nTime); + if (isnan(value)) { + jsonDataPoint.AppendValue(NJson::TJsonValue(NJson::JSON_NULL)); + } else { + jsonDataPoint.AppendValue(value); } + jsonDataPoint.AppendValue(response.GetTime(nTime)); } } - - ReplyAndPassAway(GetHTTPOKJSON(json)); - } else { - TEvViewer::TEvViewerResponse* viewerResponse = new TEvViewer::TEvViewerResponse(); - viewerResponse->Record.MutableRenderResponse()->CopyFrom(response); - ReplyAndPassAway(viewerResponse); } + + ReplyAndPassAway(GetHTTPOKJSON(json)); } void Handle(NGraph::TEvGraph::TEvMetricsResult::TPtr& ev) { HandleRenderResponse(ev->Get()->Record); } - void HandleTimeout() { - if (Event) { - ReplyAndPassAway(Viewer->GetHTTPGATEWAYTIMEOUT(Event->Get())); - } else { - auto* response = new TEvViewer::TEvViewerResponse(); - response->Record.MutableRenderResponse()->SetError("Request timed out"); - ReplyAndPassAway(response); - } - } - - void ReplyAndPassAway(TEvViewer::TEvViewerResponse* response) { - Send(ViewerRequest->Sender, response); - PassAway(); - } - - void ReplyAndPassAway(TString data) { - Send(Event->Sender, new NMon::TEvHttpInfoRes(std::move(data), 0, NMon::IEvHttpInfoRes::EContentType::Custom)); - PassAway(); - } - void ReplyAndPassAway() override { } diff --git a/ydb/core/viewer/viewer_request.cpp b/ydb/core/viewer/viewer_request.cpp index 1afcbfc69a5..357fdae9ab1 100644 --- a/ydb/core/viewer/viewer_request.cpp +++ b/ydb/core/viewer/viewer_request.cpp @@ -124,8 +124,6 @@ IActor* CreateViewerRequestHandler(TEvViewer::TEvViewerRequest::TPtr& request) { return new TViewerWhiteboardRequest<TEvWhiteboard::TEvNodeStateRequest, TEvWhiteboard::TEvNodeStateResponse>(request); case NKikimrViewer::TEvViewerRequest::kQueryRequest: return new TJsonQueryOld(request); - case NKikimrViewer::TEvViewerRequest::kRenderRequest: - return new TJsonRender(request); case NKikimrViewer::TEvViewerRequest::kAutocompleteRequest: return new TJsonAutocomplete(request); default: |