Project

General

Profile

Bug #9106 » 0003-Fix-webrequest-leak-with-websockets-due-to-race.patch

Outdated, consider 0004 version instead - Bruce Toll, 09/24/2021 07:49 PM

View differences:

src/http/HTTPRequest.C
return p->request().url_params;
}
void HTTPRequest::setWebSession(WebSessionPtr webSession)
{
reply_->setWebSession(webSession);
}
} // namespace server
} // namespace http
src/http/HTTPRequest.h
bool isSynchronous() const;
virtual Wt::WSslInfo *sslInfo() const override;
virtual const std::vector<std::pair<std::string, std::string> > &urlParams() const override;
virtual void setWebSession(WebSessionPtr webSession) override;
private:
WtReplyPtr reply_;
src/http/WtReply.C
#include "WtReply.h"
#include "StockReply.h"
#include "HTTPRequest.h"
#include "WebSession.h"
#include "WebController.h"
#include "Server.h"
#include "WebUtils.h"
......
out_buf_.consume(sending_);
sending_ = 0;
if (webSessionLock_) {
LOG_DEBUG("WtReply::writeDone webSessionLock_ about to set null, currently: " << webSessionLock_.get());
webSessionLock_ = nullptr;
}
if (fetchMoreDataCallback_) {
Wt::WebRequest::WriteCallback f = fetchMoreDataCallback_;
fetchMoreDataCallback_ = nullptr;
......
{
LOG_DEBUG("WtReply::send(): " << sending_);
webSessionLock_ = webSessionWeakPtr_.lock();
LOG_DEBUG("WtReply::send set webSessionLock_ to: " << webSessionLock_.get());
fetchMoreDataCallback_ = callBack;
if (sending_ != 0) {
......
}
void WtReply::setWebSession(Wt::WebRequest::WebSessionPtr webSession)
{
webSessionWeakPtr_ = webSession;
}
#ifdef WTHTTP_WITH_ZLIB
bool WtReply::initDeflate()
src/http/WtReply.h
#include "Reply.h"
#include "../web/Configuration.h"
#include "../web/WebRequest.h"
#include "../web/WebSession.h"
#ifdef WTHTTP_WITH_ZLIB
#include <zlib.h>
......
bool responseComplete);
void readWebSocketMessage(const Wt::WebRequest::ReadCallback& callBack);
bool readAvailable();
void setWebSession(Wt::WebRequest::WebSessionPtr webSession);
std::istream& in() { return *in_; }
std::ostream& out() { return out_; }
......
bool initDeflate();
z_stream zOutState_;
std::weak_ptr<Wt::WebSession> webSessionWeakPtr_;
Wt::WebRequest::WebSessionPtr webSessionLock_;
#endif
};
src/web/WebRequest.C
return urlParams_;
}
void WebRequest::setWebSession(WebSessionPtr webSession)
{
throw WException("should not get here");
}
}
src/web/WebRequest.h
typedef std::function<void(WebReadEvent)> ReadCallback;
typedef std::function<void(void)> DisconnectCallback;
typedef std::shared_ptr<Wt::WebSession> WebSessionPtr;
/*
* Signal that the response should be flushed.
*
......
virtual WSslInfo *sslInfo() const = 0;
virtual const std::vector<std::pair<std::string, std::string> >& urlParams() const;
virtual void setWebSession(WebSessionPtr webSession);
protected:
const EntryPoint *entryPoint_;
src/web/WebSession.C
#include "Wt/WServer.h"
#include "Wt/WTimerWidget.h"
#include "Wt/Http/Request.h"
#include "http/HTTPRequest.h"
#include "CgiParser.h"
#include "Configuration.h"
......
}
if (webSocket_) {
LOG_DEBUG("~WebSession: before webSocket_ flush/null");
webSocket_->flush();
webSocket_ = nullptr;
LOG_DEBUG("~WebSession: after webSocket_ flush/null");
}
if (deferredResponse_) {
......
void WebSession::kill()
{
state_ = State::Dead;
if (webSocket_)
webSocket_->setWebSession(shared_from_this());
/*
* Unlock the recursive eventloop that may be pending.
(3-3/4)