void run() { try { ndn::Data dataPacket = createDataPacket(); if (m_isForceDataSet) { m_face.put(dataPacket); m_isDataSent = true; } else { m_face.setInterestFilter(m_prefixName, bind(&NdnTlvPoke::onInterest, this, _1, _2, dataPacket), ndn::RegisterPrefixSuccessCallback(), bind(&NdnTlvPoke::onRegisterFailed, this, _1, _2)); } if (m_timeout < ndn::time::milliseconds::zero()) m_face.processEvents(getDefaultTimeout()); else m_face.processEvents(m_timeout); } catch (std::exception& e) { std::cerr << "ERROR: " << e.what() << "\n" << std::endl; exit(1); } }
void HttpRequestHandler::handleRequest(Transport *transport) { ExecutionProfiler ep(ThreadInfo::RuntimeFunctions); Logger::OnNewRequest(); GetAccessLog().onNewRequest(); transport->enableCompression(); ServerStatsHelper ssh("all", ServerStatsHelper::TRACK_MEMORY); Logger::Verbose("receiving %s", transport->getCommand().c_str()); // will clear all extra logging when this function goes out of scope StackTraceNoHeap::ExtraLoggingClearer clearer; StackTraceNoHeap::AddExtraLogging("URL", transport->getUrl()); // resolve virtual host const VirtualHost *vhost = HttpProtocol::GetVirtualHost(transport); assert(vhost); if (vhost->disabled() || vhost->isBlocking(transport->getCommand(), transport->getRemoteHost())) { transport->sendString("Not Found", 404); return; } // don't serve the request if it's been sitting in queue for longer than our // allowed request timeout. int requestTimeoutSeconds = vhost->getRequestTimeoutSeconds(getDefaultTimeout()); if (requestTimeoutSeconds > 0) { timespec now; Timer::GetMonotonicTime(now); const timespec& queueTime = transport->getQueueTime(); if (gettime_diff_us(queueTime, now) > requestTimeoutSeconds * 1000000) { transport->sendString("Service Unavailable", 503); m_requestTimedOutOnQueue->addValue(1); return; } } ServerStats::StartRequest(transport->getCommand().c_str(), transport->getRemoteHost(), vhost->getName().c_str()); // resolve source root string host = transport->getHeader("Host"); SourceRootInfo sourceRootInfo(host.c_str()); if (sourceRootInfo.error()) { sourceRootInfo.handleError(transport); return; } // request URI string pathTranslation = m_pathTranslation ? vhost->getPathTranslation().c_str() : ""; RequestURI reqURI(vhost, transport, sourceRootInfo.path(), pathTranslation); if (reqURI.done()) { return; // already handled with redirection or 404 } string path = reqURI.path().data(); string absPath = reqURI.absolutePath().data(); // determine whether we should compress response bool compressed = transport->decideCompression(); const char *data; int len; const char *ext = reqURI.ext(); if (reqURI.forbidden()) { transport->sendString("Forbidden", 403); return; } bool cachableDynamicContent = (!RuntimeOption::StaticFileGenerators.empty() && RuntimeOption::StaticFileGenerators.find(path) != RuntimeOption::StaticFileGenerators.end()); // If this is not a php file, check the static and dynamic content caches if (ext && strcasecmp(ext, "php") != 0) { if (RuntimeOption::EnableStaticContentCache) { bool original = compressed; // check against static content cache if (StaticContentCache::TheCache.find(path, data, len, compressed)) { Util::ScopedMem decompressed_data; // (qigao) not calling stat at this point because the timestamp of // local cache file is not valuable, maybe misleading. This way // the Last-Modified header will not show in response. // stat(RuntimeOption::FileCache.c_str(), &st); if (!original && compressed) { data = gzdecode(data, len); if (data == nullptr) { throw FatalErrorException("cannot unzip compressed data"); } decompressed_data = const_cast<char*>(data); compressed = false; } sendStaticContent(transport, data, len, 0, compressed, path, ext); StaticContentCache::TheFileCache->adviseOutMemory(); ServerStats::LogPage(path, 200); GetAccessLog().log(transport, vhost); return; } } if (RuntimeOption::EnableStaticContentFromDisk) { String translated = File::TranslatePath(String(absPath)); if (!translated.empty()) { CstrBuffer sb(translated.data()); if (sb.valid()) { struct stat st; st.st_mtime = 0; stat(translated.data(), &st); sendStaticContent(transport, sb.data(), sb.size(), st.st_mtime, false, path, ext); ServerStats::LogPage(path, 200); GetAccessLog().log(transport, vhost); return; } } } // check static contents that were generated by dynamic pages if (cachableDynamicContent) { // check against dynamic content cache assert(transport->getUrl()); string key = path + transport->getUrl(); if (DynamicContentCache::TheCache.find(key, data, len, compressed)) { sendStaticContent(transport, data, len, 0, compressed, path, ext); ServerStats::LogPage(path, 200); GetAccessLog().log(transport, vhost); return; } } } // proxy any URLs that not specified in ServeURLs if (!RuntimeOption::ProxyOrigin.empty() && ((RuntimeOption::UseServeURLs && RuntimeOption::ServeURLs.find(path) == RuntimeOption::ServeURLs.end()) || (RuntimeOption::UseProxyURLs && (RuntimeOption::ProxyURLs.find(path) != RuntimeOption::ProxyURLs.end() || MatchAnyPattern(path, RuntimeOption::ProxyPatterns) || (abs(rand()) % 100) < RuntimeOption::ProxyPercentage)))) { for (int i = 0; i < RuntimeOption::ProxyRetry; i++) { bool force = (i == RuntimeOption::ProxyRetry - 1); // last one if (handleProxyRequest(transport, force)) break; } return; } // record request for debugging purpose std::string tmpfile = HttpProtocol::RecordRequest(transport); // main body hphp_session_init(); ThreadInfo::s_threadInfo->m_reqInjectionData. setTimeout(requestTimeoutSeconds); bool ret = false; try { ret = executePHPRequest(transport, reqURI, sourceRootInfo, cachableDynamicContent); } catch (const Eval::DebuggerException &e) { transport->sendString(e.what(), 200); transport->onSendEnd(); hphp_context_exit(g_context.getNoCheck(), true, true, transport->getUrl()); } catch (...) { Logger::Error("Unhandled exception in HPHP server engine."); } GetAccessLog().log(transport, vhost); /* * HPHP logs may need to access data in ServerStats, so we have to * clear the hashtable after writing the log entry. */ ServerStats::Reset(); hphp_session_exit(); HttpProtocol::ClearRecord(ret, tmpfile); }
void RPCRequestHandler::handleRequest(Transport *transport) { if (needReset()) { cleanupState(); initState(); } ++m_requestsSinceReset; ExecutionProfiler ep(ThreadInfo::RuntimeFunctions); Logger::OnNewRequest(); HttpRequestHandler::GetAccessLog().onNewRequest(); m_context->setTransport(transport); transport->enableCompression(); ServerStatsHelper ssh("all", ServerStatsHelper::TRACK_MEMORY); Logger::Verbose("receiving %s", transport->getCommand().c_str()); // will clear all extra logging when this function goes out of scope StackTraceNoHeap::ExtraLoggingClearer clearer; StackTraceNoHeap::AddExtraLogging("RPC-URL", transport->getUrl()); // authentication const set<string> &passwords = m_serverInfo->getPasswords(); if (!passwords.empty()) { set<string>::const_iterator iter = passwords.find(transport->getParam("auth")); if (iter == passwords.end()) { transport->sendString("Unauthorized", 401); transport->onSendEnd(); HttpRequestHandler::GetAccessLog().log(transport, nullptr); /* * HPHP logs may need to access data in ServerStats, so we have to * clear the hashtable after writing the log entry. */ ServerStats::Reset(); return; } } else { const string &password = m_serverInfo->getPassword(); if (!password.empty() && password != transport->getParam("auth")) { transport->sendString("Unauthorized", 401); transport->onSendEnd(); HttpRequestHandler::GetAccessLog().log(transport, nullptr); /* * HPHP logs may need to access data in ServerStats, so we have to * clear the hashtable after writing the log entry. */ ServerStats::Reset(); return; } } // return encoding type ReturnEncodeType returnEncodeType = m_returnEncodeType; if (transport->getParam("return") == "serialize") { returnEncodeType = ReturnEncodeType::Serialize; } // resolve virtual host const VirtualHost *vhost = HttpProtocol::GetVirtualHost(transport); assert(vhost); if (vhost->disabled()) { transport->sendString("Virtual host disabled.", 404); transport->onSendEnd(); HttpRequestHandler::GetAccessLog().log(transport, vhost); return; } ThreadInfo::s_threadInfo->m_reqInjectionData. setTimeout(vhost->getRequestTimeoutSeconds(getDefaultTimeout())); // resolve source root string host = transport->getHeader("Host"); SourceRootInfo sourceRootInfo(host.c_str()); // set thread type switch (m_serverInfo->getType()) { case SatelliteServer::Type::KindOfRPCServer: transport->setThreadType(Transport::ThreadType::RpcThread); break; case SatelliteServer::Type::KindOfXboxServer: transport->setThreadType(Transport::ThreadType::XboxThread); break; default: break; } // record request for debugging purpose std::string tmpfile = HttpProtocol::RecordRequest(transport); bool ret = executePHPFunction(transport, sourceRootInfo, returnEncodeType); HttpRequestHandler::GetAccessLog().log(transport, vhost); /* * HPHP logs may need to access data in ServerStats, so we have to * clear the hashtable after writing the log entry. */ ServerStats::Reset(); HttpProtocol::ClearRecord(ret, tmpfile); }