Feature #7598 » 0003-Add-weakSessionId-support-for-dedicated-sessions.patch
| src/http/ProxyReply.C | ||
|---|---|---|
|
webSocketConnection = true;
|
||
|
}
|
||
|
} else if (boost::iequals(name, "X-Wt-Session")) {
|
||
|
sessionManager_.addSessionProcess(value, sessionProcess_);
|
||
|
std::vector<std::string> id_v;
|
||
|
boost::split(id_v, value, boost::is_any_of(","));
|
||
|
if (id_v.size() != 2) {
|
||
|
LOG_ERROR("unexpected X-Wt-Session header value: " << value);
|
||
|
if (!sendReload())
|
||
|
error(internal_server_error);
|
||
|
return;
|
||
|
}
|
||
|
sessionManager_.addSessionProcess(id_v[0], id_v[1], sessionProcess_);
|
||
|
} else if (boost::iequals(name, "Upgrade")) {
|
||
|
// Remove hop-by-hop header
|
||
|
if (boost::icontains(value, "websocket")) {
|
||
| src/http/SessionProcess.C | ||
|---|---|---|
|
sessionId_ = sessionId;
|
||
|
}
|
||
|
void SessionProcess::setWeakSessionId(const std::string& weakSessionId)
|
||
|
{
|
||
|
weakSessionId_ = weakSessionId;
|
||
|
}
|
||
|
asio::ip::tcp::endpoint SessionProcess::endpoint() const
|
||
|
{
|
||
|
return asio::ip::tcp::endpoint(asio::ip::address_v4::loopback(), port_);
|
||
| src/http/SessionProcess.h | ||
|---|---|---|
|
const std::string& sessionId() const { return sessionId_; }
|
||
|
void setSessionId(const std::string& sessionId);
|
||
|
const std::string& weakSessionId() const { return weakSessionId_; }
|
||
|
void setWeakSessionId(const std::string& weakSessionId);
|
||
|
// Get the endpoint to connect to
|
||
|
asio::ip::tcp::endpoint endpoint() const;
|
||
| ... | ... | |
|
char buf_[6];
|
||
|
std::string sessionId_;
|
||
|
std::string weakSessionId_;
|
||
|
#ifndef WT_WIN32
|
||
|
pid_t pid_;
|
||
|
#else // WT_WIN32
|
||
| src/http/SessionProcessManager.C | ||
|---|---|---|
|
#endif // WT_THREADED
|
||
|
SessionMap::const_iterator it = sessions_.find(sessionId);
|
||
|
if (it != sessions_.end()) {
|
||
|
return it->second;
|
||
|
return it->sessionProcessRef();
|
||
|
}
|
||
|
// Not a valid regular sessionId, perhaps it is a weakSessionId (used for resources)?
|
||
|
SessionMap::index<WeakSessionIdTag>::type::iterator itw =
|
||
|
sessions_.get<WeakSessionIdTag>().find(sessionId);
|
||
|
if (itw != sessions_.get<WeakSessionIdTag>().end()) {
|
||
|
return itw->sessionProcessRef();
|
||
|
}
|
||
|
return nullProcessPtr;
|
||
|
}
|
||
| ... | ... | |
|
}
|
||
|
void SessionProcessManager
|
||
|
::addSessionProcess(std::string sessionId,
|
||
|
::addSessionProcess(std::string sessionId, std::string weakSessionId,
|
||
|
const std::shared_ptr<SessionProcess>& process)
|
||
|
{
|
||
|
#ifdef WT_THREADED
|
||
|
std::unique_lock<std::mutex> lock(sessionsMutex_);
|
||
|
#endif // WT_THREADED
|
||
|
LOG_DEBUG("addSessionProcess()" << sessionId);
|
||
|
LOG_DEBUG("addSessionProcess(): sessionId: " << sessionId << ", weakSessionId" << weakSessionId);
|
||
|
for (SessionProcessList::iterator it = pendingProcesses_.begin();
|
||
|
it != pendingProcesses_.end(); ++it) {
|
||
|
if (process == *it) {
|
||
| ... | ... | |
|
sessions_.erase(process->sessionId());
|
||
|
}
|
||
|
process->setSessionId(sessionId);
|
||
|
sessions_[sessionId] = process;
|
||
|
process->setWeakSessionId(weakSessionId);
|
||
|
sessions_.insert(SessionEntry(sessionId, weakSessionId, process));
|
||
|
}
|
||
|
std::vector<Wt::WServer::SessionInfo> SessionProcessManager::sessions() const
|
||
| ... | ... | |
|
it != sessions_.end(); ++it) {
|
||
|
Wt::WServer::SessionInfo sessionInfo;
|
||
|
#ifndef WT_WIN32
|
||
|
sessionInfo.processId = it->second->pid();
|
||
|
sessionInfo.processId = it->sessionProcessRef()->pid();
|
||
|
#else // WT_WIN32
|
||
|
sessionInfo.processId = it->second->processInfo().dwProcessId;
|
||
|
sessionInfo.processId = it->sessionProcessRef()->processInfo().dwProcessId;
|
||
|
#endif // WT_WIN32
|
||
|
sessionInfo.sessionId = it->first;
|
||
|
sessionInfo.sessionId = it->sessionId();
|
||
|
result.push_back(sessionInfo);
|
||
|
}
|
||
|
return result;
|
||
| ... | ... | |
|
#endif // WT_THREADED
|
||
|
for (SessionMap::iterator it = sessions_.begin();
|
||
|
it != sessions_.end(); ++it) {
|
||
|
if(it->second->pid() == cpid) {
|
||
|
LOG_INFO("Child process " << cpid << " died, removing session " << it->first
|
||
|
if(it->sessionProcessRef()->pid() == cpid) {
|
||
|
LOG_INFO("Child process " << cpid << " died, removing session " << it->sessionId()
|
||
|
<< " (#sessions: " << (sessions_.size() - 1) << ")");
|
||
|
it->second->stop();
|
||
|
it->sessionProcessRef()->stop();
|
||
|
sessions_.erase(it);
|
||
|
-- numSessions_;
|
||
|
return;
|
||
| src/http/SessionProcessManager.h | ||
|---|---|---|
|
namespace http {
|
||
|
namespace server {
|
||
|
typedef std::map<std::string, std::shared_ptr<SessionProcess> > SessionMap;
|
||
|
typedef std::vector<std::shared_ptr<SessionProcess> > SessionProcessList;
|
||
|
/// For dedicated processes: maps session ids to child processes and their sockets
|
||
| ... | ... | |
|
bool tryToIncrementSessionCount();
|
||
|
const std::shared_ptr<SessionProcess>& sessionProcess(std::string sessionId);
|
||
|
void addPendingSessionProcess(const std::shared_ptr<SessionProcess>& process);
|
||
|
void addSessionProcess(std::string sessionId,
|
||
|
void addSessionProcess(std::string sessionId, std::string weakSessionId,
|
||
|
const std::shared_ptr<SessionProcess>& process);
|
||
|
std::vector<Wt::WServer::SessionInfo> sessions() const;
|
||
|
private:
|
||
|
class SessionMap;
|
||
|
class SessionEntry {
|
||
|
public:
|
||
|
SessionEntry(std::string sessionId, std::string weakSessionId, std::shared_ptr<SessionProcess> sessionProcess) :
|
||
|
sessionId_(sessionId), weakSessionId_(weakSessionId), sessionProcess_(sessionProcess) {}
|
||
|
std::string sessionId() const { return sessionId_; }
|
||
|
std::string weakSessionId() const { return weakSessionId_; }
|
||
|
std::shared_ptr<SessionProcess> sessionProcess() const { return sessionProcess_; }
|
||
|
const std::shared_ptr<SessionProcess>& sessionProcessRef() const { return sessionProcess_; }
|
||
|
private:
|
||
|
std::string sessionId_;
|
||
|
std::string weakSessionId_;
|
||
|
std::shared_ptr<SessionProcess> sessionProcess_;
|
||
|
friend class SessionMap;
|
||
|
};
|
||
|
struct SessionIdTag { };
|
||
|
struct WeakSessionIdTag { };
|
||
|
class SessionMap : public boost::multi_index_container<
|
||
|
SessionEntry,
|
||
|
boost::multi_index::indexed_by<
|
||
|
boost::multi_index::ordered_unique<
|
||
|
boost::multi_index::tag<SessionIdTag>,
|
||
|
boost::multi_index::member<SessionEntry, std::string, &SessionEntry::sessionId_>
|
||
|
>,
|
||
|
boost::multi_index::hashed_unique<
|
||
|
boost::multi_index::tag<WeakSessionIdTag>,
|
||
|
boost::multi_index::member<SessionEntry, std::string, &SessionEntry::weakSessionId_>
|
||
|
>
|
||
|
>
|
||
|
>{ };
|
||
|
void processDeadChildren(Wt::AsioWrapper::error_code ec);
|
||
|
#ifndef WT_WIN32
|
||
|
void removeSessionForPid(pid_t cpid);
|
||
| src/web/WebRenderer.C | ||
|---|---|---|
|
#ifndef WT_TARGET_JAVA
|
||
|
const WServer *s = session_.controller()->server();
|
||
|
if (s->dedicatedSessionProcess()) {
|
||
|
response.addHeader("X-Wt-Session", session_.sessionId());
|
||
|
response.addHeader("X-Wt-Session",
|
||
|
session_.sessionId() + "," + session_.weakSessionId());
|
||
|
}
|
||
|
#endif // WT_TARGET_JAVA
|
||