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;
}
Exemple #2
0
void
ts_lua_destroy_http_ctx(ts_lua_http_ctx* http_ctx)
{
    ts_lua_main_ctx   *main_ctx;

    main_ctx = http_ctx->mctx;

    if (http_ctx->server_request_bufp) {
        TSHandleMLocRelease(http_ctx->server_request_bufp, TS_NULL_MLOC, http_ctx->server_request_hdrp);
    }

    if (http_ctx->server_response_bufp) {
        TSHandleMLocRelease(http_ctx->server_response_bufp, TS_NULL_MLOC, http_ctx->server_response_hdrp);
    }

    if (http_ctx->client_response_bufp) {
        TSHandleMLocRelease(http_ctx->client_response_bufp, TS_NULL_MLOC, http_ctx->client_response_hdrp);
    }

    if (http_ctx->cached_response_bufp) {
        TSHandleMLocRelease(http_ctx->cached_response_bufp, TS_NULL_MLOC, http_ctx->cached_response_hdrp);
    }

    luaL_unref(main_ctx->lua, LUA_REGISTRYINDEX, http_ctx->ref);
    TSfree(http_ctx);
}
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);
}
//响应添加报文头
TSReturnCode StaSerRespMimeHdrFieldAppend(TSHttpTxn txnp,char *name,int name_length,char *value,int value_len)
{
	TSMBuffer bufp;
    TSMLoc hdr_loc;
    TSMLoc field_loc;
	if (TSHttpTxnServerRespGet(txnp, &bufp, &hdr_loc) != TS_SUCCESS) {
		return TS_ERROR;
	}
	field_loc = TSMimeHdrFieldFind(bufp, hdr_loc, name, name_length);
	if(field_loc != TS_NULL_MLOC){
	    TSMimeHdrFieldValuesClear(bufp, hdr_loc, field_loc);
	    TSMimeHdrFieldValueStringInsert(bufp, hdr_loc, field_loc, -1, value, value_len);
	    TSHandleMLocRelease(bufp, hdr_loc, field_loc);
	}else{
		if (TSMimeHdrFieldCreate(bufp, hdr_loc, &field_loc) != TS_SUCCESS) {
			return TS_ERROR;
		}
		TSMimeHdrFieldAppend(bufp, hdr_loc, field_loc);
		TSMimeHdrFieldValuesClear(bufp, hdr_loc, field_loc);
		TSMimeHdrFieldNameSet(bufp, hdr_loc, field_loc, name, name_length);
		TSMimeHdrFieldValueStringInsert(bufp, hdr_loc, field_loc, -1, value, value_len);
		TSHandleMLocRelease(bufp, hdr_loc, field_loc);
	}
	TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
	return TS_SUCCESS;
}
static int
server_response_ok(TSHttpTxn txnp)
{
  /* Is the response the server sent OK for transformation. This is
   * a good place to check the server's response to see if it is
   * transformable. In this example, we will transform only "200 OK"
   * responses.
   */

  TSMBuffer bufp;
  TSMLoc hdr_loc;
  TSHttpStatus resp_status;

  if (TSHttpTxnServerRespGet(txnp, &bufp, &hdr_loc) != TS_SUCCESS) {
    TSError("Unable to get handle to Server Response");
    return 0;
  }

  resp_status = TSHttpHdrStatusGet(bufp, hdr_loc);
  if (TS_HTTP_STATUS_OK == resp_status) {
    if (TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc) != TS_SUCCESS) {
      TSError("Unable to release handle to server request");
    }
    return 1;
  } else {
    if (TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc) != TS_SUCCESS) {
      TSError("Unable to release handle to server request");
    }
    return 0;
  }
}
Exemple #6
0
void
ts_http_fetcher_extract(http_fetcher *fch)
{
    TSMLoc      cl_loc, te_loc;
    const char  *val;
    int         val_len;
    int         i, n;

    fch->status_code = TSHttpHdrStatusGet(fch->hdr_bufp, fch->hdr_loc);

    cl_loc = TSMimeHdrFieldFind(fch->hdr_bufp, fch->hdr_loc, TS_MIME_FIELD_CONTENT_LENGTH, TS_MIME_LEN_CONTENT_LENGTH);
    if (cl_loc)
        fch->resp_cl = TSMimeHdrFieldValueInt64Get(fch->hdr_bufp, fch->hdr_loc, cl_loc, -1);
    else
        fch->resp_cl = -1;

    te_loc = TSMimeHdrFieldFind(fch->hdr_bufp, fch->hdr_loc, TS_MIME_FIELD_TRANSFER_ENCODING, TS_MIME_LEN_TRANSFER_ENCODING);
    if (te_loc) {
        n = TSMimeHdrFieldValuesCount(fch->hdr_bufp, fch->hdr_loc, te_loc);
        for (i = 0; i < n; i++) {
            val = TSMimeHdrFieldValueStringGet(fch->hdr_bufp, fch->hdr_loc, te_loc, i, &val_len);
            if ((val_len == TS_HTTP_LEN_CHUNKED) && (strncasecmp(val, TS_HTTP_VALUE_CHUNKED, val_len) == 0)) {
                fch->chunked = 1;
                break;
            }
        }
    }

    if (cl_loc)
        TSHandleMLocRelease(fch->hdr_bufp, fch->hdr_loc, cl_loc);

    if (te_loc) {

        if (fch->flags & TS_FLAG_FETCH_FORCE_DECHUNK)
            TSMimeHdrFieldDestroy(fch->hdr_bufp, fch->hdr_loc, te_loc);

        TSHandleMLocRelease(fch->hdr_bufp, fch->hdr_loc, te_loc);
    }

    if (fch->chunked) {
        if (fch->flags & TS_FLAG_FETCH_FORCE_DECHUNK) {
            chunked_info_init(&fch->cinfo, 1);
        } else {
            chunked_info_init(&fch->cinfo, 0);
        }

    } else if (fch->resp_cl >= 0) {
        fch->resp_already = 0;
    }

    fch->flow_buffer = TSIOBufferCreate();
    fch->flow_reader = TSIOBufferReaderAlloc(fch->flow_buffer);

    fch->body_buffer = TSIOBufferCreate();
    fch->body_reader = TSIOBufferReaderAlloc(fch->body_buffer);
}
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;
}
static RequestInfo *
create_request_info(TSHttpTxn txn)
{
  RequestInfo *req_info;
  char *url;
  int url_len;
  TSMBuffer buf;
  TSMLoc loc;

  req_info = (RequestInfo *)TSmalloc(sizeof(RequestInfo));

  url = TSHttpTxnEffectiveUrlStringGet(txn, &url_len);
  req_info->effective_url = TSstrndup(url, url_len);
  TSfree(url);

  TSHttpTxnClientReqGet(txn, &buf, &loc);
  req_info->buf = TSMBufferCreate();
  TSHttpHdrClone(req_info->buf, buf, loc, &(req_info->http_hdr_loc));
  TSHandleMLocRelease(buf, TS_NULL_MLOC, loc);

  req_info->client_addr = TSmalloc(sizeof(struct sockaddr));
  memmove((void *)req_info->client_addr, (void *)TSHttpTxnClientAddrGet(txn), sizeof(struct sockaddr));

  return req_info;
}
static int
transformable(TSHttpTxn txnp)
{
  /*
   *  We are only interested in transforming "200 OK" responses.
   */

  TSMBuffer bufp;
  TSMLoc hdr_loc;
  TSHttpStatus resp_status;
  int retv;

  TSDebug("null-transform", "Entering transformable()");

  TSHttpTxnServerRespGet(txnp, &bufp, &hdr_loc);
  resp_status = TSHttpHdrStatusGet(bufp, hdr_loc);
  retv = (resp_status == TS_HTTP_STATUS_OK);

  if (TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc) == TS_ERROR) {
    TSError("[null-transform] Error releasing MLOC while checking " "header status\n");
  }

  TSDebug("null-transform", "Exiting transformable with return %d", retv);
  return retv;
}
static int
ts_lua_client_request_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 (key && key_len) {

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

        } else {
            lua_pushnil(L);
        }

    } else {
        lua_pushnil(L);
    }

    return 1;
}
static int
ts_lua_client_request_get_pristine_url(lua_State *L)
{
    char        *url;
    int         url_len;

    TSMBuffer   bufp;
    TSMLoc      url_loc;

    ts_lua_http_ctx  *http_ctx;

    http_ctx = ts_lua_get_http_ctx(L);

    if (TSHttpTxnPristineUrlGet(http_ctx->txnp, &bufp, &url_loc) != TS_SUCCESS)
        return 0;

    url = TSUrlStringGet(bufp, url_loc, &url_len);

    if (url) {
        lua_pushlstring(L, url, url_len);
        TSfree(url);

    } else {
        lua_pushnil(L);
    }

    TSHandleMLocRelease(bufp, NULL, url_loc);

    return 1;
}
static int
ts_lua_cached_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;

  GET_HTTP_CONTEXT(http_ctx, L);

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

  TS_LUA_CHECK_CACHED_RESPONSE_HDR(http_ctx);

  if (key && key_len) {
    field_loc = TSMimeHdrFieldFind(http_ctx->cached_response_bufp, http_ctx->cached_response_hdrp, key, key_len);

    if (field_loc) {
      val = TSMimeHdrFieldValueStringGet(http_ctx->cached_response_bufp, http_ctx->cached_response_hdrp, field_loc, -1, &val_len);
      lua_pushlstring(L, val, val_len);
      TSHandleMLocRelease(http_ctx->cached_response_bufp, http_ctx->cached_response_hdrp, field_loc);

    } else {
      lua_pushnil(L);
    }

  } else {
    lua_pushnil(L);
  }
  return 1;
}
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;
}
Exemple #14
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;
}
/* 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;
}
static void
free_request_info(RequestInfo *req_info)
{
  TSfree(req_info->effective_url);
  TSHandleMLocRelease(req_info->buf, TS_NULL_MLOC, req_info->http_hdr_loc);
  TSMBufferDestroy(req_info->buf);
  TSfree(req_info);
}
static void
free_response_info(ResponseInfo *resp_info)
{
  TSHandleMLocRelease(resp_info->buf, TS_NULL_MLOC, resp_info->http_hdr_loc);
  TSMBufferDestroy(resp_info->buf);
  TSHttpParserDestroy(resp_info->parser);
  TSfree(resp_info);
}
static int
ts_lua_server_request_get_headers(lua_State *L)
{
  const char *name;
  const char *value;
  int name_len;
  int value_len;
  TSMLoc field_loc;
  TSMLoc next_field_loc;
  const char *tvalue;
  size_t tvalue_len;

  ts_lua_http_ctx *http_ctx;

  GET_HTTP_CONTEXT(http_ctx, L);

  TS_LUA_CHECK_SERVER_REQUEST_HDR(http_ctx);

  lua_newtable(L);

  field_loc = TSMimeHdrFieldGet(http_ctx->server_request_bufp, http_ctx->server_request_hdrp, 0);

  while (field_loc != TS_NULL_MLOC) {
    name = TSMimeHdrFieldNameGet(http_ctx->server_request_bufp, http_ctx->server_request_hdrp, field_loc, &name_len);
    if (name && name_len) {
      // retrieve the header name from table
      lua_pushlstring(L, name, name_len);
      lua_gettable(L, -2);
      if (lua_isnil(L, -1)) {
        // if header name does not exist in the table, insert it
        lua_pop(L, 1);
        value =
          TSMimeHdrFieldValueStringGet(http_ctx->server_request_bufp, http_ctx->server_request_hdrp, field_loc, -1, &value_len);
        lua_pushlstring(L, name, name_len);
        lua_pushlstring(L, value, value_len);
        lua_rawset(L, -3);
      } else {
        // if header name exists in the table, append a command and the new value to the end of the existing value
        tvalue = lua_tolstring(L, -1, &tvalue_len);
        lua_pop(L, 1);
        value =
          TSMimeHdrFieldValueStringGet(http_ctx->server_request_bufp, http_ctx->server_request_hdrp, field_loc, -1, &value_len);
        lua_pushlstring(L, name, name_len);
        lua_pushlstring(L, tvalue, tvalue_len);
        lua_pushlstring(L, ",", 1);
        lua_pushlstring(L, value, value_len);
        lua_concat(L, 3);
        lua_rawset(L, -3);
      }
    }

    next_field_loc = TSMimeHdrFieldNext(http_ctx->server_request_bufp, http_ctx->server_request_hdrp, field_loc);
    TSHandleMLocRelease(http_ctx->server_request_bufp, http_ctx->server_request_hdrp, field_loc);
    field_loc = next_field_loc;
  }

  return 1;
}
static int 
regex_match(TSCont contp, TSHttpTxn txnp)
{
	static char 	*url;
	TSMBuffer       bufp;
	TSMLoc          hdr_loc, url_loc;
	int 		url_length;
	regex_t 	*re;
	int  		ovector[30], res;

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

        if (TSHttpHdrUrlGet(bufp, hdr_loc, &url_loc) != TS_SUCCESS) {
                TSError("couldn't retrieve request url\n");
                TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
                goto done;
        }

        url = TSUrlStringGet(bufp, url_loc, &url_length);
        if (url == NULL) {
                TSError("couldn't get url");
                goto done;
        }

	for (re = reg; re; re = re->next) {
		res = pcre_exec(re->re, NULL, url, strlen(url), 0, 0, ovector, 30);
		if (res <= 0) {
			goto done;
		} 
		break;
	}
	
	TSContDataSet(contp, re->hdr);
	TSHttpTxnHookAdd(txnp, TS_HTTP_SEND_RESPONSE_HDR_HOOK, contp);

done:
        TSfree(url);
        TSHandleMLocRelease(bufp, hdr_loc, url_loc);
        TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
	TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);
	return 0;
}
bool
is_post_request(TSHttpTxn txnp)
{
  TSMLoc req_loc;
  TSMBuffer req_bufp;
  if (TSHttpTxnClientReqGet(txnp, &req_bufp, &req_loc) == TS_ERROR) {
    TSError("Error while retrieving client request header\n");
    return false;
  }
  int method_len     = 0;
  const char *method = TSHttpHdrMethodGet(req_bufp, req_loc, &method_len);
  if (method_len != (int)strlen(TS_HTTP_METHOD_POST) || strncasecmp(method, TS_HTTP_METHOD_POST, method_len) != 0) {
    TSHandleMLocRelease(req_bufp, TS_NULL_MLOC, req_loc);
    return false;
  }
  TSHandleMLocRelease(req_bufp, TS_NULL_MLOC, req_loc);
  return true;
}
static time_t
get_date_from_cached_hdr(TSHttpTxn txn)
{
  TSMBuffer buf;
  TSMLoc hdr_loc, date_loc;
  time_t date = 0;

  if (TSHttpTxnCachedRespGet(txn, &buf, &hdr_loc) == TS_SUCCESS) {
    date_loc = TSMimeHdrFieldFind(buf, hdr_loc, TS_MIME_FIELD_DATE, TS_MIME_LEN_DATE);
    if (date_loc != TS_NULL_MLOC) {
      date = TSMimeHdrFieldValueDateGet(buf, hdr_loc, date_loc);
      TSHandleMLocRelease(buf, hdr_loc, date_loc);
    }
    TSHandleMLocRelease(buf, TS_NULL_MLOC, hdr_loc);
  }

  return date;
}
static int
ts_lua_client_response_set_error_resp(lua_State *L)
{
  int n, status;
  const char *body;
  const char *reason;
  int reason_len;
  size_t body_len;
  int resp_len;
  char *resp_buf;
  TSMLoc field_loc;

  ts_lua_http_ctx *http_ctx;

  GET_HTTP_CONTEXT(http_ctx, L);

  TS_LUA_CHECK_CLIENT_RESPONSE_HDR(http_ctx);

  n = lua_gettop(L);

  status = luaL_checkinteger(L, 1);

  reason = TSHttpHdrReasonLookup(status);
  reason_len = strlen(reason);

  TSHttpHdrStatusSet(http_ctx->client_response_bufp, http_ctx->client_response_hdrp, status);
  TSHttpHdrReasonSet(http_ctx->client_response_bufp, http_ctx->client_response_hdrp, reason, reason_len);

  body_len = 0;

  if (n == 2) {
    body = luaL_checklstring(L, 2, &body_len);
  }

  if (body_len && body) {
    resp_buf = TSmalloc(body_len);
    memcpy(resp_buf, body, body_len);
    resp_len = body_len;

  } else {
    resp_buf = TSmalloc(reason_len);
    memcpy(resp_buf, reason, reason_len);
    resp_len = reason_len;
  }

  field_loc = TSMimeHdrFieldFind(http_ctx->client_response_bufp, http_ctx->client_response_hdrp, TS_MIME_FIELD_TRANSFER_ENCODING,
                                 TS_MIME_LEN_TRANSFER_ENCODING);

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

  TSHttpTxnErrorBodySet(http_ctx->txnp, resp_buf, resp_len, NULL);

  return 0;
}
//响应删除报文头
TSReturnCode StaSerRespMimeHdrFieldDestroy(TSHttpTxn txnp,char *name,int length)
{
	TSMBuffer bufp;
    TSMLoc hdr_loc;
    TSMLoc field_loc;
	TSReturnCode ret = TS_ERROR;
	if (TSHttpTxnServerRespGet(txnp, &bufp, &hdr_loc) != TS_SUCCESS) {
		return TS_ERROR;
	}
	field_loc = TSMimeHdrFieldFind(bufp, hdr_loc, name, length);
	if(field_loc != TS_NULL_MLOC)
	{
	    ret = TSMimeHdrFieldDestroy(bufp,hdr_loc,field_loc);
		TSHandleMLocRelease(bufp, hdr_loc, field_loc);
	}
	TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
	return ret;
}
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);
}
Exemple #25
0
bool
should_push(TSHttpTxn txnp)
{
  TSMBuffer mbuf;
  TSMLoc hdr, url;
  if (TSHttpTxnClientReqGet(txnp, &mbuf, &hdr) != TS_SUCCESS) {
    return false;
  }
  if (TSHttpHdrUrlGet(mbuf, hdr, &url) != TS_SUCCESS) {
    return false;
  }
  int len;
  TSUrlHttpQueryGet(mbuf, url, &len);
  TSHandleMLocRelease(mbuf, hdr, url);
  TSHandleMLocRelease(mbuf, TS_NULL_MLOC, hdr);
  if (len > 0) {
    return true;
  } else {
    return false;
  }
}
static int
ts_lua_server_request_header_get(lua_State *L)
{
  const char *key;
  const char *val;
  int val_len;
  size_t key_len;
  int count;

  TSMLoc field_loc, next_field_loc;
  ts_lua_http_ctx *http_ctx;

  GET_HTTP_CONTEXT(http_ctx, L);

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

  if (!http_ctx->server_request_hdrp) {
    if (TSHttpTxnServerReqGet(http_ctx->txnp, &http_ctx->server_request_bufp, &http_ctx->server_request_hdrp) != TS_SUCCESS) {
      lua_pushnil(L);
      return 1;
    }
  }

  if (key && key_len) {
    field_loc = TSMimeHdrFieldFind(http_ctx->server_request_bufp, http_ctx->server_request_hdrp, key, key_len);

    if (field_loc != TS_NULL_MLOC) {
      count = 0;
      while (field_loc != TS_NULL_MLOC) {
        val = TSMimeHdrFieldValueStringGet(http_ctx->server_request_bufp, http_ctx->server_request_hdrp, field_loc, -1, &val_len);
        next_field_loc = TSMimeHdrFieldNextDup(http_ctx->server_request_bufp, http_ctx->server_request_hdrp, field_loc);
        lua_pushlstring(L, val, val_len);
        count++;
        // multiple headers with the same name must be semantically the same as one value which is comma seperated
        if (next_field_loc != TS_NULL_MLOC) {
          lua_pushlstring(L, ",", 1);
          count++;
        }
        TSHandleMLocRelease(http_ctx->server_request_bufp, http_ctx->server_request_hdrp, field_loc);
        field_loc = next_field_loc;
      }
      lua_concat(L, count);
    } else {
      lua_pushnil(L);
    }

  } else {
    lua_pushnil(L);
  }

  return 1;
}
//获取源服务器响应的状态
TSHttpStatus StaServerRespStatusGet(TSHttpTxn txnp)
{
	TSMBuffer resp_bufp;
    TSMLoc resp_loc;
	TSHttpStatus resp_status = TS_HTTP_STATUS_NONE;
	if (TSHttpTxnServerRespGet(txnp, &resp_bufp, &resp_loc) != TS_SUCCESS) {
        return TS_HTTP_STATUS_NONE;                  
    }
	resp_status = TSHttpHdrStatusGet(resp_bufp, resp_loc);
	TSHandleMLocRelease(resp_bufp, TS_NULL_MLOC, resp_loc);
	return resp_status;
}
//设置源服务器响应的状态
TSReturnCode StaServerRespStatusSet(TSHttpTxn txnp,TSHttpStatus status)
{
	TSMBuffer resp_bufp;
    TSMLoc resp_loc;
	TSReturnCode ret;
	if (TSHttpTxnServerRespGet(txnp, &resp_bufp, &resp_loc) != TS_SUCCESS) {
        return TS_ERROR;                  
    }
	ret = TSHttpHdrStatusSet(resp_bufp, resp_loc, status);
	TSHandleMLocRelease(resp_bufp, TS_NULL_MLOC, resp_loc);
	return ret;
}
static int
ts_lua_server_request_get_url_host(lua_State *L)
{
  const char *host;
  int len = 0;

  ts_lua_http_ctx *http_ctx;

  GET_HTTP_CONTEXT(http_ctx, L);

  TS_LUA_CHECK_SERVER_REQUEST_URL(http_ctx);

  host = TSUrlHostGet(http_ctx->server_request_bufp, http_ctx->server_request_url, &len);

  if (len == 0) {
    char *key   = "Host";
    char *l_key = "host";
    int key_len = 4;

    TSMLoc field_loc;

    field_loc = TSMimeHdrFieldFind(http_ctx->server_request_bufp, http_ctx->server_request_hdrp, key, key_len);
    if (field_loc) {
      host = TSMimeHdrFieldValueStringGet(http_ctx->server_request_bufp, http_ctx->server_request_hdrp, field_loc, -1, &len);
      TSHandleMLocRelease(http_ctx->server_request_bufp, http_ctx->server_request_hdrp, field_loc);

    } else {
      field_loc = TSMimeHdrFieldFind(http_ctx->server_request_bufp, http_ctx->server_request_hdrp, l_key, key_len);
      if (field_loc) {
        host = TSMimeHdrFieldValueStringGet(http_ctx->server_request_bufp, http_ctx->server_request_hdrp, field_loc, -1, &len);
        TSHandleMLocRelease(http_ctx->server_request_bufp, http_ctx->server_request_hdrp, field_loc);
      }
    }
  }

  lua_pushlstring(L, host, len);

  return 1;
}
static void
replace_header(TSHttpTxn txnp)
{
    TSMBuffer resp_bufp;
    TSMLoc resp_loc;
    TSMLoc field_loc;

    if (TSHttpTxnServerRespGet(txnp, &resp_bufp, &resp_loc) != TS_SUCCESS) {
        TSError("couldn't retrieve server response header.\n");
        goto done;
    }

    field_loc = TSMimeHdrFieldFind(resp_bufp, resp_loc, TS_MIME_FIELD_ACCEPT_RANGES, TS_MIME_LEN_ACCEPT_RANGES);
    if (field_loc == TS_NULL_MLOC) {
        /* field was not found */

        /* create a new field in the header */
        TSMimeHdrFieldCreate(resp_bufp, resp_loc, &field_loc); /* Probably should check for errors. */
        /* set its name */
        TSMimeHdrFieldNameSet(resp_bufp, resp_loc, field_loc, TS_MIME_FIELD_ACCEPT_RANGES, TS_MIME_LEN_ACCEPT_RANGES);
        /* set its value */
        TSMimeHdrFieldValueAppend(resp_bufp, resp_loc, field_loc, -1, "none", 4);
        /* insert it into the header */
        TSMimeHdrFieldAppend(resp_bufp, resp_loc, field_loc);
        TSHandleMLocRelease(resp_bufp, resp_loc, field_loc);
        TSHandleMLocRelease(resp_bufp, TS_NULL_MLOC, resp_loc);
    } else {
        /* clear the field */
        TSMimeHdrFieldValuesClear(resp_bufp, resp_loc, field_loc);
        /* set the value to "none" */
        TSMimeHdrFieldValueStringInsert(resp_bufp, resp_loc, field_loc, -1, "none", 4);
        TSHandleMLocRelease(resp_bufp, resp_loc, field_loc);
        TSHandleMLocRelease(resp_bufp, TS_NULL_MLOC, resp_loc);
    }

done:
    TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);
}