Project

General

Profile

Feature #8321 ยป 0001-WIP-WResource-sequences-and-setInvalidAfterChanged.patch

Bruce Toll, 04/08/2021 05:37 PM

View differences:

src/Wt/WApplication.C
sizes(aSizes), disabled(aDisabled)
{ }
WApplication::ExposedResourceInfo::ExposedResourceInfo(WResource* resource,
unsigned long sequence)
: resource(resource), sequence(sequence)
{ }
bool WApplication::ScriptLibrary::operator< (const ScriptLibrary& other) const
{
return uri < other.uri;
......
std::string WApplication::addExposedResource(WResource *resource)
{
exposedResources_[resourceMapKey(resource)] = resource;
ExposedResourceInfo exposedResourceInfo(resource);
std::string key = resourceMapKey(resource);
ResourceMap::const_iterator i = exposedResources_.find(key);
if (i != exposedResources_.end())
exposedResourceInfo = i->second;
exposedResourceInfo.sequence++;
exposedResources_[key] = exposedResourceInfo;
std::string fn = resource->suggestedFileName().toUTF8();
if (!fn.empty() && fn[0] != '/')
fn = '/' + fn;
static unsigned long seq = 0;
if (resource->internalPath().empty())
return session_->mostRelativeUrl(fn)
+ "&request=resource&resource=" + Utils::urlEncode(resource->id())
+ "&rand=" + std::to_string(seq++);
+ "&rand=" + std::to_string(exposedResourceInfo.sequence);
else {
fn = resource->internalPath() + fn;
if (!session_->applicationName().empty() && fn[0] != '/')
......
std::string key = resourceMapKey(resource);
ResourceMap::iterator i = exposedResources_.find(key);
if (i != exposedResources_.end() && i->second == resource) {
if (i != exposedResources_.end() && i->second.resource == resource) {
#ifndef WT_TARGET_JAVA
exposedResources_.erase(i);
#else
......
ResourceMap::const_iterator i = exposedResources_.find(resourceKey);
if (i != exposedResources_.end())
return i->second;
return i->second.resource;
else {
std::size_t j = resourceKey.rfind('/');
if (j != std::string::npos && j > 1)
......
}
}
WResource *WApplication::decodeExposedResource(const std::string& resourceKey,
unsigned long rand) const
{
ResourceMap::const_iterator i = exposedResources_.find(resourceKey);
WResource *resource = nullptr;
if (i != exposedResources_.end())
resource = i->second.resource;
if (resource
&& resource->invalidAfterChanged()
&& (i->second.sequence != rand))
resource = nullptr;
return resource;
}
std::string WApplication::encodeObject(WObject *object)
{
std::string result = "w" + object->uniqueId();
src/Wt/WApplication.h
bool disabled;
};
struct ExposedResourceInfo {
ExposedResourceInfo(WResource* resource=nullptr, unsigned long sequence=0);
WResource* resource;
unsigned long sequence;
};
#ifndef WT_TARGET_JAVA
typedef std::map<std::string, EventSignalBase *> SignalMap;
typedef std::map<std::string, WResource *> ResourceMap;
typedef std::map<std::string, ExposedResourceInfo> ResourceMap;
#else
typedef std::weak_value_map<std::string, EventSignalBase *> SignalMap;
typedef std::weak_value_map<std::string, WResource *> ResourceMap;
typedef std::weak_value_map<std::string, ExposedResourceInfo> ResourceMap;
#endif
typedef std::map<std::string, WObject *> ObjectMap;
......
std::string addExposedResource(WResource *resource);
bool removeExposedResource(WResource *resource);
WResource *decodeExposedResource(const std::string& resourceMapKey) const;
WResource *decodeExposedResource(const std::string& resourceMapKey,
unsigned long rand) const;
/*
* Methods for application state handling
src/Wt/WResource.C
WResource::WResource()
: trackUploadProgress_(false),
takesUpdateLock_(false),
invalidAfterChanged_(false),
dispositionType_(ContentDisposition::None),
app_(nullptr)
{
......
dataChanged_.emit();
}
void WResource::setInvalidAfterChanged(bool enabled)
{
invalidAfterChanged_ = enabled;
}
const std::string& WResource::url() const
{
if (currentUrl_.empty())
src/Wt/WResource.h
*
* This does not work when the resource is deployed at an internal path using
* setInternalPath().
*
* \sa setInvalidAfterChanged()
*/
void setChanged();
/*! \brief Return "page not found" for prior resource URLs after change
*
* This option invalidates earlier versions of the resource url prior to
* the last call of setChanged().
*
* This does not work when the resource is deployed at an internal path using
* setInternalPath().
*
* \sa setChanged()
*/
void setInvalidAfterChanged(bool enabled);
/*! \brief Should "page not found" be returned for outdated resource URLs
*
* \sa setInvalidAfterChanged()
*/
bool invalidAfterChanged() const { return invalidAfterChanged_; }
/*! \brief Sets an internal path for this resource.
*
* Using this method you can deploy the resource at a fixed path. Unless
......
bool trackUploadProgress_;
bool takesUpdateLock_;
bool invalidAfterChanged_;
std::vector<Http::ResponseContinuationPtr> continuations_;
src/web/WebSession.C
const std::string *resourceE = request.getParameter("resource");
const std::string *signalE = getSignal(request, "");
const std::string *randE = request.getParameter("rand");
if (signalE)
progressiveBoot_ = false;
......
"<body> </body></html>";
handler.flushResponse();
} else {
if (!resource)
resource = app_->decodeExposedResource(*resourceE);
if (!resource) {
long rand = 0;
try {
if (randE)
rand = Utils::stol(*randE);
} catch (std::invalid_argument) {
rand = 0;
}
resource = app_->decodeExposedResource(*resourceE, rand);
}
if (resource) {
try {
......
<< "' not exposed");
handler.response()->setContentType("text/html");
handler.response()->out() <<
"<html><body><h1>Nothing to say about that.</h1></body></html>";
"<html><body><h1>Page not found.</h1></body></html>";
handler.response()->setStatus(404);
handler.flushResponse();
}
}
    (1-1/1)