void HttpParser::parseHeader() { if (hasHeader() && !bHeaderParsed_) { lHeaders_.Empty(); KeyValueLfBlob2List(sHeader_, lHeaders_); { // Request line Elem* e = lHeaders_.First(); if (e) { sMethod_ = e->getName(); sProtocol_ = e->getString(); sProtocol_.nextToken(" ", sUri_); lHeaders_.Remove(e); delete e; e = 0; } } { // Body size if (0) { } else if (sMethod_ == "GET") { nContentLength_ = 0; } else if (sMethod_ == "HEAD") { nContentLength_ = 0; } else { Elem* e = lHeaders_.FindByNameCase("content-length"); if (e) { nContentLength_ = String::atoi(e->getString()); } } } bHeaderParsed_ = 1; } }
int String::replace(List& lSearchReplace) { int nReplaced = 0; if (!empty()) { Flexbuf<StringPair> list(lSearchReplace.length() + 1); StringPair* pTable = (StringPair*) list; int nCnt = 0; for(Elem* e = 0; (e = lSearchReplace.Next(e));) { pTable[nCnt].szLeft = e->getName(); pTable[nCnt].szRight = e->getString(); nCnt++; } pTable[nCnt].szLeft = 0; pTable[nCnt].szRight = 0; nReplaced = replaceCore(pTable, false); } return nReplaced; }
void Apollo::KeyValueList::fromList(List& l) { for (Elem* e = 0; (e = l.Next(e)) != 0; ) { add(e->getName(), e->getString()); } }
AP_MSG_HANDLER_METHOD(SrpcGateModule, HttpServer_ReceiveRequest) { #define SrpcGateModule_HttpServer_Request_sUriPrefix "/" MODULE_NAME if (Apollo::getModuleConfig(MODULE_NAME, "HTTP/Enabled", 1) && pMsg->sUri.startsWith(SrpcGateModule_HttpServer_Request_sUriPrefix)) { String sUriPrefix = SrpcGateModule_HttpServer_Request_sUriPrefix; try { Apollo::SrpcMessage request; // Params from query String sQuery = pMsg->sUri; String sBase; sQuery.nextToken("?", sBase); List lQuery; KeyValueBlob2List(sQuery, lQuery, "&", "=", ""); for (Elem* e = 0; (e = lQuery.Next(e)) != 0; ) { String sKey = e->getName(); String sValue = e->getString(); sKey.unescape(String::EscapeURL); sValue.unescape(String::EscapeURL); request.set(sKey, sValue); } // Params from body String sBody; pMsg->sbBody.GetString(sBody); List lBody; KeyValueLfBlob2List(sBody, lBody); for (Elem* e = 0; (e = lBody.Next(e)) != 0; ) { String sKey = e->getName(); String sValue = e->getString(); sValue.unescape(String::EscapeCRLF); request.set(sKey, sValue); } // Do the call ApSRPCMessage msg(SRPCGATE_HANDLER_TYPE); request >> msg.srpc; (void) msg.Call(); String sResponse; // Create response if (msg.apStatus == ApMessage::Error) { sResponse = msg.sComment; } else { sResponse = msg.response.toString(); } Msg_HttpServer_SendResponse msgSHR; msgSHR.sbBody.SetData(sResponse); msgSHR.kvHeader.add("Content-type", "text/plain"); msgSHR.hConnection = pMsg->hConnection; msgSHR.kvHeader.add("Pragma", "no-cache"); msgSHR.kvHeader.add("Cache-Control", "no-store, no-cache, must-revalidate, post-check=0, pre-check=0"); msgSHR.kvHeader.add("Expires", "Thu, 19 Nov 1981 08:52:00 GMT"); if (!msgSHR.Request()) { throw ApException(LOG_CONTEXT, "Msg_HttpServer_SendResponse failed: conn=" ApHandleFormat "", ApHandlePrintf(msgSHR.hConnection)); } pMsg->Stop(); pMsg->apStatus = ApMessage::Ok; } catch (ApException& ex) { apLog_Warning((LOG_CHANNEL, LOG_CONTEXT, "%s", _sz(ex.getText()))); Msg_HttpServer_SendResponse msgSHR; msgSHR.hConnection = pMsg->hConnection; msgSHR.nStatus = 500; msgSHR.sMessage = "Internal Error"; msgSHR.kvHeader.add("Content-type", "text/plain"); msgSHR.kvHeader.add("Pragma", "no-cache"); msgSHR.kvHeader.add("Cache-Control", "no-store, no-cache, must-revalidate, post-check=0, pre-check=0"); msgSHR.kvHeader.add("Expires", "Thu, 19 Nov 1981 08:52:00 GMT"); String sBody = ex.getText(); msgSHR.sbBody.SetData(sBody); if (!msgSHR.Request()) { { throw ApException(LOG_CONTEXT, "Msg_HttpServer_SendResponse (for error message) failed: conn=" ApHandleFormat "", ApHandlePrintf(msgSHR.hConnection)); } } else { pMsg->Stop(); pMsg->apStatus = ApMessage::Ok; } } } // sUriPrefix
AP_MSG_HANDLER_METHOD(NetSimModule, NetSim_ContinueHttp) { int ok = 1; Http* pHttp = 0; if (http_.Get(pMsg->hClient, pHttp)) { try { String sIndexFile = Apollo::getModuleConfig(MODULE_NAME, "HTTP/IndexFile", ""); if (!sIndexFile) { throw ApException(LOG_CONTEXT, "No index file name"); } xFile fIndex(sIndexFile); if (!fIndex.Load()) { throw ApException(LOG_CONTEXT, "f.Load(%s) failed", _sz(sIndexFile)); } String sIndex; fIndex.GetData(sIndex); List lDataFiles; KeyValueBlob2List(sIndex, lDataFiles, "\r\n", " ", ""); Elem* e = lDataFiles.FindByName(pHttp->sUrl_); if (!e) { throw ApException(LOG_CONTEXT, "No data file for url=%s", _sz(pHttp->sUrl_)); } String sDataFilename = e->getString(); if (!sDataFilename) { throw ApException(LOG_CONTEXT, "No data file for url=%s", _sz(pHttp->sUrl_)); } String sDataFilepath = Apollo::getModuleConfig(MODULE_NAME, "HTTP/DataFilesBase", ""); sDataFilepath += String::filenamePathSeparator(); sDataFilepath += sDataFilename; xFile fData(sDataFilepath); if (!fData.Load()) { throw ApException(LOG_CONTEXT, "f.Load(%s) failed", _sz(sDataFilepath)); } String sHeaderFilename = sDataFilepath; sHeaderFilename += ".http"; xFile fHeader(sHeaderFilename); if (!fHeader.Load()) { throw ApException(LOG_CONTEXT, "f.Load(%s) failed", _sz(sHeaderFilename)); } { ApAsyncMessage<Msg_Net_HTTP_Connected> msg; msg->hClient = pHttp->hClient_; msg.Post(); } Apollo::Sleep(50); String sHeader; fHeader.GetData(sHeader); { ApAsyncMessage<Msg_Net_HTTP_Header> msg; msg->hClient = pHttp->hClient_; msg->nStatus = 200; List lHeader; KeyValueLfBlob2List(sHeader, lHeader); msg->kvHeader.fromList(lHeader); msg.Post(); } Apollo::Sleep(50); Buffer sbData; fData.GetData(sbData); size_t nSize = 0; while (nSize < sbData.Length()) { int nFragment = sbData.Length() - nSize; if (nFragment > 50000) { nFragment = 50000; } { ApAsyncMessage<Msg_Net_HTTP_DataIn> msg; msg->hClient = pHttp->hClient_; msg->sbData.SetData(sbData.Data() + nSize, nFragment); msg.Post(); } Apollo::Sleep(50); nSize += nFragment; } } catch (ApException& ex) { apLog_Error((LOG_CHANNEL, LOG_CONTEXT, "%s url=%s", _sz(ex.getText()), _sz(pHttp->sUrl_))); ApAsyncMessage<Msg_Net_HTTP_Failed> msg; msg->hClient = pHttp->hClient_; msg->sMessage = ex.getText(); msg.Post(); ok = 0; } { ApAsyncMessage<Msg_Net_HTTP_Closed> msg; msg->hClient = pHttp->hClient_; msg.Post(); } if (http_.Unset(pMsg->hClient)) { delete pHttp; pHttp = 0; } } pMsg->apStatus = ok ? ApMessage::Ok : ApMessage::Error; }