Skip to content

Commit 8f4bd11

Browse files
StekPerepolnenydbotactions-useradameat
authored
Route all handler responses through monitoring (#21480)
Co-authored-by: YDBot <ydbot@ydb.tech> Co-authored-by: GitHub Action <action@github.com> Co-authored-by: Alexey Efimov <xeno@prnwatch.com>
1 parent f353bd5 commit 8f4bd11

File tree

1 file changed

+57
-24
lines changed

1 file changed

+57
-24
lines changed

ydb/core/mon/mon.cpp

Lines changed: 57 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1026,32 +1026,36 @@ class THttpMonInitializator : public TActorBootstrapped<THttpMonInitializator> {
10261026
class THttpMonAuthorizedActorRequest : public TActorBootstrapped<THttpMonAuthorizedActorRequest> {
10271027
public:
10281028
NHttp::TEvHttpProxy::TEvHttpIncomingRequest::TPtr Event;
1029-
TActorId TargetActorId;
1029+
TMon::TRegisterHandlerFields Fields;
10301030
TMon::TRequestAuthorizer Authorizer;
1031-
TVector<TString> AllowedSIDs;
1031+
NHttp::TEvHttpProxy::TEvSubscribeForCancel::TPtr CancelSubscriber;
10321032

1033-
THttpMonAuthorizedActorRequest(NHttp::TEvHttpProxy::TEvHttpIncomingRequest::TPtr event, TActorId targetActorId, TMon::TRequestAuthorizer authorizer, const TVector<TString>& allowedSIDs)
1033+
THttpMonAuthorizedActorRequest(NHttp::TEvHttpProxy::TEvHttpIncomingRequest::TPtr event, const TMon::TRegisterHandlerFields& fields, TMon::TRequestAuthorizer authorizer)
10341034
: Event(std::move(event))
1035-
, TargetActorId(targetActorId)
1035+
, Fields(fields)
10361036
, Authorizer(std::move(authorizer))
1037-
, AllowedSIDs(allowedSIDs)
10381037
{}
10391038

10401039
static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
10411040
return NKikimrServices::TActivity::HTTP_MON_AUTHORIZED_ACTOR_REQUEST;
10421041
}
10431042

10441043
void Bootstrap() {
1045-
if (Authorizer) {
1044+
Send(Event->Sender, new NHttp::TEvHttpProxy::TEvSubscribeForCancel(), IEventHandle::FlagTrackDelivery);
1045+
if (Fields.UseAuth && Authorizer) {
10461046
NActors::IEventHandle* handle = Authorizer(SelfId(), Event->Get()->Request.Get());
10471047
if (handle) {
10481048
Send(handle);
10491049
Become(&THttpMonAuthorizedActorRequest::StateWork);
10501050
return;
10511051
}
10521052
}
1053-
Forward(Event, TargetActorId);
1054-
PassAway();
1053+
SendRequest();
1054+
Become(&THttpMonAuthorizedActorRequest::StateWork);
1055+
}
1056+
1057+
void ReplyWith(NHttp::THttpOutgoingResponsePtr response) {
1058+
Send(Event->Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(response));
10551059
}
10561060

10571061
bool CredentialsProvided() {
@@ -1136,7 +1140,7 @@ class THttpMonAuthorizedActorRequest : public TActorBootstrapped<THttpMonAuthori
11361140
response << "Content-Length: " << body.size() << "\r\n";
11371141
response << "\r\n";
11381142
response << body;
1139-
Send(Event->Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(request->CreateResponseString(response)));
1143+
ReplyWith(request->CreateResponseString(response));
11401144
PassAway();
11411145
}
11421146

@@ -1146,26 +1150,35 @@ class THttpMonAuthorizedActorRequest : public TActorBootstrapped<THttpMonAuthori
11461150
ReplyErrorAndPassAway(Ydb::StatusIds::UNAUTHORIZED, issues, true);
11471151
}
11481152

1149-
void SendRequest(const NKikimr::NGRpcService::TEvRequestAuthAndCheckResult& result) {
1153+
void SendRequest(const NKikimr::NGRpcService::TEvRequestAuthAndCheckResult* result = nullptr) {
11501154
NHttp::THttpIncomingRequestPtr request = Event->Get()->Request;
11511155
if (Authorizer) {
1152-
TString user = result.UserToken ? result.UserToken->GetUserSID() : "anonymous";
1156+
TString user = (result && result->UserToken) ? result->UserToken->GetUserSID() : "anonymous";
11531157
ALOG_NOTICE(NActorsServices::HTTP, (request->Address ? request->Address->ToString() : "")
11541158
<< " " << user
11551159
<< " " << request->Method
11561160
<< " " << request->URL);
11571161
}
1158-
if (result.UserToken) {
1159-
Event->Get()->UserToken = result.UserToken->GetSerializedToken();
1162+
if (result && result->UserToken) {
1163+
Event->Get()->UserToken = result->UserToken->GetSerializedToken();
1164+
}
1165+
Send(new IEventHandle(Fields.Handler, SelfId(), Event->ReleaseBase().Release(), IEventHandle::FlagTrackDelivery, Event->Cookie));
1166+
}
1167+
1168+
void Cancelled() {
1169+
if (CancelSubscriber) {
1170+
Send(CancelSubscriber->Sender, new NHttp::TEvHttpProxy::TEvRequestCancelled(), 0, CancelSubscriber->Cookie);
11601171
}
1161-
Forward(Event, TargetActorId);
11621172
PassAway();
11631173
}
11641174

1165-
void HandleUndelivered(TEvents::TEvUndelivered::TPtr&) {
1175+
void HandleUndelivered(TEvents::TEvUndelivered::TPtr& ev) {
1176+
if (ev->Get()->SourceType == NHttp::TEvHttpProxy::EvSubscribeForCancel) {
1177+
return Cancelled();
1178+
}
11661179
NHttp::THttpIncomingRequestPtr request = Event->Get()->Request;
1167-
Send(Event->Sender, new NHttp::TEvHttpProxy::TEvHttpOutgoingResponse(
1168-
request->CreateResponseServiceUnavailable(TStringBuilder() << "Auth actor is not available")));
1180+
ReplyWith(request->CreateResponseServiceUnavailable(
1181+
TStringBuilder() << "Actor is not available"));
11691182
PassAway();
11701183
}
11711184

@@ -1174,17 +1187,41 @@ class THttpMonAuthorizedActorRequest : public TActorBootstrapped<THttpMonAuthori
11741187
if (result.Status != Ydb::StatusIds::SUCCESS) {
11751188
return ReplyErrorAndPassAway(result);
11761189
}
1177-
if (IsTokenAllowed(result.UserToken.Get(), AllowedSIDs)) {
1178-
SendRequest(result);
1190+
if (IsTokenAllowed(result.UserToken.Get(), Fields.AllowedSIDs)) {
1191+
SendRequest(&result);
11791192
} else {
11801193
return ReplyForbiddenAndPassAway("SID is not allowed");
11811194
}
11821195
}
11831196

1197+
void Handle(NHttp::TEvHttpProxy::TEvHttpOutgoingResponse::TPtr& ev) {
1198+
bool endOfData = ev->Get()->Response->IsDone();
1199+
Forward(ev, Event->Sender);
1200+
if (endOfData) {
1201+
return PassAway();
1202+
}
1203+
}
1204+
1205+
void Handle(NHttp::TEvHttpProxy::TEvHttpOutgoingDataChunk::TPtr& ev) {
1206+
bool endOfData = ev->Get()->DataChunk && ev->Get()->DataChunk->IsEndOfData() || ev->Get()->Error;
1207+
Forward(ev, Event->Sender);
1208+
if (endOfData) {
1209+
PassAway();
1210+
}
1211+
}
1212+
1213+
void Handle(NHttp::TEvHttpProxy::TEvSubscribeForCancel::TPtr& ev) {
1214+
CancelSubscriber = std::move(ev);
1215+
}
1216+
11841217
STATEFN(StateWork) {
11851218
switch (ev->GetTypeRewrite()) {
11861219
hFunc(TEvents::TEvUndelivered, HandleUndelivered);
11871220
hFunc(NKikimr::NGRpcService::TEvRequestAuthAndCheckResult, Handle);
1221+
hFunc(NHttp::TEvHttpProxy::TEvHttpOutgoingResponse, Handle);
1222+
hFunc(NHttp::TEvHttpProxy::TEvHttpOutgoingDataChunk, Handle);
1223+
hFunc(NHttp::TEvHttpProxy::TEvSubscribeForCancel, Handle);
1224+
cFunc(NHttp::TEvHttpProxy::EvRequestCancelled, Cancelled);
11881225
}
11891226
}
11901227
};
@@ -1276,11 +1313,7 @@ class THttpMonIndexService : public TActor<THttpMonIndexService> {
12761313
while (!url.empty()) {
12771314
auto it = Handlers.find(TString(url));
12781315
if (it != Handlers.end()) {
1279-
if (it->second.UseAuth) {
1280-
Register(new THttpMonAuthorizedActorRequest(std::move(ev), it->second.Handler, Authorizer, it->second.AllowedSIDs));
1281-
} else {
1282-
Forward(ev, it->second.Handler);
1283-
}
1316+
Register(new THttpMonAuthorizedActorRequest(std::move(ev), it->second, Authorizer));
12841317
return;
12851318
} else {
12861319
if (url.EndsWith('/')) {

0 commit comments

Comments
 (0)