af6898753ba6d5f3872957cd270872ce4c4e3dfc
max
Tue Apr 11 08:19:27 2023 -0700
tolerate if browser CSS theme files do not exist, cleaning up the resource link mess a little, refs #7867
diff --git src/hg/lib/web.c src/hg/lib/web.c
index 360ff9b..58247fc 100644
--- src/hg/lib/web.c
+++ src/hg/lib/web.c
@@ -1207,30 +1207,74 @@
}
}
void webFinishPartialLinkOutTable(int rowIx, int itemPos, int maxPerRow)
/* Fill out partially empty last row. */
{
finishPartialTable(rowIx, itemPos, maxPerRow, webPrintLinkOutCellStart);
}
void webFinishPartialLinkTable(int rowIx, int itemPos, int maxPerRow)
/* Fill out partially empty last row. */
{
finishPartialTable(rowIx, itemPos, maxPerRow, webPrintLinkCellStart);
}
+static struct dyString* getHtdocsSubdir(char *dirName)
+/* return dystring with subdirectory under htDocs, tolerant of missing docRoot */
+{
+struct dyString *fullDirName = NULL;
+char *docRoot = hDocumentRoot();
+if (docRoot != NULL)
+ fullDirName = dyStringCreate("%s/%s", docRoot, dirName);
+else
+ // tolerate missing docRoot (i.e. when running from command line)
+ fullDirName = dyStringCreate("%s", dirName);
+return fullDirName;
+}
+
+char *webCssLink(char *fileName, boolean mustExist)
+/* alternative for webTimeStampedLinkToResource for CSS files: returns a string with a time-stamped
+ * link to a CSS file as a html fragment . returns empty string if file does not exist.
+ * */
+{
+// construct the absolute path to the file on disk
+char *relDir = cfgOptionDefault("browser.styleDir","style");
+struct dyString *absDir = getHtdocsSubdir(relDir);
+struct dyString *absFileName = dyStringCreate("%s/%s", dyStringContents(absDir), fileName);
+
+struct dyString *htmlFrag = NULL;
+if (!fileExists(dyStringContents(absFileName)))
+ {
+ if (mustExist)
+ errAbort("webTimeStampedLinkToResource: file: %s doesn't exist.\n",
+ dyStringContents(absFileName));
+ else
+ htmlFrag = dyStringNew(0);
+ }
+else
+ {
+ // construct a link with the relative path to the file on the web server
+ long mtime = fileModTime(dyStringContents(absFileName));
+ htmlFrag = dyStringCreate("\n", relDir, fileName, mtime);
+ }
+
+dyStringFree(&absFileName);
+dyStringFree(&absDir);
+return dyStringContents(htmlFrag);
+}
+
char *webTimeStampedLinkToResource(char *fileName, boolean wrapInHtml)
// If wrapInHtml
// returns versioned link embedded in style or script html (free after use).
// else
// returns full path of a versioned path to the requested resource file (js, or css).
// NOTE: png, jpg and gif should also be supported but are untested.
//
// In production sites we use a versioned softlink that includes the CGI version. This has the following benefits:
// a) flushes user's web browser cache when the user visits a GB site whose version has changed since their last visit;
// b) enforces the requirement that static files are the same version as the CGIs (something that often fails to happen in mirrors).
// (see notes in redmine #3170).
//
// In dev trees we use mtime to create a pseudo-version; this forces web browsers to reload css/js file when it changes,
// so we don't get odd behavior that can be caused by caching of mis-matched javascript and style files in dev trees.
//
@@ -1248,37 +1292,39 @@
|| sameString(".jpg",extension)
|| sameString(".gif",extension));
if (!js && !style) // && !image) NOTE: This code has not been tested on images but should work.
errAbort("webTimeStampedLinkToResource: unknown resource type for %s.\n", fileName);
char *httpHost = hHttpHost();
// Build and verify directory
char *dirName = "";
if (js)
dirName = cfgOptionDefault("browser.javaScriptDir", "js");
else if (style)
dirName = cfgOptionDefault("browser.styleDir","style");
else if (image)
dirName = cfgOptionDefault("browser.styleImagesDir","style/images");
+
struct dyString *fullDirName = NULL;
char *docRoot = hDocumentRoot();
if (docRoot != NULL)
fullDirName = dyStringCreate("%s/%s", docRoot, dirName);
else
// tolerate missing docRoot (i.e. when running from command line)
fullDirName = dyStringCreate("%s", dirName);
+
if (!fileExists(dyStringContents(fullDirName)))
errAbort("webTimeStampedLinkToResource: dir: %s doesn't exist. (host: %s)\n",
dyStringContents(fullDirName), httpHost);
// build and verify real path to file
struct dyString *realFileName = dyStringCreate("%s/%s", dyStringContents(fullDirName), fileName);
if (!fileExists(dyStringContents(realFileName)))
errAbort("webTimeStampedLinkToResource: file: %s doesn't exist.\n",
dyStringContents(realFileName));
// build and verify link path including timestamp in the form of dir/baseName + timeStamp or CGI Version + ext
long mtime = fileModTime(dyStringContents(realFileName));
struct dyString *linkWithTimestamp;
linkWithTimestamp = dyStringCreate("%s/%s%s?v=%ld", dyStringContents(fullDirName), baseName, extension, mtime);