Пример #1
0
void
TSPluginInit(int argc, const char *argv[])
{
  int i;
  TSPluginRegistrationInfo info;

  info.plugin_name = "blacklist-0";
  info.vendor_name = "MyCompany";
  info.support_email = "*****@*****.**";

  if (TSPluginRegister(&info) != TS_SUCCESS) {
    TSError("[blacklist-0] Plugin registration failed.");
  }

  nsites = argc - 1;
  if (nsites > 0) {
    sites = (char **)TSmalloc(sizeof(char *) * nsites);

    for (i = 0; i < nsites; i++) {
      sites[i] = TSstrdup(argv[i + 1]);
    }

    TSHttpHookAdd(TS_HTTP_OS_DNS_HOOK, TSContCreate(blacklist_plugin, NULL));
  }
}
Пример #2
0
TSReturnCode
TSRemapNewInstance(int argc, char **argv, void **ih, char *errbuf, int errbuf_size)
{
  int i;
  char *ptr;
  secure_link_info *sli;

  // squash unused variable warnings ...
  (void)errbuf;
  (void)errbuf_size;

  sli = (secure_link_info *)TSmalloc(sizeof(secure_link_info));
  sli->secret = NULL;
  sli->strict = 0;

  for(i = 2; i < argc; i++) {
    if((ptr = strchr(argv[i], ':')) != NULL) {
      *ptr++ = '\0';
      if(strcmp(argv[i], "secret") == 0) {
        if(sli->secret != NULL) {
          TSfree(sli->secret);
        }
        sli->secret = TSstrdup(ptr);
      } else if(strcmp(argv[i], "policy") == 0) {
        sli->strict = !strcasecmp(ptr, "strict");
      } else {
        TSDebug(PLUGIN_NAME, "Unknown parameter [%s]", argv[i]);
      }
    } else {
      TSError("Invalid parameter [%s]", argv[i]);
    }
  }

  if(sli->secret == NULL) {
    sli->secret = TSstrdup("");
  }

  *ih = (void *)sli;
  return TS_SUCCESS;
}
Пример #3
0
static int
ts_lua_http_set_retbody(lua_State *L)
{
  const char *body;
  size_t body_len;
  ts_lua_http_ctx *http_ctx;

  GET_HTTP_CONTEXT(http_ctx, L);

  body = luaL_checklstring(L, 1, &body_len);
  TSHttpTxnErrorBodySet(http_ctx->txnp, TSstrdup(body), body_len, NULL); // Defaults to text/html
  return 0;
}
Пример #4
0
static char *
make_state_path(const char *filename)
{
  if ('/' == *filename) {
    return TSstrdup(filename);
  } else {
    char buf[8192];
    const char *dir = TSInstallDirGet();

    snprintf(buf, sizeof(buf), "%s/%s/%s", dir, DEFAULT_DIR, PLUGIN_NAME);
    if (-1 == mkdir(buf, S_IRWXU)) {
      if (EEXIST != errno) {
        TSError("[%s] Unable to create directory %s: %s (%d)", PLUGIN_NAME, buf, strerror(errno), errno);
        return NULL;
      }
    }
    snprintf(buf, sizeof(buf), "%s/%s/%s/%s.genid", dir, DEFAULT_DIR, PLUGIN_NAME, filename);
    return TSstrdup(buf);
  }

  return NULL;
}
Пример #5
0
/* Initialize the plugin / global continuation hook */
void
TSPluginInit(int argc, const char *argv[])
{
  TSPluginRegistrationInfo info;
  const char *proof = "acme";

  static const struct option longopt[] = {
    {(char *)"proof-directory", optional_argument, NULL, 'p'},
    {NULL, no_argument, NULL, '\0'},
  };

  memset(&gConfig, 0, sizeof(gConfig));
  while (true) {
    int opt = getopt_long(argc, (char *const *)argv, "", longopt, NULL);

    switch (opt) {
    case 'p':
      proof = optarg;
      break;
    }

    if (opt == -1) {
      break;
    }
  }

  if ('/' != *proof) {
    const char *confdir = TSConfigDirGet();
    int len             = strlen(proof) + strlen(confdir) + 8;

    gConfig.proof = TSmalloc(len);
    snprintf(gConfig.proof, len, "%s/%s", confdir, proof);
    TSDebug(PLUGIN_NAME, "base directory for proof-types is %s", gConfig.proof);
  } else {
    gConfig.proof = TSstrdup(proof);
  }

  info.plugin_name   = "acme";
  info.vendor_name   = "Apache Software Foundation";
  info.support_email = "*****@*****.**";

  if (TS_SUCCESS != TSPluginRegister(&info)) {
    TSError("[%s] Plugin registration failed", PLUGIN_NAME);
    return;
  }

  TSDebug(PLUGIN_NAME, "Started the %s plugin", PLUGIN_NAME);
  TSDebug(PLUGIN_NAME, "\tproof-type dir = %s", gConfig.proof);

  TSHttpHookAdd(TS_HTTP_READ_REQUEST_HDR_HOOK, TSContCreate(acme_hook, NULL));
}
Пример #6
0
static void
stat_add(char *name, TSMgmtInt amount, TSStatPersistence persist_type, TSMutex create_mutex)
{
int stat_id = -1;
ENTRY search, *result = NULL;
static __thread struct hsearch_data stat_cache;
static __thread bool hash_init = false;

if (unlikely(!hash_init)) {
    hcreate_r(TS_MAX_API_STATS << 1, &stat_cache);
    hash_init = true;
    TSDebug(DEBUG_TAG, "stat cache hash init");
}

search.key  = name;
search.data = 0;
hsearch_r(search, FIND, &result, &stat_cache);

if (unlikely(result == NULL)) {
    // This is an unlikely path because we most likely have the stat cached
    // so this mutex won't be much overhead and it fixes a race condition
    // in the RecCore. Hopefully this can be removed in the future.
    TSMutexLock(create_mutex);
    if (TS_ERROR == TSStatFindName((const char *)name, &stat_id)) {
        stat_id = TSStatCreate((const char *)name, TS_RECORDDATATYPE_INT, persist_type, TS_STAT_SYNC_SUM);
        if (stat_id == TS_ERROR) {
            TSDebug(DEBUG_TAG, "Error creating stat_name: %s", name);
        } else {
            TSDebug(DEBUG_TAG, "Created stat_name: %s stat_id: %d", name, stat_id);
        }
    }
    TSMutexUnlock(create_mutex);

    if (stat_id >= 0) {
        search.key  = TSstrdup(name);
        search.data = (void *)((intptr_t)stat_id);
        hsearch_r(search, ENTER, &result, &stat_cache);
        TSDebug(DEBUG_TAG, "Cached stat_name: %s stat_id: %d", name, stat_id);
    }
} else {
    stat_id = (int)((intptr_t)result->data);
}

if (likely(stat_id >= 0)) {
    TSStatIntIncrement(stat_id, amount);
} else {
    TSDebug(DEBUG_TAG, "stat error! stat_name: %s stat_id: %d", name, stat_id);
}
}
Пример #7
0
static void
read_blacklist(TSCont contp)
{
  char blacklist_file[1024];
  TSFile file;

  sprintf(blacklist_file, "%s/blacklist.txt", TSPluginDirGet());
  file   = TSfopen(blacklist_file, "r");
  nsites = 0;

  /* If the Mutext lock is not successful try again in RETRY_TIME */
  if (TSMutexLockTry(sites_mutex) != TS_SUCCESS) {
    if (file != NULL) {
      TSfclose(file);
    }
    TSContSchedule(contp, RETRY_TIME, TS_THREAD_POOL_DEFAULT);
    return;
  }

  if (file != NULL) {
    char buffer[1024];

    while (TSfgets(file, buffer, sizeof(buffer) - 1) != NULL && nsites < MAX_NSITES) {
      char *eol;
      if ((eol = strstr(buffer, "\r\n")) != NULL) {
        /* To handle newlines on Windows */
        *eol = '\0';
      } else if ((eol = strchr(buffer, '\n')) != NULL) {
        *eol = '\0';
      } else {
        /* Not a valid line, skip it */
        continue;
      }
      if (sites[nsites] != NULL) {
        TSfree(sites[nsites]);
      }
      sites[nsites] = TSstrdup(buffer);
      nsites++;
    }

    TSfclose(file);
  } else {
    TSError("[%s] Unable to open %s", PLUGIN_NAME, blacklist_file);
    TSError("[%s] All sites will be allowed", PLUGIN_NAME);
  }

  TSMutexUnlock(sites_mutex);
}
Пример #8
0
static invalidate_t *
copy_invalidate_t(invalidate_t *i)
{
  invalidate_t *iptr;
  const char *errptr;
  int erroffset;

  iptr = (invalidate_t *)TSmalloc(sizeof(invalidate_t));
  iptr->regex_text = TSstrdup(i->regex_text);
  iptr->regex = pcre_compile(iptr->regex_text, 0, &errptr, &erroffset, NULL); // There is no pcre_copy :-(
  iptr->regex_extra = pcre_study(iptr->regex, 0, &errptr);                    // Assuming no errors since this worked before :-/
  iptr->epoch = i->epoch;
  iptr->expiry = i->expiry;
  iptr->next = NULL;
  return iptr;
}
void
TSPluginInit(int argc, const char *argv[])
{
  TSPluginRegistrationInfo info;

  static const char usage[]             = PLUGIN_NAME ".so [--integer-counters] [PATH]";
  static const struct option longopts[] = {{(char *)("integer-counters"), no_argument, NULL, 'i'},
                                           {(char *)("wrap-counters"), no_argument, NULL, 'w'},
                                           {NULL, 0, NULL, 0}};

  info.plugin_name   = PLUGIN_NAME;
  info.vendor_name   = "Apache Software Foundation";
  info.support_email = "*****@*****.**";

  if (TSPluginRegister(&info) != TS_SUCCESS) {
    TSError("[%s] registration failed", PLUGIN_NAME);
  }

  for (;;) {
    switch (getopt_long(argc, (char *const *)argv, "iw", longopts, NULL)) {
    case 'i':
      integer_counters = true;
      break;
    case 'w':
      wrap_counters = true;
      break;
    case -1:
      goto init;
    default:
      TSError("[%s] usage: %s", PLUGIN_NAME, usage);
    }
  }

init:
  argc -= optind;
  argv += optind;

  if (argc > 0) {
    url_path = TSstrdup(argv[0] + ('/' == argv[0][0] ? 1 : 0)); /* Skip leading / */
  }
  url_path_len = strlen(url_path);

  /* Create a continuation with a mutex as there is a shared global structure
     containing the headers to add */
  TSHttpHookAdd(TS_HTTP_READ_REQUEST_HDR_HOOK, TSContCreate(stats_origin, NULL));
  TSDebug(PLUGIN_NAME, "stats module registered");
}
Пример #10
0
void
TSPluginInit(int argc, const char *argv[])
{
  TSPluginRegistrationInfo info;

  info.plugin_name = "stats";
  info.vendor_name = "Apache Software Foundation";
  info.support_email = "*****@*****.**";

  if (TSPluginRegister(TS_SDK_VERSION_2_0, &info) != TS_SUCCESS)
    TSError("Plugin registration failed. \n");

  if (argc > 1) {
    url_path = TSstrdup(argv[1] + ('/' == argv[1][0] ? 1 : 0)); /* Skip leading / */
  }
  url_path_len = strlen(url_path);

  /* Create a continuation with a mutex as there is a shared global structure
     containing the headers to add */
  TSHttpHookAdd(TS_HTTP_READ_REQUEST_HDR_HOOK, TSContCreate(stats_origin, NULL));
  TSDebug("istats", "stats module registered");
}
Пример #11
0
static int
ts_lua_http_set_resp(lua_State *L)
{
  int n, status;
  const char *body;
  size_t body_len;
  ts_lua_http_ctx *http_ctx;

  GET_HTTP_CONTEXT(http_ctx, L);

  n = lua_gettop(L);

  status = luaL_checkinteger(L, 1);
  TSHttpTxnSetHttpRetStatus(http_ctx->txnp, status);

  if (n == 2) {
    body = luaL_checklstring(L, 2, &body_len);
    TSHttpTxnErrorBodySet(http_ctx->txnp, TSstrdup(body), body_len, NULL); // Defaults to text/html
  }

  return 0;
}
Пример #12
0
/* Before we can send the response, we want to modify it to a "200 OK" again,
   and produce some reasonable body output. */
static int
on_send_response_header(TSHttpTxn txnp, TSCont contp, PurgeInstance *purge)
{
  TSMBuffer bufp;
  TSMLoc hdr_loc;

  TSDebug(PLUGIN_NAME, "Fixing up the response on the successful PURGE");
  if (TS_SUCCESS == TSHttpTxnClientRespGet(txnp, &bufp, &hdr_loc)) {
    char response[1024];
    int len = snprintf(response, sizeof(response), "PURGED %s\r\n\r\n", purge->id);

    TSHttpHdrStatusSet(bufp, hdr_loc, TS_HTTP_STATUS_OK);
    TSHttpHdrReasonSet(bufp, hdr_loc, "OK", 2);
    TSHttpTxnErrorBodySet(txnp, TSstrdup(response), len >= sizeof(response) ? sizeof(response) - 1 : len, NULL);

    TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
    TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);
  } else {
    TSHttpTxnReenable(txnp, TS_EVENT_HTTP_ERROR);
  }

  return TS_SUCCESS;
}
Пример #13
0
int TSRemapNewInstance(int argc, char *argv[], void **ih, char *errbuf, int errbuf_size) {
  /* Called for each remap rule using this plugin. The parameters are parsed here */

    if (argc < 2 || argv[2] == NULL) {
        TSError("Missing parameters for " PLUGIN_NAME);
        return -1;
    }

    TSDebug(PLUGIN_NAME, "new instance fromURL: %s toURL: %s", argv[0], argv[1]);
//    fprintf(stderr, "new instance fromURL: '%s' toURL: '%s' argv[2]: '%s'\n", argv[0], argv[1], argv[2]);

    hash_remap_struct *hash = (hash_remap_struct*) TSmalloc(sizeof(hash_remap_struct));
    hash->isp_name = TSstrdup(argv[2]);
    hash->isp_name_len = strlen(hash->isp_name);

    hash->hash_len = (sizeof(uint64_t) + sizeof(uint32_t)) * 2 + hash->isp_name_len + 1;
    hash->hash = TSmalloc(hash->hash_len); //length of one hash value and a dot and isp_name...

    *ih = (void*) hash;
    TSDebug(PLUGIN_NAME, "created instance %p", *ih);

    return 0;
}
Пример #14
0
static void
handle_response(TSHttpTxn txnp)
{
  TSMBuffer bufp;
  TSMLoc hdr_loc, newfield_loc;
  char *errormsg_body = "All requests from this IP address are redirected.\n";
  char *tmp_body;

  if (TSHttpTxnClientRespGet(txnp, &bufp, &hdr_loc) != TS_SUCCESS) {
    TSError("couldn't retrieve client response header\n");
    goto done;
  }

  TSHttpHdrStatusSet(bufp, hdr_loc, TS_HTTP_STATUS_MOVED_PERMANENTLY);
  TSHttpHdrReasonSet(bufp, hdr_loc,
                      TSHttpHdrReasonLookup(TS_HTTP_STATUS_MOVED_PERMANENTLY),
                      strlen(TSHttpHdrReasonLookup(TS_HTTP_STATUS_MOVED_PERMANENTLY)));

  TSMimeHdrFieldCreate(bufp, hdr_loc, &newfield_loc); /* Probably should check for errors ... */
  TSMimeHdrFieldNameSet(bufp, hdr_loc, newfield_loc, TS_MIME_FIELD_LOCATION, TS_MIME_LEN_LOCATION);
  TSMimeHdrFieldValueStringInsert(bufp, hdr_loc, newfield_loc, -1, uri_redirect, strlen(uri_redirect));
  TSMimeHdrFieldAppend(bufp, hdr_loc, newfield_loc);

  /*
   *  Note that we can't directly use errormsg_body, as TSHttpTxnErrorBodySet()
   *  will try to free the passed buffer with TSfree().
   */
  tmp_body = TSstrdup(errormsg_body);
  TSHttpTxnErrorBodySet(txnp, tmp_body, strlen(tmp_body), NULL);
  TSHandleMLocRelease(bufp, hdr_loc, newfield_loc);
  TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);


done:
  TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);
}
Пример #15
0
TSRemapStatus
TSRemapDoRemap(void *ih, TSHttpTxn rh, TSRemapRequestInfo* rri)
{
  int i, len;
  time_t t, e;
  MD5_CTX ctx;
  struct sockaddr_in *in;
  const char *qh, *ph, *ip;
  unsigned char md[MD5_DIGEST_LENGTH];
  secure_link_info *sli = (secure_link_info *)ih;
  char *token = NULL, *expire = NULL, *path = NULL;
  char *s, *ptr, *saveptr = NULL, *val, hash[32] = "";

  in = (struct sockaddr_in *)TSHttpTxnClientAddrGet(rh);
  ip = inet_ntoa(in->sin_addr);
  s = TSUrlStringGet(rri->requestBufp, rri->requestUrl, &len);
  TSDebug(PLUGIN_NAME, "request [%.*s] from [%s]", len, s, ip);
  TSfree(s);

  qh = TSUrlHttpQueryGet(rri->requestBufp, rri->requestUrl, &len);
  if(qh && len > 0) {
    s = (char *)TSstrndup(qh, len);
    if((ptr = strtok_r(s, "&", &saveptr)) != NULL) {
      do {
        if((val = strchr(ptr, '=')) != NULL) {
          *val++ = '\0';
          if(strcmp(ptr, "st") == 0) {
            token = TSstrdup(val);
          } else if(strcmp(ptr, "ex") == 0) {
            expire = TSstrdup(val);
          }
        } else {
          TSError("Invalid parameter [%s]", ptr);
          break;
        }
      } while((ptr = strtok_r(NULL, "&", &saveptr)) != NULL);
    } else {
      TSError("strtok didn't find a & in the query string");
      /* this is just example, so set fake params to prevent plugin crash */
      token = TSstrdup("d41d8cd98f00b204e9800998ecf8427e");
      expire = TSstrdup("00000000");
    }
    TSfree(s);
  } else {
    TSError("TSUrlHttpQueryGet returns empty value");
  }

  ph = TSUrlPathGet(rri->requestBufp, rri->requestUrl, &len);
  if(ph && len > 0) {
    s = TSstrndup(ph, len);
    if((ptr = strrchr(s, '/')) != NULL) {
      *++ptr = '\0';
    }
    path = TSstrdup(s);
    TSfree(s);
  } else {
    TSError("TSUrlPathGet returns empty value");
    /* this is just example, so set fake params to prevent plugin crash */
    path = TSstrdup("example/");
  }
  MD5_Init(&ctx);
  MD5_Update(&ctx, sli->secret, strlen(sli->secret));
  MD5_Update(&ctx, ip, strlen(ip));
  if (path)
    MD5_Update(&ctx, path, strlen(path));
  if (expire)
    MD5_Update(&ctx, expire, strlen(expire));
  MD5_Final(md, &ctx);
  for(i = 0; i < MD5_DIGEST_LENGTH; i++) {
    sprintf(&hash[i * 2], "%02x", md[i]);
  }
  time(&t);
  e = strtol(expire, NULL, 16);
  i = TSREMAP_DID_REMAP;
  if(e < t || strcmp(hash, token) != 0) {
    if(e < t) {
      TSDebug(PLUGIN_NAME, "link expired: [%lu] vs [%lu]", t, e);
    } else {
      TSDebug(PLUGIN_NAME, "tokens mismatch: [%s] vs [%s]", hash, token);
    }
    if(sli->strict) {
      TSDebug(PLUGIN_NAME, "request is DENY");
      TSHttpTxnSetHttpRetStatus(rh, TS_HTTP_STATUS_FORBIDDEN);
      i = TSREMAP_NO_REMAP;
    } else {
      TSDebug(PLUGIN_NAME, "request is PASS");
    }
  }
  if(i == TSREMAP_DID_REMAP) {
    if(TSUrlHttpQuerySet(rri->requestBufp, rri->requestUrl, "", -1) == TS_SUCCESS) {
      s = TSUrlStringGet(rri->requestBufp, rri->requestUrl, &len);
      TSDebug(PLUGIN_NAME, "new request string is [%.*s]", len, s);
      TSfree(s);
    } else {
      i = TSREMAP_NO_REMAP;
    }
  }
  TSfree(expire);
  TSfree(token);
  TSfree(path);
  return i;
}
void
TSPluginInit(int argc, const char *argv[])
{
  TSPluginRegistrationInfo info;
  TSCont main_cont, config_cont;
  plugin_state_t *pstate;
  invalidate_t *iptr        = NULL;
  bool disable_timed_reload = false;

  TSDebug(LOG_PREFIX, "Starting plugin init");

  pstate = (plugin_state_t *)TSmalloc(sizeof(plugin_state_t));
  init_plugin_state_t(pstate);

  int c;
  static const struct option longopts[] = {{"config", required_argument, NULL, 'c'},
                                           {"log", required_argument, NULL, 'l'},
                                           {"disable-timed-reload", no_argument, NULL, 'd'},
                                           {NULL, 0, NULL, 0}};

  while ((c = getopt_long(argc, (char *const *)argv, "c:l:", longopts, NULL)) != -1) {
    switch (c) {
    case 'c':
      pstate->config_file = TSstrdup(optarg);
      break;
    case 'l':
      if (TS_SUCCESS == TSTextLogObjectCreate(optarg, TS_LOG_MODE_ADD_TIMESTAMP, &pstate->log)) {
        TSTextLogObjectRollingEnabledSet(pstate->log, 1);
        TSTextLogObjectRollingIntervalSecSet(pstate->log, LOG_ROLL_INTERVAL);
        TSTextLogObjectRollingOffsetHrSet(pstate->log, LOG_ROLL_OFFSET);
      }
      break;
    case 'd':
      disable_timed_reload = true;
      break;
    default:
      break;
    }
  }

  if (!pstate->config_file) {
    TSError("[regex_revalidate] Plugin requires a --config option along with a config file name");
    free_plugin_state_t(pstate);
    return;
  }

  if (!load_config(pstate, &iptr)) {
    TSDebug(LOG_PREFIX, "Problem loading config from file %s", pstate->config_file);
  } else {
    pstate->invalidate_list = iptr;
    list_config(pstate, iptr);
  }

  info.plugin_name   = LOG_PREFIX;
  info.vendor_name   = "Apache Software Foundation";
  info.support_email = "*****@*****.**";

  if (TSPluginRegister(&info) != TS_SUCCESS) {
    TSError("[regex_revalidate] Plugin registration failed");

    free_plugin_state_t(pstate);
    return;
  } else {
    TSDebug(LOG_PREFIX, "Plugin registration succeeded");
  }

  if (!check_ts_version()) {
    TSError("[regex_revalidate] Plugin requires Traffic Server %d.%d.%d", TS_VERSION_MAJOR, TS_VERSION_MINOR, TS_VERSION_MICRO);
    free_plugin_state_t(pstate);
    return;
  }

  pcre_malloc = &ts_malloc;
  pcre_free   = &ts_free;

  main_cont = TSContCreate(main_handler, NULL);
  TSContDataSet(main_cont, (void *)pstate);
  TSHttpHookAdd(TS_HTTP_CACHE_LOOKUP_COMPLETE_HOOK, main_cont);

  config_cont = TSContCreate(config_handler, TSMutexCreate());
  TSContDataSet(config_cont, (void *)pstate);

  TSMgmtUpdateRegister(config_cont, LOG_PREFIX);

  if (!disable_timed_reload) {
    TSContScheduleOnPool(config_cont, CONFIG_TMOUT, TS_THREAD_POOL_TASK);
  }

  TSDebug(LOG_PREFIX, "Plugin Init Complete");
}
Пример #17
0
static int regex_compile(regex_info **buf, char *pattern, char *replacement) {
    const char *reerror; /* Error string from pcre */
    int reerroffset;     /* Offset where any pcre error occured */

    int tokcount;
    int *tokens;
    int *tokenoffset;

    int i;

    int status = 1;      /* Status (return value) of the function */

    regex_info *info = TSmalloc(sizeof(regex_info));


    /* Precompile the regular expression */
    info->re =  pcre_compile(pattern, 0, &reerror, &reerroffset, NULL);
    if (!info->re) {
        TSError("[%s] Compilation of regex '%s' failed at char %d: %s\n",
                PLUGIN_NAME, pattern, reerroffset, reerror);
        status = 0;
    }

    /* Precalculate the location of $X tokens in the replacement */
    tokcount = 0;
    if (status) {
        tokens = TSmalloc(sizeof(int) * TOKENCOUNT);
        tokenoffset = TSmalloc(sizeof(int) * TOKENCOUNT);
        for (i=0; i<strlen(replacement); i++) {
            if (replacement[i] == '$') {
                if (tokcount >= TOKENCOUNT) {
                    TSError("[%s] Error: too many tokens in replacement "
                            "string: %s\n", PLUGIN_NAME, replacement);
                    status = 0;
                    break;
                } else if (replacement[i+1] < '0' || replacement[i+1] > '9') {
                    TSError("[%s] Error: Invalid replacement token $%c in "
                            "%s: should be $0 - $9\n", PLUGIN_NAME,
                            replacement[i+1], replacement);
                    status = 0;
                    break;
                } else {
                    /* Store the location of the replacement */
                    /* Convert '0' to 0 */
                    tokens[tokcount] = replacement[i+1] - '0';
                    tokenoffset[tokcount] = i;
                    tokcount++;
                    /* Skip the next char */
                    i++;
                }
            }
        }
    }

    if (status) {
        /* Everything went OK */
        info->tokcount = tokcount;
        info->tokens = tokens;
        info->tokenoffset = tokenoffset;

        info->pattern = TSstrdup(pattern);
        info->replacement = TSstrdup(replacement);

        *buf = info;
    } else {
        /* Something went wrong, clean up */
        if (info->tokens) TSfree(info->tokens);
        if (info->tokenoffset) TSfree(info->tokenoffset);
        if (info->re) pcre_free(info->re);
        if (info) TSfree(info);
    }
    return status;
}
Пример #18
0
/**
 * Handler function to generate an internal error response
 * when ironbee is unavailable to fill the fields or log errors.
 *
 * This may come from a TXN_START event, in which case we're
 * returning an HTTP/0.9 response and most of this is superfluous.
 */
static void internal_error_response(TSHttpTxn txnp)
{
    TSReturnCode rv;
    const char *reason = "Server Unavailable";
    TSMBuffer bufp;
    TSMLoc hdr_loc;
    TSMLoc field_loc;
    char *body;
    char clen[8];
    int i;
    const struct {
        const char *name;
        const char *val;
    } headers[2] = {
        { "Content-Type", "text/plain" },
        { "Content-Length", clen }
    };

    if (TSHttpTxnClientRespGet(txnp, &bufp, &hdr_loc) != TS_SUCCESS) {
        TSError("[ironbee] ErrorDoc: couldn't retrieve client response header.");
        return;
    }
    rv = TSHttpHdrStatusSet(bufp, hdr_loc, 503);
    if (rv != TS_SUCCESS) {
        TSError("[ironbee] ErrorDoc: TSHttpHdrStatusSet");
    }
    rv = TSHttpHdrReasonSet(bufp, hdr_loc, reason, strlen(reason));
    if (rv != TS_SUCCESS) {
        TSError("[ironbee] ErrorDoc: TSHttpHdrReasonSet");
    }

    /* this will free the body, so copy it first! */
    body = TSstrdup("Server unavailable or disabled.\n");

    snprintf(clen, sizeof(clen), "%zd", strlen(body));

    for (i = 0; i < 2; ++i) {
        rv = TSMimeHdrFieldCreate(bufp, hdr_loc, &field_loc);
        if (rv != TS_SUCCESS) {
            TSError("[ironbee] ErrorDoc: TSMimeHdrFieldCreate");
            continue;
        }
        rv = TSMimeHdrFieldNameSet(bufp, hdr_loc, field_loc,
                                   headers[i].name, strlen(headers[i].name));
        if (rv != TS_SUCCESS) {
            TSError("[ironbee] ErrorDoc: TSMimeHdrFieldNameSet");
            goto freehdr;
        }
        rv = TSMimeHdrFieldValueStringInsert(bufp, hdr_loc, field_loc, -1,
                                             headers[i].val, strlen(headers[i].val));
        if (rv != TS_SUCCESS) {
            TSError("[ironbee] ErrorDoc: TSMimeHdrFieldValueStringInsert");
            goto freehdr;
        }
        rv = TSMimeHdrFieldAppend(bufp, hdr_loc, field_loc);
        if (rv != TS_SUCCESS) {
            TSError("[ironbee] ErrorDoc: TSMimeHdrFieldAppend");
            goto freehdr;
        }

freehdr:
        rv = TSHandleMLocRelease(bufp, hdr_loc, field_loc);
        if (rv != TS_SUCCESS) {
            TSError("[ironbee] ErrorDoc: TSHandleMLocRelease 3");
            continue;
        }
    }

    TSHttpTxnErrorBodySet(txnp, body, strlen(body), NULL);

    rv = TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
    if (rv != TS_SUCCESS) {
        TSError("[ironbee] ErrorDoc: TSHandleMLocRelease 4");
    }
}
Пример #19
0
void
TSPluginInit(int argc, const char *argv[])
{
  TSMLoc chk_field_loc;

  TSPluginRegistrationInfo info;

  info.plugin_name = "response-header-1";
  info.vendor_name = "MyCompany";
  info.support_email = "*****@*****.**";

  if (TSPluginRegister(&info) != TS_SUCCESS) {
    TSError("Plugin registration failed.\n");
  }

  init_buffer_status = 0;
  if (argc > 1) {
    TSError("usage: %s \n", argv[0]);
    TSError("warning: too many args %d\n", argc);
    TSError("warning: ignoring unused arguments beginning with %s\n", argv[1]);
  }

  /*
   *  The following code sets up an "init buffer" containing an extension header
   *  and its initial value.  This will be the same for all requests, so we try
   *  to be efficient and do all of the work here rather than on a per-transaction
   *  basis.
   */


  hdr_bufp = TSMBufferCreate();
  TSMimeHdrCreate(hdr_bufp, &hdr_loc);

  mimehdr1_name = TSstrdup("x-num-served-from-cache");
  mimehdr1_value = TSstrdup("0");

  /* Create name here and set DateTime value when o.s.
   * response 200 is received
   */
  mimehdr2_name = TSstrdup("x-date-200-recvd");

  TSDebug("resphdr", "Inserting header %s with value %s into init buffer", mimehdr1_name, mimehdr1_value);

  TSMimeHdrFieldCreate(hdr_bufp, hdr_loc, &field_loc); /* Probably should check for errors */
  TSMimeHdrFieldAppend(hdr_bufp, hdr_loc, field_loc);
  TSMimeHdrFieldNameSet(hdr_bufp, hdr_loc, field_loc, mimehdr1_name, strlen(mimehdr1_name));
  TSMimeHdrFieldValueStringInsert(hdr_bufp, hdr_loc, field_loc, -1, mimehdr1_value, strlen(mimehdr1_value));
  TSDebug("resphdr", "init buffer hdr, field and value locs are %p, %p and %p", hdr_loc, field_loc, value_loc);
  init_buffer_status = 1;


  TSHttpHookAdd(TS_HTTP_READ_RESPONSE_HDR_HOOK, TSContCreate(modify_response_header_plugin, NULL));

  /*
   *  The following code demonstrates how to extract the field_loc from the header.
   *  In this plugin, the init buffer and thus field_loc never changes.  Code
   *  similar to this may be used to extract header fields from any buffer.
   */

  if (TS_NULL_MLOC == (chk_field_loc = TSMimeHdrFieldGet(hdr_bufp, hdr_loc, 0))) {
    TSError("couldn't retrieve header field from init buffer");
    TSError("marking init buffer as corrupt; no more plugin processing");
    init_buffer_status = 0;
    /* bail out here and reenable transaction */
  } else {
    if (field_loc != chk_field_loc)
      TSError("retrieved buffer field loc is %p when it should be %p", chk_field_loc, field_loc);
  }
}