void TSockSys::OnGetHost(uv_getaddrinfo_t* RequestHnd, int Status, struct addrinfo* AddrInfo) { // get SockHost PSockHost SockHost; if (SockSys.HndToSockHostH.IsKey((uint64)RequestHnd)) { SockHost = SockSys.HndToSockHostH.GetDat((uint64)RequestHnd); SockSys.HndToSockHostH.DelKey((uint64)RequestHnd); } else { free(RequestHnd); uv_freeaddrinfo(AddrInfo); SaveToErrLog("SockSys.OnGetHost: unkown RequestId"); return; } // get SockEvent PSockEvent SockEvent; if (SockHost->IsSockEvent()) { SockEvent = SockHost->GetSockEvent(); } else { free(RequestHnd); uv_freeaddrinfo(AddrInfo); SaveToErrLog("SockSys.OnGetHost: SockHost without SockEvent"); return; } // parse results if (Status == 0) { SockHost->Status = shsOk; // temporary buffer for storing IPs char _addr[64] = {'\0'}; // iterate over all the resolved IPs struct addrinfo* AddrInfoIter = AddrInfo; while (AddrInfoIter != NULL) { //if (AddrInfoIter->ai_family //AF_INET6 // get IP as string if (AddrInfoIter->ai_family == AF_INET) { uv_ip4_name((struct sockaddr_in*)AddrInfoIter->ai_addr, _addr, sizeof(_addr)); } else if (AddrInfoIter->ai_family == AF_INET6) { uv_ip6_name((struct sockaddr_in6*)AddrInfoIter->ai_addr, _addr, sizeof(_addr)); } TStr IpNum(_addr); // add to SockHost SockHost->AddIpNum(IpNum); // go to the next IP on the list AddrInfoIter = AddrInfoIter->ai_next; } } else if (Status == -1) { // something went wrong SockHost->Status = shsError; SockHost->ErrMsg = "SockSys.OnGetHost: " + SockSys.GetLastErr(); } else { // unkown status SockHost->Status = shsError; SockHost->ErrMsg = TStr::Fmt("SockSys.OnGetHost: unkown status %d", Status); } // clean up free(RequestHnd); uv_freeaddrinfo(AddrInfo); // callback SockEvent->OnGetHost(SockHost); }
void TSockSys::OnTimeOut(uv_timer_t* TimerHnd, int Status) { // check we have timer IAssert(SockSys.IsTimer((uint64)TimerHnd)); // get socket id const uint64 SockId = SockSys.TimerHndToSockIdH.GetDat((uint64)TimerHnd); IAssert(SockSys.IsSock(SockId)); // get socket event const uint64 SockHnd = (uint64)SockSys.SockIdToHndH.GetDat(SockId); const uint64 SockEventId = SockSys.SockHndToEventIdH.GetDat((uint64)SockHnd); PSockEvent SockEvent; if (SockSys.IsSockEvent(SockEventId)) { SockEvent = SockSys.GetSockEvent(SockEventId); // execute callback if (Status == 0) { SockEvent->OnTimeOut(SockId); } else { TStr ErrMsg = (Status == -1) ? "SockSys.OnTimeOut: " + SockSys.GetLastErr() : "SockSys.OnTimeOut: Error in socket timeout"; SockEvent->OnError(SockId, Status, ErrMsg); } } else { SaveToErrLog("SockSys.OnTimeOut: Socket without SockEvent"); } // cleanup uv_close((uv_handle_t*)TimerHnd, NULL); // remove shortcuts SockSys.SockIdToTimerHndH.DelKey(SockId); SockSys.TimerHndToSockIdH.DelKey((uint64)TimerHnd); }
void TSockSys::OnWrite(uv_write_t *WriteHnd, int Status) { // cast to our write request object to get access to buffer uv_write_req_t* _WriteHnd = (uv_write_req_t*)WriteHnd; // get socket handle uv_tcp_t* SockHnd = (uv_tcp_t*)WriteHnd->handle; IAssert(SockSys.IsSockHnd((uint64)SockHnd)); // free buffer and write handle free(_WriteHnd->Buffer.base); free(_WriteHnd); // get socket id const uint64 SockId = SockSys.SockHndToIdH.GetDat((uint64)SockHnd); IAssert(SockSys.IsSock(SockId)); // get socket event const uint64 SockEventId = SockSys.SockHndToEventIdH.GetDat((uint64)SockHnd); PSockEvent SockEvent; if (SockSys.IsSockEvent(SockEventId)) { SockEvent = SockSys.GetSockEvent(SockEventId); } else { SaveToErrLog("SockSys.OnWrite: Socket without SockEvent"); return; } // execute callback if (Status == 0) { SockEvent->OnWrite(SockId); } else { TStr ErrMsg = (Status == -1) ? "SockSys.OnWrite: " + SockSys.GetLastErr() : "SockSys.OnWrite: Error writing to socket"; SockEvent->OnError(SockId, Status, ErrMsg); } }
///////////////////////////////////////////////// // Simple JSON parser bool TJsonLoader::Next() { if (SIn.Empty() || SIn->Eof()) { TStr FNm; if (! SIn.Empty()) { printf(" %d items in file. %d items total. [%s]\n", LineNo, ItemCnt, ExeTm.GetTmStr()); } if (! FFile.Next(FNm)) { return false; } printf("JSON parse file %d: %s\n", ++FileCnt, FNm.CStr()); LineNo=0; if (TZipIn::IsZipExt(FNm.GetFExt())) { SIn=TZipIn::New(FNm); } else { SIn=TFIn::New(FNm); } ExeTm.Tick(); } try { SIn->GetNextLn(Line); LineNo++; ItemCnt++; Item.Parse(Line.CStr()); } catch (PExcept Except) { TStr FullMsgCStr = TStr::Fmt("%s while pasing '%s' in line %d\nBEGIN LINE\n", Except->GetStr().CStr(), GetCurFNm().CStr(), GetLineNo()); FullMsgCStr += Line; FullMsgCStr += "\nEND LINE\n"; SaveToErrLog(FullMsgCStr.CStr()); ErrNotify(FullMsgCStr.CStr()); return Next(); } return true; }
uint64 TZipIn::GetFLen(const TStr& ZipFNm) { #ifdef GLib_WIN HANDLE ZipStdoutRd, ZipStdoutWr; // create pipes SECURITY_ATTRIBUTES saAttr; saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); saAttr.bInheritHandle = TRUE; saAttr.lpSecurityDescriptor = NULL; // Create a pipe for the child process's STDOUT. const int PipeBufferSz = 32*1024; EAssertR(CreatePipe(&ZipStdoutRd, &ZipStdoutWr, &saAttr, PipeBufferSz), "Stdout pipe creation failed"); // Ensure the read handle to the pipe for STDOUT is not inherited. SetHandleInformation(ZipStdoutRd, HANDLE_FLAG_INHERIT, 0); //CreateZipProcess(GetCmd(FNm), FNm); { const TStr CmdLine = TStr::Fmt("7z.exe l %s", ZipFNm.CStr()); PROCESS_INFORMATION piProcInfo; STARTUPINFO siStartInfo; ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION)); ZeroMemory( &siStartInfo, sizeof(STARTUPINFO)); siStartInfo.cb = sizeof(STARTUPINFO); siStartInfo.hStdOutput = ZipStdoutWr; siStartInfo.dwFlags |= STARTF_USESTDHANDLES; // Create the child process. const BOOL FuncRetn = CreateProcess(NULL, (LPSTR) CmdLine.CStr(), NULL, NULL, TRUE, 0, NULL, NULL, &siStartInfo, &piProcInfo); EAssertR(FuncRetn!=0, TStr::Fmt("Can not execute '%s'", CmdLine.CStr()).CStr()); CloseHandle(piProcInfo.hProcess); CloseHandle(piProcInfo.hThread); } #else const TStr CmdLine = TStr::Fmt("7za l %s", ZipFNm.CStr()); FILE* ZipStdoutRd = popen(CmdLine.CStr(), "r"); EAssertR(ZipStdoutRd != NULL, TStr::Fmt("Can not execute '%s'", CmdLine.CStr()).CStr()); #endif // Read output from the child process const int BfSz = 32*1024; char* Bf = new char [BfSz]; int BfC=0, BfL=0; memset(Bf, 0, BfSz); #ifdef GLib_WIN DWORD BytesRead; EAssert(ReadFile(ZipStdoutRd, Bf, MxBfL, &BytesRead, NULL) != 0); #else size_t BytesRead = fread(Bf, 1, MxBfL, ZipStdoutRd); EAssert(BytesRead != 0); EAssert(pclose(ZipStdoutRd) != -1); #endif BfL = (int) BytesRead; IAssert((BfC!=0)||(BfL!=0)); BfC = 0; Bf[BfL] = 0; // find file lenght TStr Str(Bf); delete [] Bf; TStrV StrV; Str.SplitOnWs(StrV); int n = StrV.Len()-1; while (n > 0 && ! StrV[n].IsPrefix("-----")) { n--; } if (n-7 <= 0) { WrNotify(TStr::Fmt("Corrupt file %s: MESSAGE:\n", ZipFNm.CStr()).CStr(), Str.CStr()); SaveToErrLog(TStr::Fmt("Corrupt file %s. Message:\n:%s\n", ZipFNm.CStr(), Str.CStr()).CStr()); return 0; } return StrV[n-7].GetInt64(); }
void ExeStop( const char* MsgCStr, const char* ReasonCStr, const char* CondCStr, const char* FNm, const int& LnN) { char ReasonMsgCStr[1000]; #if SW_TRACE PrintBacktrace(); Crash(); #endif // construct reason message if (ReasonCStr==NULL) { ReasonMsgCStr[0]=0; } else { sprintf(ReasonMsgCStr, " [Reason:'%s']", ReasonCStr); } // construct full message char FullMsgCStr[1000]; if (MsgCStr==NULL) { if (CondCStr==NULL) { sprintf(FullMsgCStr, "Execution stopped%s!", ReasonMsgCStr); } else { sprintf(FullMsgCStr, "Execution stopped: %s%s, file %s, line %d", CondCStr, ReasonMsgCStr, FNm, LnN); } } else { if (CondCStr==NULL) { sprintf(FullMsgCStr, "%s\nExecution stopped!", MsgCStr); } else { sprintf(FullMsgCStr, "Message: %s%s\nExecution stopped: %s, file %s, line %d", MsgCStr, ReasonMsgCStr, CondCStr, FNm, LnN); } } // report full message to log file SaveToErrLog(FullMsgCStr); #if defined(SW_NOABORT) TExcept::Throw(FullMsgCStr); #endif // report to screen & stop execution bool Continue=false; // call handler if (TOnExeStop::IsOnExeStopF()) { Continue=!((*TOnExeStop::GetOnExeStopF())(FullMsgCStr)); } if (!Continue) { ErrNotify(FullMsgCStr); #ifdef GLib_WIN32 abort(); //ExitProcess(1); #else exit(1); #endif } }
void TWebNetProxy::OnHttpRespError(const int& RespFetchId, const TStr& MsgStr) { SaveToErrLog((TStr("ProxyRequestFailed: ")+MsgStr).CStr()); PProxyConn Conn; if (RespFetchIdToProxyH.IsKeyGetDat(RespFetchId,Conn)) { // send some kind of an error http response immediately to avoid timeouts PHttpResp HttpResp=THttpResp::New(503, "", false, NULL, TStr()); Conn->SendHttpResp(*this,HttpResp); RespFetchIdToProxyH.DelKey(RespFetchId); RqSockIdToProxyH.DelIfKey(Conn->GetRqSockId()); } }
void TSockSys::OnAccept(uv_stream_t* ServerSockHnd, int Status) { // get socket handle uv_tcp_t* SockHnd = (uv_tcp_t*)ServerSockHnd; IAssert(SockSys.IsSockHnd((uint64)SockHnd)); // get socket id const uint64 SockId = SockSys.SockHndToIdH.GetDat((uint64)SockHnd); IAssert(SockSys.IsSock(SockId)); // get socket event const uint64 SockEventId = SockSys.SockHndToEventIdH.GetDat((uint64)SockHnd); PSockEvent SockEvent; if (SockSys.IsSockEvent(SockEventId)) { SockEvent = SockSys.GetSockEvent(SockEventId); } else { SaveToErrLog("SockSys.OnAccept: Socket without SockEvent"); return; } // check for success status if (Status == 0) { // create a new socket for client connection PSock ClientSock = TSock::New(SockEvent); // get client socket handle uv_tcp_t* ClientSockHnd = SockSys.SockIdToHndH.GetDat(ClientSock->GetSockId()); // accept request const int AcceptResCd = uv_accept(ServerSockHnd, (uv_stream_t*)ClientSockHnd); // start listening for incoming data if (AcceptResCd == 0) { int ReadStartResCd = uv_read_start((uv_stream_t*)ClientSockHnd, TSockSys::OnAlloc, TSockSys::OnRead); // execute callback if (ReadStartResCd == 0) { SockEvent->OnAccept(ClientSock->GetSockId(), ClientSock); } else { TStr ErrMsg = (Status == -1) ? "SockSys.OnAccept: Error starting read " + SockSys.GetLastErr() : "SockSys.OnAccept: Error starting read"; SockEvent->OnError(SockId, ReadStartResCd, ErrMsg); } } else { // handle errors TStr ErrMsg = (Status == -1) ? "SockSys.OnAccept: Error accepting new connection " + SockSys.GetLastErr() : "SockSys.OnAccept: Error accepting new connection"; SockEvent->OnError(SockId, AcceptResCd, ErrMsg); } } else { TStr ErrMsg = (Status == -1) ? "SockSys.OnAccept: Error connecting" + SockSys.GetLastErr() : "SockSys.OnAccept: Error connecting"; SockEvent->OnError(SockId, Status, ErrMsg); } }
void TSockSys::OnRead(uv_stream_t* SockHnd, ssize_t BufferLen, uv_buf_t Buffer) { //TODO: check if we need to close _SockHnd //uv_tcp_t* _SockHnd = (uv_tcp_t*)SockHnd; // get socket handle IAssert(SockSys.IsSockHnd((uint64)SockHnd)); // get socket id const uint64 SockId = SockSys.SockHndToIdH.GetDat((uint64)SockHnd); IAssert(SockSys.IsSock(SockId)); // get socket event const uint64 SockEventId = SockSys.SockHndToEventIdH.GetDat((uint64)SockHnd); PSockEvent SockEvent; if (SockSys.IsSockEvent(SockEventId)) { SockEvent = SockSys.GetSockEvent(SockEventId); } else { // cleanup (using delete as it was created in OnAlloc with new) delete[] Buffer.base; SaveToErrLog("SockSys.OnRead: Socket without SockEvent"); return; } // execute callback if (BufferLen > 0) { // we got data, move the ownership of buffer to TMIn PSIn SIn = TMIn::New(Buffer.base, (int)BufferLen, true); // send SockEvent->OnRead(SockId, SIn); } else { uv_err_code Status = uv_last_error(SockSys.Loop).code; // no data, might be error or end of stream if (Status == UV_EOF) { // no more data, close the socket handle SockEvent->OnReadEof(SockId); SockSys.DelIfSockTimer(SockId); } else if (Status == UV_EAGAIN) { // we'll wait } else { // error TStr ErrMsg = "SockSys.OnRead: " + SockSys.GetLastErr(); SockEvent->OnError(SockId, Status, ErrMsg); } // cleanup (using delete as it was created in OnAlloc with new) delete[] Buffer.base; } }
void TSockSys::OnConnect(uv_connect_t* ConnectHnd, int Status) { // get socket handle uv_tcp_t* SockHnd = (uv_tcp_t*)ConnectHnd->handle; IAssert(SockSys.IsSockHnd((uint64)SockHnd)); // cleanup free(ConnectHnd); // get socket id const uint64 SockId = SockSys.SockHndToIdH.GetDat((uint64)SockHnd); IAssert(SockSys.IsSock(SockId)); // get socket event const uint64 SockEventId = SockSys.SockHndToEventIdH.GetDat((uint64)SockHnd); PSockEvent SockEvent; if (SockSys.IsSockEvent(SockEventId)) { SockEvent = SockSys.GetSockEvent(SockEventId); } else { SaveToErrLog("SockSys.OnConnect: Socket without SockEvent"); return; } // execute callback if (Status == 0) { SockEvent->OnConnect(SockId); } else { TStr ErrMsg = (Status == -1) ? "SockSys.OnConnect: " + SockSys.GetLastErr() : "SockSys.OnConnect: Error connecting"; SockEvent->OnError(SockId, Status, ErrMsg); return; } // start listening for incoming data int ResCd = uv_read_start((uv_stream_t*)SockHnd, TSockSys::OnAlloc, TSockSys::OnRead); // check for errors if (ResCd != 0) { TStr ErrMsg = (Status == -1) ? "SockSys.OnConnect: " + SockSys.GetLastErr() : "SockSys.OnConnect: Error establishing read callbacks"; SockEvent->OnError(SockId, ResCd, ErrMsg); } }