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
ts_lua_server_response_get_headers(lua_State * L)
{
  const char *name;
  const char *value;
  int name_len;
  int value_len;
  TSMLoc field_loc;
  TSMLoc next_field_loc;

  ts_lua_http_ctx *http_ctx;

  http_ctx = ts_lua_get_http_ctx(L);

  TS_LUA_CHECK_SERVER_RESPONSE_HDR(http_ctx);

  lua_newtable(L);

  field_loc = TSMimeHdrFieldGet(http_ctx->server_response_bufp, http_ctx->server_response_hdrp, 0);

  while (field_loc) {

    name = TSMimeHdrFieldNameGet(http_ctx->server_response_bufp, http_ctx->server_response_hdrp, field_loc, &name_len);
    if (name && name_len) {

      value =
        TSMimeHdrFieldValueStringGet(http_ctx->server_response_bufp, http_ctx->server_response_hdrp, field_loc, -1,
                                     &value_len);
      lua_pushlstring(L, name, name_len);
      lua_pushlstring(L, value, value_len);
      lua_rawset(L, -3);
    }

    next_field_loc = TSMimeHdrFieldNext(http_ctx->server_response_bufp, http_ctx->server_response_hdrp, field_loc);
    TSHandleMLocRelease(http_ctx->server_response_bufp, http_ctx->server_response_hdrp, field_loc);
    field_loc = next_field_loc;
  }

  return 1;
}
Example #3
0
static void
add_header(TSHttpTxn txnp, TSCont contp)
{
  TSMBuffer req_bufp;
  TSMLoc req_loc;
  TSMLoc field_loc;
  TSMLoc next_field_loc;
  TSMLoc new_field_loc;
  int retval;

  if (TSHttpTxnClientReqGet(txnp, &req_bufp, &req_loc) != TS_SUCCESS) {
    TSError("[add_header] Error while retrieving client request header\n");
    goto done;
  }

  field_loc = TSMimeHdrFieldGet(hdr_bufp, hdr_loc, 0);
  if (field_loc == TS_NULL_MLOC) {
    TSError("[add_header] Error while getting field");
    goto error;
  }

  /* Loop on our header containing fields to add */
  while (field_loc) {

    /* First create a new field in the client request header */
    if (TSMimeHdrFieldCreate(req_bufp, req_loc, &new_field_loc) != TS_SUCCESS) {
      TSError("[add_header] Error while creating new field");
      TSHandleMLocRelease(hdr_bufp, hdr_loc, field_loc);
      break;
    }

    /* Then copy our new field at this new location */
    retval = TSMimeHdrFieldCopy(req_bufp, req_loc, new_field_loc, hdr_bufp, hdr_loc, field_loc);
    if (retval == TS_ERROR) {
      TSError("[add_header] Error while copying new field");
      TSHandleMLocRelease(hdr_bufp, hdr_loc, field_loc);
      break;
    }

    /* Add this field to the Http client request header */
    retval = TSMimeHdrFieldAppend(req_bufp, req_loc, new_field_loc);
    if (retval != TS_SUCCESS) {
      TSError("[add_header] Error while appending new field");
      TSHandleMLocRelease(hdr_bufp, hdr_loc, field_loc);
      break;
    }

    /* We can now release this handle */
    TSHandleMLocRelease(req_bufp, req_loc, new_field_loc);

    next_field_loc = TSMimeHdrFieldNext(hdr_bufp, hdr_loc, field_loc);
    TSHandleMLocRelease(hdr_bufp, hdr_loc, field_loc);
    field_loc = next_field_loc;
  }


error:
  TSHandleMLocRelease(req_bufp, TS_NULL_MLOC, req_loc);

done:
  TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);
}
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 = "ts-api-support@MyCompany.com";

  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);
  }
}