static int
ts_lua_server_request_get_uri(lua_State *L)
{
  char uri[TS_LUA_MAX_URL_LENGTH];
  const char *path;
  int path_len;
  int uri_len;

  ts_lua_http_ctx *http_ctx;

  GET_HTTP_CONTEXT(http_ctx, L);

  TS_LUA_CHECK_SERVER_REQUEST_URL(http_ctx);

  path = TSUrlPathGet(http_ctx->server_request_bufp, http_ctx->server_request_url, &path_len);

  uri_len = snprintf(uri, TS_LUA_MAX_URL_LENGTH, "/%.*s", path_len, path);

  if (uri_len >= TS_LUA_MAX_URL_LENGTH) {
    lua_pushlstring(L, uri, TS_LUA_MAX_URL_LENGTH - 1);
  } else {
    lua_pushlstring(L, uri, uri_len);
  }

  return 1;
}
Esempio n. 2
0
static int
ts_lua_remap_get_to_uri(lua_State *L)
{
  char uri[TS_LUA_MAX_URL_LENGTH];
  const char *path;
  int path_len;
  int uri_len;

  ts_lua_http_ctx *http_ctx;

  GET_HTTP_CONTEXT(http_ctx, L);

  if (http_ctx->rri != NULL) {
    path = TSUrlPathGet(http_ctx->client_request_bufp, http_ctx->rri->mapToUrl, &path_len);

    uri_len = snprintf(uri, TS_LUA_MAX_URL_LENGTH, "/%.*s", path_len, path);

    if (uri_len >= TS_LUA_MAX_URL_LENGTH) {
      lua_pushlstring(L, uri, TS_LUA_MAX_URL_LENGTH - 1);
    } else {
      lua_pushlstring(L, uri, uri_len);
    }
  } else {
    lua_pushnil(L);
  }

  return 1;
}
static int
stats_origin(TSCont contp ATS_UNUSED, TSEvent event ATS_UNUSED, void *edata)
{
  TSCont icontp;
  stats_state *my_state;
  TSHttpTxn txnp = (TSHttpTxn)edata;
  TSMBuffer reqp;
  TSMLoc hdr_loc = NULL, url_loc = NULL;
  TSEvent reenable = TS_EVENT_HTTP_CONTINUE;

  TSDebug(PLUGIN_NAME, "in the read stuff");

  if (TSHttpTxnClientReqGet(txnp, &reqp, &hdr_loc) != TS_SUCCESS) {
    goto cleanup;
  }

  if (TSHttpHdrUrlGet(reqp, hdr_loc, &url_loc) != TS_SUCCESS) {
    goto cleanup;
  }

  int path_len     = 0;
  const char *path = TSUrlPathGet(reqp, url_loc, &path_len);
  TSDebug(PLUGIN_NAME, "Path: %.*s", path_len, path);

  if (!(path_len != 0 && path_len == url_path_len && !memcmp(path, url_path, url_path_len))) {
    goto notforme;
  }

  TSSkipRemappingSet(txnp, 1); // not strictly necessary, but speed is everything these days

  /* This is us -- register our intercept */
  TSDebug(PLUGIN_NAME, "Intercepting request");

  icontp   = TSContCreate(stats_dostuff, TSMutexCreate());
  my_state = (stats_state *)TSmalloc(sizeof(*my_state));
  memset(my_state, 0, sizeof(*my_state));
  TSContDataSet(icontp, my_state);
  TSHttpTxnIntercept(icontp, txnp);
  goto cleanup;

notforme:

cleanup:
  if (url_loc) {
    TSHandleMLocRelease(reqp, hdr_loc, url_loc);
  }
  if (hdr_loc) {
    TSHandleMLocRelease(reqp, TS_NULL_MLOC, hdr_loc);
  }

  TSHttpTxnReenable(txnp, reenable);
  return 0;
}
/* Read-request header continuation, used to kick off the server intercept if necessary */
static int
health_check_origin(TSCont contp, TSEvent event, void *edata)
{
  TSMBuffer reqp;
  TSMLoc hdr_loc = NULL, url_loc = NULL;
  TSCont icontp;
  HCState *my_state;
  TSHttpTxn txnp = (TSHttpTxn) edata;
  HCFileInfo *info = g_config;

  if ((TS_SUCCESS == TSHttpTxnClientReqGet(txnp, &reqp, &hdr_loc)) &&
      (TS_SUCCESS == TSHttpHdrUrlGet(reqp, hdr_loc, &url_loc))) {
    int path_len = 0;
    const char* path = TSUrlPathGet(reqp, url_loc, &path_len);

    while (info) {
      if (info->p_len == path_len && !memcmp(info->path, path, path_len))
        break;
      info = info->_next;
    }

    if (!info)
      goto cleanup;

    TSSkipRemappingSet(txnp, 1); /* not strictly necessary, but speed is everything these days */

    /* This is us -- register our intercept */
    icontp = TSContCreate(hc_intercept, TSMutexCreate());
    my_state = (HCState *)TSmalloc(sizeof(*my_state));
    memset(my_state, 0, sizeof(*my_state));
    my_state->info = info;
    my_state->data = info->data;
    TSContDataSet(icontp, my_state);
    TSHttpTxnIntercept(icontp, txnp);
  }

 cleanup:
  if (url_loc)
    TSHandleMLocRelease(reqp, hdr_loc, url_loc);
  if (hdr_loc)
    TSHandleMLocRelease(reqp, TS_NULL_MLOC, hdr_loc);

  TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);

  return 0;
}
Esempio n. 5
0
/* Read-request header continuation, used to kick off the server intercept if necessary */
static int
acme_hook(TSCont contp ATS_UNUSED, TSEvent event ATS_UNUSED, void *edata)
{
  TSMBuffer reqp;
  TSMLoc hdr_loc = NULL, url_loc = NULL;
  TSCont icontp;
  AcmeState *my_state;
  TSHttpTxn txnp = (TSHttpTxn)edata;

  TSDebug(PLUGIN_NAME, "kicking off ACME hook");

  if ((TS_SUCCESS == TSHttpTxnClientReqGet(txnp, &reqp, &hdr_loc)) && (TS_SUCCESS == TSHttpHdrUrlGet(reqp, hdr_loc, &url_loc))) {
    int path_len     = 0;
    const char *path = TSUrlPathGet(reqp, url_loc, &path_len);

    /* Short circuit the / path, common case */
    if (!path || path_len < (int)(strlen(ACME_WK_PATH) + 2) || *path != '.' || memcmp(path, ACME_WK_PATH, strlen(ACME_WK_PATH))) {
      TSDebug(PLUGIN_NAME, "skipping URL path = %.*s", path_len, path);
      goto cleanup;
    }

    TSSkipRemappingSet(txnp, 1); /* not strictly necessary, but speed is everything these days */

    /* This request is for us -- register our intercept */
    icontp = TSContCreate(acme_intercept, TSMutexCreate());

    my_state = make_acme_state();
    open_acme_file(my_state, path + strlen(ACME_WK_PATH), path_len - strlen(ACME_WK_PATH));

    TSContDataSet(icontp, my_state);
    TSHttpTxnIntercept(icontp, txnp);
    TSDebug(PLUGIN_NAME, "created intercept hook");
  }

cleanup:
  if (url_loc) {
    TSHandleMLocRelease(reqp, hdr_loc, url_loc);
  }
  if (hdr_loc) {
    TSHandleMLocRelease(reqp, TS_NULL_MLOC, hdr_loc);
  }

  TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);

  return 0;
}
Esempio n. 6
0
static int
ts_lua_client_request_get_uri(lua_State *L)
{
    char        uri[TS_LUA_MAX_URL_LENGTH];
    const char  *path;
    int         path_len;
    int         uri_len;

    ts_lua_http_ctx  *http_ctx;

    http_ctx = ts_lua_get_http_ctx(L);

    path = TSUrlPathGet(http_ctx->client_request_bufp, http_ctx->client_request_url, &path_len);

    uri_len = snprintf(uri, TS_LUA_MAX_URL_LENGTH, "/%.*s", path_len, path);

    lua_pushlstring(L, uri, uri_len);

    return 1;
}
static int
ts_lua_server_request_get_uri(lua_State *L)
{
  const char *path;
  int path_len;

  ts_lua_http_ctx *http_ctx;

  GET_HTTP_CONTEXT(http_ctx, L);

  TS_LUA_CHECK_SERVER_REQUEST_URL(http_ctx);

  path = TSUrlPathGet(http_ctx->server_request_bufp, http_ctx->server_request_url, &path_len);

  lua_pushlstring(L, "/", 1);
  lua_pushlstring(L, path, path_len >= TS_LUA_MAX_URL_LENGTH - 1 ? TS_LUA_MAX_URL_LENGTH - 2 : path_len);
  lua_concat(L, 2);

  return 1;
}
Esempio n. 8
0
TSRemapStatus TSRemapDoRemap(void* ih, TSHttpTxn rh, TSRemapRequestInfo *rri) {
    hash_remap_struct *hash = (hash_remap_struct*) ih;

    if (rri == NULL || ih == NULL) {
        TSError(PLUGIN_NAME "NULL pointer for rri or ih");
        return TSREMAP_NO_REMAP;
    }

    int req_host_len;
    int req_path_len;

    const char* req_host = TSUrlHostGet(rri->requestBufp, rri->requestUrl, &req_host_len);
    const char* req_path = TSUrlPathGet(rri->requestBufp, rri->requestUrl, &req_path_len);

    uint32_t hash_value_host = hash_fnv32((char *) req_host, req_host_len);

    uint64_t hash_value_host_and_path = hash_fnv64((char *) req_host, req_host_len);
    hash_fnv64_continue((char *) req_path, req_path_len, &hash_value_host_and_path);

    memset(hash->hash, 0, hash->hash_len);
    int len = sprintf(hash->hash, "%lx%x.%.*s", hash_value_host_and_path, hash_value_host, hash->isp_name_len, hash->isp_name);

    if (len > hash->hash_len) {
        TSError(PLUGIN_NAME "Memory probably corrupt :whistle:");
        return TSREMAP_NO_REMAP;
    }

    if (TSUrlHostSet(rri->requestBufp, rri->requestUrl, hash->hash, len) != TS_SUCCESS) {
        /* the request was not modified, TS will use the toURL from the remap rule */
        TSError(PLUGIN_NAME "Failed to modify the Host in request URL");
        return TSREMAP_NO_REMAP;
    }

    TSDebug(PLUGIN_NAME, "host changed from [%.*s] to [%.*s]", req_host_len, req_host, len, hash->hash);
//    fprintf(stderr, "host changed from [%.*s] to [%.*s/%.*s]\n", req_host_len, req_host, len, hash->hash, req_path_len, req_path);
    return TSREMAP_DID_REMAP; /* host has been modified */
}
Esempio n. 9
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;
}
Esempio n. 10
0
static void
handle_purge(TSHttpTxn txnp, PurgeInstance *purge)
{
  TSMBuffer reqp;
  TSMLoc hdr_loc = NULL, url_loc = NULL;
  bool should_purge = false;

  if (TS_SUCCESS == TSHttpTxnClientReqGet(txnp, &reqp, &hdr_loc)) {
    int method_len     = 0;
    const char *method = TSHttpHdrMethodGet(reqp, hdr_loc, &method_len);

    if ((TS_HTTP_METHOD_PURGE == method) || ((TS_HTTP_METHOD_GET == method) && purge->allow_get)) {
      /* First see if we require the "secret" to be passed in a header, and then use that */
      if (purge->header) {
        TSMLoc field_loc = TSMimeHdrFieldFind(reqp, hdr_loc, purge->header, purge->header_len);

        if (field_loc) {
          const char *header;
          int header_len;

          header = TSMimeHdrFieldValueStringGet(reqp, hdr_loc, field_loc, -1, &header_len);
          TSDebug(PLUGIN_NAME, "Checking for %.*s == %s ?", header_len, header, purge->secret);
          if (header && (header_len == purge->secret_len) && !memcmp(header, purge->secret, header_len)) {
            should_purge = true;
          }
          TSHandleMLocRelease(reqp, hdr_loc, field_loc);
        }
      } else {
        /* We are matching on the path component instead of a header */
        if (TS_SUCCESS == TSHttpHdrUrlGet(reqp, hdr_loc, &url_loc)) {
          int path_len     = 0;
          const char *path = TSUrlPathGet(reqp, url_loc, &path_len);

          TSDebug(PLUGIN_NAME, "Checking PATH = %.*s", path_len, path);
          if (path && (path_len >= purge->secret_len)) {
            int s_path = path_len - 1;

            while ((s_path >= 0) && ('/' != path[s_path])) { /* No memrchr in OSX */
              --s_path;
            }

            if (!memcmp(s_path > 0 ? path + s_path + 1 : path, purge->secret, purge->secret_len)) {
              should_purge = true;
            }
          }
          TSHandleMLocRelease(reqp, hdr_loc, url_loc);
        }
      }
    }
    TSHandleMLocRelease(reqp, TS_NULL_MLOC, hdr_loc);
  }

  /* Setup the continuation to handle this request if appropriate, if not, set the GenID if needed */
  if (should_purge) {
    TSCont cont = TSContCreate(purge_cont, TSMutexCreate());

    TSContDataSet(cont, purge);
    TSHttpTxnHookAdd(txnp, TS_HTTP_CACHE_LOOKUP_COMPLETE_HOOK, cont);
    TSHttpTxnHookAdd(txnp, TS_HTTP_SEND_RESPONSE_HDR_HOOK, cont);
  } else if (purge->gen_id > 0) {
    TSHttpTxnConfigIntSet(txnp, TS_CONFIG_HTTP_CACHE_GENERATION, purge->gen_id);
  }
}
Esempio n. 11
0
static int astats_origin(TSCont cont, TSEvent event, void *edata) {
	TSCont icontp;
	stats_state *my_state;
	config_t* config;
	TSHttpTxn txnp = (TSHttpTxn) edata;
	TSMBuffer reqp;
	TSMLoc hdr_loc = NULL, url_loc = NULL;
	TSEvent reenable = TS_EVENT_HTTP_CONTINUE;
	config = get_config(cont);

	TSDebug(PLUGIN_TAG, "in the read stuff");

	if (TSHttpTxnClientReqGet(txnp, &reqp, &hdr_loc) != TS_SUCCESS)
		goto cleanup;

	if (TSHttpHdrUrlGet(reqp, hdr_loc, &url_loc) != TS_SUCCESS)
		goto cleanup;

	int path_len = 0;
	const char* path = TSUrlPathGet(reqp,url_loc,&path_len);
	TSDebug(PLUGIN_TAG,"Path: %.*s",path_len,path);
	TSDebug(PLUGIN_TAG,"Path: %.*s",path_len,path);

	if (!(path_len == config->stats_path_len && !memcmp(path, config->stats_path, config->stats_path_len))) {
//		TSDebug(PLUGIN_TAG, "not right path: %.*s",path_len,path);
		goto notforme;
	}

	const struct sockaddr *addr = TSHttpTxnClientAddrGet(txnp);
	if(!is_ip_allowed(config, addr)) {
		TSDebug(PLUGIN_TAG, "not right ip");
		goto notforme;
	}
//	TSDebug(PLUGIN_TAG,"Path...: %.*s",path_len,path);

	int query_len;
	char *query = (char*)TSUrlHttpQueryGet(reqp,url_loc,&query_len);
	TSDebug(PLUGIN_TAG,"query: %.*s",query_len,query);

	TSSkipRemappingSet(txnp,1); //not strictly necessary, but speed is everything these days

	/* This is us -- register our intercept */
	TSDebug(PLUGIN_TAG, "Intercepting request");

	icontp = TSContCreate(stats_dostuff, TSMutexCreate());
	my_state = (stats_state *) TSmalloc(sizeof(*my_state));
	memset(my_state, 0, sizeof(*my_state));

	my_state->recordTypes = config->recordTypes;
	if (query_len) {
		my_state->query = nstrl(query, query_len);
		TSDebug(PLUGIN_TAG,"new query: %s", my_state->query);
		stats_fillState(my_state, my_state->query, query_len);
	}

	TSContDataSet(icontp, my_state);
	TSHttpTxnIntercept(icontp, txnp);

	goto cleanup;

	notforme:

	cleanup:
#if (TS_VERSION_NUMBER < 2001005)
	if (path)
		TSHandleStringRelease(reqp, url_loc, path);
#endif
	if (url_loc)
		TSHandleMLocRelease(reqp, hdr_loc, url_loc);
	if (hdr_loc)
		TSHandleMLocRelease(reqp, TS_NULL_MLOC, hdr_loc);

	TSHttpTxnReenable(txnp, reenable);

	return 0;
}