You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by zw...@apache.org on 2017/06/26 20:11:37 UTC

[trafficserver] 02/02: Extend body factory templates to have a default per custom template set. YTSATS-473

This is an automated email from the ASF dual-hosted git repository.

zwoop pushed a commit to branch 7.1.x
in repository https://gitbox.apache.org/repos/asf/trafficserver.git

commit 5231d00f21524b92026fb9c946a39e7fa773bcba
Author: Alan M. Carroll <so...@yahoo-inc.com>
AuthorDate: Mon Aug 17 19:26:43 2015 +0000

    Extend body factory templates to have a default per custom template set.
    YTSATS-473
    
    (cherry picked from commit 335543a7ffb96960fad8b5636cd0fec54394e982)
---
 doc/admin-guide/monitoring/error-messages.en.rst | 18 ++++++----
 proxy/http/HttpBodyFactory.cc                    | 43 +++++++++++++++---------
 2 files changed, 38 insertions(+), 23 deletions(-)

diff --git a/doc/admin-guide/monitoring/error-messages.en.rst b/doc/admin-guide/monitoring/error-messages.en.rst
index 61094d4..74ebca2 100644
--- a/doc/admin-guide/monitoring/error-messages.en.rst
+++ b/doc/admin-guide/monitoring/error-messages.en.rst
@@ -145,18 +145,22 @@ is provided in :ref:`appendix-http-status-codes`.
 
 The error messages can be customized. The actual response is generated from a template. These
 templates are stored in files which means the errors responses can be customized by modifying these
-files. The default directory for the template files is ``PREFIX/body_factory/default``
-but this can be changed by the configuration variable
-:ts:cv:`proxy.config.body_factory.template_sets_dir`. All files in this directory are added to a
-lookup table which is consulted when the error message is generated. The name used for lookup is by
-default that listed in the :ref:`following table <body-factory-error-table>`. It can be overridden by
+files. The default directory for the template files is ``PREFIX/body_factory/default`` but this can
+be changed by the configuration variable :ts:cv:`proxy.config.body_factory.template_sets_dir`. All
+files in this directory are added to a lookup table which is consulted when the error message is
+generated. The name used for lookup is by default that listed in the :ref:`following table
+<body-factory-error-table>`. It can be overridden by
 :ts:cv:`proxy.config.body_factory.template_base` which, if set, is a string that is prepended to the
 search name along with an underscore. For example, if the default lookup name is
 ``cache#read_error`` then by default the response will be generated from the template in the file
-named ``cache#read_error``. If the template base name were set to "apache" then the lookup would
+named ``cache#read_error``. If the template base name were set to ``apache`` then the lookup would
 look for a file named ``apache_cache#read_error`` in the template table. This can be used to switch
 out error message sets or, because this variable is overridable, to select an error message set
-based on data in the transaction.
+based on data in the transaction. In addition the suffix ``_default`` has a special meaning. If
+there is a file with the base name and that suffix it is used as the default error page for the base
+set, instead of falling back to the global (built in) default page in the case where there is not a
+file that matches the specific error. In the example case, if the file ``apache_default`` exists
+it would be used instead of ``cache#read_error`` if there is no ``apache_cache#read_error``.
 
 The text for an error message is processed as if it were a :ref:`admin-logging-fields` which
 enables customization by values present in the transaction for which the error occurred.
diff --git a/proxy/http/HttpBodyFactory.cc b/proxy/http/HttpBodyFactory.cc
index 3d3ddcf..d30b330 100644
--- a/proxy/http/HttpBodyFactory.cc
+++ b/proxy/http/HttpBodyFactory.cc
@@ -107,7 +107,7 @@ HttpBodyFactory::fabricate_with_old_api(const char *type, HttpTransact::State *c
       Log::error("BODY_FACTORY: suppressing '%s' response for url '%s'", type, url);
     }
     unlock();
-    return (nullptr);
+    return nullptr;
   }
   //////////////////////////////////////////////////////////////////////////////////
   // if language-targeting activated, get client Accept-Language & Accept-Charset //
@@ -405,7 +405,7 @@ HttpBodyFactory::fabricate(StrList *acpt_language_list, StrList *acpt_charset_li
   char *buffer;
   const char *pType = context->txn_conf->body_factory_template_base;
   const char *set;
-  HttpBodyTemplate *t;
+  HttpBodyTemplate *t = NULL;
   HttpBodySet *body_set;
   char template_base[PATH_NAME_MAX];
 
@@ -421,12 +421,12 @@ HttpBodyFactory::fabricate(StrList *acpt_language_list, StrList *acpt_charset_li
   // if error body suppressed, return NULL
   if (is_response_suppressed(context)) {
     Debug("body_factory", "  error suppression enabled, returning NULL template");
-    return (nullptr);
+    return nullptr;
   }
   // if custom error pages are disabled, return NULL
   if (!enable_customizations) {
     Debug("body_factory", "  customization disabled, returning NULL template");
-    return (nullptr);
+    return nullptr;
   }
 
   // what set should we use (language target if enable_customizations == 2)
@@ -444,20 +444,25 @@ HttpBodyFactory::fabricate(StrList *acpt_language_list, StrList *acpt_charset_li
   }
   if (pType != nullptr && 0 != *pType && 0 != strncmp(pType, "NONE", 4)) {
     sprintf(template_base, "%s_%s", pType, type);
-  } else {
-    sprintf(template_base, "%s", type);
+    t = find_template(set, template_base, &body_set);
+    // Check for default alternate.
+    if (t == nullptr) {
+      sprintf(template_base, "%s_default", pType);
+      t = find_template(set, template_base, &body_set);
+    }
   }
-  // see if we have a custom error page template
-  t = find_template(set, template_base, &body_set);
+
+  // Check for base customizations if specializations didn't work.
   if (t == nullptr) {
     if (is_response_body_precluded(context->http_return_code, context->method)) {
       return nullptr;
     }
     t = find_template(set, type, &body_set); // this executes if the template_base is wrong and doesn't exist
   }
+
   if (t == nullptr) {
     Debug("body_factory", "  can't find template, returning NULL template");
-    return (nullptr);
+    return nullptr;
   }
 
   *content_language_return = body_set->content_language;
@@ -465,7 +470,7 @@ HttpBodyFactory::fabricate(StrList *acpt_language_list, StrList *acpt_charset_li
 
   // build the custom error page
   buffer = t->build_instantiated_buffer(context, buffer_length_return);
-  return (buffer);
+  return buffer;
 }
 
 // LOCKING: must be called with lock taken
@@ -702,8 +707,9 @@ HttpBodyFactory::load_body_set_from_directory(char *set_name, char *tmpl_dir)
   DIR *dir;
   int status;
   struct stat stat_buf;
-  char path[MAXPATHLEN + 1];
   struct dirent *dirEntry;
+  char path[MAXPATHLEN + 1];
+  static const char BASED_DEFAULT[] = "_default";
 
   ////////////////////////////////////////////////
   // ensure we can open tmpl_dir as a directory //
@@ -712,7 +718,7 @@ HttpBodyFactory::load_body_set_from_directory(char *set_name, char *tmpl_dir)
   Debug("body_factory", "  load_body_set_from_directory(%s)", tmpl_dir);
   dir = opendir(tmpl_dir);
   if (dir == nullptr) {
-    return (nullptr);
+    return nullptr;
   }
 
   /////////////////////////////////////////////
@@ -723,7 +729,7 @@ HttpBodyFactory::load_body_set_from_directory(char *set_name, char *tmpl_dir)
   status = stat(path, &stat_buf);
   if ((status < 0) || !S_ISREG(stat_buf.st_mode)) {
     closedir(dir);
-    return (nullptr);
+    return nullptr;
   }
   Debug("body_factory", "    found '%s'", path);
 
@@ -739,14 +745,19 @@ HttpBodyFactory::load_body_set_from_directory(char *set_name, char *tmpl_dir)
 
   while ((dirEntry = readdir(dir))) {
     HttpBodyTemplate *tmpl;
+    size_t d_len = strlen(dirEntry->d_name);
 
     ///////////////////////////////////////////////////////////////
-    // all template files have name of the form <type>#<subtype> //
+    // all template files must have a file name of the form      //
+    // - <type>#<subtype>                                        //
+    // - <base>_<type>#<subtype>                                 //
+    // - <base>_default   [based default]                        //
+    // - default          [global default]                       //
     ///////////////////////////////////////////////////////////////
 
-    if ((strchr(dirEntry->d_name, '#') == nullptr) && (strcmp(dirEntry->d_name, "default") != 0)) {
+    if (!(nullptr != strchr(dirEntry->d_name, '#') || (0 == strcmp(dirEntry->d_name, "default")) ||
+          (d_len >= sizeof(BASED_DEFAULT) && 0 == strcmp(dirEntry->d_name + d_len - (sizeof(BASED_DEFAULT) - 1), BASED_DEFAULT))))
       continue;
-    }
 
     snprintf(path, sizeof(path), "%s/%s", tmpl_dir, dirEntry->d_name);
     status = stat(path, &stat_buf);

-- 
To stop receiving notification emails like this one, please contact
"commits@trafficserver.apache.org" <co...@trafficserver.apache.org>.