class CrossPlane::Analyzer
Constants
- CONTEXTS
- DIRECTIVES
- NGX_ANY_CONF
- NGX_CONF_1MORE
- NGX_CONF_2MORE
- NGX_CONF_ANY
- NGX_CONF_BLOCK
- NGX_CONF_FLAG
- NGX_CONF_NOARGS
bit masks for different directive argument styles
- NGX_CONF_TAKE1
- NGX_CONF_TAKE12
some helpful argument style aliases
- NGX_CONF_TAKE123
- NGX_CONF_TAKE1234
- NGX_CONF_TAKE13
- NGX_CONF_TAKE2
- NGX_CONF_TAKE23
- NGX_CONF_TAKE3
- NGX_CONF_TAKE4
- NGX_CONF_TAKE5
- NGX_CONF_TAKE6
- NGX_CONF_TAKE7
- NGX_DIRECT_CONF
bit masks for different directive locations
- NGX_EVENT_CONF
- NGX_HTTP_LIF_CONF
- NGX_HTTP_LMT_CONF
- NGX_HTTP_LOC_CONF
- NGX_HTTP_MAIN_CONF
- NGX_HTTP_SIF_CONF
- NGX_HTTP_SRV_CONF
- NGX_HTTP_UPS_CONF
- NGX_MAIL_MAIN_CONF
- NGX_MAIL_SRV_CONF
- NGX_MAIN_CONF
- NGX_STREAM_MAIN_CONF
- NGX_STREAM_SRV_CONF
- NGX_STREAM_UPS_CONF
Public Class Methods
new(*args)
click to toggle source
# File lib/crossplane/analyzer.rb, line 1871 def initialize(*args) args = args[0] || {} end
Public Instance Methods
analyze(fname, stmt, term, ctx, strict)
click to toggle source
# File lib/crossplane/analyzer.rb, line 1885 def analyze(fname, stmt, term, ctx, strict) directive = stmt['directive'] line = stmt['line'] # if strict and directive isn't recognized then throw error if strict and not DIRECTIVES[directive] reason = format('unknown directive "%s"', directive) raise CrossPlane::NgxParserDirectiveUnknownError.new(fname, line, reason) end # if we don't know where this directive is allowed and how # many arguments it can take then don't bother analyzing it if not CONTEXTS[ctx] or not DIRECTIVES[directive] return end args = stmt['args'] || [] n_args = args.length masks = DIRECTIVES[directive] ctx_mask = CONTEXTS[ctx] # if this directive can't be used in this context then throw an error masks = [] DIRECTIVES[directive].each do |mask| if mask & ctx_mask masks.push(mask) end end unless masks.length > 0 reason = format('"%s" directive is not allowed here', directive) raise CrossPlane::NgxParserDirectiveContextError.new(fname, line, reason) end valid_flag = lambda { |x| return ['on', 'off'].include?(x.downcase) ? true : false } # do this in reverse because we only throw errors at the end if no masks # are valid, and typically the first bit mask is what the parser expects masks.reverse.each do |mask| # if the directive isn't a block but should be according to the mask if (mask & NGX_CONF_BLOCK > 0) and term != '{' reason = format('directive "%s" has no opening "{"', directive) next end # if the directive is a block but shouldn't be according to the mask if (not mask & NGX_CONF_BLOCK) and term != ';' reason = format('directive "%s" is not terminated by ";"', directive) next end # use mask to check the directive's arguments if ((mask >> n_args & 1 and n_args <= 7) or (mask & NGX_CONF_FLAG and n_args == 1 and valid_flag.call(args[0])) or (mask & NGX_CONF_ANY and n_args >= 0) or (mask & NGX_CONF_1MORE and n_args >= 1) or (mask & NGX_CONF_2MORE and n_args >= 2)) return elsif (mask & NGX_CONF_FLAG) and (n_args == 1) and not valid_flag.call(args[0]) reason = format('invalid value "%s" in "%%s" directive, it must be "on" or "off"', args[0], directive) else reason = format('invalid number of arguments in "%s" directive', directive) end end if reason raise CrossPlane::NgxParserDirectiveArgumentsError.new(fname, line, reason) end end
enter_block_ctx(stmt, ctx)
click to toggle source
# File lib/crossplane/analyzer.rb, line 1875 def enter_block_ctx(stmt, ctx) # don't nest because NGX_HTTP_LOC_CONF just means "location block in http" if ctx and ctx[0] == 'http' and stmt['directive'] == 'location' return ['http', 'location'] end # no other block contexts can be nested like location so just append it return ctx + [stmt['directive'],] end
register_external_directives(directives)
click to toggle source
# File lib/crossplane/analyzer.rb, line 1956 def register_external_directives(directives) directives.each do |directive, bitmasks| if bitmasks DIRECTIVES[directive] = bitmasks end end end