569360530e4b6780aa4a75cecb37592741e42ade larrym Mon Mar 14 14:32:10 2011 -0700 use CGI version based softlinks for js and css files in production sites (see redmine 3170 diff --git src/hg/lib/web.c src/hg/lib/web.c index 02bdafe..08ed3b7 100644 --- src/hg/lib/web.c +++ src/hg/lib/web.c @@ -1318,60 +1318,64 @@ char *docRoot = hDocumentRoot(); if(docRoot != NULL) // tolerate missing docRoot (i.e. when running from command line) fullDirName = dyStringCreate("%s/%s", docRoot, dirName); else fullDirName = dyStringCreate("%s", dirName); if(!fileExists(dyStringContents(fullDirName))) errAbort("webTimeStampedLinkToResource: dir: %s doesn't exist.\n", dyStringContents(fullDirName)); // 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.ext long mtime = fileModTime(dyStringContents(realFileName)); // We add mtime to create a pseudo-version; this forces browsers to reload css/js file when it changes -struct dyString *linkWithTimestamp = dyStringCreate("%s/%s-%ld%s", dyStringContents(fullDirName), baseName, mtime, extension); +struct dyString *linkWithTimestamp; +if(hIsPreviewHost() || hIsPrivateHost()) + linkWithTimestamp = dyStringCreate("%s/%s-%ld%s", dyStringContents(fullDirName), baseName, mtime, extension); +else + linkWithTimestamp = dyStringCreate("%s/%s-v%s%s", dyStringContents(fullDirName), baseName, CGI_VERSION, extension); // If link does not exist, then create it !! if(!fileExists(dyStringContents(linkWithTimestamp))) { // The versioned copy should be created by the install process; however, mirrors may fail // to preserve mtime's when copying over the javascript/css files, in which case the // versioned softlinks won't match the real file; in that case, we try to create // the versioned links on the fly (which requires write access to the javascript or style directory!). // Remove older links struct dyString *pattern = dyStringCreate("%s-[0-9]+\\%s", baseName, extension); struct slName *file, *files = listDirRegEx(dyStringContents(fullDirName), dyStringContents(pattern), REG_EXTENDED); struct dyString *oldLink = dyStringNew(256); for (file = files; file != NULL; file = file->next) { dyStringClear(oldLink); dyStringPrintf(oldLink, "%s/%s", dyStringContents(fullDirName), file->name); unlink(dyStringContents(oldLink)); } dyStringFree(&oldLink); slFreeList(&files); dyStringFree(&pattern); // Create new link if(symlink(dyStringContents(realFileName), dyStringContents(linkWithTimestamp))) { int err = errno; - errAbort("webTimeStampedLinkToResource: symlink failed: errno: %d (%s); the directory '%s' must be writeable by user '%s'; alternatively, the installation process must create the versioned files\n", - err, strerror(err), dyStringContents(fullDirName), getUser()); + errAbort("webTimeStampedLinkToResource: symlink of %s failed: errno: %d (%s); the directory '%s' must be writeable by user '%s'; alternatively, the installation process must create the versioned files\n", + dyStringContents(linkWithTimestamp), err, strerror(err), dyStringContents(fullDirName), getUser()); } } // Free up all that extra memory dyStringFree(&realFileName); dyStringFree(&fullDirName); char *linkFull = dyStringCannibalize(&linkWithTimestamp); char *link = linkFull; if (docRoot != NULL) link = cloneString(linkFull + strlen(docRoot) + 1); freeMem(linkFull); if (wrapInHtml) // wrapped for christmas { struct dyString *wrapped = dyStringNew(0); if (js)