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("[%s] Couldn't retrieve client response header", PLUGIN_NAME);
    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);
}
Example #2
0
static int
hdr_handler(TSCont contp, TSHttpTxn txnp)
{
	TSMBuffer  	bufp;
	TSMLoc		hdr_loc, field_loc; 
	hdr_list 	*hdr;

	hdr = TSContDataGet(contp);
	if (hdr == NULL) {
		goto done;
	} 

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


	for (; hdr; hdr = hdr->next) {
		TSMimeHdrFieldCreate(bufp, hdr_loc, &field_loc);
		TSMimeHdrFieldNameSet(bufp, hdr_loc, field_loc, hdr->name, strlen(hdr->name));
		TSMimeHdrFieldValueStringInsert(bufp, hdr_loc, field_loc, -1, hdr->val, strlen(hdr->val));
		TSMimeHdrFieldAppend(bufp, hdr_loc, field_loc);

		TSHandleMLocRelease(bufp, hdr_loc, field_loc);
		TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
	}


done:
	TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);
	
	return 0;
}
static int
ts_lua_client_response_header_set(lua_State * L)
{
  const char *key;
  const char *val;
  size_t val_len;
  size_t key_len;
  int remove;

  TSMLoc field_loc;

  ts_lua_http_ctx *http_ctx;

  http_ctx = ts_lua_get_http_ctx(L);

  remove = 0;
  val = NULL;

  /*  we skip the first argument that is the table */
  key = luaL_checklstring(L, 2, &key_len);
  if (lua_isnil(L, 3)) {
    remove = 1;
  } else {
    val = luaL_checklstring(L, 3, &val_len);
  }

  if (!http_ctx->client_response_hdrp) {
    if (TSHttpTxnClientRespGet(http_ctx->txnp, &http_ctx->client_response_bufp,
                               &http_ctx->client_response_hdrp) != TS_SUCCESS) {
      return 0;
    }
  }

  field_loc = TSMimeHdrFieldFind(http_ctx->client_response_bufp, http_ctx->client_response_hdrp, key, key_len);

  if (remove) {
    if (field_loc) {
      TSMimeHdrFieldDestroy(http_ctx->client_response_bufp, http_ctx->client_response_hdrp, field_loc);
    }

  } else if (field_loc) {
    TSMimeHdrFieldValueStringSet(http_ctx->client_response_bufp, http_ctx->client_response_hdrp, field_loc, 0, val,
                                 val_len);

  } else if (TSMimeHdrFieldCreateNamed(http_ctx->client_response_bufp, http_ctx->client_response_hdrp,
                                       key, key_len, &field_loc) != TS_SUCCESS) {
    TSError("[%s] TSMimeHdrFieldCreateNamed error", __FUNCTION__);
    return 0;

  } else {
    TSMimeHdrFieldValueStringSet(http_ctx->client_response_bufp, http_ctx->client_response_hdrp, field_loc, -1, val,
                                 val_len);
    TSMimeHdrFieldAppend(http_ctx->client_response_bufp, http_ctx->client_response_hdrp, field_loc);
  }

  if (field_loc)
    TSHandleMLocRelease(http_ctx->client_response_bufp, http_ctx->client_response_hdrp, field_loc);

  return 0;
}
static int
ts_lua_client_response_header_get(lua_State * L)
{
  const char *key;
  const char *val;
  int val_len;
  size_t key_len;

  TSMLoc field_loc;

  ts_lua_http_ctx *http_ctx;

  http_ctx = ts_lua_get_http_ctx(L);

  /*  we skip the first argument that is the table */
  key = luaL_checklstring(L, 2, &key_len);

  if (!http_ctx->client_response_hdrp) {
    if (TSHttpTxnClientRespGet(http_ctx->txnp,
                               &http_ctx->client_response_bufp, &http_ctx->client_response_hdrp) != TS_SUCCESS) {

      lua_pushnil(L);
      return 1;
    }
  }

  if (key && key_len) {

    field_loc = TSMimeHdrFieldFind(http_ctx->client_response_bufp, http_ctx->client_response_hdrp, key, key_len);
    if (field_loc) {
      val =
        TSMimeHdrFieldValueStringGet(http_ctx->client_response_bufp, http_ctx->client_response_hdrp, field_loc, -1,
                                     &val_len);
      lua_pushlstring(L, val, val_len);
      TSHandleMLocRelease(http_ctx->client_response_bufp, http_ctx->client_response_hdrp, field_loc);

    } else {
      lua_pushnil(L);
    }

  } else {
    lua_pushnil(L);
  }

  return 1;
}
Example #5
0
static void
handle_response(TSHttpTxn txnp, TSCont contp ATS_UNUSED)
{
  TSMBuffer bufp;
  TSMLoc hdr_loc;
  TSMLoc url_loc;
  char *url_str;
  char *buf;
  int url_length;

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

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

  if (TSHttpTxnClientReqGet(txnp, &bufp, &hdr_loc) != TS_SUCCESS) {
    TSError("[%s] Couldn't retrieve client request header", PLUGIN_NAME);
    TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
    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;
  }

  buf = (char *)TSmalloc(4096);

  url_str = TSUrlStringGet(bufp, url_loc, &url_length);
  sprintf(buf, "You are forbidden from accessing \"%s\"\n", url_str);
  TSfree(url_str);
  TSHandleMLocRelease(bufp, hdr_loc, url_loc);
  TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);

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

done:
  TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);
}
Example #6
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;
}
static int
ts_lua_client_response_header_get_status(lua_State *L)
{
    int              status;
    ts_lua_http_ctx  *http_ctx;

    http_ctx = ts_lua_get_http_ctx(L);

    if (!http_ctx->client_response_hdrp) {
        if (TSHttpTxnClientRespGet(http_ctx->txnp,
                    &http_ctx->client_response_bufp, &http_ctx->client_response_hdrp) != TS_SUCCESS) {

            lua_pushnil(L);
            return 1;
        }
    }

    status = TSHttpHdrStatusGet(http_ctx->client_response_bufp, http_ctx->client_response_hdrp);

    lua_pushinteger(L, status);

    return 1;
}
Example #8
0
/**
 * Handler function to generate an error response
 */
static void error_response(TSHttpTxn txnp, tsib_txn_ctx *txndata)
{
    const char *reason;
    TSMBuffer bufp;
    TSMLoc hdr_loc;
    TSMLoc field_loc;
    hdr_list *hdrs;
    TSReturnCode rv;

    /* make caller responsible for sanity checking */
    assert((txndata != NULL) && (txndata->tx != NULL));

    reason = TSHttpHdrReasonLookup(txndata->status);

    if (TSHttpTxnClientRespGet(txnp, &bufp, &hdr_loc) != TS_SUCCESS) {
        ib_log_error_tx(txndata->tx,
                        "ErrorDoc: couldn't retrieve client response header.");
        TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);
        return;
    }
    rv = TSHttpHdrStatusSet(bufp, hdr_loc, txndata->status);
    if (rv != TS_SUCCESS) {
        ib_log_error_tx(txndata->tx,
                        "ErrorDoc: TSHttpHdrStatusSet");
    }
    if (reason == NULL) {
        reason = "Other";
    }
    rv = TSHttpHdrReasonSet(bufp, hdr_loc, reason, strlen(reason));
    if (rv != TS_SUCCESS) {
        ib_log_error_tx(txndata->tx,
                        "ErrorDoc: TSHttpHdrReasonSet");
    }

    while (hdrs = txndata->err_hdrs, hdrs != 0) {
        txndata->err_hdrs = hdrs->next;
        rv = TSMimeHdrFieldCreate(bufp, hdr_loc, &field_loc);
        if (rv != TS_SUCCESS) {
            ib_log_error_tx(txndata->tx,
                            "ErrorDoc: TSMimeHdrFieldCreate");
            continue;
        }
        rv = TSMimeHdrFieldNameSet(bufp, hdr_loc, field_loc,
                                   hdrs->hdr, strlen(hdrs->hdr));
        if (rv != TS_SUCCESS) {
            ib_log_error_tx(txndata->tx,
                            "ErrorDoc: TSMimeHdrFieldNameSet");
            goto errordoc_free1;
        }
        rv = TSMimeHdrFieldValueStringInsert(bufp, hdr_loc, field_loc, -1,
                                        hdrs->value, strlen(hdrs->value));
        if (rv != TS_SUCCESS) {
            ib_log_error_tx(txndata->tx,
                            "ErrorDoc: TSMimeHdrFieldValueStringInsert");
            goto errordoc_free1;
        }
        rv = TSMimeHdrFieldAppend(bufp, hdr_loc, field_loc);
        if (rv != TS_SUCCESS) {
            ib_log_error_tx(txndata->tx,
                            "ErrorDoc: TSMimeHdrFieldAppend");
            goto errordoc_free1;
        }

errordoc_free1:
        rv = TSHandleMLocRelease(bufp, hdr_loc, field_loc);
        if (rv != TS_SUCCESS) {
            ib_log_error_tx(txndata->tx,
                            "ErrorDoc: TSHandleMLocRelease 1");
            continue;
        }
    }

    if (txndata->err_body) {
        /* this will free the body, so copy it first! */
        TSHttpTxnErrorBodySet(txnp, txndata->err_body,
                              txndata->err_body_len, NULL);
    }
    rv = TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
    if (rv != TS_SUCCESS) {
        ib_log_error_tx(txndata->tx,
                        "ErrorDoc: TSHandleMLocRelease 2");
    }

    ib_log_debug_tx(txndata->tx,
                    "Sent error page %d \"%s\".", txndata->status, reason);
}
Example #9
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");
    }
}
Example #10
0
static int
handle_txn_close(TSCont cont, TSEvent event ATS_UNUSED, void *edata)
{
  TSHttpTxn txn = (TSHttpTxn) edata;
  config_t *config;
  void *txnd;
  int status_code = 0;
  TSMBuffer buf;
  TSMLoc hdr_loc;
  uint64_t out_bytes, in_bytes;
  char *remap, *hostname;
  char *unknown = "unknown";
  char stat_name[MAX_STAT_LENGTH];

  config = (config_t *) TSContDataGet(cont);
  txnd = TSHttpTxnArgGet(txn, config->txn_slot);

  hostname = (char *) ((uintptr_t) txnd & (~((uintptr_t) 0x01)));       // Get hostname

  if (txnd) {
    if ((uintptr_t) txnd & 0x01)        // remap succeeded?
    {
      if (!config->post_remap_host)
        remap = hostname;
      else
        remap = get_effective_host(txn);

      if (!remap)
        remap = unknown;

      in_bytes = TSHttpTxnClientReqHdrBytesGet(txn);
      in_bytes += TSHttpTxnClientReqBodyBytesGet(txn);

      CREATE_STAT_NAME(stat_name, remap, "in_bytes");
      stat_add(stat_name, (TSMgmtInt) in_bytes, config->persist_type, config->stat_creation_mutex);

      out_bytes = TSHttpTxnClientRespHdrBytesGet(txn);
      out_bytes += TSHttpTxnClientRespBodyBytesGet(txn);

      CREATE_STAT_NAME(stat_name, remap, "out_bytes");
      stat_add(stat_name, (TSMgmtInt) out_bytes, config->persist_type, config->stat_creation_mutex);

      if (TSHttpTxnClientRespGet(txn, &buf, &hdr_loc) == TS_SUCCESS) {
        status_code = (int) TSHttpHdrStatusGet(buf, hdr_loc);
        TSHandleMLocRelease(buf, TS_NULL_MLOC, hdr_loc);

        if (status_code < 200)
          CREATE_STAT_NAME(stat_name, remap, "status_other");
        else if (status_code <= 299)
          CREATE_STAT_NAME(stat_name, remap, "status_2xx");
        else if (status_code <= 399)
          CREATE_STAT_NAME(stat_name, remap, "status_3xx");
        else if (status_code <= 499)
          CREATE_STAT_NAME(stat_name, remap, "status_4xx");
        else if (status_code <= 599)
          CREATE_STAT_NAME(stat_name, remap, "status_5xx");
        else
          CREATE_STAT_NAME(stat_name, remap, "status_other");

        stat_add(stat_name, 1, config->persist_type, config->stat_creation_mutex);
      } else {
        CREATE_STAT_NAME(stat_name, remap, "status_unknown");
        stat_add(stat_name, 1, config->persist_type, config->stat_creation_mutex);
      }

      if (remap != unknown)
        TSfree(remap);
    } else if (hostname)
      TSfree(hostname);
  }

  TSHttpTxnReenable(txn, TS_EVENT_HTTP_CONTINUE);
  TSDebug(DEBUG_TAG, "Handler Finished");
  return 0;
}