You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@trafficserver.apache.org by mark <mn...@haskalah.org> on 2011/03/18 13:28:05 UTC
User callback on connect failure
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;