void TSAppSrv::OnHttpRq(const uint64& SockId, const PHttpRq& HttpRq) { // last appropriate error code, start with bad request int ErrStatusCd = THttp::BadRqStatusCd; try { // check http-request correctness - return if error EAssertR(HttpRq->IsOk(), "Bad HTTP request!"); // check url correctness - return if error PUrl HttpRqUrl = HttpRq->GetUrl(); EAssertR(HttpRqUrl->IsOk(), "Bad request URL!"); // extract function name TStr FunNm = HttpRqUrl->GetPathSeg(0); // check if we have the function registered if (FunNm == "favicon.ico") { PHttpResp HttpResp = THttpResp::New(THttp::OkStatusCd, THttp::ImageIcoFldVal, false, Favicon.GetSIn()); SendHttpResp(SockId, HttpResp); return; } else if (!FunNm.Empty() && !FunNmToFunH.IsKey(FunNm)) { ErrStatusCd = THttp::ErrNotFoundStatusCd; GetNotify()->OnStatusFmt("[AppSrv] Unknown function '%s'!", FunNm.CStr()); TExcept::Throw("Unknown function '" + FunNm + "'!"); } // extract parameters PUrlEnv HttpRqUrlEnv = HttpRq->GetUrlEnv(); TStrKdV FldNmValPrV; HttpRqUrlEnv->GetKeyValPrV(FldNmValPrV); // report call if (ShowParamP) { GetNotify()->OnStatus(HttpRq->GetUrl()->GetUrlStr()); } // request parsed well, from now on it's internal error ErrStatusCd = THttp::InternalErrStatusCd; // processed requested function if (!FunNm.Empty()) { // prepare request environment PSAppSrvRqEnv RqEnv = TSAppSrvRqEnv::New(this, SockId, HttpRq, FunNmToFunH); // retrieve function PSAppSrvFun SrvFun = FunNmToFunH.GetDat(FunNm); // call function SrvFun->Exec(FldNmValPrV, RqEnv); } else { // internal SAppSrv call if (!ListFunP) { // we are not allowed to list functions ErrStatusCd = THttp::ErrNotFoundStatusCd; TExcept::Throw("Unknown page"); } // prepare a list of registered functions PJsonVal FunArrVal = TJsonVal::NewArr(); int KeyId = FunNmToFunH.FFirstKeyId(); while (FunNmToFunH.FNextKeyId(KeyId)) { FunArrVal->AddToArr(TJsonVal::NewObj("name", FunNmToFunH.GetKey(KeyId))); } PJsonVal ResVal = TJsonVal::NewObj(); ResVal->AddToObj("port", GetPortN()); ResVal->AddToObj("connections", GetConns()); ResVal->AddToObj("functions", FunArrVal); TStr ResStr = ResVal->SaveStr(); // prepare response PHttpResp HttpResp = THttpResp::New(THttp::OkStatusCd, THttp::AppJSonFldVal, false, TMIn::New(ResStr)); // send response SendHttpResp(SockId, HttpResp); } } catch (PExcept Except) { // known internal error TNotify::StdNotify->OnNotifyFmt(ntErr, "Error: %s", Except->GetMsgStr().CStr()); TNotify::StdNotify->OnNotifyFmt(ntErr, "Error location info: %s", Except->GetLocStr().CStr()); PJsonVal ErrorVal = TJsonVal::NewObj(); ErrorVal->AddToObj("message", Except->GetMsgStr()); ErrorVal->AddToObj("location", Except->GetLocStr()); PJsonVal ResVal = TJsonVal::NewObj("error", ErrorVal); TStr ResStr = ResVal->SaveStr(); // prepare response PHttpResp HttpResp = THttpResp::New(ErrStatusCd, THttp::AppJSonFldVal, false, TMIn::New(ResStr)); // send response SendHttpResp(SockId, HttpResp); } catch (...) { TNotify::StdNotify->OnNotify(ntErr, "Unknown internal error"); // unknown internal error PJsonVal ResVal = TJsonVal::NewObj("error", "Unknown internal error"); TStr ResStr = ResVal->SaveStr(); // prepare response PHttpResp HttpResp = THttpResp::New(ErrStatusCd, THttp::AppJSonFldVal, false, TMIn::New(ResStr)); // send response SendHttpResp(SockId, HttpResp); } }
void TWebTxtBsSrv::OnHttpRq(const int& SockId, const PHttpRq& HttpRq){ // request parameters TStr RqContTypeStr=THttp::TextHtmlFldVal; PUrlEnv UrlEnv; TStr QueryStr; TStr EQueryStr; TStr HitSetStr; TStr AcceptStr; // prepare & extract search-environment if (HttpRq->IsOk()){ // prepare search-environment PUrl Url=HttpRq->GetUrl(); UrlEnv=HttpRq->GetUrlEnv(); // if empty search-environment and url-path is not empty if (UrlEnv->Empty()&& (Url->GetPathSegs()>0)&&(!Url->GetPathSeg(0).Empty())){ // get document name TStr DocNm=Url->GetPathSeg(Url->GetPathSegs()-1); if (WebTxtBs->GetTxtBs()->IsDoc(DocNm)){ // document exists in text-base TStr DocStr=WebTxtBs->GetTxtBs()->GetDocStr(DocNm); PSIn HttpBodySIn=TMIn::New(DocStr); PHttpResp HttpResp= THttpResp::New(THttp::OkStatusCd, RqContTypeStr, false, HttpBodySIn); SendHttpResp(SockId, HttpResp); } else { // ordinary http request TWebSrv::OnHttpRq(SockId, HttpRq); } // end if no search request return; } // extract fields from search-environment QueryStr=UrlEnv->GetVal(QueryUrlFldNm).GetTrunc(); EQueryStr=THtmlLx::GetEscapedStr(QueryStr); HitSetStr=UrlEnv->GetVal(HitSetUrlFldNm).GetTrunc(); AcceptStr=UrlEnv->GetVal(AcceptUrlFldNm).GetTrunc(); if (AcceptStr.Empty()){RqContTypeStr=GetRqContType(HttpRq);} else {RqContTypeStr=AcceptStr;} } // hit-set int HitSetN=1; HitSetStr.IsInt(true, 1, TInt::Mx, HitSetN); int HitSetDocs=GetVarVal(RqContTypeStr, "HitSetDocs").GetInt(); int StrHitSets=GetVarVal(RqContTypeStr, "StrHitSets").GetInt(); // output buffer TChA OutChA(10000); // header TStr HdTpl=GetTplVal(RqContTypeStr, "Header"); HdTpl.ChangeStrAll(QueryMacro, EQueryStr); OutChA+=HdTpl; // html body if (HttpRq->IsOk()){ if (!QueryStr.Empty()){ // execute query PTxtBsRes TxtBsRes=WebTxtBs->Search(QueryStr); TStr EWixExpStr=THtmlLx::GetEscapedStr(TxtBsRes->GetWixExpStr()); // log string TChA QueryInfoChA; QueryInfoChA+="Query: "+QueryStr; //QueryInfoChA+=" ["+GetPeerNm(SockId)+"]"; QueryInfoChA+=" ["+TSecTm::GetCurTm().GetStr()+"]"; TNotify::OnNotify(Notify, ntInfo, QueryInfoChA); SLog->PutStr(QueryInfoChA); SLog->PutLn(); SLog->Flush(); // query-results processing if (TxtBsRes->IsOk()){ // result header TStr ResultHdTpl=GetTplVal(RqContTypeStr, "ResultHd"); ResultHdTpl.ChangeStrAll(QueryMacro, EWixExpStr); ResultHdTpl.ChangeStrAll(HitsMacro, TInt::GetStr(TxtBsRes->GetDocs())); OutChA+=ResultHdTpl; // result records int MnDocN; int MxDocN; TxtBsRes->GetHitSetMnMxDocN(HitSetN, HitSetDocs, MnDocN, MxDocN); for (int DocN=MnDocN; DocN<=MxDocN; DocN++){ // get result document data int MxDocTitleLen=GetVarVal(RqContTypeStr, "MxDocTitleLen").GetInt(); int MxDocCtxLen=GetVarVal(RqContTypeStr, "MxDocCtxLen").GetInt(); TStr DocNm; TStr DocTitleStr; TStr DocStr; TStr DocCtxStr; TxtBsRes->GetDocInfo(DocN, MxDocTitleLen, MxDocCtxLen, DocNm, DocTitleStr, DocStr, DocCtxStr); if (DocTitleStr.Empty()){DocTitleStr=DocNm;} // result record TStr ResultRecTpl=GetTplVal(RqContTypeStr, "ResultRec"); ResultRecTpl.ChangeStrAll(HitNumMacro, TInt::GetStr(DocN+1)); ResultRecTpl.ChangeStrAll(DocAddrMacro, DocNm); ResultRecTpl.ChangeStrAll(DocTitleMacro, DocTitleStr); ResultRecTpl.ChangeStrAll(DocCtxMacro, DocCtxStr); OutChA+=ResultRecTpl; } // result footer TStr ResultFtTpl=GetTplVal(RqContTypeStr, "ResultFt"); OutChA+=ResultFtTpl; // hit-set AddHitSetChA(TxtBsRes, RqContTypeStr, HitSetN, HitSetDocs, StrHitSets, UrlEnv, OutChA); } else { // bad query TStr BadQueryTpl=GetTplVal(RqContTypeStr, "BadQuery"); BadQueryTpl.ChangeStrAll(QueryMacro, EWixExpStr); OutChA+=BadQueryTpl; } } } else { // bad http-request TStr BadHttpRqTpl=GetTplVal(RqContTypeStr, "BadHttpRq"); OutChA+=BadHttpRqTpl; } // footer TStr FtTpl=GetTplVal(RqContTypeStr, "Footer"); FtTpl.ChangeStrAll(QueryMacro, EQueryStr); OutChA+=FtTpl; // construct & send response PSIn HttpBodySIn=TMIn::New(OutChA); PHttpResp HttpResp= THttpResp::New(THttp::OkStatusCd, RqContTypeStr, false, HttpBodySIn); SendHttpResp(SockId, HttpResp); }
void TMongSrv::OnHttpRq(const int& SockId, const PHttpRq& HttpRq) { // check http-request correctness - return if error if (!HttpRq->IsOk()) { TNotify::OnNotify(Notify, ntInfo, "Web-Server: Bad Http Request."); return; } // check url correctness - return if error PUrl RqUrl = HttpRq->GetUrl(); if (!RqUrl->IsOk()) { TNotify::OnNotify(Notify, ntInfo, "Web-Server: Bad Url Requested."); return; } // construct http-response PHttpResp HttpResp; if (!RqUrl->GetPathStr().Empty()) { // get request-file-name TStr ExeFPath = TSysProc::GetExeFNm().GetFPath(); TStr RqFNm = RqUrl->GetPathStr(); if (RqFNm.LastCh() == '/') { RqFNm = RqFNm + "default.htm"; } if ((RqFNm[0] == '/') || (RqFNm[0] == '\\')) { RqFNm.DelSubStr(0, 0); } RqFNm = ExeFPath + RqFNm; // open file bool RqFOpened = false; PSIn RqSIn = TFIn::New(RqFNm, RqFOpened); if (!RqFOpened) { // prepare default html with time TChA HtmlChA; HtmlChA += "<html><title>Error - Not Found</title><body>"; HtmlChA += "File: "; HtmlChA += RqUrl->GetPathStr(); HtmlChA += " not found."; HtmlChA += "</body></html>"; PSIn BodySIn = TMIn::New(HtmlChA); HttpResp = PHttpResp( new THttpResp(THttp::ErrNotFoundStatusCd, THttp::TextHtmlFldVal, false, BodySIn, "")); } else { // file successfully opened PSIn BodySIn = RqSIn; if (THttp::IsHtmlFExt(RqFNm.GetFExt())) { // send text/html mime type if Html filemg_callback_t HttpResp = PHttpResp( new THttpResp(THttp::OkStatusCd, THttp::TextHtmlFldVal, false, BodySIn, "")); } else if (THttp::IsGifFExt(RqFNm.GetFExt())) { // send image/gif mime type if Gif file HttpResp = PHttpResp( new THttpResp(THttp::OkStatusCd, THttp::ImageGifFldVal, false, BodySIn, "")); } else { // send application/octet mime type HttpResp = PHttpResp( new THttpResp(THttp::OkStatusCd, THttp::AppOctetFldVal, false, BodySIn, "")); } } } else { // prepare default html with time TChA HtmlChA; HtmlChA += "<html><title>Welcome to TWebSrv (powered by mongoose 3.1)</title><body>"; HtmlChA += TSecTm::GetCurTm().GetStr(); HtmlChA += "</body></html>"; PSIn BodySIn = TMIn::New(HtmlChA); HttpResp = THttpResp::New(THttp::OkStatusCd, THttp::TextHtmlFldVal, false, BodySIn); } // construct & send response SendHttpResp(SockId, HttpResp); // notify if (RqUrl->IsOk()) { TChA MsgChA; MsgChA += "Web-Server: Request for '"; MsgChA += RqUrl->GetUrlStr(); MsgChA += "'."; TNotify::OnNotify(Notify, ntInfo, MsgChA); } }
void TSAppSrv::OnHttpRq(const uint64& SockId, const PHttpRq& HttpRq) { // last appropriate error code, start with bad request int ErrStatusCd = THttp::BadRqStatusCd; try { // check http-request correctness - return if error EAssertR(HttpRq->IsOk(), "Bad HTTP request!"); // check url correctness - return if error PUrl RqUrl = HttpRq->GetUrl(); EAssertR(RqUrl->IsOk(), "Bad request URL!"); // extract function name PUrl HttpRqUrl = HttpRq->GetUrl(); TStr FunNm = HttpRqUrl->GetPathSeg(0); // check if we have the function registered if (FunNm == "favicon.ico") { PHttpResp HttpResp = THttpResp::New(THttp::OkStatusCd, THttp::ImageIcoFldVal, false, Favicon.GetSIn()); SendHttpResp(SockId, HttpResp); return; } else if (!FunNm.Empty() && !FunNmToFunH.IsKey(FunNm)) { ErrStatusCd = THttp::ErrNotFoundStatusCd; GetNotify()->OnStatusFmt("[AppSrv] Unknown function '%s'!", FunNm.CStr()); TExcept::Throw("Unknown function '" + FunNm + "'!"); } // extract parameters TStrKdV FldNmValPrV; PUrlEnv HttpRqUrlEnv = HttpRq->GetUrlEnv(); const int Keys = HttpRqUrlEnv->GetKeys(); for (int KeyN = 0; KeyN < Keys; KeyN++) { TStr KeyNm = HttpRqUrlEnv->GetKeyNm(KeyN); const int Vals = HttpRqUrlEnv->GetVals(KeyN); for (int ValN = 0; ValN < Vals; ValN++) { TStr Val = HttpRqUrlEnv->GetVal(KeyN, ValN); FldNmValPrV.Add(TStrKd(KeyNm, Val)); } } // report call if (ShowParamP) { GetNotify()->OnStatus(" " + HttpRq->GetUrl()->GetUrlStr()); } // request parsed well, from now on it's internal error ErrStatusCd = THttp::InternalErrStatusCd; // processed requested function if (!FunNm.Empty()) { // prepare request environment PSAppSrvRqEnv RqEnv = TSAppSrvRqEnv::New(this, SockId, HttpRq, FunNmToFunH); // retrieve function PSAppSrvFun SrvFun = FunNmToFunH.GetDat(FunNm); // call function SrvFun->Exec(FldNmValPrV, RqEnv); } else { // internal SAppSrv call if (!ListFunP) { // we are not allowed to list functions ErrStatusCd = THttp::ErrNotFoundStatusCd; TExcept::Throw("Unknown page"); } // prepare a list of registered functions PXmlTok TopTok = TXmlTok::New("registered-functions"); int KeyId = FunNmToFunH.FFirstKeyId(); while (FunNmToFunH.FNextKeyId(KeyId)) { PXmlTok FunTok = TXmlTok::New("function"); FunTok->AddArg("name", FunNmToFunH.GetKey(KeyId)); TopTok->AddSubTok(FunTok); } TStr ResXmlStr; TXmlDoc::New(TopTok)->SaveStr(ResXmlStr); PSIn BodySIn = TMIn::New(TSAppSrvFun::XmlHdStr + ResXmlStr); // prepare response PHttpResp HttpResp = THttpResp::New(THttp::OkStatusCd, THttp::TextXmlFldVal, false, BodySIn); // send response SendHttpResp(SockId, HttpResp); } } catch (PExcept Except) { // known internal error PXmlTok TopTok = TXmlTok::New("error"); TopTok->AddSubTok(TXmlTok::New("message", Except->GetMsgStr())); TopTok->AddSubTok(TXmlTok::New("location", Except->GetLocStr())); PXmlDoc ErrorXmlDoc = TXmlDoc::New(TopTok); TStr ResXmlStr; ErrorXmlDoc->SaveStr(ResXmlStr); // prepare response PHttpResp HttpResp = THttpResp::New(ErrStatusCd, THttp::TextHtmlFldVal, false, TMIn::New(TSAppSrvFun::XmlHdStr + ResXmlStr)); // send response SendHttpResp(SockId, HttpResp); } catch (...) { // unknown internal error PXmlDoc ErrorXmlDoc = TXmlDoc::New(TXmlTok::New("error")); TStr ResXmlStr; ErrorXmlDoc->SaveStr(ResXmlStr); // prepare response PHttpResp HttpResp = THttpResp::New(ErrStatusCd, THttp::TextHtmlFldVal, false, TMIn::New(TSAppSrvFun::XmlHdStr + ResXmlStr)); // send response SendHttpResp(SockId, HttpResp); } }
void TSAppSrv::OnHttpRq(const int& SockId, const PHttpRq& HttpRq) { PHttpResp HttpResp; try { // check http-request correctness - return if error EAssertR(HttpRq->IsOk(), "Bad HTTP request!"); // check url correctness - return if error PUrl RqUrl = HttpRq->GetUrl(); EAssertR(RqUrl->IsOk(), "Bad request URL!"); // extract function name PUrl HttpRqUrl = HttpRq->GetUrl(); TStr FunNm = HttpRqUrl->GetPathSeg(0); EAssertR(FunNmToFunH.IsKey(FunNm) || FunNm.Empty(), "Unknown function '" + FunNm + "' !"); // extract parameters TStrKdV FldNmValPrV; PUrlEnv HttpRqUrlEnv = HttpRq->GetUrlEnv(); const int Keys = HttpRqUrlEnv->GetKeys(); for (int KeyN = 0; KeyN < Keys; KeyN++) { TStr KeyNm = HttpRqUrlEnv->GetKeyNm(KeyN); const int Vals = HttpRqUrlEnv->GetVals(KeyN); for (int ValN = 0; ValN < Vals; ValN++) { TStr Val = HttpRqUrlEnv->GetVal(KeyN, ValN); FldNmValPrV.Add(TStrKd(KeyNm, Val)); } } // log the call TStr TimeNow = TTm::GetCurLocTm().GetWebLogDateTimeStr(true); GetNotify()->OnStatus(TStr::Fmt("[%s] Request %s", TimeNow.CStr(), FunNm.CStr())); // prepare request environment PSAppSrvRqEnv RqEnv = TSAppSrvRqEnv::New(this, SockId, HttpRq); PSIn BodySIn; TStr ContTypeVal; if (!FunNm.Empty()) { // call function PSAppSrvFun SrvFun = FunNmToFunH.GetDat(FunNm); if (SrvFun->GetFunOutType() == saotXml) { PXmlDoc ResXmlDoc = SrvFun->Exec(FldNmValPrV, RqEnv); TStr ResXmlStr; ResXmlDoc->SaveStr(ResXmlStr); //ResXmlDoc->SaveTxt(TFile::GetUniqueFNm("test.xml")); BodySIn = TMIn::New(XmlHdStr + ResXmlStr); ContTypeVal = THttp::TextXmlFldVal; } else if (SrvFun->GetFunOutType() == saotJSon) { TStr ResStr = SrvFun->ExecJSon(FldNmValPrV, RqEnv); BodySIn = TMIn::New(ResStr); //ContTypeVal = THttp::TextHtmlFldVal; ContTypeVal = THttp::AppJSonFldVal; } else { BodySIn = SrvFun->ExecCustom(FldNmValPrV, RqEnv, ContTypeVal); } } else { PXmlTok TopTok = TXmlTok::New("registered-functions"); int KeyId = FunNmToFunH.FFirstKeyId(); while (FunNmToFunH.FNextKeyId(KeyId)) { PXmlTok FunTok = TXmlTok::New("function"); FunTok->AddArg("name", FunNmToFunH.GetKey(KeyId)); TopTok->AddSubTok(FunTok); } PXmlDoc ResXmlDoc = TXmlDoc::New(TopTok); TStr ResXmlStr; ResXmlDoc->SaveStr(ResXmlStr); BodySIn = TMIn::New(XmlHdStr + ResXmlStr); ContTypeVal = THttp::TextXmlFldVal; } // prepare response HttpResp = THttpResp::New(THttp::OkStatusCd, ContTypeVal, false, BodySIn); // send response } catch (PExcept Except) { PXmlTok TopTok = TXmlTok::New("error"); TopTok->AddSubTok(TXmlTok::New("message", Except->GetMsgStr())); TopTok->AddSubTok(TXmlTok::New("location", Except->GetLocStr())); PXmlDoc ErrorXmlDoc = TXmlDoc::New(TopTok); TStr ResXmlStr; ErrorXmlDoc->SaveStr(ResXmlStr); HttpResp = THttpResp::New(THttp::OkStatusCd, THttp::TextHtmlFldVal, false, TMIn::New(XmlHdStr + ResXmlStr)); } catch (...) { PXmlDoc ErrorXmlDoc = TXmlDoc::New(TXmlTok::New("error")); TStr ResXmlStr; ErrorXmlDoc->SaveStr(ResXmlStr); HttpResp = THttpResp::New(THttp::OkStatusCd, THttp::TextHtmlFldVal, false, TMIn::New(XmlHdStr + ResXmlStr)); } SendHttpResp(SockId, HttpResp); }