Skip to content

Commit 6af9463

Browse files
author
Koen Deforche
committed
relax need for baseURL property and finalize its documentation
1 parent 18e39c8 commit 6af9463

File tree

4 files changed

+101
-58
lines changed

4 files changed

+101
-58
lines changed

src/Wt/WApplication.C

Lines changed: 3 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -560,45 +560,17 @@ void WApplication::setConfirmCloseMessage(const WString& message)
560560

561561
std::string WApplication::url() const
562562
{
563-
return fixRelativeUrl(session_->applicationUrl());
563+
return fixRelativeUrl(session_->applicationName());
564564
}
565565

566566
std::string WApplication::makeAbsoluteUrl(const std::string& url) const
567567
{
568-
if (url.find("://") != std::string::npos)
569-
return url;
570-
else {
571-
if (!url.empty() && url[0] == '/')
572-
return environment().urlScheme() + "://" + environment().hostName() + url;
573-
else
574-
return session_->absoluteBaseUrl() + url;
575-
}
568+
return session_->makeAbsoluteUrl(url);
576569
}
577570

578571
std::string WApplication::fixRelativeUrl(const std::string& url) const
579572
{
580-
if (url.find("://") != std::string::npos)
581-
return url;
582-
583-
if (url.length() > 0 && url[0] == '#')
584-
return url;
585-
586-
if (session_->type() == Application) {
587-
if (!environment().javaScript()
588-
&& !WebSession::Handler::instance()->request()->pathInfo().empty())
589-
// This will break reverse proxies:
590-
// We could do a '../path/' trick? we could do this to correct
591-
// for the current internal path: as many '../' as there are
592-
// internal path folders. but why bother ? we need to fix URLs
593-
// in external resources anyway for reverse proxies
594-
if (!url.empty() && url[0] == '/')
595-
return /*session_->basePath() + url.substr(1) */ url;
596-
else
597-
return session_->basePath() + url;
598-
else
599-
return url;
600-
} else
601-
return makeAbsoluteUrl(url);
573+
return session_->fixRelativeUrl(url);
602574
}
603575

604576
void WApplication::quit()

src/web/WebSession.C

Lines changed: 67 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,18 @@ namespace {
4848
bool isAbsoluteUrl(const std::string& url) {
4949
return url.find("://") != std::string::npos;
5050
}
51+
52+
std::string host(const std::string& url) {
53+
std::size_t pos = 0;
54+
for (unsigned i = 0; i < 3; ++i) {
55+
pos = url.find('/', pos);
56+
if (pos == std::string::npos)
57+
return url;
58+
else
59+
++pos;
60+
}
61+
return url.substr(0, pos);
62+
}
5163
}
5264

5365
namespace Wt {
@@ -271,6 +283,13 @@ void WebSession::init(const WebRequest& request)
271283
}
272284
#endif
273285

286+
if (useAbsoluteUrls) {
287+
std::string::size_type slashpos = absoluteBaseUrl_.rfind('/');
288+
if (slashpos != std::string::npos
289+
&& slashpos != absoluteBaseUrl_.length() - 1)
290+
absoluteBaseUrl_ = absoluteBaseUrl_.substr(0, slashpos + 1);
291+
}
292+
274293
bookmarkUrl_ = applicationName_;
275294

276295
if (applicationName_.empty())
@@ -349,7 +368,7 @@ std::string WebSession::bootstrapUrl(const WebResponse& response,
349368
}
350369
case ClearInternalPath: {
351370
if (!isAbsoluteUrl(applicationUrl_)) {
352-
if (WebSession::Handler::instance()->request()->pathInfo().length() > 1)
371+
if (pagePathInfo_.length() > 1)
353372
return appendSessionQuery(deploymentPath_);
354373
else
355374
return appendSessionQuery(applicationName_);
@@ -364,6 +383,43 @@ std::string WebSession::bootstrapUrl(const WebResponse& response,
364383
return std::string();
365384
}
366385

386+
std::string WebSession::fixRelativeUrl(const std::string& url) const
387+
{
388+
if (isAbsoluteUrl(url))
389+
return url;
390+
391+
if (url.length() > 0 && url[0] == '#')
392+
return url;
393+
394+
if (!isAbsoluteUrl(applicationUrl_)) {
395+
if (url.empty() || url[0] == '/')
396+
return url;
397+
else {
398+
std::string rel = "";
399+
400+
for (unsigned i = 0; i < pagePathInfo_.length(); ++i) {
401+
if (pagePathInfo_[i] == '/')
402+
rel += "../";
403+
}
404+
405+
return rel + url;
406+
}
407+
} else
408+
return makeAbsoluteUrl(url);
409+
}
410+
411+
std::string WebSession::makeAbsoluteUrl(const std::string& url) const
412+
{
413+
if (isAbsoluteUrl(url))
414+
return url;
415+
else {
416+
if (url.empty() || url[0] != '/')
417+
return absoluteBaseUrl_ + url;
418+
else
419+
return host(absoluteBaseUrl_) + url;
420+
}
421+
}
422+
367423
std::string WebSession::mostRelativeUrl(const std::string& internalPath) const
368424
{
369425
return appendSessionQuery(bookmarkUrl(internalPath));
@@ -1377,8 +1433,13 @@ std::string WebSession::ajaxCanonicalUrl(const WebResponse& request) const
13771433
if (applicationName_.empty())
13781434
hashE = request.getParameter("_");
13791435

1380-
if (!request.pathInfo().empty() || (hashE && hashE->length() > 1)) {
1381-
std::string url = deploymentPath_;
1436+
if (!pagePathInfo_.empty() || (hashE && hashE->length() > 1)) {
1437+
std::string url;
1438+
if (applicationName_.empty()) {
1439+
url = fixRelativeUrl(".");
1440+
url = url.substr(0, url.length() - 1);
1441+
} else
1442+
url = fixRelativeUrl(applicationName_);
13821443

13831444
bool firstParameter = true;
13841445
for (Http::ParameterMap::const_iterator i
@@ -1910,12 +1971,14 @@ void WebSession::serveError(Handler& handler, const std::string& e)
19101971

19111972
void WebSession::serveResponse(Handler& handler)
19121973
{
1974+
if (handler.response()->responseType() == WebResponse::Page)
1975+
pagePathInfo_ = handler.request()->pathInfo();
1976+
19131977
/*
19141978
* If the request is a web socket message, then we should not actually
19151979
* render -- there may be more messages following.
19161980
*/
19171981
if (!handler.request()->isWebSocketMessage()) {
1918-
19191982
/*
19201983
* In any case, flush the style request when we are serving a new
19211984
* page (without Ajax) or the main script (with Ajax).

src/web/WebSession.h

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -112,10 +112,8 @@ class WT_API WebSession
112112
*/
113113

114114
const std::string& applicationName() const { return applicationName_; }
115-
116-
// (http://www.bigapp.com) /myapp/app.wt?wtd=ABCD
117-
const std::string applicationUrl() const { return applicationUrl_ + sessionQuery(); }
118-
115+
const std::string applicationUrl() const
116+
{ return applicationUrl_ + sessionQuery(); }
119117
const std::string& deploymentPath() const { return deploymentPath_; }
120118

121119
bool useUglyInternalPaths() const;
@@ -140,18 +138,15 @@ class WT_API WebSession
140138
std::string bootstrapUrl(const WebResponse& response, BootstrapOption option)
141139
const;
142140

141+
std::string fixRelativeUrl(const std::string& url) const;
142+
std::string makeAbsoluteUrl(const std::string& url) const;
143+
143144
// (http://www.bigapp.com/myapp/) app.wt/internal_path
144145
std::string bookmarkUrl(const std::string& internalPath) const;
145146

146147
// tries to figure out the current bookmark url (from the app or otherwise)
147148
std::string bookmarkUrl() const;
148149

149-
// http://www.bigapp.com:1234/myapp/
150-
const std::string& absoluteBaseUrl() const { return absoluteBaseUrl_; }
151-
152-
// /myapp/
153-
const std::string& basePath() const { return basePath_; }
154-
155150
std::string getCgiValue(const std::string& varName) const;
156151
std::string getCgiHeader(const std::string& headerName) const;
157152

@@ -268,6 +263,7 @@ class WT_API WebSession
268263
std::string bookmarkUrl_, basePath_, absoluteBaseUrl_;
269264
std::string applicationUrl_, deploymentPath_;
270265
std::string redirect_;
266+
std::string pagePathInfo_;
271267
WebResponse *asyncResponse_, *bootStyleResponse_;
272268
bool canWriteAsyncResponse_, noBootStyleResponse_;
273269
bool progressiveBoot_;

wt_config.xml.in

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -403,19 +403,31 @@
403403
<!-- baseURL property
404404

405405
The absolute URL at which the application is deployed
406-
(known to the user). This may be a reverse-proxified URL
407-
when the app is deployed behind a reverse proxy. This is
408-
set as base URL in the HTML so that relative URLs (to e.g.
409-
css, images, etc...) work correctly regardless of the
410-
internal path. It is also used as the self-referencing URL,
411-
instead of the relative URLs used by default.
412-
413-
Eg. "http://www.webtoolkit.eu/"
414-
415-
The default value is empty, in which case the base URL is
416-
explicitly set. Note that for most applications (which do
417-
not use internal paths and rely on relative URls) this is
418-
fine.
406+
(known to the user). This is needed only in two scenarios.
407+
408+
When you use relative URLs for images, etc... in
409+
fragments of HTML (e.g. in WTemplate) or CSS, which you
410+
would like to resolve against the deployment path of the
411+
application. This will not work as expected in the presence
412+
of an internal application path.
413+
This URL is set as base URL in the HTML, against which
414+
relative URLs are resolved so that these work correctly
415+
regardless of the internal path. It is also used explicitly
416+
in any URL generated by the library.
417+
418+
Another situation in which you need to define the baseURL is
419+
when deploying a widgetset mode application behind a reverse
420+
proxy. A widgetset mode application uses only absolute URLs
421+
because it may be hosted in a web page from an entirely
422+
different domain.
423+
424+
Eg. "http://www.webtoolkit.eu/wt"
425+
426+
The default value is empty, in which case Wt will avoid using
427+
absolute URLs. Relative URLs passed in API calls will be
428+
"fixed" so that they resolve against the location of the
429+
application deploy path, even in the presence of an
430+
internal path.
419431
-->
420432
<property name="baseURL"></property>
421433

0 commit comments

Comments
 (0)