| 90 | } |
| 91 | |
| 92 | void NehServiceQueryCallback(const NNeh::IRequestRef& req) { |
| 93 | CHROMIUM_TRACE_FUNCTION(); |
| 94 | |
| 95 | PAR_DEBUG_LOG << "At " << GetHostAndPort() << " incoming req: " << req->Scheme() << " " << req->RemoteHost() << " " << req->Service() << Endl; |
| 96 | if (req->Canceled()) { |
| 97 | PAR_DEBUG_LOG << "At " << GetHostAndPort() << " incoming req: " << req->Scheme() << " " << req->RemoteHost() << " " << req->Service() << " query is canceled in flight, don't even try to launch it" << Endl; |
| 98 | // if query is canceled in flight, don't even try to launch it |
| 99 | return; |
| 100 | } |
| 101 | auto del1pos = req->Data().find('\xff'); |
| 102 | auto del2pos = req->Data().find('\xff', del1pos + 1); |
| 103 | if (del1pos == TStringBuf::npos || del2pos == TStringBuf::npos) { |
| 104 | req->SendError(NNeh::IRequest::BadRequest, "no \\xff delimiters found"); |
| 105 | return; |
| 106 | } |
| 107 | |
| 108 | TGUID reqId; |
| 109 | if (!GetGuid(ToString(req->Data().substr(0, del1pos)), reqId)) { |
| 110 | req->SendError(NNeh::IRequest::BadRequest, "incorrect guid"); |
| 111 | return; |
| 112 | } |
| 113 | auto Url = req->Data().substr(del1pos + 1, del2pos - del1pos - 1); |
| 114 | auto del3pos = req->Data().find('\xff', del2pos + 1); |
| 115 | TVector<char> Data; |
| 116 | if (del3pos != TStringBuf::npos) { |
| 117 | auto crc32ref = FromString<ui32>(TStringBuf(req->Data().begin() + del2pos + 1, del3pos - del2pos - 1)); |
| 118 | auto dataSize = req->Data().end() - (req->Data().begin() + del3pos + 1); |
| 119 | auto crc32actual = Crc32c(req->Data().begin() + del3pos + 1, dataSize); |
| 120 | if (crc32actual != crc32ref) { |
| 121 | TStringBuilder errorString; |
| 122 | errorString << "Invalid crc32 for data, expected " << crc32ref << " got " << crc32actual; |
| 123 | |
| 124 | PAR_DEBUG_LOG << "At " << GetHostAndPort() << ": " << errorString << Endl; |
| 125 | req->SendError(NNeh::IRequest::BadRequest, errorString); |
| 126 | return; |
| 127 | } |
| 128 | Data.assign(req->Data().begin() + del3pos + 1, req->Data().end()); |
| 129 | } |
| 130 | QuickLZDecompress(&Data); |
| 131 | PAR_DEBUG_LOG << "At " << GetHostAndPort() << " got request " << GetGuidAsString(reqId) << " service: " << Url << " data len: " << Data.size() << Endl; |
| 132 | NNeh::TData ok = {'O', 'K'}; |
| 133 | req->SendReply(ok); |
| 134 | if (Url == "_ping_") { |
| 135 | return; |
| 136 | } else if (Url == "_cancel_") { |
| 137 | if (!IncomingRequestsInfo.EraseValueIfPresent(reqId)) { |
| 138 | return; |
| 139 | } |
| 140 | QueryCancelCallback(reqId); |
| 141 | } else if (Url == "_reply_") { |
| 142 | if (!RequestsInfo.EraseValueIfPresent(reqId)) { |
| 143 | return; |
| 144 | } |
| 145 | TAutoPtr<TNetworkResponse> httpResponse = new TNetworkResponse; |
| 146 | httpResponse->ReqId = reqId; |
| 147 | httpResponse->Data = std::move(Data); |
| 148 | httpResponse->Status = TNetworkResponse::EStatus::Ok; |
| 149 | auto directReplyNotifier = [&httpResponse](TIntrusivePtr<TSyncRequestsInfo>& syncRequestInfo) { |
nothing calls this directly
no test coverage detected