I've been trying to implement the ability to allow a user-defined callback for each failure to an origin server or parent proxy. The idea being that when ATS' built-in failover mechanisms are exhausted and it is about to send an error response to the user, a plugin author might be able to (heuristically?) determine a different path to take in order to retrieve the content.

I've been poking around the code a bit and tried to implement at least an internal hook, but to no avail.

Here's what i tried to do (using a 5-day old trunk):

--- ../tsorig/proxy/http/HttpTransact.cc 2011-03-09 21:43:58.000000000 +0000
+++ proxy/http/HttpTransact.cc    2011-03-18 12:05:48.000000000 +0000
@@ -33,6 +33,7 @@
 #include "HttpDebugNames.h"
 #include "time.h"
 #include "ParseRules.h"
+#include <string.h>
 #include "HTTP.h"
 #include "HdrUtils.h"
 #include "HttpMessageBody.h"
@@ -47,6 +48,7 @@
 #include "StatPages.h"
 #include "HttpClientSession.h"
 #include "I_Machine.h"
+#include <pcre.h>

 static const char *URL_MSG = "Unable to process requested URL.\n";

@@ -278,6 +280,36 @@ is_negative_caching_appropriate(HttpTran
 }

 inline static HttpTransact::LookingUp_t
+maybe_override_retry(HttpTransact::State *s, HttpTransact::LookingUp_t in)
+{
+    static int counter = 0;
+    Debug("mndebug(override_retry)", "begin. Counter is %d", counter);
+    if(counter < 5) {
+        counter++;
+    } else {
+        counter = 0;
+ Debug("mndebug(override_retry)", "arbitrarily returning same input to avoid infinite looping");
+        return in;
+    }
+    if (in == HttpTransact::HOST_NONE || HttpTransact::ORIGIN_SERVER) {
+ Debug("mndebug(override_retry", "Trying to override.. wish me luck");
+        s->parent_result.hostname = "127.0.0.1";
+        s->parent_result.port = 54321;
+        s->parent_result.r = PARENT_SPECIFIED;
+        s->parent_info.name = (char*)"127.0.0.1";
+        s->parent_info.port = 54321;
+        update_current_info(
+ &s->current, &s->parent_info, HttpTransact::PARENT_PROXY,
+                (s->current.attempts)++);
+        in = HttpTransact::PARENT_PROXY;
+ ink_debug_assert(s->current.request_to == HttpTransact::PARENT_PROXY);
+    }
+    Debug("mndebug(override_retry)", "Returning..");
+    return in;
+}
+
+
+inline static HttpTransact::LookingUp_t
 find_server_and_update_current_info(HttpTransact::State* s)
 {
   URL *url = s->hdr_info.client_request.url_get();
@@ -1248,7 +1280,6 @@ HttpTransact::HandleRequest(State* s)
     if ((int32_t) addr != -1) {
       s->request_data.dest_ip = addr;
     }
-
     if (s->parent_params->parentExists(&s->request_data)) {
       // If the proxy is behind and firewall and there is no
       //  DNS service available, we just want to forward the request
@@ -1279,8 +1310,6 @@ HttpTransact::HandleRequest(State* s)
if (s->txn_conf->cache_http && s->redirect_info.redirect_in_process && s->state_machine->enable_redirection) {
     TRANSACT_RETURN(CACHE_LOOKUP, NULL);
   }
-
-
   if (s->force_dns) {
TRANSACT_RETURN(DNS_LOOKUP, OSDNSLookup); // After handling the request, DNS is done.
   } else {
@@ -3366,6 +3395,7 @@ HttpTransact::handle_response_from_icp_s
 #endif //INK_NO_ICP


+
 ///////////////////////////////////////////////////////////////////////////////
 // Name       : handle_response_from_parent
 // Description: response came from a parent proxy
@@ -3452,9 +3482,11 @@ HttpTransact::handle_response_from_paren
         s->parent_result.r = PARENT_FAIL;
         next_lookup = find_server_and_update_current_info(s);
       }
-
       // We have either tried to find a new parent or failed over to the
       //   origin server
+
+      //See if we can override this with maybe_override_retry();
+      next_lookup = maybe_override_retry(s, next_lookup);
       switch (next_lookup) {
       case PARENT_PROXY:
         ink_debug_assert(s->current.request_to == PARENT_PROXY);
@@ -7646,6 +7678,12 @@ HttpTransact::handle_parent_died(State*
 void
 HttpTransact::handle_server_died(State* s)
 {
+ LookingUp_t retry_type = maybe_override_retry(s, HttpTransact::HOST_NONE);
+  if (retry_type == PARENT_PROXY) {
+
+      TRANSACT_RETURN(DNS_LOOKUP, PPDNSLookup);
+      return;
+  }
   const char *reason = NULL;
   const char *body_type = "UNKNOWN";
   HTTPStatus status = HTTP_STATUS_BAD_GATEWAY;

Reply via email to