如何针对任何请求调用自定义 nginx 模块?是否始终需要处理程序?是否可以直接调用过滤器?

如何针对任何请求调用自定义 nginx 模块?是否始终需要处理程序?是否可以直接调用过滤器?

我正在尝试编写一个 nginx 模块,它将过滤掉任何大小大于 1000KB 的资源的 GET 请求。我按照教程操作,模块编译并安装正常。但是我认为模块没有在传入请求上被调用。该模块由标头和正文过滤器组成,它们将检查传出请求的内容大小,如果大于 1000KB,它将清除响应正文并重定向到我将在防火墙中限制的不同端口。我使用了一些日志记录语句,但我在日志中看不到任何东西,因此我认为它没有被调用。我附上了完整的源代码

#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_http.h>




typedef struct {
    ngx_str_t     download_filter;

} ngx_http_download_conf_t;


static void *ngx_http_download_create_conf(ngx_conf_t *cf);
static ngx_int_t ngx_http_download_filter_init(ngx_conf_t *cf);
static ngx_int_t ngx_http_download_header_filter(ngx_http_request_t *r);
static ngx_int_t ngx_http_download_body_filter(ngx_http_request_t *r, ngx_chain_t *in);




//static char *ngx_http_download_module( ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
//static u_char ngx_download_filter_module[] = "download filter";

static ngx_command_t ngx_download_filter_module_commands[] = {
  {
    ngx_string("download_filter"),
    NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS,
    ngx_conf_set_str_slot,
    NGX_HTTP_LOC_CONF_OFFSET,
    offsetof(ngx_http_download_conf_t, download_filter),
    NULL },
    ngx_null_command
};

static ngx_http_module_t  ngx_http_download_filter_module_ctx = {
  NULL,                            /* preconfiguration */
  ngx_http_download_filter_init,   /* postconfiguration */

  NULL,                           /* create main configuration */
  NULL,                           /* init main configuration */

  NULL,                           /* create server configuration */
  NULL,                           /* merge server configuration */

  ngx_http_download_create_conf,  /* create location configuration */
  NULL                            /* merge location configuration */
};


ngx_module_t ngx_http_download_filter_module = {
  NGX_MODULE_V1,
  &ngx_http_download_filter_module_ctx, /* module context */
  ngx_download_filter_module_commands,                          /* module directives */
  NGX_HTTP_MODULE,               /* module type */
  NULL,                          /* init master */
  NULL,                          /* init module */
  NULL,                          /* init process */
  NULL,                          /* init thread */
  NULL,                          /* exit thread */
  NULL,                          /* exit process */
  NULL,                          /* exit master */
  NGX_MODULE_V1_PADDING
};

static ngx_http_output_header_filter_pt  ngx_http_next_header_filter;
static ngx_http_output_body_filter_pt    ngx_http_next_body_filter;



static ngx_int_t
ngx_http_download_filter_init(ngx_conf_t *cf)
{
  printf("hello world: inside init function\n");


  ngx_http_next_header_filter = ngx_http_top_header_filter;
  ngx_http_top_header_filter = ngx_http_download_header_filter;

  ngx_http_next_body_filter = ngx_http_top_body_filter;
  ngx_http_top_body_filter = ngx_http_download_body_filter;

  return NGX_OK;
}

static
ngx_int_t ngx_http_download_header_filter( ngx_http_request_t *r)
{


  ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "inside the header filter");
  printf("inside header filter hello world\n");

  ngx_str_t new_location= ngx_string("http://localhost:5000/flake.jpg");

  if ( r->headers_out.content_length_n > 1000 && r->headers_out.status == NGX_HTTP_OK )
  {
      r->headers_out.status = NGX_HTTP_MOVED_TEMPORARILY;
      r->headers_out.content_type.len = 0;
      r->headers_out.location->value.data = new_location.data;
      r->headers_out.location->value.len = new_location.len;
      ngx_http_clear_content_length(r);
      ngx_http_clear_accept_ranges(r);

  }

 r->headers_out.status = NGX_HTTP_MOVED_TEMPORARILY;


  return ngx_http_next_header_filter(r);
}

static
ngx_int_t ngx_http_download_body_filter ( ngx_http_request_t *r, ngx_chain_t *in )
{

  if ( r->headers_out.content_length_n > 1000 && r->headers_out.status == NGX_HTTP_OK )
  { 
    r->discard_body = 0;
    return ngx_http_next_body_filter(r, in);
  }

  return ngx_http_next_body_filter(r, in);

}

static void *
ngx_http_download_create_conf(ngx_conf_t *cf)
{
    ngx_http_download_conf_t  *conf;
    conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_download_conf_t));
    if (conf == NULL) {
        return NULL;
    }

    /*
     * set by ngx_pcalloc():
     *
     *     conf->before_body = { 0, NULL };
     *     conf->after_body = { 0, NULL };
     *     conf->types = { NULL };
     *     conf->types_keys = NULL;
     */

    return conf;
}

我的 nginx 配置使用了该download_filter指令。以下是代码片段。

http {
    include       mime.types;
    default_type  application/octet-stream;

   log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                     '$status $body_bytes_sent "$http_referer" '
                     '"$http_user_agent" "$http_x_forwarded_for"';



     access_log  /tmp/log/access.log  main;
       error_log   /tmp/log/error.log info;
        sendfile        on;
        #tcp_nopush     on;

        #keepalive_timeout  0;
        keepalive_timeout  65;


        download_filter;

当我启动 nginx 时,当我看到“hello world,inside init function”字符串时,模块就会初始化。

我遗漏了什么导致过滤器停止运行?我这里不使用处理程序,因为我不需要提供任何服务,只需让 nginx 完成工作并在提供服务之前使用过滤器即可。我需要处理程序吗?如果是,我该如何制作一个仅提供内容并让过滤器完成工作的处理程序。

相关内容