static void
list_config(plugin_state_t *pstate, invalidate_t *i)
{
  invalidate_t *iptr;

  TSDebug(LOG_PREFIX, "Current config:");
  if (pstate->log) {
    TSTextLogObjectWrite(pstate->log, "Current config:");
  }
  if (i) {
    iptr = i;
    while (iptr) {
      TSDebug(LOG_PREFIX, "%s epoch: %d expiry: %d", iptr->regex_text, (int)iptr->epoch, (int)iptr->expiry);
      if (pstate->log) {
        TSTextLogObjectWrite(pstate->log, "%s epoch: %d expiry: %d", iptr->regex_text, (int)iptr->epoch, (int)iptr->expiry);
      }
      iptr = iptr->next;
    }
  } else {
    TSDebug(LOG_PREFIX, "EMPTY");
    if (pstate->log) {
      TSTextLogObjectWrite(pstate->log, "EMPTY");
    }
  }
}
示例#2
0
文件: ironbee.c 项目: igalic/ironbee
static void ironbee_logger(void *dummy, int level,
                           const char *prefix, const char *file, int line,
                           const char *fmt, va_list ap)
{
    char buf[8192 + 1];
    int limit = 7000;
    int ec;
    TSReturnCode rc;
    const char *errmsg = NULL;

    /* Buffer the log line. */
    ec = vsnprintf(buf, sizeof(buf), fmt, ap);
    if (ec >= limit) {
        /* Mark as truncated, with a " ...". */
        memcpy(buf + (limit - 5), " ...", 5);
        errmsg = "Data truncated in log";
    }

    /* Write it to the ironbee log. */
    /* FIXME: why is the format arg's prototype not const char* ? */
    rc = prefix ? TSTextLogObjectWrite(ironbee_log, (char*)"%s: %s", prefix, buf)
                : TSTextLogObjectWrite(ironbee_log, (char*)"%s", buf);
    if (rc != TS_SUCCESS) {
        errmsg = "Data logging failed!";
    }
    if (errmsg != NULL)
        TSError("[ts-ironbee] %s\n", errmsg);
}
示例#3
0
/**
 * Handle a single log record. This is a @ref ib_logger_standard_msg_t.
 *
 * @param[in] element A @ref ib_logger_standard_msg_t holding
 *            a serialized transaction log to be written to the
 *            Traffic Server transaction log.
 * @param[in] cbdata A @ref module_data_t.
 */
static void txlog_record_element(
    void *element,
    void *cbdata
)
{
    assert(element != NULL);
    assert(cbdata != NULL);

    ib_logger_standard_msg_t *msg      = (ib_logger_standard_msg_t *)element;
    module_data_t            *mod_data = (module_data_t *)cbdata;

    /* FIXME - expand msg->msg with Traffic Server variables. */
    /* I don't understand what is TBD here! */

    if (!mod_data->txlogger) {
        /* txlogging off  */
        return;
    }

    /* write log file. */
    if (msg->msg != NULL) {
        /* In practice, this is always NULL for txlogs. */
        if (msg->prefix != NULL) {
            TSTextLogObjectWrite(mod_data->txlogger, "%s %.*s", msg->prefix,
                                 (int)msg->msg_sz, (const char *)msg->msg);
        }
        else {
            TSTextLogObjectWrite(mod_data->txlogger, "%.*s",
                                 (int)msg->msg_sz, (const char *)msg->msg);
        }
        /* FIXME: once debugged, take this out for speed */
        TSTextLogObjectFlush(mod_data->txlogger);
    }
}
示例#4
0
static void
protocol_init(int accept_port, int server_port ATS_UNUSED)
{
  TSCont contp;
  int ret_val;

  /* create customized log */
  ret_val = TSTextLogObjectCreate("protocol", TS_LOG_MODE_ADD_TIMESTAMP, &protocol_plugin_log);
  if (ret_val != TS_SUCCESS) {
    TSError("[protocol] Failed to create log");
  }

  /* format of the log entries, for caching_status, 1 for HIT and 0 for MISS */
  ret_val = TSTextLogObjectWrite(protocol_plugin_log, "timestamp filename servername caching_status\n\n");
  if (ret_val != TS_SUCCESS) {
    TSError("[protocol] Failed to write into log");
  }

  contp = TSContCreate(accept_handler, TSMutexCreate());

  /* Accept network traffic from the accept_port.
     When there are requests coming in, contp's handler
     should be called, in this case, contp's handler
     is accept_event, see AcceptSM.c */
  pending_action = TSNetAccept(contp, accept_port, -1, 1);
}
示例#5
0
/**
 * Log a message to the server plugin.
 *
 * @param[in] ib_logger The IronBee logger.
 * @param[in] rec The record to use in logging.
 * @param[in] log_msg The user's log message.
 * @param[in] log_msg_sz The user's log message size.
 * @param[out] writer_record Unused. We always return IB_DECLINED.
 * @param[in] cbdata The server plugin module data used for logging.
 *
 * @returns
 * - IB_DECLINED when everything goes well.
 * - IB_OK is not returned.
 * - Other on error.
 */
static ib_status_t logger_format(
    ib_logger_t           *ib_logger,
    const ib_logger_rec_t *rec,
    const uint8_t         *log_msg,
    const size_t           log_msg_sz,
    void                  *writer_record,
    void                  *cbdata
)
{
    assert(ib_logger != NULL);
    assert(rec != NULL);
    assert(log_msg != NULL);
    assert(cbdata != NULL);

    if (cbdata == NULL) {
        return IB_DECLINED;
    }

    module_data_t   *mod_data = (module_data_t *)cbdata;
    TSTextLogObject  logger = mod_data->logger;

    if (logger == NULL) {
        return IB_DECLINED;
    }
    if (log_msg == NULL || log_msg_sz == 0) {
        TSTextLogObjectFlush(logger);
    }
    else {

        ib_logger_standard_msg_t *std_msg = NULL;

        ib_status_t rc = ib_logger_standard_formatter_notime(
            ib_logger,
            rec,
            log_msg,
            log_msg_sz,
            &std_msg,
            NULL);
        if (rc != IB_OK) {
            return rc;
        }

        TSTextLogObjectWrite(
            logger,
            "%s %.*s",
            std_msg->prefix,
            (int)std_msg->msg_sz,
            (const char *)std_msg->msg);

        ib_logger_standard_msg_free(ib_logger, std_msg, cbdata);
    }

    return IB_DECLINED;
}
static void
list_config(config_holder_t *config_holder, invalidate_t *i)
{
  invalidate_t *iptr;

  TSDebug(PLUGIN_TAG, "Current config:");
  if (config_holder->log)
    TSTextLogObjectWrite(config_holder->log, "Current config:");
  if (i) {
    iptr = i;
    while (iptr) {
      TSDebug(PLUGIN_TAG, "%s epoch: %d expiry: %d", iptr->regex_text, (int)iptr->epoch, (int)iptr->expiry);
      if (config_holder->log)
        TSTextLogObjectWrite(config_holder->log, "%s epoch: %d expiry: %d", iptr->regex_text, (int)iptr->epoch, (int)iptr->expiry);
      iptr = iptr->next;
    }
  } else {
    TSDebug(PLUGIN_TAG, "EMPTY");
    if (config_holder->log)
      TSTextLogObjectWrite(config_holder->log, "EMPTY");
  }
}
static int
ts_lua_log_object_write(lua_State *L)
{
  const char *text;
  size_t text_len;

  text = luaL_checklstring(L, 1, &text_len);
  if (log) {
    TSTextLogObjectWrite(log, (char *)text, NULL);
  } else {
    TSError("[ts_lua][%s] log object does not exist for write", __FUNCTION__);
  }

  return 0;
}
示例#8
0
static int rewrite_cacheurl(pr_list *prl, TSHttpTxn txnp) {
    int ok = 1;
    char *newurl = 0;
    int retval;

    char *url;
    int url_length;
    int i;
    if (ok) {
        url = TSHttpTxnEffectiveUrlStringGet(txnp, &url_length);
        if (!url) {
            TSError("[%s] couldn't retrieve request url\n",
                    PLUGIN_NAME);
            ok = 0;
        }
    }

    if (ok) {
        i=0;
        while (i < prl->patterncount && prl->pr[i]) {
            retval = regex_substitute(&newurl, url, prl->pr[i]);
            if (retval) {
                /* Successful match/substitution */
                break;
            }
            i++;
        }
        if (newurl) {
            if (log) {
                TSTextLogObjectWrite(log,
                        "Rewriting cache URL for %s to %s", url,
                        newurl);
            }
            TSDebug(PLUGIN_NAME, "Rewriting cache URL for %s to %s\n",
                    url, newurl);
            if (TSCacheUrlSet(txnp, newurl, strlen(newurl))
                    != TS_SUCCESS) {
                TSError("[%s] Unable to modify cache url from "
                        "%s to %s\n", PLUGIN_NAME, url, newurl);
                ok = 0;
            }
        }
    }
    /* Clean up */
    if (url) TSfree(url);
    if (newurl) TSfree(newurl);
    return ok;
}
示例#9
0
static void
handle_dns(TSHttpTxn txnp, TSCont contp)
{
  TSMBuffer bufp;
  TSMLoc hdr_loc;
  TSMLoc url_loc;
  const char *host;
  int i;
  int host_length;

  if (TSHttpTxnClientReqGet(txnp, &bufp, &hdr_loc) != TS_SUCCESS) {
    TSError("[%s] Couldn't retrieve client request header", PLUGIN_NAME);
    goto done;
  }

  if (TSHttpHdrUrlGet(bufp, hdr_loc, &url_loc) != TS_SUCCESS) {
    TSError("[%s] Couldn't retrieve request url", PLUGIN_NAME);
    TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
    goto done;
  }

  host = TSUrlHostGet(bufp, url_loc, &host_length);
  if (!host) {
    TSError("[%s] Couldn't retrieve request hostname", PLUGIN_NAME);
    TSHandleMLocRelease(bufp, hdr_loc, url_loc);
    TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
    goto done;
  }

  /* We need to lock the sites_mutex as that is the mutex that is
     protecting the global list of all blacklisted sites. */
  if (TSMutexLockTry(sites_mutex) != TS_SUCCESS) {
    TSDebug(PLUGIN_NAME, "Unable to get lock. Will retry after some time");
    TSHandleMLocRelease(bufp, hdr_loc, url_loc);
    TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
    TSContSchedule(contp, RETRY_TIME, TS_THREAD_POOL_DEFAULT);
    return;
  }

  for (i = 0; i < nsites; i++) {
    if (strncmp(host, sites[i], host_length) == 0) {
      if (log) {
        TSTextLogObjectWrite(log, "blacklisting site: %s", sites[i]);
      } else {
        TSDebug(PLUGIN_NAME, "blacklisting site: %s", sites[i]);
      }
      TSHttpTxnHookAdd(txnp, TS_HTTP_SEND_RESPONSE_HDR_HOOK, contp);
      TSHandleMLocRelease(bufp, hdr_loc, url_loc);
      TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
      TSHttpTxnReenable(txnp, TS_EVENT_HTTP_ERROR);
      TSMutexUnlock(sites_mutex);
      return;
    }
  }

  TSMutexUnlock(sites_mutex);
  TSHandleMLocRelease(bufp, hdr_loc, url_loc);
  TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);

done:
  TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);
}
示例#10
0
/*-------------------------------------------------------------------------
  psi_include
  Read file to include. Copy its content into an iobuffer.

  This is the function doing blocking calls and called by the plugin's threads

  Input:
    data      continuation for the current transaction
  Output :
    data->psi_buffer  contains the file content
    data->psi_sucess  0 if include failed, 1 if success
  Return Value:
    0  if failure
    1  if success
  -------------------------------------------------------------------------*/
static int
psi_include(TSCont contp, void *edata)
{
#define BUFFER_SIZE 1024
  ContData *data;
  TSFile filep;
  char buf[BUFFER_SIZE];
  char inc_file[PSI_PATH_MAX_SIZE + PSI_FILENAME_MAX_SIZE];

  /* We manipulate plugin continuation data from a separate thread.
     Grab mutex to avoid concurrent access */
  TSMutexLock(TSContMutexGet(contp));
  data = TSContDataGet(contp);
  TSAssert(data->magic == MAGIC_ALIVE);

  if (!data->psi_buffer) {
    data->psi_buffer = TSIOBufferCreate();
    data->psi_reader = TSIOBufferReaderAlloc(data->psi_buffer);
  }

  /* For security reason, we do not allow to include files that are
     not in the directory <plugin_path>/include.
     Also include file cannot contain any path. */
  sprintf(inc_file, "%s/%s", psi_directory, _basename(data->psi_filename));

  /* Read the include file and copy content into iobuffer */
  if ((filep = TSfopen(inc_file, "r")) != NULL) {
    TSDebug(DBG_TAG, "Reading include file %s", inc_file);

    while (TSfgets(filep, buf, BUFFER_SIZE) != NULL) {
      TSIOBufferBlock block;
      int64_t len, avail, ndone, ntodo, towrite;
      char *ptr_block;

      len = strlen(buf);
      ndone = 0;
      ntodo = len;
      while (ntodo > 0) {
        /* TSIOBufferStart allocates more blocks if required */
        block = TSIOBufferStart(data->psi_buffer);
        ptr_block = TSIOBufferBlockWriteStart(block, &avail);
        towrite = MIN(ntodo, avail);

        memcpy(ptr_block, buf + ndone, towrite);
        TSIOBufferProduce(data->psi_buffer, towrite);
        ntodo -= towrite;
        ndone += towrite;
      }
    }
    TSfclose(filep);
    data->psi_success = 1;
    if (log) {
      TSTextLogObjectWrite(log, "Successfully included file: %s", inc_file);
    }
  } else {
    data->psi_success = 0;
    if (log) {
      TSTextLogObjectWrite(log, "Failed to include file: %s", inc_file);
    }
  }

  /* Change state and schedule an event EVENT_IMMEDIATE on the plugin continuation
     to let it know we're done. */

  /* Note: if the blocking call was not in the transformation state (i.e. in
     TS_HTTP_READ_REQUEST_HDR, TS_HTTP_OS_DNS and so on...) we could
     use TSHttpTxnReenable to wake up the transaction instead of sending an event. */

  TSContSchedule(contp, 0, TS_THREAD_POOL_DEFAULT);
  data->psi_success = 0;
  data->state = STATE_READ_DATA;
  TSMutexUnlock(TSContMutexGet(contp));

  return 0;
}
示例#11
0
static pr_list* load_config_file(const char *config_file) {
    char buffer[1024];
    char default_config_file[1024];
    TSFile fh;
    pr_list *prl = TSmalloc(sizeof(pr_list));
    prl->patterncount = 0;

    /* locations in a config file line, end of line, split start, split end */
    char *eol, *spstart, *spend;
    int lineno = 0;
    int retval;
    regex_info *info = 0;

    if (!config_file) {
        /* Default config file of plugins/cacheurl.config */
        sprintf(default_config_file, "%s/cacheurl.config", TSPluginDirGet());
        config_file = (const char *)default_config_file;
    }
    TSDebug(PLUGIN_NAME, "Opening config file: %s", config_file);
    fh = TSfopen(config_file, "r");

    if (!fh) {
        TSError("[%s] Unable to open %s. No patterns will be loaded\n",
                PLUGIN_NAME, config_file);
        return prl;
    }

    while (TSfgets(fh, buffer, sizeof(buffer) - 1)) {
        lineno++;
        if (*buffer == '#') {
            /* # Comments, only at line beginning */
            continue;
        }
        eol = strstr(buffer, "\n");
        if (eol) {
            *eol = 0; /* Terminate string at newline */
        } else {
            /* Malformed line - skip */
            continue;
        }
        /* Split line into two parts based on whitespace */
        /* Find first whitespace */
        spstart = strstr(buffer, " ");
        if (!spstart) {
            spstart = strstr(buffer, "\t");
        }
        if (!spstart) {
            TSError("[%s] ERROR: Invalid format on line %d. Skipping\n",
                    PLUGIN_NAME, lineno);
            continue;
        }
        /* Find part of the line after any whitespace */
        spend = spstart + 1;
        while(*spend == ' ' || *spend == '\t') {
            spend++;
        }
        if (*spend == 0) {
            /* We reached the end of the string without any non-whitepace */
            TSError("[%s] ERROR: Invalid format on line %d. Skipping\n",
                    PLUGIN_NAME, lineno);
            continue;
        }

        *spstart = 0;
        /* We have the pattern/replacement, now do precompilation.
         * buffer is the first part of the line. spend is the second part just
         * after the whitespace */
        if (log) {
            TSTextLogObjectWrite(log,
                    "Adding pattern/replacement pair: '%s' -> '%s'",
                    buffer, spend);
        }
        TSDebug(PLUGIN_NAME, "Adding pattern/replacement pair: '%s' -> '%s'\n",
                buffer, spend);
        retval = regex_compile(&info, buffer, spend);
        if (!retval) {
            TSError("[%s] Error precompiling regex/replacement. Skipping.\n",
                    PLUGIN_NAME);
        }
        // TODO - remove patterncount and make pr_list infinite (linked list)
        if (prl->patterncount >= PATTERNCOUNT) {
            TSError("[%s] Warning, too many patterns - skipping the rest"
                    "(max: %d)\n", PLUGIN_NAME, PATTERNCOUNT);
            TSfree(info);
            break;
        }
        prl->pr[prl->patterncount] = info;
        prl->patterncount++;
    }
    TSfclose(fh);
    // Make sure the last element is null
    if (prl->patterncount < PATTERNCOUNT) {
        prl->pr[prl->patterncount] = NULL;
    }
    return prl;
}