Project

General

Profile

Bug #11301 » 0002-WT-11301-add-WServer-addResource-taking-a-shared_ptr.patch

Roel Standaert, 03/08/2023 04:27 PM

View differences:

ReleaseNotes.html
71 71
    When the user tries to log in now, an info message will be shown saying they need to verify their email first along with a new button to resend the verification email. The user must then enter the email address again in a dialog before the email is sent.<br/>
72 72
    The virtual methods <a href="classWt_1_1Auth_1_1AuthWidget.html#a42f87508868746e5ccef5695fcbd8763">AuthWidget::letResendEmailVerification()</a> and <a href="classWt_1_1Auth_1_1AuthWidget.html#af45dea06ac5751e96499d62507fea69d">AuthWidget::createResendEmailVerificationView()</a> can be used to customize the UI.
73 73
  </li>
74
  <li>
75
    <a href="classWt_1_1WServer.html#aa17f85dc130b616b3fcf63aa857ff579">WServer::addResource()</a>
76
    can now take a <code>shared_ptr</code> instead of a raw pointer,
77
    enforcing that the resource lives at least as long as the server, unless removed with
78
    <a href="classWt_1_1WServer.html#a9f5a82118198a1d2341fb89572fd8693">WServer::removeEntryPoint()</a>.
79
    The overload that takes a raw pointer is now deprecated.
80
    This also fixes <a href="https://redmine.webtoolkit.eu/issues/11301" target="_blank">issue #11301</a>, where there
81
    could be a use-after-free in <code>test.http</code>.
82
  </li>
74 83
</ul>
75 84

  
76 85
<h2>Release 4.9.2 (TBD)</h2>
examples/blog/blog.C
44 44
    std::unique_ptr<Wt::Dbo::SqlConnectionPool> blogDb
45 45
      = BlogSession::createConnectionPool(server.appRoot() + "blog.db");
46 46

  
47
    BlogRSSFeed rssFeed(*blogDb, "Wt blog example", "", "It's just an example.");
47
    auto rssFeed = std::make_shared<BlogRSSFeed>(*blogDb, "Wt blog example", "", "It's just an example.");
48 48

  
49
    server.addResource(&rssFeed, FeedUrl);
49
    server.addResource(rssFeed, FeedUrl);
50 50
    //When the blog application is deployed in ISAPI on the path "/blog"
51 51
    //the resources (css+images) are not fetched correctly
52 52
    server.addEntryPoint(Wt::EntryPointType::Application,
examples/feature/oidc/Oidc.C
103 103
  });
104 104

  
105 105
  Session tokenSession(dbPath);
106
  Wt::Auth::OAuthTokenEndpoint tokenEndpoint{tokenSession.users(), deployUrl};
107
  server.addResource(&tokenEndpoint, "/oauth2/token");
106
  auto tokenEndpoint = std::make_shared<Wt::Auth::OAuthTokenEndpoint>(tokenSession.users(), deployUrl);
107
  server.addResource(tokenEndpoint, "/oauth2/token");
108 108

  
109 109
  Session userInfoSession(dbPath);
110
  Wt::Auth::OidcUserInfoEndpoint userInfoEndpoint{userInfoSession.users()};
111
  server.addResource(&userInfoEndpoint, "/oidc/userinfo");
110
  auto userInfoEndpoint = std::make_shared<Wt::Auth::OidcUserInfoEndpoint>(userInfoSession.users());
111
  server.addResource(userInfoEndpoint, "/oidc/userinfo");
112 112

  
113 113
  Session::configureAuth();
114 114

  
examples/feature/urlparams/urlparams.C
45 45

  
46 46
int main(int argc, char *argv[])
47 47
{
48
  Resource resource;
49

  
50 48
  try {
51 49
    Wt::WServer server{argc, argv, WTHTTP_CONFIGURATION};
52 50

  
53
    server.addResource(&resource, "/users");
54
    server.addResource(&resource, "/users/${user}");
55
    server.addResource(&resource, "/users/${user}/posts");
56
    server.addResource(&resource, "/users/${user}/posts/${post}");
51
    auto resource = std::make_shared<Resource>();
52

  
53
    server.addResource(resource, "/users");
54
    server.addResource(resource, "/users/${user}");
55
    server.addResource(resource, "/users/${user}/posts");
56
    server.addResource(resource, "/users/${user}/posts/${post}");
57 57

  
58 58
    server.run();
59 59
  } catch (const Wt::WServer::Exception &e) {
examples/te-benchmark/benchmark.cpp
337 337
    bundle->use(server.appRoot() + "fortunes");
338 338
    server.setLocalizedStrings(bundle);
339 339

  
340
    JsonResource jsonResource;
341
    server.addResource(&jsonResource, "/json");
340
    server.addResource(std::make_shared<JsonResource>(), "/json");
342 341

  
343
    DbResource dbResource;
344
    server.addResource(&dbResource, "/db");
342
    server.addResource(std::make_shared<DbResource>(), "/db");
345 343

  
346
    QueriesResource queriesResource;
347
    server.addResource(&queriesResource, "/queries");
344
    server.addResource(std::make_shared<QueriesResource>(), "/queries");
348 345

  
349
    FortuneResource fortuneResource;
350
    server.addResource(&fortuneResource, "/fortune");
346
    server.addResource(std::make_shared<FortuneResource>(), "/fortune");
351 347

  
352
    UpdateResource updateResource;
353
    server.addResource(&updateResource, "/updates");
348
    server.addResource(std::make_shared<UpdateResource>(), "/updates");
354 349

  
355
    PlaintextResource plaintextResource;
356
    server.addResource(&plaintextResource, "/plaintext");
350
    server.addResource(std::make_shared<PlaintextResource>(), "/plaintext");
357 351

  
358 352
    if (server.start()) {
359 353
      int sig = Wt::WServer::waitForShutdown();
examples/wt-homepage/main.C
26 26
    std::unique_ptr<Dbo::SqlConnectionPool> blogDb
27 27
      = BlogSession::createConnectionPool(server.appRoot() + "blog.db");
28 28

  
29
    BlogRSSFeed rssFeed(*blogDb, "Wt and JWt blog",
30
                        "http://www.webtoolkit.eu/wt/blog",
31
                        "We care about our webtoolkits.");
29
    auto rssFeed = std::make_shared<BlogRSSFeed>(*blogDb,
30
                                                 "Wt and JWt blog",
31
                                                 "http://www.webtoolkit.eu/wt/blog",
32
                                                 "We care about our webtoolkits.");
32 33

  
33
    server.addResource(&rssFeed, "/wt/blog/feed/");
34
    server.addResource(rssFeed, "/wt/blog/feed/");
34 35

  
35 36
    server.addEntryPoint(EntryPointType::Application,
36 37
                         std::bind(&createJWtHomeApplication, std::placeholders::_1, blogDb.get()),
src/Wt/Auth/OAuthService.C
31 31
#include "WebSession.h"
32 32
#include "WebRequest.h"
33 33

  
34
#include <memory>
35

  
34 36
#ifdef WT_THREADED
35 37
#include <mutex>
36 38
#endif // WT_THREADED
......
608 610
    const OAuthService& service_;
609 611
  };
610 612

  
611
  std::unique_ptr<RedirectEndpoint> redirectResource_;
613
  std::shared_ptr<RedirectEndpoint> redirectResource_;
612 614
  std::string secret_;
613 615
};
614 616

  
......
693 695
    std::unique_lock<std::mutex> guard(impl_->mutex_);
694 696
#endif
695 697
    if (!impl_->redirectResource_) {
696
      auto r = std::unique_ptr<Impl::RedirectEndpoint>(new Impl::RedirectEndpoint(*this));
698
      auto r = std::make_shared<Impl::RedirectEndpoint>(*this);
697 699
      std::string path = redirectEndpointPath();
698 700

  
699 701
      LOG_INFO("deploying endpoint at " << path);
......
704 706
      else
705 707
        server = WServer::instance();
706 708

  
707
      server->addResource(r.get(), path);
709
      server->addResource(r, path);
708 710

  
709
      impl_->redirectResource_ = std::move(r);
711
      impl_->redirectResource_ = r;
710 712
    }
711 713
  }
712 714
}
src/Wt/Auth/Saml/Service.C
391 391

  
392 392
void Service::generateAcsEndpoint()
393 393
{
394
  auto resource = std::make_unique<StaticAcsResource>(*this);
394
  auto resource = std::make_shared<StaticAcsResource>(*this);
395 395
  std::string path = acsPath();
396 396

  
397 397
  LOG_INFO("deploying endpoint at " << path);
......
403 403
    server = WServer::instance();
404 404
  }
405 405

  
406
  server->addResource(resource.get(), path);
407

  
408
  staticAcsResource_ = std::move(resource);
406
  server->addResource(resource, path);
409 407
}
410 408

  
411 409
void Service::generateMetadataEndpoint()
......
413 411
  if (metadataPath_.empty())
414 412
    return;
415 413

  
416
  metadataResource_ = std::make_unique<MetadataResource>(*this);
414
  auto resource = std::make_shared<MetadataResource>(*this);
417 415
  WApplication *app = WApplication::instance();
418 416
  WServer *server = nullptr;
419 417
  if (app) {
......
422 420
    server = WServer::instance();
423 421
  }
424 422

  
425
  server->addResource(metadataResource_.get(), metadataPath_);
423
  server->addResource(resource, metadataPath_);
426 424
}
427 425

  
428 426
std::string Service::metadata() const
src/Wt/Auth/Saml/Service.h
750 750

  
751 751
  // state
752 752
  std::unique_ptr<ServiceImpl> impl_;
753
  std::unique_ptr<StaticAcsResource> staticAcsResource_;
754
  std::unique_ptr<MetadataResource> metadataResource_;
755 753

  
756 754
  // configuration
757 755
  std::string secret_;
src/Wt/WServer.C
279 279
  }
280 280
}
281 281

  
282
void WServer::addResource(const std::shared_ptr<WResource> &resource,
283
                          const std::string &path)
284
{
285
  bool success = configuration().tryAddResource(EntryPoint(resource, prependDefaultPath(path)));
286
  if (success) {
287
    resource->setInternalPath(path);
288
  } else {
289
    WString error(Wt::utf8("WServer::addResource() error: "
290
                           "a static resource was already deployed on path '{1}'"));
291
    throw WServer::Exception(error.arg(path).toUTF8());
292
  }
293
}
294

  
282 295
void WServer::removeEntryPoint(const std::string& path){
283 296
  configuration().removeEntryPoint(path);
284 297
}
src/Wt/WServer.h
300 300
   * public. Use this method to add a public resource with a fixed
301 301
   * path.
302 302
   *
303
   * \throw Exception if an entrypoint was already registered at the given path
304
   *
303 305
   * \sa removeEntryPoint()
304 306
   */
307
  WT_API void addResource(const std::shared_ptr<WResource>& resource, const std::string& path);
308

  
309
  /*! \brief Binds a resource to a fixed path.
310
   *
311
   * Resources may either be private to a single session or
312
   * public. Use this method to add a public resource with a fixed
313
   * path.
314
   *
315
   * \note Ownership of the resource is external to %WServer. The resource first needs
316
   *       to be \link removeEntryPoint() removed\endlink (while the server is
317
   *       \link stop() stopped\endlink) before being destroyed, or has to outlive the %WServer.
318
   *
319
   * \throw Exception if an entrypoint was already registered at the given path
320
   *
321
   * \sa removeEntryPoint()
322
   *
323
   * \deprecated Use addResource(const std::shared_ptr<WResource>&, const std::string&) instead.
324
   */
325
  WT_DEPRECATED("Use addResource(const std::shared_ptr<WResource>&, const std::string&) instead")
305 326
  WT_API void addResource(WResource *resource, const std::string& path);
306 327

  
307 328
  /*! \brief Removes an entry point.
src/web/EntryPoint.C
18 18
    path_(path)
19 19
{ }
20 20

  
21
EntryPoint::EntryPoint(const std::shared_ptr<WResource>& resource, const std::string& path)
22
  : type_(EntryPointType::StaticResource),
23
    resource_(resource.get()),
24
    ownedResource_(resource),
25
    appCallback_(nullptr),
26
    path_(path)
27
{ }
28

  
21 29
EntryPoint::~EntryPoint()
22 30
{
23 31
}
src/web/EntryPoint.h
20 20
             const std::string& path,
21 21
             const std::string& favicon);
22 22
  EntryPoint(WResource *resource, const std::string& path);
23
  EntryPoint(const std::shared_ptr<WResource>& resource, const std::string& path);
23 24
  ~EntryPoint();
24 25

  
25 26
  void setPath(const std::string& path);
......
33 34
private:
34 35
  EntryPointType type_;
35 36
  WResource *resource_;
37
  std::shared_ptr<WResource> ownedResource_;
36 38
  ApplicationCreator appCallback_;
37 39
  std::string path_;
38 40
  std::string favicon_;
test/http/HttpClientServerTest.C
151 151
            "--docroot", "." 
152 152
          };
153 153
      setServerConfiguration(argc, (char **)argv);
154
      addResource(&resource_, "/test");
154
      resource_ = std::make_shared<TestResource>();
155
      addResource(resource_, "/test");
155 156
    }
156 157

  
157 158
    std::string address() 
......
159 160
      return "127.0.0.1:" + std::to_string(httpPort());
160 161
    }
161 162

  
162
    TestResource& resource() { return resource_; }
163
    TestResource& resource() { return *resource_; }
163 164

  
164 165
  private:
165
    TestResource resource_;
166
    std::shared_ptr<TestResource> resource_;
166 167
  };
167 168

  
168 169
  class Client : public Wt::WObject {
169
- 
(3-3/4)