Help developing a block directive

Eran Kornblau eran.kornblau at kaltura.com
Thu Jun 29 06:03:09 UTC 2017


I believe it happens because you changed cf->cmd_type, so when nginx tries to parse the second location,
it thinks it’s in a scope of ‘my custom module conf’ and not in a scope of ‘server’, and therefore doesn’t
recognize the location directive.
Nginx doesn’t automatically parse the contents of the block, you have to handle that yourself in your block
handler. Usually this is done by updating the ngx_conf_t and calling ngx_conf_parse (make sure to save the
original cf in a local variable so that you can restore it when ngx_conf_parse returns)
There quite a few built-in nginx modules that add block directives, I suggest you look at one of them and
match your code to their implementation (for example, I used ‘map’ as reference)

Hope this help,

Eran

From: nginx-devel [mailto:nginx-devel-bounces at nginx.org] On Behalf Of Joseph Spencer
Sent: Thursday, June 29, 2017 1:01 AM
To: nginx-devel at nginx.org
Subject: Re: Help developing a block directive

Thanks for the fast reply!

So I think I see how this works now; however, I'm getting a new error.  Seems to be parsing related.  Here is what I have now:

  #define NGX_MY_CUSTOM_MODULE_CONF 0x80000001

  static ngx_command_t ngx_my_custom_module_commands[] = {
      {
        ngx_string("my_custom_module_block"), /* directive */
        NGX_HTTP_SRV_CONF |
        NGX_HTTP_LOC_CONF |
        NGX_CONF_NOARGS |
        NGX_CONF_BLOCK,
        my_custom_module_block, /* configuration setup function */
        0, /* No offset. Only one context is supported. */
        0, /* No offset when storing the module configuration on struct. */
        NULL
      },

     {
        ngx_string("directive_for_my_custom_module_block"), /* directive */
        NGX_CONF_TAKE1|NGX_MY_CUSTOM_MODULE_CONF,
        ngx_directive_for_my_custom_module_block_cmd, /* configuration setup function */
        0, /* No offset. Only one context is supported. */
        0, /* No offset when storing the module configuration on struct. */
        NULL
     },

      ngx_null_command /* command termination */
  };

  static char *my_custom_module_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  {
      cf->cmd_type = NGX_MY_CUSTOM_MODULE_CONF;
      ngx_http_core_loc_conf_t *clcf;
      clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
      clcf->handler = ngx_my_custom_module_handler;
      return NGX_CONF_OK;
  }


How I'm seeing the following error:

2017/06/28 21:48:46 [emerg] 1#1: "location" directive is not allowed here in /etc/nginx/nginx.conf:26
nginx: [emerg] "location" directive is not allowed here in /etc/nginx/nginx.conf:26

Here is my full configuration file:

worker_processes  1;

load_module "modules/ngx_my_custom_module.so";

events {
    worker_connections  1024;
}

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

    sendfile        on;
    keepalive_timeout  65;
    server {
        listen       80;
        server_name  localhost;

        location / {
          my_custom_module_block {
            directive_for_my_custom_module_block "Some value";
          }
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}




On Wed, Jun 28, 2017 at 2:38 PM, Vladimir Homutov <vl at nginx.com<mailto:vl at nginx.com>> wrote:
On 29.06.2017 00:15, Joseph Spencer wrote:
> Hello,
>
> I'm trying to support this in my nginx.conf:
>
> my_custom_module_block {
>   directive_for_my_custom_module_block "Some value";
> }
>
> Here is how I'm setting up the commands:
>
>   static ngx_command_t ngx_my_custom_module_commands[] = {
>
>       {
>
>        ngx_string("my_custom_module_block"), /* directive */
>
>         NGX_HTTP_SRV_CONF |
>
>         NGX_HTTP_LOC_CONF |
>
>         NGX_CONF_NOARGS |
>
>         NGX_CONF_BLOCK,
>
>         my_custom_module_block, /* configuration setup function */
>
>         0, /* No offset. Only one context is supported. */
>
>         0, /* No offset when storing the module configuration on struct.
> */
>         NULL
>
>       },
>
>
>
>      {
>
>         ngx_string("directive_for_my_custom_module_block"), /* directive
> */
>         NGX_CONF_TAKE1,
>
>         ngx_directive_for_my_custom_module_block_cmd, /* configuration
> setup function */
>         0, /* No offset. Only one context is supported. */
>
>         0, /* No offset when storing the module configuration on struct.
> */
>         NULL
>
>      },
>
>
>
>       ngx_null_command /* command termination */
>
>   };
>
> Everything compiles fine; however, I receive the following error and
> nginx won't start:
>
> 2017/06/28 21:02:44 [emerg] 1#1: "directive_for_my_custom_module_block"
> directive is not allowed here in /etc/nginx/nginx.conf:19
> nginx: [emerg] "directive_for_my_custom_module_block" directive is not
> allowed here in /etc/nginx/nginx.conf:19
>
> If anyone could be of assistance I would greatly appreciate it.
>
Take a look at ngx_conf_file.h to understand which structure flags have.
You did not specify any possible context for the command that will
appear in your block: NGX_CONF_TAKE1 solo only describes number of
arguments, but command is not matching anything, thus the error.

You can either declare your own context, like ngx_http_upstream_module
does (NGX_HTTP_UPS_CONF for commands inside upstream{} block) or
use API from ngx_conf_file.h to process commands inside your block
like ngx_conf_handler() does.






_______________________________________________
nginx-devel mailing list
nginx-devel at nginx.org<mailto:nginx-devel at nginx.org>
http://mailman.nginx.org/mailman/listinfo/nginx-devel



--
Thanks,
Joe Spencer (member)
Kogo Software LLC
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.nginx.org/pipermail/nginx-devel/attachments/20170629/2c4d10df/attachment-0001.html>


More information about the nginx-devel mailing list